Add clean module for cleaning output

This allows cleaning build artifacts without deleting the entire
output directory.

Change-Id: I04ecf1ff1d0651b54acfc5ddb90710762adf2b27
diff --git a/build.go b/build.go
index 05bc666..18adcc8 100644
--- a/build.go
+++ b/build.go
@@ -35,7 +35,7 @@
 		blueprint.RuleParams{
 			Command: "$envVars $gnCmd gen $buildDir " +
 				"--root=$gnDir --script-executable=/usr/bin/env --args='$gnArgs'",
-			Generator: true,
+			Generator:   true,
 			Description: "gn $gnDir",
 		},
 		"envVars", "gnDir", "gnArgs", "buildDir")
@@ -81,6 +81,13 @@
 			Description: "mkdir $out",
 		})
 
+	rm = pctx.StaticRule("rm",
+		blueprint.RuleParams{
+			Command:     "rm -rf $files",
+			Description: "rm $out",
+		},
+		"files")
+
 	stamp = pctx.StaticRule("stamp",
 		blueprint.RuleParams{
 			Command:     "touch $out",
@@ -125,6 +132,45 @@
 	})
 }
 
+type Clean struct {
+	builderModule
+	properties struct {
+		Dirs []string
+	}
+	config Config
+}
+
+func newCleanModuleFactory(config Config) func() (blueprint.Module, []interface{}) {
+	return func() (blueprint.Module, []interface{}) {
+		module := &Clean{
+			config: config,
+		}
+		return module, []interface{}{&module.properties}
+	}
+}
+
+func (c *Clean) GenerateBuildActions(ctx blueprint.ModuleContext) {
+	c.targetName = ctx.ModuleName()
+
+	if len(c.properties.Dirs) != 0 {
+		// Add a rule for deleting all the specified files
+		ctx.Build(pctx, blueprint.BuildParams{
+			Rule:    rm,
+			Outputs: []string{ctx.ModuleName()},
+			Args: map[string]string{
+				"files": strings.Join(c.properties.Dirs, " "),
+			},
+			Implicits: getDirectDependencies(ctx),
+		})
+	} else {
+		ctx.Build(pctx, blueprint.BuildParams{
+			Rule:      blueprint.Phony,
+			Outputs:   []string{ctx.ModuleName()},
+			Implicits: getDirectDependencies(ctx),
+		})
+	}
+}
+
 type CMake struct {
 	builderModule
 	properties struct {
diff --git a/main.go b/main.go
index c46656d..9feb0e7 100644
--- a/main.go
+++ b/main.go
@@ -83,6 +83,7 @@
 
 	// Register custom module types.
 	ctx.RegisterModuleType("alias", newAliasModuleFactory(config))
+	ctx.RegisterModuleType("clean", newCleanModuleFactory(config))
 	ctx.RegisterModuleType("cmake", newCMakeModuleFactory(config))
 	ctx.RegisterModuleType("copy", newCopyModuleFactory(config))
 	ctx.RegisterModuleType("gn", newGnModuleFactory(config))