github.com/bazelbuild/bazel-gazelle@v0.36.1-0.20240520142334-61b277ba6fed/internal/wspace/finder.go (about)

     1  /* Copyright 2016 The Bazel Authors. All rights reserved.
     2  Licensed under the Apache License, Version 2.0 (the "License");
     3  you may not use this file except in compliance with the License.
     4  You may obtain a copy of the License at
     5     http://www.apache.org/licenses/LICENSE-2.0
     6  Unless required by applicable law or agreed to in writing, software
     7  distributed under the License is distributed on an "AS IS" BASIS,
     8  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     9  See the License for the specific language governing permissions and
    10  limitations under the License.
    11  */
    12  
    13  // Package wspace provides functions to locate and modify a bazel WORKSPACE file.
    14  package wspace
    15  
    16  import (
    17  	"os"
    18  	"path/filepath"
    19  	"strings"
    20  )
    21  
    22  var workspaceFiles = []string{"WORKSPACE.bazel", "WORKSPACE"}
    23  
    24  // IsWORKSPACE checks whether path is named WORKSPACE or WORKSPACE.bazel
    25  func IsWORKSPACE(path string) bool {
    26  	base := filepath.Base(path)
    27  	for _, workspaceFile := range workspaceFiles {
    28  		if base == workspaceFile {
    29  			return true
    30  		}
    31  	}
    32  	return false
    33  }
    34  
    35  // FindWORKSPACEFile returns a path to a file in the provided root directory,
    36  // either to an existing WORKSPACE or WORKSPACE.bazel file, or to root/WORKSPACE
    37  // if neither exists. Note that this function does NOT recursively check parent directories.
    38  func FindWORKSPACEFile(root string) string {
    39  	for _, workspaceFile := range workspaceFiles {
    40  		path := filepath.Join(root, workspaceFile)
    41  		if fileInfo, err := os.Stat(path); err == nil && !fileInfo.IsDir() {
    42  			return path
    43  		}
    44  	}
    45  	return filepath.Join(root, "WORKSPACE")
    46  }
    47  
    48  // FindRepoRoot searches from the given dir and up for a directory containing a WORKSPACE file
    49  // returning the directory containing it, or an error if none found in the tree.
    50  func FindRepoRoot(dir string) (string, error) {
    51  	dir, err := filepath.Abs(dir)
    52  	if err != nil {
    53  		return "", err
    54  	}
    55  
    56  	for {
    57  		for _, workspaceFile := range workspaceFiles {
    58  			filepath := filepath.Join(dir, workspaceFile)
    59  			info, err := os.Stat(filepath)
    60  			if err == nil && !info.IsDir() {
    61  				return dir, nil
    62  			}
    63  			if err != nil && !os.IsNotExist(err) {
    64  				return "", err
    65  			}
    66  		}
    67  		if strings.HasSuffix(dir, string(os.PathSeparator)) { // stop at root dir
    68  			return "", os.ErrNotExist
    69  		}
    70  		dir = filepath.Dir(dir)
    71  	}
    72  }