...

Source file src/github.com/bazelbuild/buildtools/buildifier/utils/utils.go

Documentation: github.com/bazelbuild/buildtools/buildifier/utils

     1  /*
     2  Copyright 2020 Google LLC
     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      https://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 utils contains shared methods that can be used by different implementations of
    18  // buildifier binary
    19  package utils
    20  
    21  import (
    22  	"io/ioutil"
    23  	"os"
    24  	"path/filepath"
    25  	"strings"
    26  
    27  	"github.com/bazelbuild/buildtools/build"
    28  	"github.com/bazelbuild/buildtools/warn"
    29  )
    30  
    31  func isStarlarkFile(name string) bool {
    32  	ext := filepath.Ext(name)
    33  	switch ext {
    34  	case ".bzl", ".sky", ".star":
    35  		return true
    36  	}
    37  
    38  	switch ext {
    39  	case ".bazel", ".oss":
    40  		// BUILD.bazel or BUILD.foo.bazel should be treated as Starlark files, same for WORSKSPACE and MODULE
    41  		return strings.HasPrefix(name, "BUILD.") || strings.HasPrefix(name, "WORKSPACE.") || strings.HasPrefix(name, "MODULE.")
    42  	}
    43  
    44  	return name == "BUILD" || name == "WORKSPACE"
    45  }
    46  
    47  func skip(info os.FileInfo) bool {
    48  	return info.IsDir() && info.Name() == ".git"
    49  }
    50  
    51  // ExpandDirectories takes a list of file/directory names and returns a list with file names
    52  // by traversing each directory recursively and searching for relevant Starlark files.
    53  func ExpandDirectories(args *[]string) ([]string, error) {
    54  	files := []string{}
    55  	for _, arg := range *args {
    56  		info, err := os.Stat(arg)
    57  		if err != nil {
    58  			return []string{}, err
    59  		}
    60  		if !info.IsDir() {
    61  			files = append(files, arg)
    62  			continue
    63  		}
    64  		err = filepath.Walk(arg, func(path string, info os.FileInfo, err error) error {
    65  			if err != nil {
    66  				return err
    67  			}
    68  			if skip(info) {
    69  				return filepath.SkipDir
    70  			}
    71  			if !info.IsDir() && isStarlarkFile(info.Name()) {
    72  				files = append(files, path)
    73  			}
    74  			return nil
    75  		})
    76  		if err != nil {
    77  			return []string{}, err
    78  		}
    79  	}
    80  	return files, nil
    81  }
    82  
    83  // GetParser returns a parser for a given file type
    84  func GetParser(inputType string) func(filename string, data []byte) (*build.File, error) {
    85  	switch inputType {
    86  	case "build":
    87  		return build.ParseBuild
    88  	case "bzl":
    89  		return build.ParseBzl
    90  	case "auto":
    91  		return build.Parse
    92  	case "workspace":
    93  		return build.ParseWorkspace
    94  	case "module":
    95  		return build.ParseModule
    96  	default:
    97  		return build.ParseDefault
    98  	}
    99  }
   100  
   101  // getFileReader returns a *FileReader object that reads files from the local
   102  // filesystem if the workspace root is known.
   103  func getFileReader(workspaceRoot string) *warn.FileReader {
   104  	if workspaceRoot == "" {
   105  		return nil
   106  	}
   107  
   108  	readFile := func(filename string) ([]byte, error) {
   109  		// Use OS-specific path separators
   110  		filename = strings.ReplaceAll(filename, "/", string(os.PathSeparator))
   111  		path := filepath.Join(workspaceRoot, filename)
   112  
   113  		return ioutil.ReadFile(path)
   114  	}
   115  
   116  	return warn.NewFileReader(readFile)
   117  }
   118  
   119  // Lint calls the linter and returns a list of unresolved findings
   120  func Lint(f *build.File, lint string, warningsList *[]string, verbose bool) []*warn.Finding {
   121  	fileReader := getFileReader(f.WorkspaceRoot)
   122  
   123  	switch lint {
   124  	case "warn":
   125  		return warn.FileWarnings(f, *warningsList, nil, warn.ModeWarn, fileReader)
   126  	case "fix":
   127  		warn.FixWarnings(f, *warningsList, verbose, fileReader)
   128  	}
   129  	return nil
   130  }
   131  

View as plain text