func (c *APIUnitsCmd) Execute(args []string) error { context, err := prepareCommandContext(c.Args.Dir.String()) if err != nil { return err } var unitSlice []unit.SourceUnit unitSuffix := buildstore.DataTypeSuffix(unit.SourceUnit{}) foundUnit := false w := fs.WalkFS(".", context.commitFS) for w.Step() { unitFile := w.Path() if strings.HasSuffix(unitFile, unitSuffix) { var unit unit.SourceUnit foundUnit = true f, err := context.commitFS.Open(unitFile) if err != nil { return err } defer f.Close() if err := json.NewDecoder(f).Decode(&unit); err != nil { return fmt.Errorf("%s: %s", unitFile, err) } unitSlice = append(unitSlice, unit) } } if foundUnit == false { return errors.New("No source units found. Try running `src config` first.") } return json.NewEncoder(os.Stdout).Encode(unitSlice) }
func getSourceUnits(commitFS rwvfs.WalkableFileSystem, repo *Repo) []string { var unitFiles []string unitSuffix := buildstore.DataTypeSuffix(unit.SourceUnit{}) w := fs.WalkFS(".", commitFS) for w.Step() { if strings.HasSuffix(w.Path(), unitSuffix) { unitFiles = append(unitFiles, w.Path()) } } return unitFiles }
// ReadCached reads a Tree's configuration from all of its source unit // definition files (which may either be in a local VFS rooted at a // .srclib-cache/<COMMITID> dir, or a remote VFS). It does not read // the Srcfile; the Srcfile's directives are already accounted for in // the cached source unit definition files. // // bdfs should be a VFS obtained from a call to // (buildstore.RepoBuildStore).Commit. func ReadCached(bdfs vfs.FileSystem) (*Tree, error) { if _, err := bdfs.Lstat("."); os.IsNotExist(err) { return nil, fmt.Errorf("build cache dir does not exist (did you run `srclib config` to create it)?") } else if err != nil { return nil, err } // Collect all **/*.unit.json files. var unitFiles []string unitSuffix := buildstore.DataTypeSuffix(unit.SourceUnit{}) w := fs.WalkFS(".", rwvfs.Walkable(rwvfs.ReadOnly(bdfs))) for w.Step() { if err := w.Err(); err != nil { return nil, err } if path := w.Path(); strings.HasSuffix(path, unitSuffix) { unitFiles = append(unitFiles, path) } } // Parse units sort.Strings(unitFiles) units := make([]*unit.SourceUnit, len(unitFiles)) par := parallel.NewRun(runtime.GOMAXPROCS(0)) for i_, unitFile_ := range unitFiles { i, unitFile := i_, unitFile_ par.Acquire() go func() { defer par.Release() f, err := bdfs.Open(unitFile) if err != nil { par.Error(err) return } if err := json.NewDecoder(f).Decode(&units[i]); err != nil { f.Close() par.Error(err) return } if err := f.Close(); err != nil { par.Error(err) return } }() } if err := par.Wait(); err != nil { return nil, err } return &Tree{SourceUnits: units}, nil }
func (c *APIDepsCmd) Execute(args []string) error { // HACK(samertm): append a backslash to Dir to assure that it's parsed // as a directory, but Directory should have an unmarshalling // method that does this. context, err := prepareCommandContext(c.Args.Dir.String()) if err != nil { return err } var depSlice []*dep.Resolution // TODO: Make DataTypeSuffix work with type of depSlice depSuffix := buildstore.DataTypeSuffix([]*dep.ResolvedDep{}) depCache := make(map[string]struct{}) foundDepresolve := false w := fs.WalkFS(".", context.commitFS) for w.Step() { depfile := w.Path() if strings.HasSuffix(depfile, depSuffix) { foundDepresolve = true var deps []*dep.Resolution f, err := context.commitFS.Open(depfile) if err != nil { return err } defer f.Close() if err := json.NewDecoder(f).Decode(&deps); err != nil { return fmt.Errorf("%s: %s", depfile, err) } for _, d := range deps { key, err := d.RawKeyId() if err != nil { return err } if _, ok := depCache[key]; !ok { depCache[key] = struct{}{} depSlice = append(depSlice, d) } } } } if foundDepresolve == false { return errors.New("No dependency information found. Try running `src config` first.") } return json.NewEncoder(os.Stdout).Encode(depSlice) }
// getSourceUnitsWithFile gets a list of all source units that contain // the given file. func getSourceUnitsWithFile(buildStore buildstore.RepoBuildStore, repo *Repo, filename string) ([]*unit.SourceUnit, error) { filename = filepath.Clean(filename) // TODO(sqs): This whole lookup is totally inefficient. The storage format // is not optimized for lookups. commitFS := buildStore.Commit(repo.CommitID) unitFiles := getSourceUnits(commitFS, repo) // Find all source unit definition files. unitSuffix := buildstore.DataTypeSuffix(unit.SourceUnit{}) w := fs.WalkFS(".", commitFS) for w.Step() { if strings.HasSuffix(w.Path(), unitSuffix) { unitFiles = append(unitFiles, w.Path()) } } // Find which source units the file belongs to. var units []*unit.SourceUnit for _, unitFile := range unitFiles { var u *unit.SourceUnit f, err := commitFS.Open(unitFile) if err != nil { return nil, err } defer f.Close() if err := json.NewDecoder(f).Decode(&u); err != nil { return nil, fmt.Errorf("%s: %s", unitFile, err) } for _, f2 := range u.Files { if filepath.Clean(f2) == filename { units = append(units, u) break } } } return units, nil }
func RepositoryCommitDataFilename(emptyData interface{}) string { return buildstore.DataTypeSuffix(emptyData) }
func SourceUnitDataFilename(emptyData interface{}, u *unit.SourceUnit) string { if u.Name == "" { return u.Type + "." + buildstore.DataTypeSuffix(emptyData) } return filepath.Join(u.Name, u.Type+"."+buildstore.DataTypeSuffix(emptyData)) }