mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-29 10:57:44 +09:00 
			
		
		
		
	* Use vendored go-swagger * vendor go-swagger * revert un wanteed change * remove un-needed GO111MODULE * Update Makefile Co-Authored-By: techknowlogick <matti@mdranta.net>
		
			
				
	
	
		
			213 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
			
		
		
	
	
			213 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
		
			Vendored
		
	
	
	
| // Copyright 2014 The Go Authors. All rights reserved.
 | |
| // Use of this source code is governed by a BSD-style
 | |
| // license that can be found in the LICENSE file.
 | |
| 
 | |
| package buildutil
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"go/ast"
 | |
| 	"go/build"
 | |
| 	"go/parser"
 | |
| 	"go/token"
 | |
| 	"io"
 | |
| 	"io/ioutil"
 | |
| 	"os"
 | |
| 	"path"
 | |
| 	"path/filepath"
 | |
| 	"strings"
 | |
| )
 | |
| 
 | |
| // ParseFile behaves like parser.ParseFile,
 | |
| // but uses the build context's file system interface, if any.
 | |
| //
 | |
| // If file is not absolute (as defined by IsAbsPath), the (dir, file)
 | |
| // components are joined using JoinPath; dir must be absolute.
 | |
| //
 | |
| // The displayPath function, if provided, is used to transform the
 | |
| // filename that will be attached to the ASTs.
 | |
| //
 | |
| // TODO(adonovan): call this from go/loader.parseFiles when the tree thaws.
 | |
| //
 | |
| func ParseFile(fset *token.FileSet, ctxt *build.Context, displayPath func(string) string, dir string, file string, mode parser.Mode) (*ast.File, error) {
 | |
| 	if !IsAbsPath(ctxt, file) {
 | |
| 		file = JoinPath(ctxt, dir, file)
 | |
| 	}
 | |
| 	rd, err := OpenFile(ctxt, file)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	defer rd.Close() // ignore error
 | |
| 	if displayPath != nil {
 | |
| 		file = displayPath(file)
 | |
| 	}
 | |
| 	return parser.ParseFile(fset, file, rd, mode)
 | |
| }
 | |
| 
 | |
| // ContainingPackage returns the package containing filename.
 | |
| //
 | |
| // If filename is not absolute, it is interpreted relative to working directory dir.
 | |
| // All I/O is via the build context's file system interface, if any.
 | |
| //
 | |
| // The '...Files []string' fields of the resulting build.Package are not
 | |
| // populated (build.FindOnly mode).
 | |
| //
 | |
