mirror of
				https://github.com/docker/compose.git
				synced 2025-10-31 11:14:02 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			127 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			127 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| /*
 | |
| Copyright (c) 2009 The Go Authors. All rights reserved.
 | |
| 
 | |
| Redistribution and use in source and binary forms, with or without
 | |
| modification, are permitted provided that the following conditions are
 | |
| met:
 | |
| 
 | |
| * Redistributions of source code must retain the above copyright
 | |
| notice, this list of conditions and the following disclaimer.
 | |
| * Redistributions in binary form must reproduce the above
 | |
| copyright notice, this list of conditions and the following disclaimer
 | |
| in the documentation and/or other materials provided with the
 | |
| distribution.
 | |
| * Neither the name of Google Inc. nor the names of its
 | |
| contributors may be used to endorse or promote products derived from
 | |
| this software without specific prior written permission.
 | |
| 
 | |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
| */
 | |
| 
 | |
| package resolvepath
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"os"
 | |
| 	"os/exec"
 | |
| 	"path/filepath"
 | |
| 	"strings"
 | |
| )
 | |
| 
 | |
| // ErrNotFound is the error resulting if a path search failed to find an executable file.
 | |
| var ErrNotFound = errors.New("executable file not found in %PATH%")
 | |
| 
 | |
| func chkStat(file string) error {
 | |
| 	d, err := os.Stat(file)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	if d.IsDir() {
 | |
| 		return os.ErrPermission
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func hasExt(file string) bool {
 | |
| 	i := strings.LastIndex(file, ".")
 | |
| 	if i < 0 {
 | |
| 		return false
 | |
| 	}
 | |
| 	return strings.LastIndexAny(file, `:\/`) < i
 | |
| }
 | |
| 
 | |
| func findExecutable(file string, exts []string) (string, error) {
 | |
| 	if len(exts) == 0 {
 | |
| 		return file, chkStat(file)
 | |
| 	}
 | |
| 	if hasExt(file) {
 | |
| 		if chkStat(file) == nil {
 | |
| 			return file, nil
 | |
| 		}
 | |
| 	}
 | |
| 	for _, e := range exts {
 | |
| 		if f := file + e; chkStat(f) == nil {
 | |
| 			return f, nil
 | |
| 		}
 | |
| 	}
 | |
| 	return "", os.ErrNotExist
 | |
| }
 | |
| 
 | |
| // LookPath searches for an executable named file in the
 | |
| // directories named by the PATH environment variable.
 | |
| // If file contains a slash, it is tried directly and the PATH is not consulted.
 | |
| // LookPath also uses PATHEXT environment variable to match
 | |
| // a suitable candidate.
 | |
| // The result may be an absolute path or a path relative to the current directory.
 | |
| func LookPath(file string) (string, error) {
 | |
| 	var exts []string
 | |
| 	x := os.Getenv(`PATHEXT`)
 | |
| 	if x != "" {
 | |
| 		for _, e := range strings.Split(strings.ToLower(x), `;`) {
 | |
| 			if e == "" {
 | |
| 				continue
 | |
| 			}
 | |
| 			if e[0] != '.' {
 | |
| 				e = "." + e
 | |
| 			}
 | |
| 			exts = append(exts, e)
 | |
| 		}
 | |
| 	} else {
 | |
| 		exts = []string{".com", ".exe", ".bat", ".cmd"}
 | |
| 	}
 | |
| 
 | |
| 	if strings.ContainsAny(file, `:\/`) {
 | |
| 		if f, err := findExecutable(file, exts); err == nil {
 | |
| 			return f, nil
 | |
| 		} else {
 | |
| 			return "", &exec.Error{file, err}
 | |
| 		}
 | |
| 	}
 | |
| 	// See https://github.com/golang/go/issues/38736
 | |
| 	// DO NOT lookup current folder
 | |
| 	//if f, err := findExecutable(filepath.Join(".", file), exts); err == nil {
 | |
| 	//	return f, nil
 | |
| 	//}
 | |
| 	path := os.Getenv("path")
 | |
| 	for _, dir := range filepath.SplitList(path) {
 | |
| 		// empty dir means dupicate semicolon in PATH, should not resolve files in current working dir...
 | |
| 		if strings.TrimSpace(dir) == "" {
 | |
| 			continue
 | |
| 		}
 | |
| 		if f, err := findExecutable(filepath.Join(dir, file), exts); err == nil {
 | |
| 			return f, nil
 | |
| 		}
 | |
| 	}
 | |
| 	return "", &exec.Error{file, ErrNotFound}
 | |
| }
 |