diff --git a/new.go b/new.go index 56efc07..fc7a6b1 100644 --- a/new.go +++ b/new.go @@ -2,6 +2,8 @@ package repostatus import ( "errors" + "io/ioutil" + "net/http" "os" "path/filepath" "strings" @@ -103,19 +105,87 @@ func guessPaths(path string) (string, string, string, bool, error) { } // attempt to git clone if the go path doesn't exist -func clone(wdir string, path string) { +func clone(wdir string, path string) error { fullpath := filepath.Join(wdir, path) if IsDirectory(fullpath) { - return + // directory already exists + return nil } err := os.Chdir(wdir) if err != nil { - return + return err } base := filepath.Join(wdir, filepath.Dir(path)) os.MkdirAll(base, 0750) + err = os.Chdir(base) + if err != nil { + return err + } shell.RunPath(base, []string{"git", "clone", "http://" + path}) + if IsDirectory(fullpath) { + // clone worked + return nil + } + var url string + if url, err = findGoImport("http://" + path); err != nil { + return err + } + log.Info("URL:", url) + shell.RunPath(base, []string{"git", "clone", url}) + if IsDirectory(fullpath) { + // clone worked + return nil + } + return errors.New("resolve go import") +} + +// this is a terrible hack and really +// shouldn't be here. Hopefully this can +// be removed and the GO compiler code can +// be involked directly (it appears to currently +// be an internal/ function in the GO sources +// so it can't be imported from outside the compiler +func findGoImport(url string) (string, error) { + resp, err := http.Get(url) + if err != nil { + return "", err + } + defer resp.Body.Close() + + bodyBytes, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + + tmp := string(bodyBytes) + parts := strings.Split(tmp, "go-import") + if len(parts) < 2 { + return "", errors.New("missing go-import") + } + // this is terrible, it doesn't even look for 'content=' + // but again, this is just a hack for my own code to be + // usuable after the removal in go v1.22 of the go get clone behavior that was in v1.21 + parts = strings.Split(parts[1], "\"") + var newurl string + for { + if len(parts) == 0 { + break + } + tmp := strings.TrimSpace(parts[0]) + fields := strings.Split(tmp, " ") + log.Info("FIELDS:", fields) + if len(fields) == 3 { + newurl = fields[2] + break + } + parts = parts[1:] + } + if newurl == "" { + return "", errors.New("missing git content string") + } + + return newurl, nil } func NewRepoStatusWindow(path string) (error, *RepoStatus) {