Source file src/cmd/go/internal/load/search.go

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package load
     6  
     7  import (
     8  	"path/filepath"
     9  	"strings"
    10  
    11  	"cmd/go/internal/modload"
    12  	"cmd/go/internal/search"
    13  	"cmd/internal/pkgpattern"
    14  )
    15  
    16  // MatchPackage(pattern, cwd)(p) reports whether package p matches pattern in the working directory cwd.
    17  func MatchPackage(pattern, cwd string) func(*Package) bool {
    18  	switch {
    19  	case search.IsRelativePath(pattern):
    20  		// Split pattern into leading pattern-free directory path
    21  		// (including all . and .. elements) and the final pattern.
    22  		var dir string
    23  		i := strings.Index(pattern, "...")
    24  		if i < 0 {
    25  			dir, pattern = pattern, ""
    26  		} else {
    27  			j := strings.LastIndex(pattern[:i], "/")
    28  			dir, pattern = pattern[:j], pattern[j+1:]
    29  		}
    30  		dir = filepath.Join(cwd, dir)
    31  		if pattern == "" {
    32  			return func(p *Package) bool { return p.Dir == dir }
    33  		}
    34  		matchPath := pkgpattern.MatchPattern(pattern)
    35  		return func(p *Package) bool {
    36  			// Compute relative path to dir and see if it matches the pattern.
    37  			rel, err := filepath.Rel(dir, p.Dir)
    38  			if err != nil {
    39  				// Cannot make relative - e.g. different drive letters on Windows.
    40  				return false
    41  			}
    42  			rel = filepath.ToSlash(rel)
    43  			if rel == ".." || strings.HasPrefix(rel, "../") {
    44  				return false
    45  			}
    46  			return matchPath(rel)
    47  		}
    48  	case pattern == "all":
    49  		// This is slightly inaccurate: it matches every package, which isn't the same
    50  		// as matching the "all" package pattern.
    51  		// TODO(matloob): Should we make this more accurate? Does anyone depend on this behavior?
    52  		return func(p *Package) bool { return true }
    53  	case pattern == "std":
    54  		return func(p *Package) bool { return p.Standard }
    55  	case pattern == "cmd":
    56  		return func(p *Package) bool { return p.Standard && strings.HasPrefix(p.ImportPath, "cmd/") }
    57  	case pattern == "tool" && modload.Enabled():
    58  		return func(p *Package) bool {
    59  			return modload.MainModules.Tools()[p.ImportPath]
    60  		}
    61  	case pattern == "work" && modload.Enabled():
    62  		return func(p *Package) bool {
    63  			return p.Module != nil && modload.MainModules.Contains(p.Module.Path)
    64  		}
    65  
    66  	default:
    67  		matchPath := pkgpattern.MatchPattern(pattern)
    68  		return func(p *Package) bool { return matchPath(p.ImportPath) }
    69  	}
    70  }
    71  

View as plain text