浏览代码

Merge pull request #3422 from infosiftr/dry-run

Add a "--dry-run" flag to "build", "tag", "push", and "put-shared"
yosifkit 8 年之前
父节点
当前提交
c5e1a63d58

+ 26 - 21
bashbrew/go/src/bashbrew/cmd-build.go

@@ -26,6 +26,7 @@ func cmdBuild(c *cli.Context) error {
 	default:
 		return fmt.Errorf(`invalid value for --pull: %q`, pull)
 	}
+	dryRun := c.Bool("dry-run")
 
 	for _, repo := range repos {
 		r, err := fetch(repo)
@@ -62,7 +63,9 @@ func cmdBuild(c *cli.Context) error {
 				if doPull {
 					// TODO detect if "from" is something we've built (ie, "python:3-onbuild" is "FROM python:3" but we don't want to pull "python:3" if we "bashbrew build python")
 					fmt.Printf("Pulling %s (%s)\n", from, r.EntryIdentifier(entry))
-					dockerPull(from)
+					if !dryRun {
+						dockerPull(from)
+					}
 				}
 			}
 
@@ -75,33 +78,35 @@ func cmdBuild(c *cli.Context) error {
 			_, err = dockerInspect("{{.Id}}", cacheTag)
 			if err != nil {
 				fmt.Printf("Building %s (%s)\n", cacheTag, r.EntryIdentifier(entry))
-
-				commit, err := r.fetchGitRepo(arch, &entry)
-				if err != nil {
-					return cli.NewMultiError(fmt.Errorf(`failed fetching git repo for %q (tags %q)`, r.RepoName, entry.TagsString()), err)
-				}
-
-				archive, err := gitArchive(commit, entry.ArchDirectory(arch))
-				if err != nil {
-					return cli.NewMultiError(fmt.Errorf(`failed generating git archive for %q (tags %q)`, r.RepoName, entry.TagsString()), err)
+				if !dryRun {
+					commit, err := r.fetchGitRepo(arch, &entry)
+					if err != nil {
+						return cli.NewMultiError(fmt.Errorf(`failed fetching git repo for %q (tags %q)`, r.RepoName, entry.TagsString()), err)
+					}
+
+					archive, err := gitArchive(commit, entry.ArchDirectory(arch))
+					if err != nil {
+						return cli.NewMultiError(fmt.Errorf(`failed generating git archive for %q (tags %q)`, r.RepoName, entry.TagsString()), err)
+					}
+					defer archive.Close()
+
+					err = dockerBuild(cacheTag, archive)
+					if err != nil {
+						return cli.NewMultiError(fmt.Errorf(`failed building %q (tags %q)`, r.RepoName, entry.TagsString()), err)
+					}
+					archive.Close() // be sure this happens sooner rather than later (defer might take a while, and we want to reap zombies more aggressively)
 				}
-				defer archive.Close()
-
-				err = dockerBuild(cacheTag, archive)
-				if err != nil {
-					return cli.NewMultiError(fmt.Errorf(`failed building %q (tags %q)`, r.RepoName, entry.TagsString()), err)
-				}
-				archive.Close() // be sure this happens sooner rather than later (defer might take a while, and we want to reap zombies more aggressively)
 			} else {
 				fmt.Printf("Using %s (%s)\n", cacheTag, r.EntryIdentifier(entry))
 			}
 
 			for _, tag := range r.Tags(namespace, uniq, entry) {
 				fmt.Printf("Tagging %s\n", tag)
-
-				err := dockerTag(cacheTag, tag)
-				if err != nil {
-					return cli.NewMultiError(fmt.Errorf(`failed tagging %q as %q`, cacheTag, tag), err)
+				if !dryRun {
+					err := dockerTag(cacheTag, tag)
+					if err != nil {
+						return cli.NewMultiError(fmt.Errorf(`failed tagging %q as %q`, cacheTag, tag), err)
+					}
 				}
 			}
 		}

+ 8 - 4
bashbrew/go/src/bashbrew/cmd-push.go

@@ -2,6 +2,7 @@ package main
 
 import (
 	"fmt"
+	"os"
 	"time"
 
 	"github.com/codegangsta/cli"
@@ -15,6 +16,7 @@ func cmdPush(c *cli.Context) error {
 
 	uniq := c.Bool("uniq")
 	namespace := c.String("namespace")
+	dryRun := c.Bool("dry-run")
 
 	if namespace == "" {
 		return fmt.Errorf(`"--namespace" is a required flag for "push"`)
@@ -36,12 +38,14 @@ func cmdPush(c *cli.Context) error {
 				lastUpdated := fetchDockerHubTagMeta(tag).lastUpdatedTime()
 				if created.After(lastUpdated) {
 					fmt.Printf("Pushing %s\n", tag)
-					err = dockerPush(tag)
-					if err != nil {
-						return cli.NewMultiError(fmt.Errorf(`failed pushing %q`, tag), err)
+					if !dryRun {
+						err = dockerPush(tag)
+						if err != nil {
+							return cli.NewMultiError(fmt.Errorf(`failed pushing %q`, tag), err)
+						}
 					}
 				} else {
-					fmt.Printf("Skipping %s (created %s, last updated %s)\n", tag, created.Local().Format(time.RFC3339), lastUpdated.Local().Format(time.RFC3339))
+					fmt.Fprintf(os.Stderr, "skipping %s (created %s, last updated %s)\n", tag, created.Local().Format(time.RFC3339), lastUpdated.Local().Format(time.RFC3339))
 				}
 			}
 		}

+ 7 - 4
bashbrew/go/src/bashbrew/cmd-put-shared.go

@@ -73,6 +73,7 @@ func cmdPutShared(c *cli.Context) error {
 	}
 
 	namespace := c.String("namespace")
+	dryRun := c.Bool("dry-run")
 
 	if namespace == "" {
 		return fmt.Errorf(`"--namespace" is a required flag for "put-shared"`)
@@ -121,7 +122,7 @@ func cmdPutShared(c *cli.Context) error {
 				if mostRecentPush.After(tagUpdated) {
 					tagsToPush = append(tagsToPush, tag)
 				} else {
-					fmt.Printf("Skipping %s (created %s, last updated %s)\n", image, mostRecentPush.Local().Format(time.RFC3339), tagUpdated.Local().Format(time.RFC3339))
+					fmt.Fprintf(os.Stderr, "skipping %s (created %s, last updated %s)\n", image, mostRecentPush.Local().Format(time.RFC3339), tagUpdated.Local().Format(time.RFC3339))
 				}
 			}
 
@@ -131,9 +132,11 @@ func cmdPutShared(c *cli.Context) error {
 
 			groupIdentifier := fmt.Sprintf("%s:%s", targetRepo, tagsToPush[0])
 			fmt.Printf("Putting %s\n", groupIdentifier)
-			tagYaml := tagsToManifestToolYaml(targetRepo, tagsToPush...) + yaml
-			if err := manifestToolPushFromSpec(tagYaml); err != nil {
-				return fmt.Errorf("failed pushing %s", groupIdentifier)
+			if !dryRun {
+				tagYaml := tagsToManifestToolYaml(targetRepo, tagsToPush...) + yaml
+				if err := manifestToolPushFromSpec(tagYaml); err != nil {
+					return fmt.Errorf("failed pushing %s", groupIdentifier)
+				}
 			}
 		}
 	}

+ 6 - 3
bashbrew/go/src/bashbrew/cmd-tag.go

@@ -15,6 +15,7 @@ func cmdTag(c *cli.Context) error {
 
 	uniq := c.Bool("uniq")
 	namespace := c.String("namespace")
+	dryRun := c.Bool("dry-run")
 
 	if namespace == "" {
 		return fmt.Errorf(`"--namespace" is a required flag for "tag"`)
@@ -34,9 +35,11 @@ func cmdTag(c *cli.Context) error {
 			for _, tag := range r.Tags("", uniq, entry) {
 				namespacedTag := path.Join(namespace, tag)
 				fmt.Printf("Tagging %s\n", namespacedTag)
-				err = dockerTag(tag, namespacedTag)
-				if err != nil {
-					return cli.NewMultiError(fmt.Errorf(`failed tagging %q as %q`, tag, namespacedTag), err)
+				if !dryRun {
+					err = dockerTag(tag, namespacedTag)
+					if err != nil {
+						return cli.NewMultiError(fmt.Errorf(`failed tagging %q as %q`, tag, namespacedTag), err)
+					}
 				}
 			}
 		}

+ 8 - 0
bashbrew/go/src/bashbrew/main.go

@@ -198,6 +198,10 @@ func main() {
 			Value: 0,
 			Usage: "maximum number of levels to traverse (0 for unlimited)",
 		},
+		"dry-run": cli.BoolFlag{
+			Name:  "dry-run",
+			Usage: "do everything except the final action (for testing whether actions will be performed)",
+		},
 	}
 
 	app.Commands = []cli.Command{
@@ -234,6 +238,7 @@ func main() {
 					EnvVar: flagEnvVars["pull"],
 					Usage:  `pull FROM before building (always, missing, never)`,
 				},
+				commonFlags["dry-run"],
 			},
 			Before: subcommandBeforeFactory("build"),
 			Action: cmdBuild,
@@ -245,6 +250,7 @@ func main() {
 				commonFlags["all"],
 				commonFlags["uniq"],
 				commonFlags["namespace"],
+				commonFlags["dry-run"],
 			},
 			Before: subcommandBeforeFactory("tag"),
 			Action: cmdTag,
@@ -256,6 +262,7 @@ func main() {
 				commonFlags["all"],
 				commonFlags["uniq"],
 				commonFlags["namespace"],
+				commonFlags["dry-run"],
 			},
 			Before: subcommandBeforeFactory("push"),
 			Action: cmdPush,
@@ -266,6 +273,7 @@ func main() {
 			Flags: []cli.Flag{
 				commonFlags["all"],
 				commonFlags["namespace"],
+				commonFlags["dry-run"],
 			},
 			Before: subcommandBeforeFactory("put-shared"),
 			Action: cmdPutShared,