瀏覽代碼

Merge pull request #14567 from Microsoft/10662-fixbuilder

Windows: Fix builder
Jessie Frazelle 10 年之前
父節點
當前提交
15f9766691
共有 1 個文件被更改,包括 36 次插入20 次删除
  1. 36 20
      builder/internals.go

+ 36 - 20
builder/internals.go

@@ -139,7 +139,8 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowDecomp
 		return fmt.Errorf("Invalid %s format - at least two arguments required", cmdName)
 		return fmt.Errorf("Invalid %s format - at least two arguments required", cmdName)
 	}
 	}
 
 
-	dest := args[len(args)-1] // last one is always the dest
+	// Work in daemon-specific filepath semantics
+	dest := filepath.FromSlash(args[len(args)-1]) // last one is always the dest
 
 
 	copyInfos := []*copyInfo{}
 	copyInfos := []*copyInfo{}
 
 
@@ -174,8 +175,7 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowDecomp
 	if len(copyInfos) == 0 {
 	if len(copyInfos) == 0 {
 		return fmt.Errorf("No source files were specified")
 		return fmt.Errorf("No source files were specified")
 	}
 	}
-
-	if len(copyInfos) > 1 && !strings.HasSuffix(dest, "/") {
+	if len(copyInfos) > 1 && !strings.HasSuffix(dest, string(os.PathSeparator)) {
 		return fmt.Errorf("When using %s with more than one source file, the destination must be a directory and end with a /", cmdName)
 		return fmt.Errorf("When using %s with more than one source file, the destination must be a directory and end with a /", cmdName)
 	}
 	}
 
 
