Merge pull request #17599 from perhapszzy/master
Add line information in the parsed Dockerfile.
This commit is contained in:
commit
a5f3ed4801
3 changed files with 85 additions and 0 deletions
|
@ -30,6 +30,8 @@ type Node struct {
|
|||
Attributes map[string]bool // special attributes for this node
|
||||
Original string // original line used before parsing
|
||||
Flags []string // only top Node should have this set
|
||||
StartLine int // the line in the original dockerfile where the node begins
|
||||
EndLine int // the line in the original dockerfile where the node ends
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -101,19 +103,24 @@ func parseLine(line string) (string, *Node, error) {
|
|||
// Parse is the main parse routine.
|
||||
// It handles an io.ReadWriteCloser and returns the root of the AST.
|
||||
func Parse(rwc io.Reader) (*Node, error) {
|
||||
currentLine := 0
|
||||
root := &Node{}
|
||||
root.StartLine = -1
|
||||
scanner := bufio.NewScanner(rwc)
|
||||
|
||||
for scanner.Scan() {
|
||||
scannedLine := strings.TrimLeftFunc(scanner.Text(), unicode.IsSpace)
|
||||
currentLine++
|
||||
line, child, err := parseLine(scannedLine)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
startLine := currentLine
|
||||
|
||||
if line != "" && child == nil {
|
||||
for scanner.Scan() {
|
||||
newline := scanner.Text()
|
||||
currentLine++
|
||||
|
||||
if stripComments(strings.TrimSpace(newline)) == "" {
|
||||
continue
|
||||
|
@ -137,6 +144,15 @@ func Parse(rwc io.Reader) (*Node, error) {
|
|||
}
|
||||
|
||||
if child != nil {
|
||||
// Update the line information for the current child.
|
||||
child.StartLine = startLine
|
||||
child.EndLine = currentLine
|
||||
// Update the line information for the root. The starting line of the root is always the
|
||||
// starting line of the first child and the ending line is the ending line of the last child.
|
||||
if root.StartLine < 0 {
|
||||
root.StartLine = currentLine
|
||||
}
|
||||
root.EndLine = currentLine
|
||||
root.Children = append(root.Children, child)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
|
||||
const testDir = "testfiles"
|
||||
const negativeTestDir = "testfiles-negative"
|
||||
const testFileLineInfo = "testfile-line/Dockerfile"
|
||||
|
||||
func getDirs(t *testing.T, dir string) []string {
|
||||
f, err := os.Open(dir)
|
||||
|
@ -117,3 +118,37 @@ func TestParseWords(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLineInformation(t *testing.T) {
|
||||
df, err := os.Open(testFileLineInfo)
|
||||
if err != nil {
|
||||
t.Fatalf("Dockerfile missing for %s: %v", testFileLineInfo, err)
|
||||
}
|
||||
defer df.Close()
|
||||
|
||||
ast, err := Parse(df)
|
||||
if err != nil {
|
||||
t.Fatalf("Error parsing dockerfile %s: %v", testFileLineInfo, err)
|
||||
}
|
||||
|
||||
if ast.StartLine != 4 || ast.EndLine != 30 {
|
||||
fmt.Fprintf(os.Stderr, "Wrong root line information: expected(%d-%d), actual(%d-%d)\n", 4, 30, ast.StartLine, ast.EndLine)
|
||||
t.Fatalf("Root line information doesn't match result.")
|
||||
}
|
||||
if len(ast.Children) != 3 {
|
||||
fmt.Fprintf(os.Stderr, "Wrong number of child: expected(%d), actual(%d)\n", 3, len(ast.Children))
|
||||
t.Fatalf("Root line information doesn't match result.")
|
||||
}
|
||||
expected := [][]int{
|
||||
{4, 4},
|
||||
{10, 11},
|
||||
{16, 30},
|
||||
}
|
||||
for i, child := range ast.Children {
|
||||
if child.StartLine != expected[i][0] || child.EndLine != expected[i][1] {
|
||||
fmt.Fprintf(os.Stderr, "Wrong line information for child %d: expected(%d-%d), actual(%d-%d)\n",
|
||||
i, expected[i][0], expected[i][1], child.StartLine, child.EndLine)
|
||||
t.Fatalf("Root line information doesn't match result.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
34
builder/dockerfile/parser/testfile-line/Dockerfile
Normal file
34
builder/dockerfile/parser/testfile-line/Dockerfile
Normal file
|
@ -0,0 +1,34 @@
|
|||
|
||||
|
||||
|
||||
FROM brimstone/ubuntu:14.04
|
||||
|
||||
|
||||
# TORUN -v /var/run/docker.sock:/var/run/docker.sock
|
||||
|
||||
|
||||
ENV GOPATH \
|
||||
/go
|
||||
|
||||
|
||||
|
||||
# Install the packages we need, clean up after them and us
|
||||
RUN apt-get update \
|
||||
&& dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.clean \
|
||||
|
||||
|
||||
&& apt-get install -y --no-install-recommends git golang ca-certificates \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists \
|
||||
|
||||
&& go get -v github.com/brimstone/consuldock \
|
||||
&& mv $GOPATH/bin/consuldock /usr/local/bin/consuldock \
|
||||
|
||||
&& dpkg -l | awk '/^ii/ {print $2}' > /tmp/dpkg.dirty \
|
||||
&& apt-get remove --purge -y $(diff /tmp/dpkg.clean /tmp/dpkg.dirty | awk '/^>/ {print $2}') \
|
||||
&& rm /tmp/dpkg.* \
|
||||
&& rm -rf $GOPATH
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in a new issue