Browse code

Support whitespaces in ADD and COPY continued

Add tests and documentation for this new feature.

Signed-off-by: Arnaud Porterie <arnaud.porterie@docker.com>

Arnaud Porterie authored on 2014/12/27 09:30:34
Showing 3 changed files
... ...
@@ -131,7 +131,11 @@ or
131 131
  interactively, as with the following command: **docker run -t -i image bash**
132 132
 
133 133
 **ADD**
134
- --**ADD <src>... <dest>** The ADD instruction copies new files, directories
134
+ --ADD has two forms:
135
+ **ADD <src>... <dest>**
136
+ **ADD ["<src>"... "<dest>"]** This form is required for paths containing
137
+ whitespace.
138
+ The ADD instruction copies new files, directories
135 139
  or remote file URLs to the filesystem of the container at path <dest>.
136 140
  Mutliple <src> resources may be specified but if they are files or directories
137 141
  then they must be relative to the source directory that is being built
... ...
@@ -141,7 +145,11 @@ or
141 141
  and gid of 0.
142 142
 
143 143
 **COPY**
144
- --**COPY <src> <dest>** The COPY instruction copies new files from <src> and
144
+ --COPY has two forms:
145
+ **COPY <src>... <dest>**
146
+ **COPY ["<src>"... "<dest>"]** This form is required for paths containing
147
+ whitespace.
148
+ The COPY instruction copies new files from <src> and
145 149
  adds them to the filesystem of the container at path <dest>. The <src> must be
146 150
  the path to a file or directory relative to the source directory that is
147 151
  being built (the context of the build) or a remote file URL. The `<dest>` is an
... ...
@@ -381,7 +381,11 @@ change them using `docker run --env <key>=<value>`.
381 381
 
382 382
 ## ADD
383 383
 
384
-    ADD <src>... <dest>
384
+ADD has two forms:
385
+
386
+- `ADD <src>... <dest>`
387
+- `ADD ["<src>"... "<dest>"]` (this form is required for paths containing
388
+whitespace)
385 389
 
386 390
 The `ADD` instruction copies new files, directories or remote file URLs from `<src>`
387 391
 and adds them to the filesystem of the container at the path `<dest>`.  
... ...
@@ -481,7 +485,11 @@ The copy obeys the following rules:
481 481
 
482 482
 ## COPY
483 483
 
484
-    COPY <src>... <dest>
484
+COPY has two forms:
485
+
486
+- `COPY <src>... <dest>`
487
+- `COPY ["<src>"... "<dest>"]` (this form is required for paths containing
488
+whitespace)
485 489
 
486 490
 The `COPY` instruction copies new files or directories from `<src>`
487 491
 and adds them to the filesystem of the container at the path `<dest>`.
... ...
@@ -762,7 +762,7 @@ RUN [ $(ls -l /exists/exists_file | awk '{print $3":"$4}') = 'dockerio:dockerio'
762 762
 	if _, err := buildImageFromContext(name, ctx, true); err != nil {
763 763
 		t.Fatal(err)
764 764
 	}
765
-	logDone("build - mulitple file copy/add tests")
765
+	logDone("build - multiple file copy/add tests")
766 766
 }
767 767
 
