Esempio n. 1
0
// CreateMakefile creates a Makefile to build a tree. The cwd should
// be the root of the tree you want to make (due to some probably
// unnecessary assumptions that CreateMaker makes).
func CreateMakefile(execOpt ToolchainExecOpt, cacheOpt BuildCacheOpt) (*makex.Makefile, error) {
	localRepo, err := OpenRepo(".")
	if err != nil {
		return nil, err
	}
	buildStore, err := buildstore.LocalRepo(localRepo.RootDir)
	if err != nil {
		return nil, err
	}

	treeConfig, err := config.ReadCached(buildStore.Commit(localRepo.CommitID))
	if err != nil {
		return nil, err
	}
	if len(treeConfig.SourceUnits) == 0 {
		log.Println("No source unit files found. Did you mean to run `src config`? (This is not an error; it just means that src didn't find anything to build or analyze here.)")
	}

	toolchainExecOptArgs, err := flagutil.MarshalArgs(&execOpt)
	if err != nil {
		return nil, err
	}

	// TODO(sqs): buildDataDir is hardcoded.
	buildDataDir := filepath.Join(buildstore.BuildDataDirName, localRepo.CommitID)
	mf, err := plan.CreateMakefile(buildDataDir, buildStore, localRepo.VCSType, treeConfig, plan.Options{
		ToolchainExecOpt: strings.Join(toolchainExecOptArgs, " "),
		NoCache:          cacheOpt.NoCacheWrite,
	})
	if err != nil {
		return nil, err
	}
	return mf, nil
}
Esempio n. 2
0
// prepareCommandContext prepare the context for the the "src"
// command. If file is "." or ends in a "/", then it is a directory. It is safe
// for "file" to have multiple trailing slashes. prepareCommandContext
// creates commandContext, changes the process' working directory to
// file's directory and ensures that a build has been made. It is
// meant to be used by user-facing commands.
func prepareCommandContext(file string) (commandContext, error) {
	var (
		err   error
		c     commandContext
		isDir bool
	)
	if file == "" {
		return commandContext{}, errors.New("prepareCommandContext: file cannot be empty")
	}
	if file == "." || file[len(file)-1] == os.PathSeparator {
		isDir = true
	}
	file, err = filepath.Abs(file)
	if err != nil {
		return commandContext{}, err
	}
	// filepath.Abs returns a cleaned file path, so we need to add
	// the path separator to it to presrve filepath.Dir's
	// semantics.
	if isDir {
		file += string(os.PathSeparator)
	}

	repo, err := OpenRepo(filepath.Dir(file))
	if err != nil {
		return commandContext{}, err
	}
	c.repo = repo

	rel, err := filepath.Rel(repo.RootDir, file)
	if err != nil {
		return commandContext{}, err
	}
	c.relativeFile = rel

	if err := os.Chdir(repo.RootDir); err != nil {
		return commandContext{}, err
	}

	buildStore, err := buildstore.LocalRepo(repo.RootDir)
	if err != nil {
		return commandContext{}, err
	}
	c.buildStore = buildStore
	c.commitFS = buildStore.Commit(repo.CommitID)

	if err := ensureBuild(buildStore, repo); err != nil {
		if err := buildstore.RemoveAllDataForCommit(buildStore, repo.CommitID); err != nil {
			log.Println(err)
		}
		return commandContext{}, err
	}
	return c, nil
}
Esempio n. 3
0
func getLocalBuildDataFS(commitID string) (rwvfs.FileSystem, string, error) {
	lrepo, err := openLocalRepo()
	if lrepo == nil || lrepo.RootDir == "" || commitID == "" {
		return nil, "", err
	}
	localStore, err := buildstore.LocalRepo(lrepo.RootDir)
	if err != nil {
		return nil, "", err
	}
	return localStore.Commit(commitID), fmt.Sprintf("local repository (root dir %s, commit %s)", lrepo.RootDir, commitID), nil
}
Esempio n. 4
0
func (c *ConfigCmd) Execute(args []string) error {
	if c.w == nil {
		c.w = os.Stdout
	}
	if c.Quiet {
		c.w = nopWriteCloser{}
	}

	cfg, err := getInitialConfig(c.Options, c.Args.Dir.String())
	if err != nil {
		return err
	}

	if len(cfg.PreConfigCommands) > 0 {
		if err := runPreConfigCommands(c.Args.Dir.String(), cfg.PreConfigCommands, c.ToolchainExecOpt, c.Quiet); err != nil {
			return fmt.Errorf("PreConfigCommands: %s", err)
		}
	}

	if err := scanUnitsIntoConfig(cfg, c.Options, c.ToolchainExecOpt, c.Quiet); err != nil {
		return fmt.Errorf("failed to scan for source units: %s", err)
	}

	localRepo, err := OpenRepo(c.Args.Dir.String())
	if err != nil {
		return fmt.Errorf("failed to open repo: %s", err)
	}
	buildStore, err := buildstore.LocalRepo(localRepo.RootDir)
	if err != nil {
		return err
	}
	commitFS := buildStore.Commit(localRepo.CommitID)

	// Write source units to build cache.
	if !c.NoCacheWrite {
		if err := rwvfs.MkdirAll(commitFS, "."); err != nil {
			return err
		}
		for _, u := range cfg.SourceUnits {
			unitFile := plan.SourceUnitDataFilename(unit.SourceUnit{}, u)
			if err := rwvfs.MkdirAll(commitFS, filepath.Dir(unitFile)); err != nil {
				return err
			}
			f, err := commitFS.Create(unitFile)
			if err != nil {
				return err
			}
			defer f.Close()
			if err := json.NewEncoder(f).Encode(u); err != nil {
				return err
			}
			if err := f.Close(); err != nil {
				log.Fatal(err)
			}
		}
	}

	if c.Output.Output == "json" {
		PrintJSON(cfg, "")
	} else {
		fmt.Fprintf(c.w, "SCANNERS (%d)\n", len(cfg.Scanners))
		for _, s := range cfg.Scanners {
			fmt.Fprintf(c.w, " - %s\n", s)
		}
		fmt.Fprintln(c.w)

		fmt.Fprintf(c.w, "SOURCE UNITS (%d)\n", len(cfg.SourceUnits))
		for _, u := range cfg.SourceUnits {
			fmt.Fprintf(c.w, " - %s: %s\n", u.Type, u.Name)
		}
		fmt.Fprintln(c.w)

		fmt.Fprintf(c.w, "CONFIG PROPERTIES (%d)\n", len(cfg.Config))
		for _, kv := range sortedMap(cfg.Config) {
			fmt.Fprintf(c.w, " - %s: %s\n", kv[0], kv[1])
		}
	}

	return nil
}