diff options
author | Colin Cross <ccross@google.com> | 2015-01-23 13:38:48 -0800 |
---|---|---|
committer | Colin Cross <ccross@google.com> | 2015-01-23 14:23:27 -0800 |
commit | 3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2 (patch) | |
tree | 2599d6ac3c3810a41a87a709a004fc1fab4a7b74 /bootstrap/cleanup.go | |
parent | 6bb4af9e208ea9769ae52933e8d9f42a4e75938e (diff) | |
download | android_build_blueprint-3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2.tar.gz android_build_blueprint-3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2.tar.bz2 android_build_blueprint-3e8e74f276eafaf709e8e4c4291431a1d4ccb7e2.zip |
Move blueprint/* up a directory
Make integrating with go tools easier by putting the blueprint package
files in the top level directory of the git project instead of in a
subdirectory called blueprint.
Change-Id: I35c144c5fe7ddf34e478d0c47c50b2f6c92c2a03
Diffstat (limited to 'bootstrap/cleanup.go')
-rw-r--r-- | bootstrap/cleanup.go | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/bootstrap/cleanup.go b/bootstrap/cleanup.go new file mode 100644 index 0000000..4a44b49 --- /dev/null +++ b/bootstrap/cleanup.go @@ -0,0 +1,141 @@ +package bootstrap + +import ( + "blueprint" + "bufio" + "errors" + "fmt" + "os" + "path/filepath" + "strings" + "syscall" +) + +const logFileName = ".ninja_log" + +// removeAbandonedFiles removes any files that appear in the Ninja log that are +// not currently build targets. +func removeAbandonedFiles(ctx *blueprint.Context, config interface{}, + srcDir, manifestFile string) error { + + buildDir := "." + if generatingBootstrapper(config) { + buildDir = bootstrapDir + } + + targetRules, err := ctx.AllTargets() + if err != nil { + return fmt.Errorf("error determining target list: %s", err) + } + + replacer := strings.NewReplacer( + "@@SrcDir@@", srcDir, + "@@BootstrapManifest@@", manifestFile) + targets := make(map[string]bool) + for target := range targetRules { + replacedTarget := replacer.Replace(target) + targets[replacedTarget] = true + } + + filePaths, err := parseNinjaLog(buildDir) + if err != nil { + return err + } + + for _, filePath := range filePaths { + isTarget := targets[filePath] + if !isTarget { + err = removeFileAndEmptyDirs(filePath) + if err != nil { + return err + } + } + } + + return nil +} + +func parseNinjaLog(buildDir string) ([]string, error) { + logFilePath := filepath.Join(buildDir, logFileName) + logFile, err := os.Open(logFilePath) + if err != nil { + if os.IsNotExist(err) { + return nil, nil + } + return nil, err + } + defer logFile.Close() + + scanner := bufio.NewScanner(logFile) + + // Check that the first line indicates that this is a Ninja log version 5 + const expectedFirstLine = "# ninja log v5" + if !scanner.Scan() || scanner.Text() != expectedFirstLine { + return nil, errors.New("unrecognized ninja log format") + } + + var filePaths []string + for scanner.Scan() { + line := scanner.Text() + if strings.HasPrefix(line, "#") { + continue + } + + const fieldSeperator = "\t" + fields := strings.Split(line, fieldSeperator) + + const precedingFields = 3 + const followingFields = 1 + + if len(fields) < precedingFields+followingFields+1 { + return nil, fmt.Errorf("log entry has too few fields: %q", line) + } + + start := precedingFields + end := len(fields) - followingFields + filePath := strings.Join(fields[start:end], fieldSeperator) + + filePaths = append(filePaths, filePath) + } + if err := scanner.Err(); err != nil { + return nil, err + } + + return filePaths, nil +} + +func removeFileAndEmptyDirs(path string) error { + err := os.Remove(path) + if err != nil { + if os.IsNotExist(err) { + return nil + } + return err + } + + path, err = filepath.Abs(path) + if err != nil { + return err + } + + cwd, err := os.Getwd() + if err != nil { + return err + } + + for dir := filepath.Dir(path); dir != cwd; dir = filepath.Dir(dir) { + err = os.Remove(dir) + if err != nil { + pathErr := err.(*os.PathError) + switch pathErr.Err { + case syscall.ENOTEMPTY, syscall.EEXIST: + // We've come to a nonempty directory, so we're done. + return nil + default: + return err + } + } + } + + return nil +} |