How to resolve commit into branches? - go-git

I need to find all branches (tags) with a commit. On CLI using git command it's possible by using git branch --contains <commit> command.
How do to something like that using go-git library?

I tried to make a solution and got this:
func FindBranchesByCoommit(r *git.Repository, c *object.Commit) (branches []*plumbing.Reference, err error) {
brIt, err := r.Branches()
if err != nil {
return
}
defer brIt.Close()
if err := brIt.ForEach(func(ref *plumbing.Reference) error {
com, err := r.CommitObject(ref.Hash())
if err != nil {
return err
}
comIt, err := r.Log(&git.LogOptions{From: com.Hash})
if err != nil {
return err
}
defer comIt.Close()
for {
if com, err := comIt.Next(); err == nil {
if c.Hash == com.Hash {
branches = append(branches, ref)
break
}
} else if err == io.EOF {
break
} else {
return err
}
}
return nil
}); err != nil {
return nil, err
}
return
}

Related

How i can fetch all data by latitude and longitude from wigle api

I wrote simple script to receive all data from wigle api using wigleapiv2, definitely this endpoint /api/v2/network/search. But I faced the problem, that I can receive only 1000 unique ssid's. I'm changing URL every iteration, and put in URL previous page's searchAfter. How can I fix it and receive all data from certain latitude and longitude?
Here an example of first iteration Uri (https://api.wigle.net/api/v2/network/search?closestLat=12.9&closestLong=1.2&latrange1=1.9&latrange2=1.8&longrange1=1.2&longrange2=1.4)
And here an example of remaining iterations uris (https://api.wigle.net/api/v2/network/search?closestLat=12.9&closestLong=1.2&latrange1=1.9&latrange2=1.8&longrange1=1.2&longrange2=1.4&searchAfter=1976621348&first=1). For every iteration I'm changing searchAfter and first.
It would be great id someone can say me where I'm doing wrong:)
I've tried to using only first or search after parameters, but it has the same result. One mark that I noticed, that when I'm using only searchAfter param I can receive only 100 unique ssids, but when I'm using both (searchAfter and first) I can receive 1000 unique ssids.
Here my main.go code
var (
wg = sync.WaitGroup{}
receiveResp = make(chan []*response.WiFiNetworkWithLocation, 100)
)
func main() {
startTime := time.Now()
viper.AddConfigPath(".")
viper.SetConfigFile("config.json")
if err := viper.ReadInConfig(); err != nil {
log.Fatal("error trying read from config: %w", err)
}
u := user.NewUser(viper.GetString("users.user.username"), viper.GetString("users.user.password"))
db, err := postgres.NewPG()
if err != nil {
log.Fatalf("Cannot create postgres connection: %v", err)
}
postgres.WG.Add(1)
go getResponse(u)
go parseResponse(db)
postgres.WG.Wait()
fmt.Printf("Execution time: %v ", time.Since(startTime))
}
func getResponse(u *user.Creds) {
url := fmt.Sprintf("%s? closestLat=%s&closestLong=%s&latrange1=%s&latrange2=%s&longrange1=%s&longrange2=%s",
viper.GetString("wigle.url"),
viper.GetString("queries.closestLat"),
viper.GetString("queries.closestLong"),
viper.GetString("queries.latrange1"),
viper.GetString("queries.latrange2"),
viper.GetString("queries.longrange1"),
viper.GetString("queries.longrange2"),
)
j := 0
i := 0
for {
i++
fmt.Println(url)
req, err := http.NewRequest("GET", url, bytes.NewBuffer([]byte("")))
if err != nil {
log.Printf("Failed wraps request: %v", err)
continue
}
req.SetBasicAuth(u.Username, u.Password)
c := http.Client{}
resp, err := c.Do(req)
if err != nil {
log.Printf("Failed send request: %v", err)
continue
}
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Printf("Failed read response body: %v", err)
continue
}
var r response.NetSearchResponse
if err := json.Unmarshal(bytes, &r); err != nil {
log.Printf("Failed unmarshal: %v", err)
continue
}
receiveResp <- r.Results
fmt.Println(r.TotalResults, r.SearchAfter)
if r.SearchAfter == "" {
postgres.WG.Done()
return
}
url = fmt.Sprintf("%s? closestLat=%s&closestLong=%s&latrange1=%s&latrange2=%s&longrange1=%s&longrange2=%s&searchAfter=%s&first=%v" ,
viper.GetString("wigle.url"),
viper.GetString("queries.closestLat"),
viper.GetString("queries.closestLong"),
viper.GetString("queries.latrange1"),
viper.GetString("queries.latrange2"),
viper.GetString("queries.longrange1"),
viper.GetString("queries.longrange2"),
r.SearchAfter,
i,
)
j++
fmt.Println(j)
}
func parseResponse(db *sql.DB) {
for {
select {
case responses := <-receiveResp:
clearResponses := make([]response.WiFiNetworkWithLocation, 0, len(responses))
for _, val := range responses {
clearResponses = append(clearResponses, *val)
}
postgres.WG.Add(1)
go postgres.SaveToDB(db, "test", clearResponses)
}
}
}

Unable to execute a command inside a docker container

I am trying to spin up a Postgres container via the Docker Go SDK. I can get the container started, and I copy my SQL file into the container and verified the file is there.
I cannot run this file, which right now just contains CREATE TABLE tester;
Here is my Go code that I am trying to use:
package gosqlcontainer
import (
"archive/tar"
"bufio"
"bytes"
"context"
"fmt"
"io"
"log"
"os"
"os/exec"
"time"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
)
func StartContainer() string {
ctx := context.Background()
cli, err := client.NewClientWithOpts(client.WithAPIVersionNegotiation())
if err != nil {
panic(err)
}
imageName := "postgres"
out, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{})
if err != nil {
panic(err)
}
defer out.Close()
io.Copy(os.Stdout, out)
container, err := cli.ContainerCreate(ctx, &container.Config{
Image: imageName, Env: []string{"POSTGRES_PASSWORD=password"},
}, nil, nil, nil, "")
if err != nil {
panic(err)
}
if err := cli.ContainerStart(ctx, container.ID, types.ContainerStartOptions{}); err != nil {
panic(err)
}
tarFile := TarFile("test.sql")
if err = cli.CopyToContainer(ctx, container.ID, "/home/", tarFile, types.CopyToContainerOptions{AllowOverwriteDirWithFile: true}); err != nil {
fmt.Println("error copying to container", err)
}
time.Sleep(1 * time.Second)
execCommand, err := cli.ContainerExecCreate(ctx, container.ID, types.ExecConfig{AttachStdin: true, AttachStderr: true, AttachStdout: true, Cmd: []string{"psql", "-U postgres -f /home/test.sql"}})
if err != nil {
fmt.Println("exec err is", err)
}
if err := cli.ContainerExecStart(ctx, execCommand.ID, types.ExecStartCheck{}); err != nil {
fmt.Println("Err Start", err)
}
return container.ID
}
When I try to do this from CLI, I can run that file and verify that the DB is created. However, programmatically it does not work, and I do not see any errors returned.
The goal is for this to be a library I can reference to spin up a container, import data, and used for integration tests. I am currently calling it from a basic client locally, using go run main.go I am working on macOS Monterey v12.4

400 Bad Request for frappe.cloud API

I'm getting 400 Bad Request for frappe.cloud API, when I'm trying to call it using golang code using http.NewRequest, this API is working fine when I check it using postman. following is the API
https://xxxx.frappe.cloud/api/resource/Item?fields=["name","item_name","item_group","description"]&filters=[["Item","item_group","=","xxx Product"]]
If I use the same golang code to call same API with out filters it works fine. following is the working API
https://xxxx.frappe.cloud/api/resource/Item?fields=["name","item_name","item_group","description"]
code as follows
func FetchProperties(dataChannel models.DataChannel) (map[string]interface{}, error) {
thisMap := make(map[string][]map[string]interface{})
client := &http.Client{}
req, err := http.NewRequest("GET", dataChannel.APIPath, nil)
if err != nil {
commons.ErrorLogger.Println(err.Error())
return nil, err
}
eds, err := GetDecryptedEDSByEDSID(dataChannel.EDSId)
if err != nil {
commons.ErrorLogger.Println(err.Error())
return nil, &commons.RequestError{StatusCode: 400, Err: err}
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", eds.DataSource.Auth.Token)
response, err := client.Do(req)
if err != nil {
commons.ErrorLogger.Println(err.Error())
return nil, err
}
data, err := ioutil.ReadAll(response.Body)
if err != nil {
commons.ErrorLogger.Println(err.Error())
return nil, &commons.RequestError{StatusCode: 400, Err: err}
}
if response.StatusCode == 200 {
err = json.Unmarshal(data, &thisMap)
if err != nil {
commons.ErrorLogger.Println(err.Error())
return nil, &commons.RequestError{StatusCode: 400, Err: err}
}
return thisMap["data"][0], err
} else {
return nil, &commons.RequestError{StatusCode: response.StatusCode, Err: errors.New("getting " + strconv.Itoa(response.StatusCode) + " From Data channel API")}
}
Postman has an option to convert request to programming language equivalent.
Here is a working go code for sending the request. package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://xxx.frappe.cloud/api/resource/Item?fields=%5B%22name%22,%22item_name%22,%22item_group%22,%22description%22%5D&filters=%5B%5B%22Item%22,%22item_group%22,%22=%22,%22xxx%20Product%22%5D%5D%0A"
method := "GET"
payload := strings.NewReader(`{
"payload": {},
"url_key": "",
"req_type": ""
}`)
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Cookie", "full_name=foo; sid=secret_sid; system_user=yes; user_id=foobar; user_image=")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}

GO: Confluence API not getting all the attachments

i am using golang for my application and in this application i tried getting attachments from Confluence, following are detail
req:="https://domain.atlassian.net/wiki/rest/api/content?expand=body.view,version&type=page&start=0&limit="
res, err := w.sendRequest(req)
if err != nil {
return nil, err
}
if strings.EqualFold(contentID, "") == false {
if len(res.Results) != 0 {
for i, _ := range res.Results {
Log.Info("files processed is:", i)
extension := filepath.Ext(res.Results[i].Title)
isExtenstionExclude := isExcludedExtenstion(sbConfig, extension)
ispathExclude := isExcludedFolder(sbConfig, res.Results[i].Links.Webui)
if sbgoclient.ExtesionMap[extension] == 0 || isExtenstionExclude == true || ispathExclude == true {
binarycount++
Log.Info("Excluded by extension" + extension + " for file" + res.Results[i].Title)
} else {
md5HashInBytes := md5.Sum([]byte(res.Results[i].Title))
md5HashInString := hex.EncodeToString(md5HashInBytes[:])
file_path := parameter[0] + "/" + md5HashInString + strings.Replace(res.Results[i].Title, " ", "", -1)
file, err := os.Create(file_path)
if err != nil {
fmt.Println(err)
panic(err)
}
url_1 := sbConfig.ConfluenceUrl + res.Results[i].Links.Download
req, err := http.NewRequest("GET", url_1, nil)
resp, _ := w.client.Do(req) // add a filter to check redirect
if err != nil {
fmt.Println(err)
panic(err)
}
// Close body on function exit
defer resp.Body.Close()
fmt.Println(resp.Status)
size, err = io.Copy(file, resp.Body)
if err != nil {
panic(err)
}
defer file.Close()
fmt.Printf("%s with %v bytes downloaded", res.Results[i].Title, size)
meta := map[string]string{
"size": strconv.FormatInt(size, 10),
}
}
}
}
} else {
if len(res.Results) != 0 {
for i, _ := range res.Results {
Log.Info("page indexing is", res.Results[i].Title, "and i value is:", i)
fmt.Println("hmtl content is", res.Results[i].Body.View.Value)
fmt.Println("page name is:", res.Results[i].Title)
md5HashInBytes := md5.Sum([]byte(res.Results[i].Title))
md5HashInString := hex.EncodeToString(md5HashInBytes[:])
file_path := parameter[0] + "/" + md5HashInString + strings.Replace(res.Results[i].Title, " ", "", -1) + ".html"
file, err := os.Create(file_path)
if err != nil {
fmt.Println(err)
panic(err)
}
defer file.Close()
html_content := "<html><body>" + res.Results[i].Body.View.Value + "</body></html>"
err = ioutil.WriteFile(file.Name(), []byte(html_content), 0777)
if err != nil {
fmt.Println("error writing into file", err)
panic(err)
}
file.Close()
}
func (w *Wiki) sendRequest(req *http.Request) (*vijay_content, error) {
var testjson vijay_content
req.Header.Add("Accept", "application/json, */*")
w.authMethod.auth(req)
resp, err := w.client.Do(req)
if err != nil {
return nil, err
}
bodyBytes, _ := ioutil.ReadAll(resp.Body)
body := string(bodyBytes)
fmt.Printf("response is %s\n", body)
err = json.Unmarshal(bodyBytes, &testjson)
if err != nil {
fmt.Println("error here is", err)
return nil, err
}
switch resp.StatusCode {
case http.StatusOK, http.StatusCreated, http.StatusPartialContent:
return &testjson, nil
case http.StatusNoContent, http.StatusResetContent:
return nil, nil
case http.StatusUnauthorized:
return nil, fmt.Errorf("Authentication failed.")
case http.StatusServiceUnavailable:
return nil, fmt.Errorf("Service is not available (%s).", resp.Status)
case http.StatusInternalServerError:
return nil, fmt.Errorf("Internal server error: %s", resp.Status)
}
return nil, fmt.Errorf("Unknown response status %s", resp.Status)
}
and here in this confluence domain actually i have more than 1000 documents but i am able to download only around 80 to 90, i don't know whats happening here please suggest any changes to be done
and following is the struct used to get values from response json
type Links struct {
Download string `json:"download,omitempty"`
Self string `json:"self,omitempty"`
Webui string `json:"webui,omitempty"`
}
type View_struct struct {
Value string `json:",innerxml"`
}
type Body_struct struct {
View View_struct `json:"view,omitempty"`
}
type Vijay_Results struct {
ID string `json:"id,omitempty"`
Links Links `json:"_links,omitempty"`
Title string `json:"title,omitempty"`
Body Body_struct `json:"body,omitempty"`
}
type vijay_content struct {
Results []Vijay_Results `json:"results,omitempty"`
Start int `json:"start,omitempty"`
Limit int `json:"limit,omitempty"`
Size int `json:"size,omitempty"`
}
The API paginates the results. You should fetch the whole list in multiple requests by specifying start and limit.
E.g. request the list of first 30 documents with start=0&limit=30, then the next 30 with start=30&limit=30, and so on, until you get a response with empty list.
You can read more details in the docs on pagination.

GO - Unknown error on executing a command via ssh connection

I'm trying to execute a command via session.Run() function over a ssh connection. So far I can successfully execute some commands but on others I keep getting the following error: "Process exited with: 1. Reason was: () exit status 1"
func (p *project) connect(config *ssh.ClientConfig) {
log.Printf("Trying connection...\n")
conn, err := ssh.Dial("tcp", fmt.Sprintf("%s:%s", p.hostname.name, p.port.name), config)
checkError("Failed to dial: ", err)
log.Printf("Connection established.\n")
for step := range p.typ.program.setup {
p.install(step, conn)
}
}
func (p *project) install(step int, conn *ssh.Client) {
session, err := conn.NewSession()
checkError("Failed to build session: ", err)
defer session.Close()
var stdoutBuf bytes.Buffer
session.Stdout = &stdoutBuf
log.Printf("Executing command: %s", p.typ.program.setup[step])
if err := session.Run(p.typ.program.setup[step]); err != nil {
log.Println(session.Stdout)
log.Fatal("Error on command execution", err.Error())
}
}
// That would be an example of a command which returns me an error
// "cd ~/www/www/ && git commit -m 'on the beginning was the commit'"
// That comes inside a slice on p.typ.program.setup accessed by the step(index).
The command output (session.Stdout) is the one i expect:
"# On branch master nothing to commit, working directory clean"
And just to note I already tried to execute the command directly on the console and it works just fine.
So, the code seems to be okay, the command ran on the remote but I still have an error no matter what.
Does anyone have a clue about why is that happening?
Thanks in advance.
Maybe my library will helps in your case: https://github.com/shagabutdinov/shell; it covers basic cases of running ssh commands in one session.
Try following:
handler := func(outputType int, message string) {
if(outputType == shell.Stdout) {
log.Println("stdout: ", message)
} else if(outputType == shell.Stdout) {
log.Println("stderr: ", message)
}
}
key, err := ssh.ParsePrivateKey([]byte(YOUR_PRIVATE_KEY))
if(err != nil) {
panic(err)
}
auth := []ssh.AuthMethod{ssh.PublicKeys(key)}
shell = shell.NewRemote(shell.RemoteConfig{
Host: "root#example.com:22",
Auth: auth,
})
if(err != nil) {
panic(err)
}
status, err := shell.Run("cd ~/www/www/", handler)
if(err != nil) {
panic(err)
}
status, err := shell.Run("git commit -m 'on the beginning was the commit'", handler)
if(err != nil) {
panic(err)
}
if(status == 0) {
console.log("command executed successfully")
} else {
console.log("command execution failed")
}