| func ContainingPackage(ctxt *build.Context, dir, filename string) (*build.Package, error) {
 | |
| 	if !IsAbsPath(ctxt, filename) {
 | |
| 		filename = JoinPath(ctxt, dir, filename)
 | |
| 	}
 | |
| 
 | |
| 	// We must not assume the file tree uses
 | |
| 	// "/" always,
 | |
| 	// `\` always,
 | |
| 	// or os.PathSeparator (which varies by platform),
 | |
| 	// but to make any progress, we are forced to assume that
 | |
| 	// paths will not use `\` unless the PathSeparator
 | |
| 	// is also `\`, thus we can rely on filepath.ToSlash for some sanity.
 | |
| 
 | |
| 	dirSlash := path.Dir(filepath.ToSlash(filename)) + "/"
 | |
| 
 | |
| 	// We assume that no source root (GOPATH[i] or GOROOT) contains any other.
 | |
| 	for _, srcdir := range ctxt.SrcDirs() {
 | |
| 		srcdirSlash := filepath.ToSlash(srcdir) + "/"
 | |
| 		if importPath, ok := HasSubdir(ctxt, srcdirSlash, dirSlash); ok {
 | |
| 			return ctxt.Import(importPath, dir, build.FindOnly)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return nil, fmt.Errorf("can't find package containing %s", filename)
 | |
| }
 | |
| 
 | |
| // -- Effective methods of file system interface -------------------------
 | |
| 
 | |
| // (go/build.Context defines these as methods, but does not export them.)
 | |
| 
 | |
| // hasSubdir calls ctxt.HasSubdir (if not nil) or else uses
 | |
| // the local file system to answer the question.
 | |
| func HasSubdir(ctxt *build.Context, root, dir string) (rel string, ok bool) {
 | |
| 	if f := ctxt.HasSubdir; f != nil {
 | |
| 		return f(root, dir)
 | |
| 	}
 | |
| 
 | |
| 	// Try using paths we received.
 | |
| 	if rel, ok = hasSubdir(root, dir); ok {
 | |
| 		return
 | |
| 	}
 | |
| 
 | |
| 	// Try expanding symlinks and comparing
 | |
| 	// expanded against unexpanded and
 | |
| 	// expanded against expanded.
 | |
| 	rootSym, _ := filepath.EvalSymlinks(root)
 | |
| 	dirSym, _ := filepath.EvalSymlinks(dir)
 | |
| 
 | |
| 	if rel, ok = hasSubdir(rootSym, dir); ok {
 | |
| 		return
 | |
| 	}
 | |
| 	if rel, ok = hasSubdir(root, dirSym); ok {
 | |
| 		return
 | |
| 	}
 | |
| 	return hasSubdir(rootSym, dirSym)
 | |
| }
 | |
| 
 | |
| func hasSubdir(root, dir string) (rel string, ok bool) {
 | |
| 	const sep = string(filepath.Separator)
 | |
| 	root = filepath.Clean(root)
 | |
| 	if !strings.HasSuffix(root, sep) {
 | |
| 		root += sep
 | |
| 	}
 | |
| 
 | |
| 	dir = filepath.Clean(dir)
 | |
| 	if !strings.HasPrefix(dir, root) {
 | |
| 		return "", false
 | |
| 	}
 | |
| 
 | |
| 	return filepath.ToSlash(dir[len(root):]), true
 | |
| }
 | |
| 
 | |
| // FileExists returns true if the specified file exists,
 | |
| // using the build context's file system interface.
 | |
| func FileExists(ctxt *build.Context, path string) bool {
 | |
| 	if ctxt.OpenFile != nil {
 | |
| 		r, err := ctxt.OpenFile(path)
 | |
| 		if err != nil {
 | |
| 			return false
 | |
| 		}
 | |
| 		r.Close() // ignore error
 | |
| 		return true
 | |
| 	}
 | |
| 	_, err := os.Stat(path)
 | |
| 	return err == nil
 | |
| }
 | |
| 
 | |
| // OpenFile behaves like os.Open,
 | |
| // but uses the build context's file system interface, if any.
 | |
| func OpenFile(ctxt *build.Context, path string) (io.ReadCloser, error) {
 | |
| 	if ctxt.OpenFile != nil {
 | |
| 		return ctxt.OpenFile(path)
 | |
| 	}
 | |
| 	return os.Open(path)
 | |
| }
 | |
| 
 | |
| // IsAbsPath behaves like filepath.IsAbs,
 | |
| // but uses the build context's file system interface, if any.
 | |
| func IsAbsPath(ctxt *build.Context, path string) bool {
 | |
| 	if ctxt.IsAbsPath != nil {
 | |
| 		return ctxt.IsAbsPath(path)
 | |
| 	}
 | |
| 	return filepath.IsAbs(path)
 | |
| }
 | |
| 
 | |
| // JoinPath behaves like filepath.Join,
 | |
| // but uses the build context's file system interface, if any.
 | |
| func JoinPath(ctxt *build.Context, path ...string) string {
 | |
| 	if ctxt.JoinPath != nil {
 | |
| 		return ctxt.JoinPath(path...)
 | |
| 	}
 | |
| 	return filepath.Join(path...)
 | |
| }
 | |
| 
 | |
| // IsDir behaves like os.Stat plus IsDir,
 | |
| // but uses the build context's file system interface, if any.
 | |
| func IsDir(ctxt *build.Context, path string) bool {
 | |
| 	if ctxt.IsDir != nil {
 | |
| 		return ctxt.IsDir(path)
 | |
| 	}
 | |
| 	fi, err := os.Stat(path)
 | |
| 	return err == nil && fi.IsDir()
 | |
| }
 | |
| 
 | |
| // ReadDir behaves like ioutil.ReadDir,
 | |
| // but uses the build context's file system interface, if any.
 | |
| func ReadDir(ctxt *build.Context, path string) ([]os.FileInfo, error) {
 | |
| 	if ctxt.ReadDir != nil {
 | |
| 		return ctxt.ReadDir(path)
 | |
| 	}
 | |
| 	return ioutil.ReadDir(path)
 | |
| }
 | |
| 
 | |
| // SplitPathList behaves like filepath.SplitList,
 | |
| // but uses the build context's file system interface, if any.
 | |
| func SplitPathList(ctxt *build.Context, s string) []string {
 | |
| 	if ctxt.SplitPathList != nil {
 | |
| 		return ctxt.SplitPathList(s)
 | |
| 	}
 | |
| 	return filepath.SplitList(s)
 | |
| }
 | |
| 
 | |
| // sameFile returns true if x and y have the same basename and denote
 | |
| // the same file.
 | |
| //
 | |
| func sameFile(x, y string) bool {
 | |
| 	if path.Clean(x) == path.Clean(y) {
 | |
| 		return true
 | |
| 	}
 | |
| 	if filepath.Base(x) == filepath.Base(y) { // (optimisation)
 | |
| 		if xi, err := os.Stat(x); err == nil {
 | |
| 			if yi, err := os.Stat(y); err == nil {
 | |
| 				return os.SameFile(xi, yi)
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return false
 | |
| }
 |