// Detect turns a source string into another source string if it is // detected to be of a known pattern. // // This is safe to be called with an already valid source string: Detect // will just return it. func Detect(src string, pwd string) (string, error) { getForce, getSrc := getForcedGetter(src) // Separate out the subdir if there is one, we don't pass that to detect getSrc, subDir := getDirSubdir(getSrc) u, err := url.Parse(getSrc) if err == nil && u.Scheme != "" { // Valid URL return src, nil } for _, d := range Detectors { result, ok, err := d.Detect(getSrc, pwd) if err != nil { return "", err } if !ok { continue } var detectForce string detectForce, result = getForcedGetter(result) result, detectSubdir := getDirSubdir(result) // If we have a subdir from the detection, then prepend it to our // requested subdir. if detectSubdir != "" { if subDir != "" { subDir = filepath.Join(detectSubdir, subDir) } else { subDir = detectSubdir } } if subDir != "" { u, err := url.Parse(result) if err != nil { return "", fmt.Errorf("Error parsing URL: %s", err) } u.Path += "//" + subDir result = u.String() } // Preserve the forced getter if it exists. We try to use the // original set force first, followed by any force set by the // detector. if getForce != "" { result = fmt.Sprintf("%s::%s", getForce, result) } else if detectForce != "" { result = fmt.Sprintf("%s::%s", detectForce, result) } return result, nil } return "", fmt.Errorf("invalid source string: %s", src) }
// GetFile for Hg doesn't support updating at this time. It will download // the file every time. func (g *HgGetter) GetFile(dst string, u *url.URL) error { td, err := ioutil.TempDir("", "getter-hg") if err != nil { return err } if err := os.RemoveAll(td); err != nil { return err } // Get the filename, and strip the filename from the URL so we can // just get the repository directly. filename := filepath.Base(u.Path) u.Path = filepath.Dir(u.Path) // Get the full repository if err := g.Get(td, u); err != nil { return err } // Copy the single file u, err = urlhelper.Parse(fmtFileURL(filepath.Join(td, filename))) if err != nil { return err } fg := &FileGetter{Copy: true} return fg.GetFile(dst, u) }
func testModuleURL(n string) *url.URL { u, err := urlhelper.Parse(testModule(n)) if err != nil { panic(err) } return u }
func testURL(s string) *url.URL { u, err := urlhelper.Parse(s) if err != nil { panic(err) } return u }
// Get downloads the module specified by src into the folder specified by // dst. If dst already exists, Get will attempt to update it. // // src is a URL, whereas dst is always just a file path to a folder. This // folder doesn't need to exist. It will be created if it doesn't exist. func Get(dst, src string) error { var force string force, src = getForcedGetter(src) // If there is a subdir component, then we download the root separately // and then copy over the proper subdir. var realDst string src, subDir := getDirSubdir(src) if subDir != "" { tmpDir, err := ioutil.TempDir("", "tf") if err != nil { return err } if err := os.RemoveAll(tmpDir); err != nil { return err } defer os.RemoveAll(tmpDir) realDst = dst dst = tmpDir } u, err := urlhelper.Parse(src) if err != nil { return err } if force == "" { force = u.Scheme } g, ok := Getters[force] if !ok { return fmt.Errorf( "module download not supported for scheme '%s'", force) } err = g.Get(dst, u) if err != nil { err = fmt.Errorf("error downloading module '%s': %s", src, err) return err } // If we have a subdir, copy that over if subDir != "" { if err := os.RemoveAll(realDst); err != nil { return err } if err := os.MkdirAll(realDst, 0755); err != nil { return err } return copyDir(realDst, filepath.Join(dst, subDir)) } return nil }
func (g *HgGetter) Get(dst string, u *url.URL) error { if _, err := exec.LookPath("hg"); err != nil { return fmt.Errorf("hg must be available and on the PATH") } newURL, err := urlhelper.Parse(u.String()) if err != nil { return err } if fixWindowsDrivePath(newURL) { // See valid file path form on http://www.selenic.com/hg/help/urls newURL.Path = fmt.Sprintf("/%s", newURL.Path) } // Extract some query parameters we use var rev string q := newURL.Query() if len(q) > 0 { rev = q.Get("rev") q.Del("rev") newURL.RawQuery = q.Encode() } _, err = os.Stat(dst) if err != nil && !os.IsNotExist(err) { return err } if err != nil { if err := g.clone(dst, newURL); err != nil { return err } } if err := g.pull(dst, newURL); err != nil { return err } return g.update(dst, newURL, rev) }
// Get downloads the configured source to the destination. func (c *Client) Get() error { force, src := getForcedGetter(c.Src) // If there is a subdir component, then we download the root separately // and then copy over the proper subdir. var realDst string dst := c.Dst src, subDir := getDirSubdir(src) if subDir != "" { tmpDir, err := ioutil.TempDir("", "tf") if err != nil { return err } if err := os.RemoveAll(tmpDir); err != nil { return err } defer os.RemoveAll(tmpDir) realDst = dst dst = tmpDir } u, err := urlhelper.Parse(src) if err != nil { return err } if force == "" { force = u.Scheme } g, ok := c.Getters[force] if !ok { return fmt.Errorf( "download not supported for scheme '%s'", force) } // If we're not downloading a directory, then just download the file // and return. if !c.Dir { return g.GetFile(dst, u) } // We're downloading a directory, which might require a bit more work // if we're specifying a subdir. err = g.Get(dst, u) if err != nil { err = fmt.Errorf("error downloading '%s': %s", src, err) return err } // If we have a subdir, copy that over if subDir != "" { if err := os.RemoveAll(realDst); err != nil { return err } if err := os.MkdirAll(realDst, 0755); err != nil { return err } return copyDir(realDst, filepath.Join(dst, subDir), false) } return nil }