@@ -250,25 +250,37 @@ func (b *Builder) runContextCommand(args []string, allowRemote bool, allowDecomp
 
 
 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 {
 
 
-	if origPath != "" && origPath[0] == '/' && len(origPath) > 1 {
+	// Work in daemon-specific OS filepath semantics. However, we save
+	// the the origPath passed in here, as it might also be a URL which
+	// we need to check for in this function.
+	passedInOrigPath := origPath
+	origPath = filepath.FromSlash(origPath)
+	destPath = filepath.FromSlash(destPath)
+
+	if origPath != "" && origPath[0] == os.PathSeparator && len(origPath) > 1 {
 		origPath = origPath[1:]
 		origPath = origPath[1:]
 	}
 	}
-	origPath = strings.TrimPrefix(origPath, "./")
+	origPath = strings.TrimPrefix(origPath, "."+string(os.PathSeparator))
 
 
 	// Twiddle the destPath when its a relative path - meaning, make it
 	// Twiddle the destPath when its a relative path - meaning, make it
 	// relative to the WORKINGDIR
 	// relative to the WORKINGDIR
 	if !filepath.IsAbs(destPath) {
 	if !filepath.IsAbs(destPath) {
-		hasSlash := strings.HasSuffix(destPath, "/")
-		destPath = filepath.Join("/", b.Config.WorkingDir, destPath)
+		hasSlash := strings.HasSuffix(destPath, string(os.PathSeparator))
+		destPath = filepath.Join(string(os.PathSeparator), filepath.FromSlash(b.Config.WorkingDir), destPath)
 
 
 		// Make sure we preserve any trailing slash
 		// Make sure we preserve any trailing slash
 		if hasSlash {
 		if hasSlash {
-			destPath += "/"
+			destPath += string(os.PathSeparator)
 		}
 		}
 	}
 	}
 
 
 	// In the remote/URL case, download it and gen its hashcode
 	// In the remote/URL case, download it and gen its hashcode
-	if urlutil.IsURL(origPath) {
+	if urlutil.IsURL(passedInOrigPath) {
+
+		// As it's a URL, we go back to processing on what was passed in
+		// to this function
+		origPath = passedInOrigPath
+
 		if !allowRemote {
 		if !allowRemote {
 			return fmt.Errorf("Source can't be a URL for %s", cmdName)
 			return fmt.Errorf("Source can't be a URL for %s", cmdName)
 		}
 		}
@@ -337,16 +349,16 @@ func calcCopyInfo(b *Builder, cmdName string, cInfos *[]*copyInfo, origPath stri
 		ci.origPath = filepath.Join(filepath.Base(tmpDirName), filepath.Base(tmpFileName))
 		ci.origPath = filepath.Join(filepath.Base(tmpDirName), filepath.Base(tmpFileName))
 
 
 		// If the destination is a directory, figure out the filename.
 		// If the destination is a directory, figure out the filename.
-		if strings.HasSuffix(ci.destPath, "/") {
+		if strings.HasSuffix(ci.destPath, string(os.PathSeparator)) {
 			u, err := url.Parse(origPath)
 			u, err := url.Parse(origPath)
 			if err != nil {
 			if err != nil {
 				return err
 				return err
 			}
 			}
 			path := u.Path
 			path := u.Path
-			if strings.HasSuffix(path, "/") {
+			if strings.HasSuffix(path, string(os.PathSeparator)) {
 				path = path[:len(path)-1]
 				path = path[:len(path)-1]
 			}
 			}
-			parts := strings.Split(path, "/")
+			parts := strings.Split(path, string(os.PathSeparator))
 			filename := parts[len(parts)-1]
 			filename := parts[len(parts)-1]
 			if filename == "" {
 			if filename == "" {
 				return fmt.Errorf("cannot determine filename from url: %s", u)
 				return fmt.Errorf("cannot determine filename from url: %s", u)
@@ -421,11 +433,11 @@ func calcCopyInfo(b *Builder, cmdName string, cInfos *[]*copyInfo, origPath stri
 	// Add a trailing / to make sure we only pick up nested files under
 	// Add a trailing / to make sure we only pick up nested files under
 	// the dir and not sibling files of the dir that just happen to
 	// the dir and not sibling files of the dir that just happen to
 	// start with the same chars
 	// start with the same chars
-	if !strings.HasSuffix(absOrigPath, "/") {
-		absOrigPath += "/"
+	if !strings.HasSuffix(absOrigPath, string(os.PathSeparator)) {
+		absOrigPath += string(os.PathSeparator)
 	}
 	}
 
 
-	// Need path w/o / too to find matching dir w/o trailing /
+	// Need path w/o slash too to find matching dir w/o trailing slash
 	absOrigPathNoSlash := absOrigPath[:len(absOrigPath)-1]
 	absOrigPathNoSlash := absOrigPath[:len(absOrigPath)-1]
 
 
 	for _, fileInfo := range b.context.GetSums() {
 	for _, fileInfo := range b.context.GetSums() {
@@ -689,19 +701,23 @@ func (b *Builder) addContext(container *daemon.Container, orig, dest string, dec
 		destPath   string
 		destPath   string
 	)
 	)
 
 
+	// Work in daemon-local OS specific file paths
+	dest = filepath.FromSlash(dest)
+
 	destPath, err = container.GetResourcePath(dest)
 	destPath, err = container.GetResourcePath(dest)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 
 
-	// Preserve the trailing '/'
-	if strings.HasSuffix(dest, "/") || dest == "." {
-		destPath = destPath + "/"
+	// Preserve the trailing slash
+	if strings.HasSuffix(dest, string(os.PathSeparator)) || dest == "." {
+		destPath = destPath + string(os.PathSeparator)
 	}
 	}
 
 
 	destStat, err := os.Stat(destPath)
 	destStat, err := os.Stat(destPath)
 	if err != nil {
 	if err != nil {
 		if !os.IsNotExist(err) {
 		if !os.IsNotExist(err) {
+			logrus.Errorf("Error performing os.Stat on %s. %s", destPath, err)
 			return err
 			return err
 		}
 		}
 		destExists = false
 		destExists = false
@@ -724,9 +740,9 @@ func (b *Builder) addContext(container *daemon.Container, orig, dest string, dec
 		// First try to unpack the source as an archive
 		// First try to unpack the source as an archive
 		// to support the untar feature we need to clean up the path a little bit
 		// to support the untar feature we need to clean up the path a little bit
 		// because tar is very forgiving.  First we need to strip off the archive's
 		// because tar is very forgiving.  First we need to strip off the archive's
-		// filename from the path but this is only added if it does not end in / .
+		// filename from the path but this is only added if it does not end in slash
 		tarDest := destPath
 		tarDest := destPath
-		if strings.HasSuffix(tarDest, "/") {
+		if strings.HasSuffix(tarDest, string(os.PathSeparator)) {
 			tarDest = filepath.Dir(destPath)
 			tarDest = filepath.Dir(destPath)
 		}
 		}