Ejemplo n.º 1
0
func downloadDependency(dep vendor.Dependency, errors *uint32, vendorDir string, recursive bool) error {
	extraMsg := ""
	if !dep.NoTests {
		extraMsg = "(including tests)"
	}
	if dep.AllFiles {
		extraMsg = "(without file exclusions)"
	}
	if recursive {
		log.Printf("fetching recursive %s %s", dep.Importpath, extraMsg)
	} else {
		log.Printf("fetching %s %s", dep.Importpath, extraMsg)
	}

	repo, err := vendor.NewRemoteRepo(dep.Repository, dep.VCS, rbInsecure)
	if err != nil {
		return fmt.Errorf("dependency could not be processed: %s", err)
	}
	// We can't pass the branch here, and benefit from narrow clones, as the
	// revision might not be in the branch tree anymore. Thanks rebase.
	wc, err := GlobalDownloader.Get(repo, "", "", dep.Revision)
	if err != nil {
		return fmt.Errorf("dependency could not be fetched: %s", err)
	}
	dst := filepath.Join(vendorDir, dep.Importpath)
	src := filepath.Join(wc.Dir(), dep.Path)

	if _, err := os.Stat(dst); err == nil {
		if err := fileutils.RemoveAll(dst); err != nil {
			return fmt.Errorf("dependency could not be deleted: %v", err)
		}
	}

	if err := fileutils.Copypath(dst, src, !dep.NoTests, dep.AllFiles); err != nil {
		return err
	}

	if err := fileutils.CopyLicense(dst, wc.Dir()); err != nil {
		return err
	}

	// Check for for manifests in dependencies
	man := filepath.Join(dst, "vendor", "manifest")
	venDir := filepath.Join(dst, "vendor")
	if _, err := os.Stat(man); err == nil {
		m, err := vendor.ReadManifest(man)
		if err != nil {
			return fmt.Errorf("could not load manifest: %v", err)
		}
		for _, d := range m.Dependencies {
			if err := downloadDependency(d, errors, venDir, true); err != nil {
				log.Printf("%s: %v", d.Importpath, err)
				atomic.AddUint32(errors, 1)
			}
		}
	}

	return nil
}
Ejemplo n.º 2
0
func fetchRecursive(m *vendor.Manifest, fullPath string, level int) error {
	path := stripscheme(fullPath)

	// Don't even bother the user about skipping packages we just fetched
	for _, p := range fetchedToday {
		if contains(p, path) {
			return nil
		}
	}

	// First, check if this or a parent is already vendored
	if m.HasImportpath(path) {
		if level == 0 {
			return fmt.Errorf("%s or a parent of it is already vendored", path)
		} else {
			// TODO: print a different message for packages fetched during this session
			logIndent(level, "Skipping (existing):", path)
			return nil
		}
	}

	// Next, check if we are trying to vendor from the same repository we are in
	if importPath != "" && contains(importPath, path) {
		if level == 0 {
			return fmt.Errorf("refusing to vendor a subpackage of \".\"")
		} else {
			logIndent(level, "Skipping (subpackage of \".\"):", path)
			return nil
		}
	}

	if level == 0 {
		log.Println("Fetching:", path)
	} else {
		logIndent(level, "Fetching recursive dependency:", path)
	}

	// Finally, check if we already vendored a subpackage and remove it
	for _, subp := range m.GetSubpackages(path) {
		if !contains(subp.Importpath, fetchRoot) { // ignore parents of the root
			ignore := false
			for _, d := range fetchedToday {
				if contains(d, subp.Importpath) {
					ignore = true // No need to warn the user if we just downloaded it
				}
			}
			if !ignore {
				logIndent(level, "Deleting existing subpackage to prevent overlap:", subp.Importpath)
			}
		}
		if err := m.RemoveDependency(subp); err != nil {
			return fmt.Errorf("failed to remove subpackage: %v", err)
		}
	}
	if err := fileutils.RemoveAll(filepath.Join(vendorDir, path)); err != nil && !os.IsNotExist(err) {
		return fmt.Errorf("failed to remove existing folder: %v", err)
	}

	// Find and download the repository

	repo, extra, err := GlobalDownloader.DeduceRemoteRepo(fullPath, insecure)
	if err != nil {
		return err
	}

	if level == 0 {
		rootRepoURL = repo.URL()
	}

	var wc vendor.WorkingCopy
	if repo.URL() == rootRepoURL {
		wc, err = GlobalDownloader.Get(repo, branch, tag, revision)
	} else {
		wc, err = GlobalDownloader.Get(repo, "", "", "")
	}
	if err != nil {
		return err
	}

	// Add the dependency to the manifest

	rev, err := wc.Revision()
	if err != nil {
		return err
	}

	b, err := wc.Branch()
	if err != nil {
		return err
	}

	dep := vendor.Dependency{
		Importpath: path,
		Repository: repo.URL(),
		VCS:        repo.Type(),
		Revision:   rev,
		Branch:     b,
		Path:       extra,
		NoTests:    !tests,
		AllFiles:   all,
	}

	if err := m.AddDependency(dep); err != nil {
		return err
	}

	// Copy the code to the vendor folder

	dst := filepath.Join(vendorDir, dep.Importpath)
	src := filepath.Join(wc.Dir(), dep.Path)

	if err := fileutils.Copypath(dst, src, !dep.NoTests, dep.AllFiles); err != nil {
		return err
	}

	if err := fileutils.CopyLicense(dst, wc.Dir()); err != nil {
		return err
	}

	if err := vendor.WriteManifest(manifestFile, m); err != nil {
		return err
	}

	// Recurse

	fetchedToday = append(fetchedToday, path)

	if !noRecurse {
		// Look for dependencies in src, not going past wc.Dir() when looking for /vendor/,
		// knowing that wc.Dir() corresponds to rootRepoPath
		if !strings.HasSuffix(dep.Importpath, dep.Path) {
			return fmt.Errorf("unable to derive the root repo import path")
		}
		rootRepoPath := strings.TrimRight(strings.TrimSuffix(dep.Importpath, dep.Path), "/")
		deps, err := vendor.ParseImports(src, wc.Dir(), rootRepoPath, tests, all)
		if err != nil {
			return fmt.Errorf("failed to parse imports: %s", err)
		}

		for d := range deps {
			if strings.Index(d, ".") == -1 { // TODO: replace this silly heuristic
				continue
			}
			if err := fetchRecursive(m, d, level+1); err != nil {
				if strings.HasPrefix(err.Error(), "error fetching") { // I know, ok?
					return err
				} else {
					return fmt.Errorf("error fetching %s: %s", d, err)
				}
			}
		}
	}

	return nil
}
Ejemplo n.º 3
0
				AllFiles:   d.AllFiles,
			}

			if err := fileutils.RemoveAll(filepath.Join(vendorDir, filepath.FromSlash(d.Importpath))); err != nil {
				// TODO(dfc) need to apply vendor.cleanpath here to remove intermediate directories.
				return fmt.Errorf("dependency could not be deleted: %v", err)
			}

			dst := filepath.Join(vendorDir, filepath.FromSlash(dep.Importpath))
			src := filepath.Join(wc.Dir(), dep.Path)

			if err := fileutils.Copypath(dst, src, !d.NoTests, d.AllFiles); err != nil {
				return err
			}

			if err := fileutils.CopyLicense(dst, wc.Dir()); err != nil {
				return err
			}

			if err := m.AddDependency(dep); err != nil {
				return err
			}

			if err := vendor.WriteManifest(manifestFile, m); err != nil {
				return err
			}
		}

		return nil
	},
	AddFlags: addUpdateFlags,