mirror of
				https://github.com/docker/compose.git
				synced 2025-11-04 05:34:09 +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}
 | 
						|
}
 |