Browse code

Merge pull request #24978 from yongtang/24912-build-with-progress

Add hint of progress to the output of `docker build`

Doug Davis authored on 2016/08/19 05:10:48
Showing 5 changed files
... ...
@@ -233,6 +233,7 @@ func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (stri
233 233
 	}
234 234
 
235 235
 	var shortImgID string
236
+	total := len(b.dockerfile.Children)
236 237
 	for i, n := range b.dockerfile.Children {
237 238
 		select {
238 239
 		case <-b.clientCtx.Done():
... ...
@@ -242,7 +243,7 @@ func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (stri
242 242
 		default:
243 243
 			// Not cancelled yet, keep going...
244 244
 		}
245
-		if err := b.dispatch(i, n); err != nil {
245
+		if err := b.dispatch(i, total, n); err != nil {
246 246
 			if b.options.ForceRemove {
247 247
 				b.clearTmp()
248 248
 			}
... ...
@@ -320,8 +321,9 @@ func BuildFromConfig(config *container.Config, changes []string) (*container.Con
320 320
 	b.Stderr = ioutil.Discard
321 321
 	b.disableCommit = true
322 322
 
323
+	total := len(ast.Children)
323 324
 	for i, n := range ast.Children {
324
-		if err := b.dispatch(i, n); err != nil {
325
+		if err := b.dispatch(i, total, n); err != nil {
325 326
 			return nil, err
326 327
 		}
327 328
 	}
... ...
@@ -93,7 +93,7 @@ func init() {
93 93
 // such as `RUN` in ONBUILD RUN foo. There is special case logic in here to
94 94
 // deal with that, at least until it becomes more of a general concern with new
95 95
 // features.
96
-func (b *Builder) dispatch(stepN int, ast *parser.Node) error {
96
+func (b *Builder) dispatch(stepN int, stepTotal int, ast *parser.Node) error {
97 97
 	cmd := ast.Value
98 98
 	upperCasedCmd := strings.ToUpper(cmd)
99 99
 
... ...
@@ -107,7 +107,7 @@ func (b *Builder) dispatch(stepN int, ast *parser.Node) error {
107 107
 	original := ast.Original
108 108
 	flags := ast.Flags
109 109
 	strList := []string{}
110
-	msg := fmt.Sprintf("Step %d : %s", stepN+1, upperCasedCmd)
110
+	msg := fmt.Sprintf("Step %d/%d : %s", stepN+1, stepTotal, upperCasedCmd)
111 111
 
112 112
 	if len(ast.Flags) > 0 {
113 113
 		msg += " " + strings.Join(ast.Flags, " ")
... ...
@@ -184,7 +184,7 @@ func executeTestCase(t *testing.T, testCase dispatchTestCase) {
184 184
 
185 185
 	b := &Builder{runConfig: config, options: options, Stdout: ioutil.Discard, context: context}
186 186
 
187
-	err = b.dispatch(0, n.Children[0])
187
+	err = b.dispatch(0, len(n.Children), n.Children[0])
188 188
 
189 189
 	if err == nil {
190 190
 		t.Fatalf("No error when executing test %s", testCase.name)
... ...
@@ -434,6 +434,7 @@ func (b *Builder) processImageFrom(img builder.Image) error {
434 434
 			return err
435 435
 		}
436 436
 
437
+		total := len(ast.Children)
437 438
 		for i, n := range ast.Children {
438 439
 			switch strings.ToUpper(n.Value) {
439 440
 			case "ONBUILD":
... ...
@@ -442,7 +443,7 @@ func (b *Builder) processImageFrom(img builder.Image) error {
442 442
 				return fmt.Errorf("%s isn't allowed as an ONBUILD trigger", n.Value)
443 443
 			}
444 444
 
445
-			if err := b.dispatch(i, n); err != nil {
445
+			if err := b.dispatch(i, total, n); err != nil {
446 446
 				return err
447 447
 			}
448 448
 		}
... ...
@@ -5417,7 +5417,7 @@ func (s *DockerSuite) TestBuildNoDupOutput(c *check.C) {
5417 5417
 		c.Fatalf("Build should have worked: %q", err)
5418 5418
 	}
5419 5419
 
5420
-	exp := "\nStep 2 : RUN env\n"
5420
+	exp := "\nStep 2/2 : RUN env\n"
5421 5421
 	if !strings.Contains(out, exp) {
5422 5422
 		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
5423 5423
 	}
... ...
@@ -5434,7 +5434,7 @@ func (s *DockerSuite) TestBuildStartsFromOne(c *check.C) {
5434 5434
 		c.Fatalf("Build should have worked: %q", err)
5435 5435
 	}
5436 5436
 
5437
-	exp := "\nStep 1 : FROM busybox\n"
5437
+	exp := "\nStep 1/1 : FROM busybox\n"
5438 5438
 	if !strings.Contains(out, exp) {
5439 5439
 		c.Fatalf("Bad output\nGot:%s\n\nExpected to contain:%s\n", out, exp)
5440 5440
 	}
... ...
@@ -6981,3 +6981,16 @@ func (s *DockerSuite) TestBuildCmdShellArgsEscaped(c *check.C) {
6981 6981
 		c.Fatalf("CMD was not escaped Config.Cmd: got %v", res)
6982 6982
 	}
6983 6983
 }
6984
+
6985
+// Test case for #24912.
6986
+func (s *DockerSuite) TestBuildStepsWithProgress(c *check.C) {
6987
+	name := "testbuildstepswithprogress"
6988
+
6989
+	totalRun := 5
6990
+	_, out, err := buildImageWithOut(name, "FROM busybox\n"+strings.Repeat("RUN echo foo\n", totalRun), true)
6991
+	c.Assert(err, checker.IsNil)
6992
+	c.Assert(out, checker.Contains, fmt.Sprintf("Step 1/%d : FROM busybox", 1+totalRun))
6993
+	for i := 2; i <= 1+totalRun; i++ {
6994
+		c.Assert(out, checker.Contains, fmt.Sprintf("Step %d/%d : RUN echo foo", i, 1+totalRun))
6995
+	}
6996
+}