768 768
 func TestBuildAddMultipleFilesToFile(t *testing.T) {
... ...
@@ -770,7 +770,7 @@ func TestBuildAddMultipleFilesToFile(t *testing.T) {
770 770
 	defer deleteImages(name)
771 771
 	ctx, err := fakeContext(`FROM scratch
772 772
 	ADD file1.txt file2.txt test
773
-        `,
773
+	`,
774 774
 		map[string]string{
775 775
 			"file1.txt": "test1",
776 776
 			"file2.txt": "test1",
... ...
@@ -782,18 +782,41 @@ func TestBuildAddMultipleFilesToFile(t *testing.T) {
782 782
 
783 783
 	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
784 784
 	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
785
-		t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
785
+		t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
786 786
 	}
787 787
 
788 788
 	logDone("build - multiple add files to file")
789 789
 }
790 790
 
791
+func TestBuildJSONAddMultipleFilesToFile(t *testing.T) {
792
+	name := "testjsonaddmultiplefilestofile"
793
+	defer deleteImages(name)
794
+	ctx, err := fakeContext(`FROM scratch
795
+	ADD ["file1.txt", "file2.txt", "test"]
796
+	`,
797
+		map[string]string{
798
+			"file1.txt": "test1",
799
+			"file2.txt": "test1",
800
+		})
801
+	defer ctx.Close()
802
+	if err != nil {
803
+		t.Fatal(err)
804
+	}
805
+
806
+	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
807
+	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
808
+		t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
809
+	}
810
+
811
+	logDone("build - multiple add files to file json syntax")
812
+}
813
+
791 814
 func TestBuildAddMultipleFilesToFileWild(t *testing.T) {
792 815
 	name := "testaddmultiplefilestofilewild"
793 816
 	defer deleteImages(name)
794 817
 	ctx, err := fakeContext(`FROM scratch
795 818
 	ADD file*.txt test
796
-        `,
819
+	`,
797 820
 		map[string]string{
798 821
 			"file1.txt": "test1",
799 822
 			"file2.txt": "test1",
... ...
@@ -805,18 +828,41 @@ func TestBuildAddMultipleFilesToFileWild(t *testing.T) {
805 805
 
806 806
 	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
807 807
 	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
808
-		t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
808
+		t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
809 809
 	}
810 810
 
811 811
 	logDone("build - multiple add files to file wild")
812 812
 }
813 813
 
814
+func TestBuildJSONAddMultipleFilesToFileWild(t *testing.T) {
815
+	name := "testjsonaddmultiplefilestofilewild"
816
+	defer deleteImages(name)
817
+	ctx, err := fakeContext(`FROM scratch
818
+	ADD ["file*.txt", "test"]
819
+	`,
820
+		map[string]string{
821
+			"file1.txt": "test1",
822
+			"file2.txt": "test1",
823
+		})
824
+	defer ctx.Close()
825
+	if err != nil {
826
+		t.Fatal(err)
827
+	}
828
+
829
+	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
830
+	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
831
+		t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
832
+	}
833
+
834
+	logDone("build - multiple add files to file wild json syntax")
835
+}
836
+
814 837
 func TestBuildCopyMultipleFilesToFile(t *testing.T) {
815 838
 	name := "testcopymultiplefilestofile"
816 839
 	defer deleteImages(name)
817 840
 	ctx, err := fakeContext(`FROM scratch
818 841
 	COPY file1.txt file2.txt test
819
-        `,
842
+	`,
820 843
 		map[string]string{
821 844
 			"file1.txt": "test1",
822 845
 			"file2.txt": "test1",
... ...
@@ -828,12 +874,35 @@ func TestBuildCopyMultipleFilesToFile(t *testing.T) {
828 828
 
829 829
 	expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
830 830
 	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
831
-		t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
831
+		t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
832 832
 	}
833 833
 
834 834
 	logDone("build - multiple copy files to file")
835 835
 }
836 836
 
837
+func TestBuildJSONCopyMultipleFilesToFile(t *testing.T) {
838
+	name := "testjsoncopymultiplefilestofile"
839
+	defer deleteImages(name)
840
+	ctx, err := fakeContext(`FROM scratch
841
+	COPY ["file1.txt", "file2.txt", "test"]
842
+	`,
843
+		map[string]string{
844
+			"file1.txt": "test1",
845
+			"file2.txt": "test1",
846
+		})
847
+	defer ctx.Close()
848
+	if err != nil {
849
+		t.Fatal(err)
850
+	}
851
+
852
+	expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
853
+	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
854
+		t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
855
+	}
856
+
857
+	logDone("build - multiple copy files to file json syntax")
858
+}
859
+
837 860
 func TestBuildAddFileWithWhitespace(t *testing.T) {
838 861
 	name := "testaddfilewithwhitespace"
839 862
 	defer deleteImages(name)
... ...
@@ -913,7 +982,7 @@ func TestBuildAddMultipleFilesToFileWithWhitespace(t *testing.T) {
913 913
 	defer deleteImages(name)
914 914
 	ctx, err := fakeContext(`FROM busybox
915 915
 	ADD [ "test file1", "test file2", "test" ]
916
-        `,
916
+    `,
917 917
 		map[string]string{
918 918
 			"test file1": "test1",
919 919
 			"test file2": "test2",
... ...
@@ -925,7 +994,7 @@ func TestBuildAddMultipleFilesToFileWithWhitespace(t *testing.T) {
925 925
 
926 926
 	expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
927 927
 	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
928
-		t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
928
+		t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
929 929
 	}
930 930
 
931 931
 	logDone("build - multiple add files to file with whitespace")
... ...
@@ -948,7 +1017,7 @@ func TestBuildCopyMultipleFilesToFileWithWhitespace(t *testing.T) {
948 948
 
949 949
 	expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
950 950
 	if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
951
-		t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err)
951
+		t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
952 952
 	}
953 953
 
954 954
 	logDone("build - multiple copy files to file with whitespace")