mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
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
|
Attributes map[string]bool // special attributes for this node
|
||||||
Original string // original line used before parsing
|
Original string // original line used before parsing
|
||||||
Flags []string // only top Node should have this set
|
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 (
|
var (
|
||||||
|
@ -101,19 +103,24 @@ func parseLine(line string) (string, *Node, error) {
|
||||||
// Parse is the main parse routine.
|
// Parse is the main parse routine.
|
||||||
// It handles an io.ReadWriteCloser and returns the root of the AST.
|
// It handles an io.ReadWriteCloser and returns the root of the AST.
|
||||||
func Parse(rwc io.Reader) (*Node, error) {
|
func Parse(rwc io.Reader) (*Node, error) {
|
||||||
|
currentLine := 0
|
||||||
root := &Node{}
|
root := &Node{}
|
||||||
|
root.StartLine = -1
|
||||||
scanner := bufio.NewScanner(rwc)
|
scanner := bufio.NewScanner(rwc)
|
||||||
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
scannedLine := strings.TrimLeftFunc(scanner.Text(), unicode.IsSpace)
|
scannedLine := strings.TrimLeftFunc(scanner.Text(), unicode.IsSpace)
|
||||||
|
currentLine++
|
||||||
line, child, err := parseLine(scannedLine)
|
line, child, err := parseLine(scannedLine)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
startLine := currentLine
|
||||||
|
|
||||||
if line != "" && child == nil {
|
if line != "" && child == nil {
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
newline := scanner.Text()
|
newline := scanner.Text()
|
||||||
|
currentLine++
|
||||||
|
|
||||||
if stripComments(strings.TrimSpace(newline)) == "" {
|
if stripComments(strings.TrimSpace(newline)) == "" {
|
||||||
continue
|
continue
|
||||||
|
@ -137,6 +144,15 @@ func Parse(rwc io.Reader) (*Node, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if child != nil {
|
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)
|
root.Children = append(root.Children, child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
|
|
||||||
const testDir = "testfiles"
|
const testDir = "testfiles"
|
||||||
const negativeTestDir = "testfiles-negative"
|
const negativeTestDir = "testfiles-negative"
|
||||||
|
const testFileLineInfo = "testfile-line/Dockerfile"
|
||||||
|
|
||||||
func getDirs(t *testing.T, dir string) []string {
|
func getDirs(t *testing.T, dir string) []string {
|
||||||
f, err := os.Open(dir)
|
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…
Add table
Reference in a new issue