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

     1  /* Copyright 2016 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  // Command gazelle is a BUILD file generator for Go projects.
    17  // See "gazelle --help" for more details.
    18  package main
    19  
    20  import (
    21  	"flag"
    22  	"fmt"
    23  	"log"
    24  	"os"
    25  
    26  	"github.com/bazelbuild/bazel-gazelle/config"
    27  	"github.com/bazelbuild/bazel-gazelle/language"
    28  )
    29  
    30  type command int
    31  
    32  const (
    33  	updateCmd command = iota
    34  	fixCmd
    35  	updateReposCmd
    36  	helpCmd
    37  )
    38  
    39  var commandFromName = map[string]command{
    40  	"fix":          fixCmd,
    41  	"help":         helpCmd,
    42  	"update":       updateCmd,
    43  	"update-repos": updateReposCmd,
    44  }
    45  
    46  var nameFromCommand = []string{
    47  	// keep in sync with definition above
    48  	"update",
    49  	"fix",
    50  	"update-repos",
    51  	"help",
    52  }
    53  
    54  func (cmd command) String() string {
    55  	return nameFromCommand[cmd]
    56  }
    57  
    58  func main() {
    59  	log.SetPrefix("gazelle: ")
    60  	log.SetFlags(0) // don't print timestamps
    61  
    62  	var wd string
    63  	if wsDir := os.Getenv("BUILD_WORKSPACE_DIRECTORY"); wsDir != "" {
    64  		wd = wsDir
    65  	} else {
    66  		var err error
    67  		if wd, err = os.Getwd(); err != nil {
    68  			log.Fatal(err)
    69  		}
    70  	}
    71  
    72  	if err := run(wd, os.Args[1:]); err != nil && err != flag.ErrHelp {
    73  		if err == errExit {
    74  			os.Exit(1)
    75  		} else {
    76  			log.Fatal(err)
    77  		}
    78  	}
    79  }
    80  
    81  func run(wd string, args []string) error {
    82  	cmd := updateCmd
    83  	if len(args) == 1 && (args[0] == "-h" || args[0] == "-help" || args[0] == "--help") {
    84  		cmd = helpCmd
    85  	} else if len(args) > 0 {
    86  		c, ok := commandFromName[args[0]]
    87  		if ok {
    88  			cmd = c
    89  			args = args[1:]
    90  		}
    91  	}
    92  
    93  	switch cmd {
    94  	case fixCmd, updateCmd:
    95  		return runFixUpdate(wd, cmd, args)
    96  	case helpCmd:
    97  		return help()
    98  	case updateReposCmd:
    99  		return updateRepos(wd, args)
   100  	default:
   101  		log.Panicf("unknown command: %v", cmd)
   102  	}
   103  	return nil
   104  }
   105  
   106  func help() error {
   107  	fmt.Fprint(os.Stderr, `usage: gazelle <command> [args...]
   108  
   109  Gazelle is a BUILD file generator for Go projects. It can create new BUILD files
   110  for a project that follows "go build" conventions, and it can update BUILD files
   111  if they already exist. It can be invoked directly in a project workspace, or
   112  it can be run on an external dependency during the build as part of the
   113  go_repository rule.
   114  
   115  Gazelle may be run with one of the commands below. If no command is given,
   116  Gazelle defaults to "update".
   117  
   118    update - Gazelle will create new BUILD files or update existing BUILD files
   119        if needed.
   120    fix - in addition to the changes made in update, Gazelle will make potentially
   121        breaking changes. For example, it may delete obsolete rules or rename
   122        existing rules.
   123    update-repos - updates repository rules in the WORKSPACE file. Run with
   124        -h for details.
   125    help - show this message.
   126  
   127  For usage information for a specific command, run the command with the -h flag.
   128  For example:
   129  
   130    gazelle update -h
   131  
   132  Gazelle is under active development, and its interface may change
   133  without notice.
   134  
   135  `)
   136  	return flag.ErrHelp
   137  }
   138  
   139  // filterLanguages returns the subset of input languages that pass the config's
   140  // filter, if any. Gazelle should not generate rules for languages not returned.
   141  func filterLanguages(c *config.Config, langs []language.Language) []language.Language {
   142  	if len(c.Langs) == 0 {
   143  		return langs
   144  	}
   145  
   146  	var result []language.Language
   147  	for _, inputLang := range langs {
   148  		if containsLang(c.Langs, inputLang) {
   149  			result = append(result, inputLang)
   150  		}
   151  	}
   152  	return result
   153  }
   154  
   155  func containsLang(langNames []string, lang language.Language) bool {
   156  	for _, langName := range langNames {
   157  		if langName == lang.Name() {
   158  			return true
   159  		}
   160  	}
   161  	return false
   162  }