mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	Fix golint warnings for builder
Addresses: #14756 Signed-off-by: Qiang Huang <h.huangqiang@huawei.com>
This commit is contained in:
		
							parent
							
								
									c986f85f73
								
							
						
					
					
						commit
						8c4a282a57
					
				
					 13 changed files with 131 additions and 107 deletions
				
			
		| 
						 | 
				
			
			@ -688,7 +688,7 @@ func (s *Server) postCommit(version version.Version, w http.ResponseWriter, r *h
 | 
			
		|||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	commitCfg := &builder.BuilderCommitConfig{
 | 
			
		||||
	commitCfg := &builder.CommitConfig{
 | 
			
		||||
		Pause:   pause,
 | 
			
		||||
		Repo:    r.Form.Get("repo"),
 | 
			
		||||
		Tag:     r.Form.Get("tag"),
 | 
			
		||||
| 
						 | 
				
			
			@ -1276,11 +1276,11 @@ func (s *Server) postBuild(version version.Version, w http.ResponseWriter, r *ht
 | 
			
		|||
	buildConfig.AuthConfigs = authConfigs
 | 
			
		||||
	buildConfig.MemorySwap = int64ValueOrZero(r, "memswap")
 | 
			
		||||
	buildConfig.Memory = int64ValueOrZero(r, "memory")
 | 
			
		||||
	buildConfig.CpuShares = int64ValueOrZero(r, "cpushares")
 | 
			
		||||
	buildConfig.CpuPeriod = int64ValueOrZero(r, "cpuperiod")
 | 
			
		||||
	buildConfig.CpuQuota = int64ValueOrZero(r, "cpuquota")
 | 
			
		||||
	buildConfig.CpuSetCpus = r.FormValue("cpusetcpus")
 | 
			
		||||
	buildConfig.CpuSetMems = r.FormValue("cpusetmems")
 | 
			
		||||
	buildConfig.CPUShares = int64ValueOrZero(r, "cpushares")
 | 
			
		||||
	buildConfig.CPUPeriod = int64ValueOrZero(r, "cpuperiod")
 | 
			
		||||
	buildConfig.CPUQuota = int64ValueOrZero(r, "cpuquota")
 | 
			
		||||
	buildConfig.CPUSetCpus = r.FormValue("cpusetcpus")
 | 
			
		||||
	buildConfig.CPUSetMems = r.FormValue("cpusetmems")
 | 
			
		||||
	buildConfig.CgroupParent = r.FormValue("cgroupparent")
 | 
			
		||||
 | 
			
		||||
	// Job cancellation. Note: not all job types support this.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// FlagType is the type of the build flag
 | 
			
		||||
type FlagType int
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
| 
						 | 
				
			
			@ -12,28 +13,32 @@ const (
 | 
			
		|||
	stringType
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type BuilderFlags struct {
 | 
			
		||||
// BFlags contains all flags information for the builder
 | 
			
		||||
type BFlags struct {
 | 
			
		||||
	Args  []string // actual flags/args from cmd line
 | 
			
		||||
	flags map[string]*Flag
 | 
			
		||||
	used  map[string]*Flag
 | 
			
		||||
	Err   error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Flag contains all information for a flag
 | 
			
		||||
type Flag struct {
 | 
			
		||||
	bf       *BuilderFlags
 | 
			
		||||
	bf       *BFlags
 | 
			
		||||
	name     string
 | 
			
		||||
	flagType FlagType
 | 
			
		||||
	Value    string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewBuilderFlags() *BuilderFlags {
 | 
			
		||||
	return &BuilderFlags{
 | 
			
		||||
// NewBFlags return the new BFlags struct
 | 
			
		||||
func NewBFlags() *BFlags {
 | 
			
		||||
	return &BFlags{
 | 
			
		||||
		flags: make(map[string]*Flag),
 | 
			
		||||
		used:  make(map[string]*Flag),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bf *BuilderFlags) AddBool(name string, def bool) *Flag {
 | 
			
		||||
// AddBool adds a bool flag to BFlags
 | 
			
		||||
func (bf *BFlags) AddBool(name string, def bool) *Flag {
 | 
			
		||||
	flag := bf.addFlag(name, boolType)
 | 
			
		||||
	if flag == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
| 
						 | 
				
			
			@ -46,7 +51,8 @@ func (bf *BuilderFlags) AddBool(name string, def bool) *Flag {
 | 
			
		|||
	return flag
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bf *BuilderFlags) AddString(name string, def string) *Flag {
 | 
			
		||||
// AddString adds a string flag to BFlags
 | 
			
		||||
func (bf *BFlags) AddString(name string, def string) *Flag {
 | 
			
		||||
	flag := bf.addFlag(name, stringType)
 | 
			
		||||
	if flag == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
| 
						 | 
				
			
			@ -55,7 +61,7 @@ func (bf *BuilderFlags) AddString(name string, def string) *Flag {
 | 
			
		|||
	return flag
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bf *BuilderFlags) addFlag(name string, flagType FlagType) *Flag {
 | 
			
		||||
func (bf *BFlags) addFlag(name string, flagType FlagType) *Flag {
 | 
			
		||||
	if _, ok := bf.flags[name]; ok {
 | 
			
		||||
		bf.Err = fmt.Errorf("Duplicate flag defined: %s", name)
 | 
			
		||||
		return nil
 | 
			
		||||
| 
						 | 
				
			
			@ -71,6 +77,7 @@ func (bf *BuilderFlags) addFlag(name string, flagType FlagType) *Flag {
 | 
			
		|||
	return newFlag
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsUsed checks if the flag is used
 | 
			
		||||
func (fl *Flag) IsUsed() bool {
 | 
			
		||||
	if _, ok := fl.bf.used[fl.name]; ok {
 | 
			
		||||
		return true
 | 
			
		||||
| 
						 | 
				
			
			@ -78,6 +85,7 @@ func (fl *Flag) IsUsed() bool {
 | 
			
		|||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// IsTrue checks if a bool flag is true
 | 
			
		||||
func (fl *Flag) IsTrue() bool {
 | 
			
		||||
	if fl.flagType != boolType {
 | 
			
		||||
		// Should never get here
 | 
			
		||||
| 
						 | 
				
			
			@ -86,7 +94,8 @@ func (fl *Flag) IsTrue() bool {
 | 
			
		|||
	return fl.Value == "true"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (bf *BuilderFlags) Parse() error {
 | 
			
		||||
// Parse parses and checks if the BFlags is valid
 | 
			
		||||
func (bf *BFlags) Parse() error {
 | 
			
		||||
	// If there was an error while defining the possible flags
 | 
			
		||||
	// go ahead and bubble it back up here since we didn't do it
 | 
			
		||||
	// earlier in the processing
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ func TestBuilderFlags(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	// ---
 | 
			
		||||
 | 
			
		||||
	bf := NewBuilderFlags()
 | 
			
		||||
	bf := NewBFlags()
 | 
			
		||||
	bf.Args = []string{}
 | 
			
		||||
	if err := bf.Parse(); err != nil {
 | 
			
		||||
		t.Fatalf("Test1 of %q was supposed to work: %s", bf.Args, err)
 | 
			
		||||
| 
						 | 
				
			
			@ -18,7 +18,7 @@ func TestBuilderFlags(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	// ---
 | 
			
		||||
 | 
			
		||||
	bf = NewBuilderFlags()
 | 
			
		||||
	bf = NewBFlags()
 | 
			
		||||
	bf.Args = []string{"--"}
 | 
			
		||||
	if err := bf.Parse(); err != nil {
 | 
			
		||||
		t.Fatalf("Test2 of %q was supposed to work: %s", bf.Args, err)
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ func TestBuilderFlags(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	// ---
 | 
			
		||||
 | 
			
		||||
	bf = NewBuilderFlags()
 | 
			
		||||
	bf = NewBFlags()
 | 
			
		||||
	flStr1 := bf.AddString("str1", "")
 | 
			
		||||
	flBool1 := bf.AddBool("bool1", false)
 | 
			
		||||
	bf.Args = []string{}
 | 
			
		||||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ func TestBuilderFlags(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	// ---
 | 
			
		||||
 | 
			
		||||
	bf = NewBuilderFlags()
 | 
			
		||||
	bf = NewBFlags()
 | 
			
		||||
	flStr1 = bf.AddString("str1", "HI")
 | 
			
		||||
	flBool1 = bf.AddBool("bool1", false)
 | 
			
		||||
	bf.Args = []string{}
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +67,7 @@ func TestBuilderFlags(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	// ---
 | 
			
		||||
 | 
			
		||||
	bf = NewBuilderFlags()
 | 
			
		||||
	bf = NewBFlags()
 | 
			
		||||
	flStr1 = bf.AddString("str1", "HI")
 | 
			
		||||
	bf.Args = []string{"--str1"}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +77,7 @@ func TestBuilderFlags(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	// ---
 | 
			
		||||
 | 
			
		||||
	bf = NewBuilderFlags()
 | 
			
		||||
	bf = NewBFlags()
 | 
			
		||||
	flStr1 = bf.AddString("str1", "HI")
 | 
			
		||||
	bf.Args = []string{"--str1="}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -92,7 +92,7 @@ func TestBuilderFlags(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	// ---
 | 
			
		||||
 | 
			
		||||
	bf = NewBuilderFlags()
 | 
			
		||||
	bf = NewBFlags()
 | 
			
		||||
	flStr1 = bf.AddString("str1", "HI")
 | 
			
		||||
	bf.Args = []string{"--str1=BYE"}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ func TestBuilderFlags(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	// ---
 | 
			
		||||
 | 
			
		||||
	bf = NewBuilderFlags()
 | 
			
		||||
	bf = NewBFlags()
 | 
			
		||||
	flBool1 = bf.AddBool("bool1", false)
 | 
			
		||||
	bf.Args = []string{"--bool1"}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +121,7 @@ func TestBuilderFlags(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	// ---
 | 
			
		||||
 | 
			
		||||
	bf = NewBuilderFlags()
 | 
			
		||||
	bf = NewBFlags()
 | 
			
		||||
	flBool1 = bf.AddBool("bool1", false)
 | 
			
		||||
	bf.Args = []string{"--bool1=true"}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -135,7 +135,7 @@ func TestBuilderFlags(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	// ---
 | 
			
		||||
 | 
			
		||||
	bf = NewBuilderFlags()
 | 
			
		||||
	bf = NewBFlags()
 | 
			
		||||
	flBool1 = bf.AddBool("bool1", false)
 | 
			
		||||
	bf.Args = []string{"--bool1=false"}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -149,7 +149,7 @@ func TestBuilderFlags(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	// ---
 | 
			
		||||
 | 
			
		||||
	bf = NewBuilderFlags()
 | 
			
		||||
	bf = NewBFlags()
 | 
			
		||||
	flBool1 = bf.AddBool("bool1", false)
 | 
			
		||||
	bf.Args = []string{"--bool1=false1"}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -159,7 +159,7 @@ func TestBuilderFlags(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	// ---
 | 
			
		||||
 | 
			
		||||
	bf = NewBuilderFlags()
 | 
			
		||||
	bf = NewBFlags()
 | 
			
		||||
	flBool1 = bf.AddBool("bool1", false)
 | 
			
		||||
	bf.Args = []string{"--bool2"}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -169,7 +169,7 @@ func TestBuilderFlags(t *testing.T) {
 | 
			
		|||
 | 
			
		||||
	// ---
 | 
			
		||||
 | 
			
		||||
	bf = NewBuilderFlags()
 | 
			
		||||
	bf = NewBFlags()
 | 
			
		||||
	flStr1 = bf.AddString("str1", "HI")
 | 
			
		||||
	flBool1 = bf.AddBool("bool1", false)
 | 
			
		||||
	bf.Args = []string{"--bool1", "--str1=BYE"}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
// This package contains the set of Dockerfile commands.
 | 
			
		||||
// Package command contains the set of Dockerfile commands.
 | 
			
		||||
package command
 | 
			
		||||
 | 
			
		||||
// Define constants for the command strings
 | 
			
		||||
const (
 | 
			
		||||
	Env        = "env"
 | 
			
		||||
	Label      = "label"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ const (
 | 
			
		|||
)
 | 
			
		||||
 | 
			
		||||
// dispatch with no layer / parsing. This is effectively not a command.
 | 
			
		||||
func nullDispatch(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func nullDispatch(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ func nullDispatch(b *Builder, args []string, attributes map[string]bool, origina
 | 
			
		|||
// Sets the environment variable foo to bar, also makes interpolation
 | 
			
		||||
// in the dockerfile available from the next statement on via ${foo}.
 | 
			
		||||
//
 | 
			
		||||
func env(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func env(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	if len(args) == 0 {
 | 
			
		||||
		return fmt.Errorf("ENV requires at least one argument")
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +98,7 @@ func env(b *Builder, args []string, attributes map[string]bool, original string)
 | 
			
		|||
// MAINTAINER some text <maybe@an.email.address>
 | 
			
		||||
//
 | 
			
		||||
// Sets the maintainer metadata.
 | 
			
		||||
func maintainer(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func maintainer(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	if len(args) != 1 {
 | 
			
		||||
		return fmt.Errorf("MAINTAINER requires exactly one argument")
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -115,7 +115,7 @@ func maintainer(b *Builder, args []string, attributes map[string]bool, original
 | 
			
		|||
//
 | 
			
		||||
// Sets the Label variable foo to bar,
 | 
			
		||||
//
 | 
			
		||||
func label(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func label(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	if len(args) == 0 {
 | 
			
		||||
		return fmt.Errorf("LABEL requires at least one argument")
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +151,7 @@ func label(b *Builder, args []string, attributes map[string]bool, original strin
 | 
			
		|||
// Add the file 'foo' to '/path'. Tarball and Remote URL (git, http) handling
 | 
			
		||||
// exist here. If you do not wish to have this automatic handling, use COPY.
 | 
			
		||||
//
 | 
			
		||||
func add(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func add(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	if len(args) < 2 {
 | 
			
		||||
		return fmt.Errorf("ADD requires at least two arguments")
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -167,7 +167,7 @@ func add(b *Builder, args []string, attributes map[string]bool, original string)
 | 
			
		|||
//
 | 
			
		||||
// Same as 'ADD' but without the tar and remote url handling.
 | 
			
		||||
//
 | 
			
		||||
func dispatchCopy(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func dispatchCopy(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	if len(args) < 2 {
 | 
			
		||||
		return fmt.Errorf("COPY requires at least two arguments")
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -183,7 +183,7 @@ func dispatchCopy(b *Builder, args []string, attributes map[string]bool, origina
 | 
			
		|||
//
 | 
			
		||||
// This sets the image the dockerfile will build on top of.
 | 
			
		||||
//
 | 
			
		||||
func from(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func from(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	if len(args) != 1 {
 | 
			
		||||
		return fmt.Errorf("FROM requires one argument")
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -231,7 +231,7 @@ func from(b *Builder, args []string, attributes map[string]bool, original string
 | 
			
		|||
// special cases. search for 'OnBuild' in internals.go for additional special
 | 
			
		||||
// cases.
 | 
			
		||||
//
 | 
			
		||||
func onbuild(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func onbuild(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	if len(args) == 0 {
 | 
			
		||||
		return fmt.Errorf("ONBUILD requires at least one argument")
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -258,7 +258,7 @@ func onbuild(b *Builder, args []string, attributes map[string]bool, original str
 | 
			
		|||
//
 | 
			
		||||
// Set the working directory for future RUN/CMD/etc statements.
 | 
			
		||||
//
 | 
			
		||||
func workdir(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func workdir(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	if len(args) != 1 {
 | 
			
		||||
		return fmt.Errorf("WORKDIR requires exactly one argument")
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -315,7 +315,7 @@ func workdir(b *Builder, args []string, attributes map[string]bool, original str
 | 
			
		|||
// RUN echo hi          # cmd /S /C echo hi   (Windows)
 | 
			
		||||
// RUN [ "echo", "hi" ] # echo hi
 | 
			
		||||
//
 | 
			
		||||
func run(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func run(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	if b.image == "" && !b.noBaseImage {
 | 
			
		||||
		return fmt.Errorf("Please provide a source image with `from` prior to run")
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -324,7 +324,7 @@ func run(b *Builder, args []string, attributes map[string]bool, original string)
 | 
			
		|||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	args = handleJsonArgs(args, attributes)
 | 
			
		||||
	args = handleJSONArgs(args, attributes)
 | 
			
		||||
 | 
			
		||||
	if !attributes["json"] {
 | 
			
		||||
		if runtime.GOOS != "windows" {
 | 
			
		||||
| 
						 | 
				
			
			@ -386,12 +386,12 @@ func run(b *Builder, args []string, attributes map[string]bool, original string)
 | 
			
		|||
// Set the default command to run in the container (which may be empty).
 | 
			
		||||
// Argument handling is the same as RUN.
 | 
			
		||||
//
 | 
			
		||||
func cmd(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func cmd(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	if err := b.BuilderFlags.Parse(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cmdSlice := handleJsonArgs(args, attributes)
 | 
			
		||||
	cmdSlice := handleJSONArgs(args, attributes)
 | 
			
		||||
 | 
			
		||||
	if !attributes["json"] {
 | 
			
		||||
		if runtime.GOOS != "windows" {
 | 
			
		||||
| 
						 | 
				
			
			@ -422,12 +422,12 @@ func cmd(b *Builder, args []string, attributes map[string]bool, original string)
 | 
			
		|||
// Handles command processing similar to CMD and RUN, only b.Config.Entrypoint
 | 
			
		||||
// is initialized at NewBuilder time instead of through argument parsing.
 | 
			
		||||
//
 | 
			
		||||
func entrypoint(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func entrypoint(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	if err := b.BuilderFlags.Parse(); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	parsed := handleJsonArgs(args, attributes)
 | 
			
		||||
	parsed := handleJSONArgs(args, attributes)
 | 
			
		||||
 | 
			
		||||
	switch {
 | 
			
		||||
	case attributes["json"]:
 | 
			
		||||
| 
						 | 
				
			
			@ -463,7 +463,7 @@ func entrypoint(b *Builder, args []string, attributes map[string]bool, original
 | 
			
		|||
// Expose ports for links and port mappings. This all ends up in
 | 
			
		||||
// b.Config.ExposedPorts for runconfig.
 | 
			
		||||
//
 | 
			
		||||
func expose(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func expose(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	portsTab := args
 | 
			
		||||
 | 
			
		||||
	if len(args) == 0 {
 | 
			
		||||
| 
						 | 
				
			
			@ -504,9 +504,9 @@ func expose(b *Builder, args []string, attributes map[string]bool, original stri
 | 
			
		|||
// Set the user to 'foo' for future commands and when running the
 | 
			
		||||
// ENTRYPOINT/CMD at container run time.
 | 
			
		||||
//
 | 
			
		||||
func user(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func user(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	if runtime.GOOS == "windows" {
 | 
			
		||||
		return fmt.Errorf("USER is not supported on Windows.")
 | 
			
		||||
		return fmt.Errorf("USER is not supported on Windows")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if len(args) != 1 {
 | 
			
		||||
| 
						 | 
				
			
			@ -525,9 +525,9 @@ func user(b *Builder, args []string, attributes map[string]bool, original string
 | 
			
		|||
//
 | 
			
		||||
// Expose the volume /foo for use. Will also accept the JSON array form.
 | 
			
		||||
//
 | 
			
		||||
func volume(b *Builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
func volume(b *builder, args []string, attributes map[string]bool, original string) error {
 | 
			
		||||
	if runtime.GOOS == "windows" {
 | 
			
		||||
		return fmt.Errorf("VOLUME is not supported on Windows.")
 | 
			
		||||
		return fmt.Errorf("VOLUME is not supported on Windows")
 | 
			
		||||
	}
 | 
			
		||||
	if len(args) == 0 {
 | 
			
		||||
		return fmt.Errorf("VOLUME requires at least one argument")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,10 +53,10 @@ var replaceEnvAllowed = map[string]struct{}{
 | 
			
		|||
	command.User:    {},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var evaluateTable map[string]func(*Builder, []string, map[string]bool, string) error
 | 
			
		||||
var evaluateTable map[string]func(*builder, []string, map[string]bool, string) error
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	evaluateTable = map[string]func(*Builder, []string, map[string]bool, string) error{
 | 
			
		||||
	evaluateTable = map[string]func(*builder, []string, map[string]bool, string) error{
 | 
			
		||||
		command.Env:        env,
 | 
			
		||||
		command.Label:      label,
 | 
			
		||||
		command.Maintainer: maintainer,
 | 
			
		||||
| 
						 | 
				
			
			@ -74,9 +74,9 @@ func init() {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// internal struct, used to maintain configuration of the Dockerfile's
 | 
			
		||||
// builder is an internal struct, used to maintain configuration of the Dockerfile's
 | 
			
		||||
// processing as it evaluates the parsing result.
 | 
			
		||||
type Builder struct {
 | 
			
		||||
type builder struct {
 | 
			
		||||
	Daemon *daemon.Daemon
 | 
			
		||||
 | 
			
		||||
	// effectively stdio for the run. Because it is not stdio, I said
 | 
			
		||||
| 
						 | 
				
			
			@ -115,7 +115,7 @@ type Builder struct {
 | 
			
		|||
	image          string        // image name for commit processing
 | 
			
		||||
	maintainer     string        // maintainer name. could probably be removed.
 | 
			
		||||
	cmdSet         bool          // indicates is CMD was set in current Dockerfile
 | 
			
		||||
	BuilderFlags   *BuilderFlags // current cmd's BuilderFlags - temporary
 | 
			
		||||
	BuilderFlags   *BFlags       // current cmd's BuilderFlags - temporary
 | 
			
		||||
	context        tarsum.TarSum // the context is a tarball that is uploaded by the client
 | 
			
		||||
	contextPath    string        // the path of the temporary directory the local context is unpacked to (server side)
 | 
			
		||||
	noBaseImage    bool          // indicates that this build does not start from any base image, but is being built from an empty file system.
 | 
			
		||||
| 
						 | 
				
			
			@ -148,7 +148,7 @@ type Builder struct {
 | 
			
		|||
//   processing.
 | 
			
		||||
// * Print a happy message and return the image ID.
 | 
			
		||||
//
 | 
			
		||||
func (b *Builder) Run(context io.Reader) (string, error) {
 | 
			
		||||
func (b *builder) Run(context io.Reader) (string, error) {
 | 
			
		||||
	if err := b.readContext(context); err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -199,7 +199,7 @@ func (b *Builder) Run(context io.Reader) (string, error) {
 | 
			
		|||
 | 
			
		||||
// Reads a Dockerfile from the current context. It assumes that the
 | 
			
		||||
// 'filename' is a relative path from the root of the context
 | 
			
		||||
func (b *Builder) readDockerfile() error {
 | 
			
		||||
func (b *builder) readDockerfile() error {
 | 
			
		||||
	// If no -f was specified then look for 'Dockerfile'. If we can't find
 | 
			
		||||
	// that then look for 'dockerfile'.  If neither are found then default
 | 
			
		||||
	// back to 'Dockerfile' and use that in the error message.
 | 
			
		||||
| 
						 | 
				
			
			@ -277,7 +277,7 @@ func (b *Builder) readDockerfile() error {
 | 
			
		|||
// such as `RUN` in ONBUILD RUN foo. There is special case logic in here to
 | 
			
		||||
// deal with that, at least until it becomes more of a general concern with new
 | 
			
		||||
// features.
 | 
			
		||||
func (b *Builder) dispatch(stepN int, ast *parser.Node) error {
 | 
			
		||||
func (b *builder) dispatch(stepN int, ast *parser.Node) error {
 | 
			
		||||
	cmd := ast.Value
 | 
			
		||||
	attrs := ast.Attributes
 | 
			
		||||
	original := ast.Original
 | 
			
		||||
| 
						 | 
				
			
			@ -340,7 +340,7 @@ func (b *Builder) dispatch(stepN int, ast *parser.Node) error {
 | 
			
		|||
	// XXX yes, we skip any cmds that are not valid; the parser should have
 | 
			
		||||
	// picked these out already.
 | 
			
		||||
	if f, ok := evaluateTable[cmd]; ok {
 | 
			
		||||
		b.BuilderFlags = NewBuilderFlags()
 | 
			
		||||
		b.BuilderFlags = NewBFlags()
 | 
			
		||||
		b.BuilderFlags.Args = flags
 | 
			
		||||
		return f(b, strList, attrs, original)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,7 +40,7 @@ import (
 | 
			
		|||
	"github.com/docker/docker/runconfig"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (b *Builder) readContext(context io.Reader) (err error) {
 | 
			
		||||
func (b *builder) readContext(context io.Reader) (err error) {
 | 
			
		||||
	tmpdirPath, err := ioutil.TempDir("", "docker-build")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ func (b *Builder) readContext(context io.Reader) (err error) {
 | 
			
		|||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Builder) commit(id string, autoCmd *runconfig.Command, comment string) error {
 | 
			
		||||
func (b *builder) commit(id string, autoCmd *runconfig.Command, comment string) error {
 | 
			
		||||
	if b.disableCommit {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +143,7 @@ type copyInfo struct {
 | 
			
		|||
	tmpDir     string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Builder) runContextCommand(args []string, allowRemote bool, allowDecompression bool, cmdName string) error {
 | 
			
		||||
func (b *builder) runContextCommand(args []string, allowRemote bool, allowDecompression bool, cmdName string) error {
 | 
			
		||||
	if b.context == nil {
 | 
			
		||||
		return fmt.Errorf("No context given. Impossible to use %s", cmdName)
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -261,7 +261,7 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowDecomp
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func calcCopyInfo(b *Builder, cmdName string, cInfos *[]*copyInfo, origPath string, destPath string, allowRemote bool, allowDecompression bool, allowWildcards bool) error {
 | 
			
		||||
func calcCopyInfo(b *builder, cmdName string, cInfos *[]*copyInfo, origPath string, destPath string, allowRemote bool, allowDecompression bool, allowWildcards bool) error {
 | 
			
		||||
 | 
			
		||||
	// Work in daemon-specific OS filepath semantics. However, we save
 | 
			
		||||
	// the the origPath passed in here, as it might also be a URL which
 | 
			
		||||
| 
						 | 
				
			
			@ -398,7 +398,7 @@ func calcCopyInfo(b *Builder, cmdName string, cInfos *[]*copyInfo, origPath stri
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	// Deal with wildcards
 | 
			
		||||
	if allowWildcards && ContainsWildcards(origPath) {
 | 
			
		||||
	if allowWildcards && containsWildcards(origPath) {
 | 
			
		||||
		for _, fileInfo := range b.context.GetSums() {
 | 
			
		||||
			if fileInfo.Name() == "" {
 | 
			
		||||
				continue
 | 
			
		||||
| 
						 | 
				
			
			@ -475,7 +475,7 @@ func calcCopyInfo(b *Builder, cmdName string, cInfos *[]*copyInfo, origPath stri
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ContainsWildcards(name string) bool {
 | 
			
		||||
func containsWildcards(name string) bool {
 | 
			
		||||
	for i := 0; i < len(name); i++ {
 | 
			
		||||
		ch := name[i]
 | 
			
		||||
		if ch == '\\' {
 | 
			
		||||
| 
						 | 
				
			
			@ -487,7 +487,7 @@ func ContainsWildcards(name string) bool {
 | 
			
		|||
	return false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Builder) pullImage(name string) (*image.Image, error) {
 | 
			
		||||
func (b *builder) pullImage(name string) (*image.Image, error) {
 | 
			
		||||
	remote, tag := parsers.ParseRepositoryTag(name)
 | 
			
		||||
	if tag == "" {
 | 
			
		||||
		tag = "latest"
 | 
			
		||||
| 
						 | 
				
			
			@ -525,7 +525,7 @@ func (b *Builder) pullImage(name string) (*image.Image, error) {
 | 
			
		|||
	return image, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Builder) processImageFrom(img *image.Image) error {
 | 
			
		||||
func (b *builder) processImageFrom(img *image.Image) error {
 | 
			
		||||
	b.image = img.ID
 | 
			
		||||
 | 
			
		||||
	if img.Config != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -577,7 +577,7 @@ func (b *Builder) processImageFrom(img *image.Image) error {
 | 
			
		|||
// in the current server `b.Daemon`. If an image is found, probeCache returns
 | 
			
		||||
// `(true, nil)`. If no image is found, it returns `(false, nil)`. If there
 | 
			
		||||
// is any error, it returns `(false, err)`.
 | 
			
		||||
func (b *Builder) probeCache() (bool, error) {
 | 
			
		||||
func (b *builder) probeCache() (bool, error) {
 | 
			
		||||
	if !b.UtilizeCache || b.cacheBusted {
 | 
			
		||||
		return false, nil
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -600,7 +600,7 @@ func (b *Builder) probeCache() (bool, error) {
 | 
			
		|||
	return true, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Builder) create() (*daemon.Container, error) {
 | 
			
		||||
func (b *builder) create() (*daemon.Container, error) {
 | 
			
		||||
	if b.image == "" && !b.noBaseImage {
 | 
			
		||||
		return nil, fmt.Errorf("Please provide a source image with `from` prior to run")
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -643,7 +643,7 @@ func (b *Builder) create() (*daemon.Container, error) {
 | 
			
		|||
	return c, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Builder) run(c *daemon.Container) error {
 | 
			
		||||
func (b *builder) run(c *daemon.Container) error {
 | 
			
		||||
	var errCh chan error
 | 
			
		||||
	if b.Verbose {
 | 
			
		||||
		errCh = c.Attach(nil, b.OutStream, b.ErrStream)
 | 
			
		||||
| 
						 | 
				
			
			@ -683,7 +683,7 @@ func (b *Builder) run(c *daemon.Container) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Builder) checkPathForAddition(orig string) error {
 | 
			
		||||
func (b *builder) checkPathForAddition(orig string) error {
 | 
			
		||||
	origPath := filepath.Join(b.contextPath, orig)
 | 
			
		||||
	origPath, err := filepath.EvalSymlinks(origPath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -708,7 +708,7 @@ func (b *Builder) checkPathForAddition(orig string) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Builder) addContext(container *daemon.Container, orig, dest string, decompress bool) error {
 | 
			
		||||
func (b *builder) addContext(container *daemon.Container, orig, dest string, decompress bool) error {
 | 
			
		||||
	var (
 | 
			
		||||
		err        error
 | 
			
		||||
		destExists = true
 | 
			
		||||
| 
						 | 
				
			
			@ -791,7 +791,7 @@ func copyAsDirectory(source, destination string, destExisted bool) error {
 | 
			
		|||
	return fixPermissions(source, destination, 0, 0, destExisted)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (b *Builder) clearTmp() {
 | 
			
		||||
func (b *builder) clearTmp() {
 | 
			
		||||
	for c := range b.TmpContainers {
 | 
			
		||||
		rmConfig := &daemon.ContainerRmConfig{
 | 
			
		||||
			ForceRemove:  true,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,6 +44,7 @@ var validCommitCommands = map[string]bool{
 | 
			
		|||
	"workdir":    true,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Config contains all configs for a build job
 | 
			
		||||
type Config struct {
 | 
			
		||||
	DockerfileName string
 | 
			
		||||
	RemoteURL      string
 | 
			
		||||
| 
						 | 
				
			
			@ -55,11 +56,11 @@ type Config struct {
 | 
			
		|||
	Pull           bool
 | 
			
		||||
	Memory         int64
 | 
			
		||||
	MemorySwap     int64
 | 
			
		||||
	CpuShares      int64
 | 
			
		||||
	CpuPeriod      int64
 | 
			
		||||
	CpuQuota       int64
 | 
			
		||||
	CpuSetCpus     string
 | 
			
		||||
	CpuSetMems     string
 | 
			
		||||
	CPUShares      int64
 | 
			
		||||
	CPUPeriod      int64
 | 
			
		||||
	CPUQuota       int64
 | 
			
		||||
	CPUSetCpus     string
 | 
			
		||||
	CPUSetMems     string
 | 
			
		||||
	CgroupParent   string
 | 
			
		||||
	AuthConfigs    map[string]cliconfig.AuthConfig
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,18 +73,20 @@ type Config struct {
 | 
			
		|||
	cancelOnce sync.Once
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// When called, causes the Job.WaitCancelled channel to unblock.
 | 
			
		||||
// Cancel signals the build job to cancel
 | 
			
		||||
func (b *Config) Cancel() {
 | 
			
		||||
	b.cancelOnce.Do(func() {
 | 
			
		||||
		close(b.cancelled)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Returns a channel which is closed ("never blocks") when the job is cancelled.
 | 
			
		||||
// WaitCancelled returns a channel which is closed ("never blocks") when
 | 
			
		||||
// the job is cancelled.
 | 
			
		||||
func (b *Config) WaitCancelled() <-chan struct{} {
 | 
			
		||||
	return b.cancelled
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NewBuildConfig returns a new Config struct
 | 
			
		||||
func NewBuildConfig() *Config {
 | 
			
		||||
	return &Config{
 | 
			
		||||
		AuthConfigs: map[string]cliconfig.AuthConfig{},
 | 
			
		||||
| 
						 | 
				
			
			@ -91,6 +94,8 @@ func NewBuildConfig() *Config {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Build is the main interface of the package, it gathers the Builder
 | 
			
		||||
// struct and calls builder.Run() to do all the real build job.
 | 
			
		||||
func Build(d *daemon.Daemon, buildConfig *Config) error {
 | 
			
		||||
	var (
 | 
			
		||||
		repoName string
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +178,7 @@ func Build(d *daemon.Daemon, buildConfig *Config) error {
 | 
			
		|||
 | 
			
		||||
	defer context.Close()
 | 
			
		||||
 | 
			
		||||
	builder := &Builder{
 | 
			
		||||
	builder := &builder{
 | 
			
		||||
		Daemon: d,
 | 
			
		||||
		OutStream: &streamformatter.StdoutFormater{
 | 
			
		||||
			Writer:          buildConfig.Stdout,
 | 
			
		||||
| 
						 | 
				
			
			@ -192,11 +197,11 @@ func Build(d *daemon.Daemon, buildConfig *Config) error {
 | 
			
		|||
		StreamFormatter: sf,
 | 
			
		||||
		AuthConfigs:     buildConfig.AuthConfigs,
 | 
			
		||||
		dockerfileName:  buildConfig.DockerfileName,
 | 
			
		||||
		cpuShares:       buildConfig.CpuShares,
 | 
			
		||||
		cpuPeriod:       buildConfig.CpuPeriod,
 | 
			
		||||
		cpuQuota:        buildConfig.CpuQuota,
 | 
			
		||||
		cpuSetCpus:      buildConfig.CpuSetCpus,
 | 
			
		||||
		cpuSetMems:      buildConfig.CpuSetMems,
 | 
			
		||||
		cpuShares:       buildConfig.CPUShares,
 | 
			
		||||
		cpuPeriod:       buildConfig.CPUPeriod,
 | 
			
		||||
		cpuQuota:        buildConfig.CPUQuota,
 | 
			
		||||
		cpuSetCpus:      buildConfig.CPUSetCpus,
 | 
			
		||||
		cpuSetMems:      buildConfig.CPUSetMems,
 | 
			
		||||
		cgroupParent:    buildConfig.CgroupParent,
 | 
			
		||||
		memory:          buildConfig.Memory,
 | 
			
		||||
		memorySwap:      buildConfig.MemorySwap,
 | 
			
		||||
| 
						 | 
				
			
			@ -218,6 +223,11 @@ func Build(d *daemon.Daemon, buildConfig *Config) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// BuildFromConfig will do build directly from parameter 'changes', which comes
 | 
			
		||||
// from Dockerfile entries, it will:
 | 
			
		||||
//
 | 
			
		||||
// - call parse.Parse() to get AST root from Dockerfile entries
 | 
			
		||||
// - do build by calling builder.dispatch() to call all entries' handling routines
 | 
			
		||||
func BuildFromConfig(d *daemon.Daemon, c *runconfig.Config, changes []string) (*runconfig.Config, error) {
 | 
			
		||||
	ast, err := parser.Parse(bytes.NewBufferString(strings.Join(changes, "\n")))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -231,7 +241,7 @@ func BuildFromConfig(d *daemon.Daemon, c *runconfig.Config, changes []string) (*
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	builder := &Builder{
 | 
			
		||||
	builder := &builder{
 | 
			
		||||
		Daemon:        d,
 | 
			
		||||
		Config:        c,
 | 
			
		||||
		OutStream:     ioutil.Discard,
 | 
			
		||||
| 
						 | 
				
			
			@ -248,7 +258,8 @@ func BuildFromConfig(d *daemon.Daemon, c *runconfig.Config, changes []string) (*
 | 
			
		|||
	return builder.Config, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type BuilderCommitConfig struct {
 | 
			
		||||
// CommitConfig contains build configs for commit operation
 | 
			
		||||
type CommitConfig struct {
 | 
			
		||||
	Pause   bool
 | 
			
		||||
	Repo    string
 | 
			
		||||
	Tag     string
 | 
			
		||||
| 
						 | 
				
			
			@ -258,7 +269,8 @@ type BuilderCommitConfig struct {
 | 
			
		|||
	Config  *runconfig.Config
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Commit(name string, d *daemon.Daemon, c *BuilderCommitConfig) (string, error) {
 | 
			
		||||
// Commit will create a new image from a container's changes
 | 
			
		||||
func Commit(name string, d *daemon.Daemon, c *CommitConfig) (string, error) {
 | 
			
		||||
	container, err := d.Get(name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -151,7 +151,7 @@ func parseNameVal(rest string, key string) (*Node, map[string]bool, error) {
 | 
			
		|||
	if !strings.Contains(words[0], "=") {
 | 
			
		||||
		node := &Node{}
 | 
			
		||||
		rootnode = node
 | 
			
		||||
		strs := TOKEN_WHITESPACE.Split(rest, 2)
 | 
			
		||||
		strs := tokenWhitespace.Split(rest, 2)
 | 
			
		||||
 | 
			
		||||
		if len(strs) < 2 {
 | 
			
		||||
			return nil, nil, fmt.Errorf(key + " must have two arguments")
 | 
			
		||||
| 
						 | 
				
			
			@ -205,7 +205,7 @@ func parseStringsWhitespaceDelimited(rest string) (*Node, map[string]bool, error
 | 
			
		|||
	node := &Node{}
 | 
			
		||||
	rootnode := node
 | 
			
		||||
	prevnode := node
 | 
			
		||||
	for _, str := range TOKEN_WHITESPACE.Split(rest, -1) { // use regexp
 | 
			
		||||
	for _, str := range tokenWhitespace.Split(rest, -1) { // use regexp
 | 
			
		||||
		prevnode = node
 | 
			
		||||
		node.Value = str
 | 
			
		||||
		node.Next = &Node{}
 | 
			
		||||
| 
						 | 
				
			
			@ -232,13 +232,13 @@ func parseString(rest string) (*Node, map[string]bool, error) {
 | 
			
		|||
 | 
			
		||||
// parseJSON converts JSON arrays to an AST.
 | 
			
		||||
func parseJSON(rest string) (*Node, map[string]bool, error) {
 | 
			
		||||
	var myJson []interface{}
 | 
			
		||||
	if err := json.NewDecoder(strings.NewReader(rest)).Decode(&myJson); err != nil {
 | 
			
		||||
	var myJSON []interface{}
 | 
			
		||||
	if err := json.NewDecoder(strings.NewReader(rest)).Decode(&myJSON); err != nil {
 | 
			
		||||
		return nil, nil, err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var top, prev *Node
 | 
			
		||||
	for _, str := range myJson {
 | 
			
		||||
	for _, str := range myJSON {
 | 
			
		||||
		s, ok := str.(string)
 | 
			
		||||
		if !ok {
 | 
			
		||||
			return nil, nil, errDockerfileNotStringArray
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
// This package implements a parser and parse tree dumper for Dockerfiles.
 | 
			
		||||
// Package parser implements a parser and parse tree dumper for Dockerfiles.
 | 
			
		||||
package parser
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
| 
						 | 
				
			
			@ -33,10 +33,10 @@ type Node struct {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	dispatch                map[string]func(string) (*Node, map[string]bool, error)
 | 
			
		||||
	TOKEN_WHITESPACE        = regexp.MustCompile(`[\t\v\f\r ]+`)
 | 
			
		||||
	TOKEN_LINE_CONTINUATION = regexp.MustCompile(`\\[ \t]*$`)
 | 
			
		||||
	TOKEN_COMMENT           = regexp.MustCompile(`^#.*$`)
 | 
			
		||||
	dispatch              map[string]func(string) (*Node, map[string]bool, error)
 | 
			
		||||
	tokenWhitespace       = regexp.MustCompile(`[\t\v\f\r ]+`)
 | 
			
		||||
	tokenLineContinuation = regexp.MustCompile(`\\[ \t]*$`)
 | 
			
		||||
	tokenComment          = regexp.MustCompile(`^#.*$`)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
| 
						 | 
				
			
			@ -70,8 +70,8 @@ func parseLine(line string) (string, *Node, error) {
 | 
			
		|||
		return "", nil, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if TOKEN_LINE_CONTINUATION.MatchString(line) {
 | 
			
		||||
		line = TOKEN_LINE_CONTINUATION.ReplaceAllString(line, "")
 | 
			
		||||
	if tokenLineContinuation.MatchString(line) {
 | 
			
		||||
		line = tokenLineContinuation.ReplaceAllString(line, "")
 | 
			
		||||
		return line, nil, nil
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -96,8 +96,8 @@ func parseLine(line string) (string, *Node, error) {
 | 
			
		|||
	return "", node, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// The main parse routine. Handles an io.ReadWriteCloser and returns the root
 | 
			
		||||
// of the AST.
 | 
			
		||||
// 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) {
 | 
			
		||||
	root := &Node{}
 | 
			
		||||
	scanner := bufio.NewScanner(rwc)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,8 +7,8 @@ import (
 | 
			
		|||
	"unicode"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// dumps the AST defined by `node` as a list of sexps. Returns a string
 | 
			
		||||
// suitable for printing.
 | 
			
		||||
// Dump dumps the AST defined by `node` as a list of sexps.
 | 
			
		||||
// Returns a string suitable for printing.
 | 
			
		||||
func (node *Node) Dump() string {
 | 
			
		||||
	str := ""
 | 
			
		||||
	str += node.Value
 | 
			
		||||
| 
						 | 
				
			
			@ -59,7 +59,7 @@ func splitCommand(line string) (string, []string, string, error) {
 | 
			
		|||
	var flags []string
 | 
			
		||||
 | 
			
		||||
	// Make sure we get the same results irrespective of leading/trailing spaces
 | 
			
		||||
	cmdline := TOKEN_WHITESPACE.Split(strings.TrimSpace(line), 2)
 | 
			
		||||
	cmdline := tokenWhitespace.Split(strings.TrimSpace(line), 2)
 | 
			
		||||
	cmd := strings.ToLower(cmdline[0])
 | 
			
		||||
 | 
			
		||||
	if len(cmdline) == 2 {
 | 
			
		||||
| 
						 | 
				
			
			@ -77,8 +77,8 @@ func splitCommand(line string) (string, []string, string, error) {
 | 
			
		|||
// this function.
 | 
			
		||||
func stripComments(line string) string {
 | 
			
		||||
	// string is already trimmed at this point
 | 
			
		||||
	if TOKEN_COMMENT.MatchString(line) {
 | 
			
		||||
		return TOKEN_COMMENT.ReplaceAllString(line, "")
 | 
			
		||||
	if tokenComment.MatchString(line) {
 | 
			
		||||
		return tokenComment.ReplaceAllString(line, "")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return line
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,6 +18,8 @@ type shellWord struct {
 | 
			
		|||
	pos  int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ProcessWord will use the 'env' list of environment variables,
 | 
			
		||||
// and replace any env var references in 'word'.
 | 
			
		||||
func ProcessWord(word string, env []string) (string, error) {
 | 
			
		||||
	sw := &shellWord{
 | 
			
		||||
		word: word,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,7 @@ func selectAcceptableMIME(ct string) string {
 | 
			
		|||
	return mimeRe.FindString(ct)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func handleJsonArgs(args []string, attributes map[string]bool) []string {
 | 
			
		||||
func handleJSONArgs(args []string, attributes map[string]bool) []string {
 | 
			
		||||
	if len(args) == 0 {
 | 
			
		||||
		return []string{}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue