package imagebuilder import ( "flag" "fmt" "os" "path/filepath" "runtime" "strings" "time" ) // hasEnvName returns true if the provided environment contains the named ENV var. func hasEnvName(env []string, name string) bool { for _, e := range env { if strings.HasPrefix(e, name+"=") { return true } } return false } // platformSupports is a short-term function to give users a quality error // message if a Dockerfile uses a command not supported on the platform. func platformSupports(command string) error { if runtime.GOOS != "windows" { return nil } switch command { case "expose", "user", "stopsignal", "arg": return fmt.Errorf("The daemon on this platform does not support the command '%s'", command) } return nil } func handleJSONArgs(args []string, attributes map[string]bool) []string { if len(args) == 0 { return []string{} } if attributes != nil && attributes["json"] { return args } // literal string command, not an exec array return []string{strings.Join(args, " ")} } func hasSlash(input string) bool { return strings.HasSuffix(input, string(os.PathSeparator)) || strings.HasSuffix(input, string(os.PathSeparator)+".") } // makeAbsolute ensures that the provided path is absolute. func makeAbsolute(dest, workingDir string) string { // Twiddle the destination when its a relative path - meaning, make it // relative to the WORKINGDIR if dest == "." { if !hasSlash(workingDir) { workingDir += string(os.PathSeparator) } dest = workingDir } if !filepath.IsAbs(dest) { hasSlash := hasSlash(dest) dest = filepath.Join(string(os.PathSeparator), filepath.FromSlash(workingDir), dest) // Make sure we preserve any trailing slash if hasSlash { dest += string(os.PathSeparator) } } return dest } // parseOptInterval(flag) is the duration of flag.Value, or 0 if // empty. An error is reported if the value is given and is not positive. func parseOptInterval(f *flag.Flag) (time.Duration, error) { if f == nil { return 0, fmt.Errorf("No flag defined") } s := f.Value.String() if s == "" { return 0, nil } d, err := time.ParseDuration(s) if err != nil { return 0, err } if d <= 0 { return 0, fmt.Errorf("Interval %#v must be positive", f.Name) } return d, nil } // mergeEnv merges two lists of environment variables, avoiding duplicates. func mergeEnv(defaults, overrides []string) []string { s := make([]string, 0, len(defaults)+len(overrides)) index := make(map[string]int) for _, envSpec := range append(defaults, overrides...) { envVar := strings.SplitN(envSpec, "=", 2) if i, ok := index[envVar[0]]; ok { s[i] = envSpec continue } s = append(s, envSpec) index[envVar[0]] = len(s) - 1 } return s } // envMapAsSlice returns the contents of a map[string]string as a slice of keys // and values joined with "=". func envMapAsSlice(m map[string]string) []string { s := make([]string, 0, len(m)) for k, v := range m { s = append(s, k+"="+v) } return s }