Implementation of multiline syntax for Dockerfile
| ... | ... |
@@ -445,7 +445,7 @@ func TestGetContainersChanges(t *testing.T) {
|
| 445 | 445 |
} |
| 446 | 446 |
|
| 447 | 447 |
func TestGetContainersTop(t *testing.T) {
|
| 448 |
- t.Skip("Fixme. Skipping test for now. Reported error when testing using dind: 'api_test.go:527: Expected 2 processes, found 0.'")
|
|
| 448 |
+ t.Skip("Fixme. Skipping test for now. Reported error when testing using dind: 'api_test.go:527: Expected 2 processes, found 0.'")
|
|
| 449 | 449 |
runtime, err := newTestRuntime() |
| 450 | 450 |
if err != nil {
|
| 451 | 451 |
t.Fatal(err) |
| ... | ... |
@@ -1,7 +1,6 @@ |
| 1 | 1 |
package docker |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 |
- "bufio" |
|
| 5 | 4 |
"encoding/json" |
| 6 | 5 |
"fmt" |
| 7 | 6 |
"github.com/dotcloud/docker/utils" |
| ... | ... |
@@ -458,6 +457,9 @@ func (b *buildFile) commit(id string, autoCmd []string, comment string) error {
|
| 458 | 458 |
return nil |
| 459 | 459 |
} |
| 460 | 460 |
|
| 461 |
+// Long lines can be split with a backslash |
|
| 462 |
+var lineContinuation = regexp.MustCompile(`\s*\\\s*\n`) |
|
| 463 |
+ |
|
| 461 | 464 |
func (b *buildFile) Build(context io.Reader) (string, error) {
|
| 462 | 465 |
// FIXME: @creack any reason for using /tmp instead of ""? |
| 463 | 466 |
// FIXME: @creack "name" is a terrible variable name |
| ... | ... |
@@ -470,22 +472,18 @@ func (b *buildFile) Build(context io.Reader) (string, error) {
|
| 470 | 470 |
} |
| 471 | 471 |
defer os.RemoveAll(name) |
| 472 | 472 |
b.context = name |
| 473 |
- dockerfile, err := os.Open(path.Join(name, "Dockerfile")) |
|
| 474 |
- if err != nil {
|
|
| 473 |
+ filename := path.Join(name, "Dockerfile") |
|
| 474 |
+ if _, err := os.Stat(filename); os.IsNotExist(err) {
|
|
| 475 | 475 |
return "", fmt.Errorf("Can't build a directory with no Dockerfile")
|
| 476 | 476 |
} |
| 477 |
- // FIXME: "file" is also a terrible variable name ;) |
|
| 478 |
- file := bufio.NewReader(dockerfile) |
|
| 477 |
+ fileBytes, err := ioutil.ReadFile(filename) |
|
| 478 |
+ if err != nil {
|
|
| 479 |
+ return "", err |
|
| 480 |
+ } |
|
| 481 |
+ dockerfile := string(fileBytes) |
|
| 482 |
+ dockerfile = lineContinuation.ReplaceAllString(dockerfile, " ") |
|
| 479 | 483 |
stepN := 0 |
| 480 |
- for {
|
|
| 481 |
- line, err := file.ReadString('\n')
|
|
| 482 |
- if err != nil {
|
|
| 483 |
- if err == io.EOF && line == "" {
|
|
| 484 |
- break |
|
| 485 |
- } else if err != io.EOF {
|
|
| 486 |
- return "", err |
|
| 487 |
- } |
|
| 488 |
- } |
|
| 484 |
+ for _, line := range strings.Split(dockerfile, "\n") {
|
|
| 489 | 485 |
line = strings.Trim(strings.Replace(line, "\t", " ", -1), " \t\r\n") |
| 490 | 486 |
// Skip comments and empty line |
| 491 | 487 |
if len(line) == 0 || line[0] == '#' {
|
| ... | ... |
@@ -45,6 +45,34 @@ run [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ] |
| 45 | 45 |
nil, |
| 46 | 46 |
}, |
| 47 | 47 |
|
| 48 |
+ // Exactly the same as above, except uses a line split with a \ to test |
|
| 49 |
+ // multiline support. |
|
| 50 |
+ {
|
|
| 51 |
+ ` |
|
| 52 |
+from {IMAGE}
|
|
| 53 |
+run sh -c 'echo root:testpass \ |
|
| 54 |
+ > /tmp/passwd' |
|
| 55 |
+run mkdir -p /var/run/sshd |
|
| 56 |
+run [ "$(cat /tmp/passwd)" = "root:testpass" ] |
|
| 57 |
+run [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ] |
|
| 58 |
+`, |
|
| 59 |
+ nil, |
|
| 60 |
+ nil, |
|
| 61 |
+ }, |
|
| 62 |
+ |
|
| 63 |
+ // Line containing literal "\n" |
|
| 64 |
+ {
|
|
| 65 |
+ ` |
|
| 66 |
+from {IMAGE}
|
|
| 67 |
+run sh -c 'echo root:testpass > /tmp/passwd' |
|
| 68 |
+run echo "foo \n bar"; echo "baz" |
|
| 69 |
+run mkdir -p /var/run/sshd |
|
| 70 |
+run [ "$(cat /tmp/passwd)" = "root:testpass" ] |
|
| 71 |
+run [ "$(ls -d /var/run/sshd)" = "/var/run/sshd" ] |
|
| 72 |
+`, |
|
| 73 |
+ nil, |
|
| 74 |
+ nil, |
|
| 75 |
+ }, |
|
| 48 | 76 |
{
|
| 49 | 77 |
` |
| 50 | 78 |
from {IMAGE}
|
| ... | ... |
@@ -366,7 +366,6 @@ func TestParseRelease(t *testing.T) {
|
| 366 | 366 |
assertParseRelease(t, "3.8.0-19-generic", &KernelVersionInfo{Kernel: 3, Major: 8, Minor: 0, Flavor: "19-generic"}, 0)
|
| 367 | 367 |
} |
| 368 | 368 |
|
| 369 |
- |
|
| 370 | 369 |
func TestDependencyGraphCircular(t *testing.T) {
|
| 371 | 370 |
g1 := NewDependencyGraph() |
| 372 | 371 |
a := g1.NewNode("a")
|
| ... | ... |
@@ -421,4 +420,4 @@ func TestDependencyGraph(t *testing.T) {
|
| 421 | 421 |
if len(res[2]) != 1 || res[2][0] != "d" {
|
| 422 | 422 |
t.Fatalf("Expected [d], found %v instead", res[2])
|
| 423 | 423 |
} |
| 424 |
-} |
|
| 425 | 424 |
\ No newline at end of file |
| 425 |
+} |