Support whitespaces in ADD and COPY continued

Add tests and documentation for this new feature.

Signed-off-by: Arnaud Porterie <arnaud.porterie@docker.com>
This commit is contained in:
Arnaud Porterie 2014-12-26 16:30:34 -08:00
Родитель abfb713887
Коммит cf455017e0
3 изменённых файлов: 99 добавлений и 14 удалений

Просмотреть файл

@ -131,7 +131,11 @@ or
interactively, as with the following command: **docker run -t -i image bash** interactively, as with the following command: **docker run -t -i image bash**
**ADD** **ADD**
--**ADD <src>... <dest>** The ADD instruction copies new files, directories --ADD has two forms:
**ADD <src>... <dest>**
**ADD ["<src>"... "<dest>"]** This form is required for paths containing
whitespace.
The ADD instruction copies new files, directories
or remote file URLs to the filesystem of the container at path <dest>. or remote file URLs to the filesystem of the container at path <dest>.
Mutliple <src> resources may be specified but if they are files or directories Mutliple <src> resources may be specified but if they are files or directories
then they must be relative to the source directory that is being built then they must be relative to the source directory that is being built
@ -141,7 +145,11 @@ or
and gid of 0. and gid of 0.
**COPY** **COPY**
--**COPY <src> <dest>** The COPY instruction copies new files from <src> and --COPY has two forms:
**COPY <src>... <dest>**
**COPY ["<src>"... "<dest>"]** This form is required for paths containing
whitespace.
The COPY instruction copies new files from <src> and
adds them to the filesystem of the container at path <dest>. The <src> must be adds them to the filesystem of the container at path <dest>. The <src> must be
the path to a file or directory relative to the source directory that is the path to a file or directory relative to the source directory that is
being built (the context of the build) or a remote file URL. The `<dest>` is an 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>`.
## ADD ## ADD
ADD <src>... <dest> ADD has two forms:
- `ADD <src>... <dest>`
- `ADD ["<src>"... "<dest>"]` (this form is required for paths containing
whitespace)
The `ADD` instruction copies new files, directories or remote file URLs from `<src>` The `ADD` instruction copies new files, directories or remote file URLs from `<src>`
and adds them to the filesystem of the container at the path `<dest>`. and adds them to the filesystem of the container at the path `<dest>`.
@ -481,7 +485,11 @@ The copy obeys the following rules:
## COPY ## COPY
COPY <src>... <dest> COPY has two forms:
- `COPY <src>... <dest>`
- `COPY ["<src>"... "<dest>"]` (this form is required for paths containing
whitespace)
The `COPY` instruction copies new files or directories from `<src>` The `COPY` instruction copies new files or directories from `<src>`
and adds them to the filesystem of the container at the path `<dest>`. 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'
if _, err := buildImageFromContext(name, ctx, true); err != nil { if _, err := buildImageFromContext(name, ctx, true); err != nil {
t.Fatal(err) t.Fatal(err)
} }
logDone("build - mulitple file copy/add tests") logDone("build - multiple file copy/add tests")
} }
func TestBuildAddMultipleFilesToFile(t *testing.T) { func TestBuildAddMultipleFilesToFile(t *testing.T) {
@ -770,7 +770,7 @@ func TestBuildAddMultipleFilesToFile(t *testing.T) {
defer deleteImages(name) defer deleteImages(name)
ctx, err := fakeContext(`FROM scratch ctx, err := fakeContext(`FROM scratch
ADD file1.txt file2.txt test ADD file1.txt file2.txt test
`, `,
map[string]string{ map[string]string{
"file1.txt": "test1", "file1.txt": "test1",
"file2.txt": "test1", "file2.txt": "test1",
@ -782,18 +782,41 @@ func TestBuildAddMultipleFilesToFile(t *testing.T) {
expected := "When using ADD with more than one source file, the destination must be a directory and end with a /" expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) { if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err) t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
} }
logDone("build - multiple add files to file") logDone("build - multiple add files to file")
} }
func TestBuildJSONAddMultipleFilesToFile(t *testing.T) {
name := "testjsonaddmultiplefilestofile"
defer deleteImages(name)
ctx, err := fakeContext(`FROM scratch
ADD ["file1.txt", "file2.txt", "test"]
`,
map[string]string{
"file1.txt": "test1",
"file2.txt": "test1",
})
defer ctx.Close()
if err != nil {
t.Fatal(err)
}
expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
}
logDone("build - multiple add files to file json syntax")
}
func TestBuildAddMultipleFilesToFileWild(t *testing.T) { func TestBuildAddMultipleFilesToFileWild(t *testing.T) {
name := "testaddmultiplefilestofilewild" name := "testaddmultiplefilestofilewild"
defer deleteImages(name) defer deleteImages(name)
ctx, err := fakeContext(`FROM scratch ctx, err := fakeContext(`FROM scratch
ADD file*.txt test ADD file*.txt test
`, `,
map[string]string{ map[string]string{
"file1.txt": "test1", "file1.txt": "test1",
"file2.txt": "test1", "file2.txt": "test1",
@ -805,18 +828,41 @@ func TestBuildAddMultipleFilesToFileWild(t *testing.T) {
expected := "When using ADD with more than one source file, the destination must be a directory and end with a /" expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) { if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err) t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
} }
logDone("build - multiple add files to file wild") logDone("build - multiple add files to file wild")
} }
func TestBuildJSONAddMultipleFilesToFileWild(t *testing.T) {
name := "testjsonaddmultiplefilestofilewild"
defer deleteImages(name)
ctx, err := fakeContext(`FROM scratch
ADD ["file*.txt", "test"]
`,
map[string]string{
"file1.txt": "test1",
"file2.txt": "test1",
})
defer ctx.Close()
if err != nil {
t.Fatal(err)
}
expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
}
logDone("build - multiple add files to file wild json syntax")
}
func TestBuildCopyMultipleFilesToFile(t *testing.T) { func TestBuildCopyMultipleFilesToFile(t *testing.T) {
name := "testcopymultiplefilestofile" name := "testcopymultiplefilestofile"
defer deleteImages(name) defer deleteImages(name)
ctx, err := fakeContext(`FROM scratch ctx, err := fakeContext(`FROM scratch
COPY file1.txt file2.txt test COPY file1.txt file2.txt test
`, `,
map[string]string{ map[string]string{
"file1.txt": "test1", "file1.txt": "test1",
"file2.txt": "test1", "file2.txt": "test1",
@ -828,12 +874,35 @@ func TestBuildCopyMultipleFilesToFile(t *testing.T) {
expected := "When using COPY with more than one source file, the destination must be a directory and end with a /" expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) { if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err) t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
} }
logDone("build - multiple copy files to file") logDone("build - multiple copy files to file")
} }
func TestBuildJSONCopyMultipleFilesToFile(t *testing.T) {
name := "testjsoncopymultiplefilestofile"
defer deleteImages(name)
ctx, err := fakeContext(`FROM scratch
COPY ["file1.txt", "file2.txt", "test"]
`,
map[string]string{
"file1.txt": "test1",
"file2.txt": "test1",
})
defer ctx.Close()
if err != nil {
t.Fatal(err)
}
expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
}
logDone("build - multiple copy files to file json syntax")
}
func TestBuildAddFileWithWhitespace(t *testing.T) { func TestBuildAddFileWithWhitespace(t *testing.T) {
name := "testaddfilewithwhitespace" name := "testaddfilewithwhitespace"
defer deleteImages(name) defer deleteImages(name)
@ -913,7 +982,7 @@ func TestBuildAddMultipleFilesToFileWithWhitespace(t *testing.T) {
defer deleteImages(name) defer deleteImages(name)
ctx, err := fakeContext(`FROM busybox ctx, err := fakeContext(`FROM busybox
ADD [ "test file1", "test file2", "test" ] ADD [ "test file1", "test file2", "test" ]
`, `,
map[string]string{ map[string]string{
"test file1": "test1", "test file1": "test1",
"test file2": "test2", "test file2": "test2",
@ -925,7 +994,7 @@ func TestBuildAddMultipleFilesToFileWithWhitespace(t *testing.T) {
expected := "When using ADD with more than one source file, the destination must be a directory and end with a /" expected := "When using ADD with more than one source file, the destination must be a directory and end with a /"
if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) { if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err) t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
} }
logDone("build - multiple add files to file with whitespace") logDone("build - multiple add files to file with whitespace")
@ -948,7 +1017,7 @@ func TestBuildCopyMultipleFilesToFileWithWhitespace(t *testing.T) {
expected := "When using COPY with more than one source file, the destination must be a directory and end with a /" expected := "When using COPY with more than one source file, the destination must be a directory and end with a /"
if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) { if _, err := buildImageFromContext(name, ctx, true); err == nil || !strings.Contains(err.Error(), expected) {
t.Fatalf("Wrong error: (should contain \"%s\") got:\n%v", expected, err) t.Fatalf("Wrong error: (should contain %q) got:\n%v", expected, err)
} }
logDone("build - multiple copy files to file with whitespace") logDone("build - multiple copy files to file with whitespace")