github.com/afking/bazel-gazelle@v0.0.0-20180301150245-c02bc0f529e8/internal/config/config.go (about)

     1  /* Copyright 2017 The Bazel Authors. All rights reserved.
     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     http://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  
    16  package config
    17  
    18  import (
    19  	"fmt"
    20  	"go/build"
    21  	"strings"
    22  )
    23  
    24  // Config holds information about how Gazelle should run. This is mostly
    25  // based on command-line arguments.
    26  type Config struct {
    27  	// Dirs is a list of absolute paths to directories where Gazelle should run.
    28  	Dirs []string
    29  
    30  	// RepoRoot is the absolute path to the root directory of the repository.
    31  	RepoRoot string
    32  
    33  	// ValidBuildFileNames is a list of base names that are considered valid
    34  	// build files. Some repositories may have files named "BUILD" that are not
    35  	// used by Bazel and should be ignored. Must contain at least one string.
    36  	ValidBuildFileNames []string
    37  
    38  	// GenericTags is a set of build constraints that are true on all platforms.
    39  	// It should not be nil.
    40  	GenericTags BuildTags
    41  
    42  	// GoPrefix is the portion of the import path for the root of this repository.
    43  	// This is used to map imports to labels within the repository.
    44  	GoPrefix string
    45  
    46  	// GoPrefixRel is the slash-separated path to the directory where GoPrefix
    47  	// was set, relative to the repository root. "" for the repository root.
    48  	GoPrefixRel string
    49  
    50  	// ShouldFix determines whether Gazelle attempts to remove and replace
    51  	// usage of deprecated rules.
    52  	ShouldFix bool
    53  
    54  	// DepMode determines how imports outside of GoPrefix are resolved.
    55  	DepMode DependencyMode
    56  
    57  	// ProtoMode determines how rules are generated for protos.
    58  	ProtoMode ProtoMode
    59  
    60  	// ProtoModeExplicit indicates whether the proto mode was set explicitly.
    61  	ProtoModeExplicit bool
    62  }
    63  
    64  var DefaultValidBuildFileNames = []string{"BUILD.bazel", "BUILD"}
    65  
    66  func (c *Config) IsValidBuildFileName(name string) bool {
    67  	for _, n := range c.ValidBuildFileNames {
    68  		if name == n {
    69  			return true
    70  		}
    71  	}
    72  	return false
    73  }
    74  
    75  func (c *Config) DefaultBuildFileName() string {
    76  	return c.ValidBuildFileNames[0]
    77  }
    78  
    79  // BuildTags is a set of build constraints.
    80  type BuildTags map[string]bool
    81  
    82  // SetBuildTags sets GenericTags by parsing as a comma separated list. An
    83  // error will be returned for tags that wouldn't be recognized by "go build".
    84  // PreprocessTags should be called after this.
    85  func (c *Config) SetBuildTags(tags string) error {
    86  	c.GenericTags = make(BuildTags)
    87  	if tags == "" {
    88  		return nil
    89  	}
    90  	for _, t := range strings.Split(tags, ",") {
    91  		if strings.HasPrefix(t, "!") {
    92  			return fmt.Errorf("build tags can't be negated: %s", t)
    93  		}
    94  		c.GenericTags[t] = true
    95  	}
    96  	return nil
    97  }
    98  
    99  // PreprocessTags adds some tags which are on by default before they are
   100  // used to match files.
   101  func (c *Config) PreprocessTags() {
   102  	if c.GenericTags == nil {
   103  		c.GenericTags = make(BuildTags)
   104  	}
   105  	c.GenericTags["gc"] = true
   106  }
   107  
   108  // CheckPrefix checks that a string may be used as a prefix. We forbid local
   109  // (relative) imports and those beginning with "/". We allow the empty string,
   110  // but generated rules must not have an empty importpath.
   111  func CheckPrefix(prefix string) error {
   112  	if strings.HasPrefix(prefix, "/") || build.IsLocalImport(prefix) {
   113  		return fmt.Errorf("invalid prefix: %q", prefix)
   114  	}
   115  	return nil
   116  }
   117  
   118  // DependencyMode determines how imports of packages outside of the prefix
   119  // are resolved.
   120  type DependencyMode int
   121  
   122  const (
   123  	// ExternalMode indicates imports should be resolved to external dependencies
   124  	// (declared in WORKSPACE).
   125  	ExternalMode DependencyMode = iota
   126  
   127  	// VendorMode indicates imports should be resolved to libraries in the
   128  	// vendor directory.
   129  	VendorMode
   130  )
   131  
   132  // DependencyModeFromString converts a string from the command line
   133  // to a DependencyMode. Valid strings are "external", "vendor". An error will
   134  // be returned for an invalid string.
   135  func DependencyModeFromString(s string) (DependencyMode, error) {
   136  	switch s {
   137  	case "external":
   138  		return ExternalMode, nil
   139  	case "vendored":
   140  		return VendorMode, nil
   141  	default:
   142  		return 0, fmt.Errorf("unrecognized dependency mode: %q", s)
   143  	}
   144  }
   145  
   146  // ProtoMode determines how proto rules are generated.
   147  type ProtoMode int
   148  
   149  const (
   150  	// DefaultProtoMode generates proto_library and new grpc_proto_library rules.
   151  	// .pb.go files are excluded when there is a .proto file with a similar name.
   152  	DefaultProtoMode ProtoMode = iota
   153  
   154  	// DisableProtoMode ignores .proto files. .pb.go files are treated
   155  	// as normal sources.
   156  	DisableProtoMode
   157  
   158  	// LegacyProtoMode generates filegroups for .proto files if .pb.go files
   159  	// are present in the same directory.
   160  	LegacyProtoMode
   161  )
   162  
   163  func ProtoModeFromString(s string) (ProtoMode, error) {
   164  	switch s {
   165  	case "default":
   166  		return DefaultProtoMode, nil
   167  	case "disable":
   168  		return DisableProtoMode, nil
   169  	case "legacy":
   170  		return LegacyProtoMode, nil
   171  	default:
   172  		return 0, fmt.Errorf("unrecognized proto mode: %q", s)
   173  	}
   174  }