kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/extractors/bazel/treeset/treeset.go (about)

     1  /*
     2   * Copyright 2021 The Kythe Authors. All rights reserved.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *   http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  // Package treeset provides functions for extracting targets that use bazel treesets.
    18  package treeset
    19  
    20  import (
    21  	"context"
    22  	"os"
    23  	"path/filepath"
    24  
    25  	"kythe.io/kythe/go/platform/vfs"
    26  	"kythe.io/kythe/go/util/log"
    27  
    28  	"bitbucket.org/creachadair/stringset"
    29  )
    30  
    31  // ListSources returns the source files underneath path. If path is a file, it returns a set with
    32  // a single element. If path is a directory, it returns a set containing all the files
    33  // (recursively) under path.
    34  func ListSources(ctx context.Context, arg string) (stringset.Set, error) {
    35  	fi, err := vfs.Stat(ctx, arg)
    36  	if err != nil {
    37  		return nil, err
    38  	}
    39  	if fi.IsDir() {
    40  		s := stringset.New()
    41  		if err := filepath.Walk(arg, func(path string, info os.FileInfo, err error) error {
    42  			if err != nil {
    43  				return err
    44  			}
    45  			if !info.IsDir() {
    46  				s.Add(path)
    47  			}
    48  			return nil
    49  		}); err != nil {
    50  			return nil, err
    51  		}
    52  		return s, nil
    53  	}
    54  	return stringset.New(arg), nil
    55  }
    56  
    57  // FindMissingTreeInputs returns the required files that are not explicitly listed in bazel's
    58  // inputs because they were tree artifacts.
    59  //
    60  // Some bazel rules use tree artifacts for the inputs to the compiler. These are directories that
    61  // Bazel expands to files when the action is run. Consequently, the list of inputs that Bazel has
    62  // only contains the tree artifact directory. This function reports the files that are (1) required,
    63  // (2) not included in bazel's inputs, and (3) have their parent directory included in Bazel's
    64  // inputs.
    65  func FindMissingTreeInputs(inputs []string, requiredFiles stringset.Set) []string {
    66  	missingInputs := stringset.New()
    67  	inputsSet := stringset.New(inputs...)
    68  	for file := range requiredFiles {
    69  		if inputsSet.Contains(file) {
    70  			continue
    71  		}
    72  		dir := filepath.Dir(file)
    73  		for dir != "" {
    74  			if inputsSet.Contains(dir) {
    75  				missingInputs.Add(file)
    76  				break
    77  			}
    78  			dir = filepath.Dir(dir)
    79  		}
    80  		if dir == "" {
    81  			log.Warningf("couldn't find an input for %s\n", file)
    82  		}
    83  
    84  	}
    85  	return missingInputs.Elements()
    86  }
    87  
    88  // ExpandDirectories returns the list of files contained in the provided paths.
    89  //
    90  // Paths can be individual files or directories. If it's a directory - all files
    91  // within that directory added to the result.
    92  func ExpandDirectories(ctx context.Context, paths []string) []string {
    93  	var nps []string
    94  	for _, root := range paths {
    95  		files, err := ListSources(ctx, root)
    96  		if err != nil {
    97  			log.WarningContextf(ctx, "couldn't list files for %s: %s\n", root, err)
    98  			nps = append(nps, root)
    99  		} else {
   100  			nps = append(nps, files.Elements()...)
   101  		}
   102  	}
   103  
   104  	return nps
   105  }