...

Source file src/github.com/bazelbuild/rules_go/go/runfiles/global.go

Documentation: github.com/bazelbuild/rules_go/go/runfiles

     1  // Copyright 2020, 2021 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     https://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package runfiles
    16  
    17  import (
    18  	"regexp"
    19  	"runtime"
    20  	"sync"
    21  )
    22  
    23  // Rlocation returns the absolute path name of a runfile.  The runfile name must be
    24  // a relative path, using the slash (not backslash) as directory separator.  If
    25  // the runfiles manifest maps s to an empty name (indicating an empty runfile
    26  // not present in the filesystem), Rlocation returns an error that wraps ErrEmpty.
    27  func Rlocation(path string) (string, error) {
    28  	return RlocationFrom(path, CallerRepository())
    29  }
    30  
    31  func RlocationFrom(path string, sourceRepo string) (string, error) {
    32  	r, err := g.get()
    33  	if err != nil {
    34  		return "", err
    35  	}
    36  	return r.WithSourceRepo(sourceRepo).Rlocation(path)
    37  }
    38  
    39  // Env returns additional environmental variables to pass to subprocesses.
    40  // Each element is of the form “key=value”.  Pass these variables to
    41  // Bazel-built binaries so they can find their runfiles as well.  See the
    42  // Runfiles example for an illustration of this.
    43  //
    44  // The return value is a newly-allocated slice; you can modify it at will.
    45  func Env() ([]string, error) {
    46  	r, err := g.get()
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  	return r.Env(), nil
    51  }
    52  
    53  var legacyExternalGeneratedFile = regexp.MustCompile(`^bazel-out[/][^/]+/bin/external/([^/]+)/`)
    54  var legacyExternalFile = regexp.MustCompile(`^external/([^/]+)/`)
    55  
    56  // CurrentRepository returns the canonical name of the Bazel repository that
    57  // contains the source file of the caller of CurrentRepository.
    58  func CurrentRepository() string {
    59  	return callerRepository(1)
    60  }
    61  
    62  // CallerRepository returns the canonical name of the Bazel repository that
    63  // contains the source file of the caller of the function that itself calls
    64  // CallerRepository.
    65  func CallerRepository() string {
    66  	return callerRepository(2)
    67  }
    68  
    69  func callerRepository(skip int) string {
    70  	_, file, _, _ := runtime.Caller(skip + 1)
    71  	if match := legacyExternalGeneratedFile.FindStringSubmatch(file); match != nil {
    72  		return match[1]
    73  	}
    74  	if match := legacyExternalFile.FindStringSubmatch(file); match != nil {
    75  		return match[1]
    76  	}
    77  	// If a file is not in an external repository, it is in the main repository,
    78  	// which has the empty string as its canonical name.
    79  	return ""
    80  }
    81  
    82  type global struct {
    83  	once     sync.Once
    84  	runfiles *Runfiles
    85  	err      error
    86  }
    87  
    88  func (g *global) get() (*Runfiles, error) {
    89  	g.once.Do(g.init)
    90  	return g.runfiles, g.err
    91  }
    92  
    93  func (g *global) init() {
    94  	g.runfiles, g.err = New()
    95  }
    96  
    97  var g global
    98  

View as plain text