...

Source file src/github.com/bazelbuild/buildtools/warn/warn_visibility.go

Documentation: github.com/bazelbuild/buildtools/warn

     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  // Warnings about visibility of .bzl files
    18  
    19  package warn
    20  
    21  import (
    22  	"fmt"
    23  	"regexp"
    24  	"strings"
    25  
    26  	"github.com/bazelbuild/buildtools/build"
    27  )
    28  
    29  var internalDirectory = regexp.MustCompile("/(internal|private)[/:]")
    30  
    31  func bzlVisibilityWarning(f *build.File) []*LinterFinding {
    32  	var findings []*LinterFinding
    33  
    34  	if f.WorkspaceRoot == "" {
    35  		// Empty workspace root means buildifier doesn't know the location of
    36  		// the file relative to the workspace directory and can't warn about .bzl
    37  		// file visibility correctly.
    38  		return findings
    39  	}
    40  
    41  	for _, stmt := range f.Stmt {
    42  		load, ok := stmt.(*build.LoadStmt)
    43  		if !ok || load.Module == nil {
    44  			continue
    45  		}
    46  
    47  		// A load statement may use a fully qualified module name (including a
    48  		// repository name). Buildifier should check if the repository name refers
    49  		// to the current repository, but because it doesn't know the current
    50  		// repository name it's better to assume that it matches the repository name
    51  		// in the load statement: this way it may miss some usages of private .bzl
    52  		// files that aren't supposed to be visible, but won't show false-positive
    53  		// warnings in case the private file is actually allowed to be used.
    54  		module := load.Module.Value
    55  		if strings.HasPrefix(module, "@") {
    56  			if chunks := strings.SplitN(module, "//", 2); len(chunks) == 2 {
    57  				module = "//" + chunks[1]
    58  			}
    59  		}
    60  
    61  		path := f.CanonicalPath() // Canonical name of the file
    62  		chunks := internalDirectory.Split(module, 2)
    63  		if len(chunks) < 2 {
    64  			continue
    65  		}
    66  
    67  		if strings.HasPrefix(path, chunks[0]) ||
    68  			strings.HasPrefix(strings.Replace(path, "/javatests/", "/java/", 1), chunks[0]) {
    69  			continue
    70  		}
    71  
    72  		findings = append(findings, makeLinterFinding(
    73  			load.Module,
    74  			fmt.Sprintf("Module %q can only be loaded from files located inside %q, not from %q.", load.Module.Value, chunks[0], path)))
    75  	}
    76  
    77  	return findings
    78  }
    79  

View as plain text