Beispiel #1
0
func TestBug3486(t *testing.T) { // http://code.google.com/p/go/issues/detail?id=3486
	root, err := filepath.EvalSymlinks(runtime.GOROOT())
	if err != nil {
		t.Fatal(err)
	}
	lib := filepath.Join(root, "lib")
	src := filepath.Join(root, "src")
	seenSrc := false
	walker := fs.Walk(root)
	for walker.Step() {
		if walker.Err() != nil {
			t.Fatal(walker.Err())
		}

		switch walker.Path() {
		case lib:
			walker.SkipDir()
		case src:
			seenSrc = true
		}
	}
	if !seenSrc {
		t.Fatalf("%q not seen", src)
	}
}
Beispiel #2
0
func ExampleWalker() {
	walker := fs.Walk("/usr/lib")
	for walker.Step() {
		if err := walker.Err(); err != nil {
			fmt.Fprintln(os.Stderr, err)
			continue
		}
		fmt.Println(walker.Path())
	}
}
Beispiel #3
0
func (c *LintCmd) Execute(args []string) error {
	if len(c.Args.Paths) == 0 {
		c.Args.Paths = []string{"."}
	}

	issuec := make(chan string)
	quitc := make(chan struct{})
	go func() {
		for {
			select {
			case issue := <-issuec:
				fmt.Println(issue)
			case <-quitc:
				return
			}
		}
	}()

	lrepo, lrepoErr := openLocalRepo()
	if lrepoErr != nil {
		log.Printf("warning: while opening current dir's repo: %s", lrepoErr)
	}

	var wg sync.WaitGroup
	for _, path := range c.Args.Paths {
		w := fs.Walk(path)
		for w.Step() {
			if err := w.Err(); err != nil {
				return err
			}
			if fi := w.Stat(); fi.Mode().IsRegular() {
				suffix, typ := buildstore.DataType(fi.Name())
				if suffix != "" {
					absPath, err := filepath.Abs(w.Path())
					if err != nil {
						return err
					}

					var unitType, unitName string
					if !c.NoCheckResolve {
						if !strings.Contains(absPath, buildstore.BuildDataDirName) {
							return fmt.Errorf("couldn't infer which source unit %s corresponds to, because its absolute path is not under any %s dir; either run with --no-check-resolve to skip checking that internal refs resolve to valid defs (which requires knowing what source unit each output file is from), or run 'src lint' against .srclib-cache or subdirectories of it", w.Path(), buildstore.BuildDataDirName)
						}
						unitType = strings.TrimSuffix(fi.Name(), "."+suffix+".json")
						// Infer source unit name from file path (the
						// path components after .srclib-cache until
						// the basename).
						pcs := strings.Split(absPath, string(os.PathSeparator))
						for i, pc := range pcs {
							if pc == buildstore.BuildDataDirName && len(pcs) > i+2 {
								unitName = filepath.Clean(strings.Join(pcs[i+2:len(pcs)-1], "/"))
								break
							}
						}
					}

					var commitID string
					if !c.NoCheckFiles {
						// Infer commit ID from file path (the path component after .srclib-cache).
						pcs := strings.Split(absPath, string(os.PathSeparator))
						for i, pc := range pcs {
							if pc == buildstore.BuildDataDirName && len(pcs) > i+1 {
								commitID = pcs[i+1]
								break
							}
						}
					}
					if commitID == "" && !c.NoCheckFiles {
						return fmt.Errorf("couldn't infer which commit ID %s was built from, which is necessary to check that file/dir fields refer to actual files; either run with --no-check-files to skip the file/dir check or pass paths that contain '.../.srclib-cache/COMMITID/...' (which allows this command to infer the commit ID)", w.Path())
					}

					// Ensure that commitID matches the local repo's commit ID.
					if commitID != "" && !c.NoCheckFiles {
						if lrepo != nil && lrepo.CommitID != commitID {
							return fmt.Errorf("%s was built from commit %s, but the current repo working tree HEAD is commit %s; these must be the same to check that file/dir fields refer to actual files in the repo that their specific commit, so you must either (1) only run lint against build data files for commit %s; (2) run with --no-check-files to skip the file/dir check; or (3) check out commit %s in this repo", w.Path(), commitID, lrepo.CommitID, lrepo.CommitID, commitID)
						}
					}

					checkFilesExist := !c.NoCheckFiles

					wg.Add(1)
					go func(path string) {
						defer wg.Done()

						var issues []string
						var err error
						switch typ.(type) {
						case unit.SourceUnit:
							issues, err = lintSourceUnit(lrepo.RootDir, path, checkFilesExist)
						case *graph.Output:
							issues, err = lintGraphOutput(lrepo.RootDir, c.Repo, unitType, unitName, path, checkFilesExist)
						case []*dep.ResolvedDep:
							issues, err = lintDepresolveOutput(lrepo.RootDir, path, checkFilesExist)
						}
						for _, issue := range prependLabelToStrings(path, issues) {
							issuec <- issue
						}
						if err != nil {
							log.Fatalf(redbg("ERR")+" %s: %s", path, err)
						}
					}(w.Path())
				}
			}
		}
	}

	wg.Wait()
	close(quitc)

	return nil
}
Beispiel #4
0
func TestWalk(t *testing.T) {
	makeTree(t)
	errors := make([]error, 0, 10)
	clear := true
	markFn := func(walker *fs.Walker) (err error) {
		for walker.Step() {
			err = mark(walker.Path(), walker.Stat(), walker.Err(), &errors, clear)
			if err != nil {
				break
			}
		}
		return err
	}
	// Expect no errors.
	err := markFn(fs.Walk(tree.name))
	if err != nil {
		t.Fatalf("no error expected, found: %s", err)
	}
	if len(errors) != 0 {
		t.Fatalf("unexpected errors: %s", errors)
	}
	checkMarks(t, true)
	errors = errors[0:0]

	// Test permission errors.  Only possible if we're not root
	// and only on some file systems (AFS, FAT).  To avoid errors during
	// all.bash on those file systems, skip during go test -short.
	if os.Getuid() > 0 && !testing.Short() {
		// introduce 2 errors: chmod top-level directories to 0
		os.Chmod(filepath.Join(tree.name, tree.entries[1].name), 0)
		os.Chmod(filepath.Join(tree.name, tree.entries[3].name), 0)

		// 3) capture errors, expect two.
		// mark respective subtrees manually
		markTree(tree.entries[1])
		markTree(tree.entries[3])
		// correct double-marking of directory itself
		tree.entries[1].mark--
		tree.entries[3].mark--
		err := markFn(fs.Walk(tree.name))
		if err != nil {
			t.Fatalf("expected no error return from Walk, got %s", err)
		}
		if len(errors) != 2 {
			t.Errorf("expected 2 errors, got %d: %s", len(errors), errors)
		}
		// the inaccessible subtrees were marked manually
		checkMarks(t, true)
		errors = errors[0:0]

		// 4) capture errors, stop after first error.
		// mark respective subtrees manually
		markTree(tree.entries[1])
		markTree(tree.entries[3])
		// correct double-marking of directory itself
		tree.entries[1].mark--
		tree.entries[3].mark--
		clear = false // error will stop processing
		err = markFn(fs.Walk(tree.name))
		if err == nil {
			t.Fatalf("expected error return from Walk")
		}
		if len(errors) != 1 {
			t.Errorf("expected 1 error, got %d: %s", len(errors), errors)
		}
		// the inaccessible subtrees were marked manually
		checkMarks(t, false)
		errors = errors[0:0]

		// restore permissions
		os.Chmod(filepath.Join(tree.name, tree.entries[1].name), 0770)
		os.Chmod(filepath.Join(tree.name, tree.entries[3].name), 0770)
	}

	// cleanup
	if err := os.RemoveAll(tree.name); err != nil {
		t.Errorf("removeTree: %v", err)
	}
}
Beispiel #5
0
// List finds all toolchains in the SRCLIBPATH.
//
// List does not find nested toolchains; i.e., if DIR is a toolchain
// dir (with a DIR/Srclibtoolchain file), then none of DIR's
// subdirectories are searched for toolchains.
func List() ([]*Info, error) {
	if noToolchains {
		return nil, nil
	}

	var found []*Info
	seen := map[string]string{}

	dirs := strings.Split(srclib.Path, ":")

	// maps symlinked trees to their original path
	origDirs := map[string]string{}

	for i := 0; i < len(dirs); i++ {
		dir := dirs[i]
		if dir == "" {
			dir = "."
		}
		w := fs.Walk(dir)
		for w.Step() {
			if w.Err() != nil {
				return nil, w.Err()
			}
			fi := w.Stat()
			name := fi.Name()
			path := w.Path()
			if path != dir && (name[0] == '.' || name[0] == '_') {
				w.SkipDir()
			} else if fi.Mode()&os.ModeSymlink != 0 {
				// Check if symlink points to a directory.
				if sfi, err := os.Stat(path); err == nil {
					if !sfi.IsDir() {
						continue
					}
				} else if os.IsNotExist(err) {
					continue
				} else {
					return nil, err
				}

				// traverse symlinks but refer to symlinked trees' toolchains using
				// the path to them through the original entry in SRCLIBPATH
				dirs = append(dirs, path+"/")
				origDirs[path+"/"] = dir
			} else if fi.Mode().IsDir() {
				// Check for Srclibtoolchain file in this dir.
				if _, err := os.Stat(filepath.Join(path, ConfigFilename)); os.IsNotExist(err) {
					continue
				} else if err != nil {
					return nil, err
				}

				// Found a Srclibtoolchain file.
				path = filepath.Clean(path)

				var base string
				if orig, present := origDirs[dir]; present {
					base = orig
				} else {
					base = dir
				}

				toolchainPath, _ := filepath.Rel(base, path)

				if otherDir, seen := seen[toolchainPath]; seen {
					return nil, fmt.Errorf("saw 2 toolchains at path %s in dirs %s and %s", toolchainPath, otherDir, path)
				}
				seen[toolchainPath] = path

				info, err := newInfo(toolchainPath, path, ConfigFilename)
				if err != nil {
					return nil, err
				}
				found = append(found, info)

				// Disallow nested toolchains to speed up List. This
				// means that if DIR/Srclibtoolchain exists, no other
				// Srclibtoolchain files underneath DIR will be read.
				w.SkipDir()
			}
		}
	}
	return found, nil
}