/vendor/github.com/docker/docker/builder/dockerfile/dispatchers_windows.go
https://gitlab.com/unofficial-mirrors/openshift-origin · Go · 120 lines · 73 code · 11 blank · 36 comment · 26 complexity · b87edf7c466c3597cc1d932e42f625ce MD5 · raw file
- package dockerfile
- import (
- "errors"
- "fmt"
- "os"
- "path"
- "path/filepath"
- "regexp"
- "strings"
- "github.com/docker/docker/pkg/system"
- )
- var pattern = regexp.MustCompile(`^[a-zA-Z]:\.$`)
- // normalizeWorkdir normalizes a user requested working directory in a
- // platform semantically consistent way.
- func normalizeWorkdir(platform string, current string, requested string) (string, error) {
- if platform == "" {
- platform = "windows"
- }
- if platform == "windows" {
- return normalizeWorkdirWindows(current, requested)
- }
- return normalizeWorkdirUnix(current, requested)
- }
- // normalizeWorkdirUnix normalizes a user requested working directory in a
- // platform semantically consistent way.
- func normalizeWorkdirUnix(current string, requested string) (string, error) {
- if requested == "" {
- return "", errors.New("cannot normalize nothing")
- }
- current = strings.Replace(current, string(os.PathSeparator), "/", -1)
- requested = strings.Replace(requested, string(os.PathSeparator), "/", -1)
- if !path.IsAbs(requested) {
- return path.Join(`/`, current, requested), nil
- }
- return requested, nil
- }
- // normalizeWorkdirWindows normalizes a user requested working directory in a
- // platform semantically consistent way.
- func normalizeWorkdirWindows(current string, requested string) (string, error) {
- if requested == "" {
- return "", errors.New("cannot normalize nothing")
- }
- // `filepath.Clean` will replace "" with "." so skip in that case
- if current != "" {
- current = filepath.Clean(current)
- }
- if requested != "" {
- requested = filepath.Clean(requested)
- }
- // If either current or requested in Windows is:
- // C:
- // C:.
- // then an error will be thrown as the definition for the above
- // refers to `current directory on drive C:`
- // Since filepath.Clean() will automatically normalize the above
- // to `C:.`, we only need to check the last format
- if pattern.MatchString(current) {
- return "", fmt.Errorf("%s is not a directory. If you are specifying a drive letter, please add a trailing '\\'", current)
- }
- if pattern.MatchString(requested) {
- return "", fmt.Errorf("%s is not a directory. If you are specifying a drive letter, please add a trailing '\\'", requested)
- }
- // Target semantics is C:\somefolder, specifically in the format:
- // UPPERCASEDriveLetter-Colon-Backslash-FolderName. We are already
- // guaranteed that `current`, if set, is consistent. This allows us to
- // cope correctly with any of the following in a Dockerfile:
- // WORKDIR a --> C:\a
- // WORKDIR c:\\foo --> C:\foo
- // WORKDIR \\foo --> C:\foo
- // WORKDIR /foo --> C:\foo
- // WORKDIR c:\\foo \ WORKDIR bar --> C:\foo --> C:\foo\bar
- // WORKDIR C:/foo \ WORKDIR bar --> C:\foo --> C:\foo\bar
- // WORKDIR C:/foo \ WORKDIR \\bar --> C:\foo --> C:\bar
- // WORKDIR /foo \ WORKDIR c:/bar --> C:\foo --> C:\bar
- if len(current) == 0 || system.IsAbs(requested) {
- if (requested[0] == os.PathSeparator) ||
- (len(requested) > 1 && string(requested[1]) != ":") ||
- (len(requested) == 1) {
- requested = filepath.Join(`C:\`, requested)
- }
- } else {
- requested = filepath.Join(current, requested)
- }
- // Upper-case drive letter
- return (strings.ToUpper(string(requested[0])) + requested[1:]), nil
- }
- func errNotJSON(command, original string) error {
- // For Windows users, give a hint if it looks like it might contain
- // a path which hasn't been escaped such as ["c:\windows\system32\prog.exe", "-param"],
- // as JSON must be escaped. Unfortunate...
- //
- // Specifically looking for quote-driveletter-colon-backslash, there's no
- // double backslash and a [] pair. No, this is not perfect, but it doesn't
- // have to be. It's simply a hint to make life a little easier.
- extra := ""
- original = filepath.FromSlash(strings.ToLower(strings.Replace(strings.ToLower(original), strings.ToLower(command)+" ", "", -1)))
- if len(regexp.MustCompile(`"[a-z]:\\.*`).FindStringSubmatch(original)) > 0 &&
- !strings.Contains(original, `\\`) &&
- strings.Contains(original, "[") &&
- strings.Contains(original, "]") {
- extra = fmt.Sprintf(`. It looks like '%s' includes a file path without an escaped back-slash. JSON requires back-slashes to be escaped such as ["c:\\path\\to\\file.exe", "/parameter"]`, original)
- }
- return fmt.Errorf("%s requires the arguments to be in JSON form%s", command, extra)
- }
- // equalEnvKeys compare two strings and returns true if they are equal. On
- // Windows this comparison is case insensitive.
- func equalEnvKeys(from, to string) bool {
- return strings.ToUpper(from) == strings.ToUpper(to)
- }