github.com/rivy-go/git-changelog@v0.0.0-20240424224517-b86e6ab57773/cmd/git-changelog/main.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  
     8  	"github.com/fatih/color"
     9  	"github.com/mattn/go-colorable"
    10  	gitcmd "github.com/tsuyoshiwada/go-gitcmd"
    11  	"github.com/urfave/cli"
    12  )
    13  
    14  func createApp(actionFunc cli.ActionFunc) *cli.App {
    15  	ttl := color.New(color.FgYellow).SprintFunc()
    16  
    17  	cli.AppHelpTemplate = fmt.Sprintf(`
    18  %s
    19    {{.Name}} [options] <tag query>
    20  
    21      There are the following specification methods for <tag query>.
    22  
    23      1. <old>..<new> - Commit contained in <old> tags from <new>.
    24      2. <name>..     - Commit from the <name> to the latest tag.
    25      3. ..<name>     - Commit from the oldest tag to <name>.
    26      4. <name>       - Commit contained in <name>.
    27  
    28  %s
    29    {{range .Flags}}{{.}}
    30    {{end}}
    31  %s
    32  
    33    $ {{.Name}}
    34  
    35      If <tag query> is not specified, it corresponds to all tags.
    36      This is the simplest example.
    37  
    38    $ {{.Name}} 1.0.0..2.0.0
    39  
    40      The above is a command to generate CHANGELOG including commit of 1.0.0 to 2.0.0.
    41  
    42    $ {{.Name}} 1.0.0
    43  
    44      The above is a command to generate CHANGELOG including commit of only 1.0.0.
    45  
    46    $ {{.Name}} $(git describe --tags $(git rev-list --tags --max-count=1))
    47  
    48      The above is a command to generate CHANGELOG with the commit included in the latest tag.
    49  
    50    $ {{.Name}} --output CHANGELOG.md
    51  
    52      The above is a command to output to CHANGELOG.md instead of standard output.
    53  
    54    $ {{.Name}} --config custom/dir/config.yml
    55  
    56      The above is a command that uses a configuration file placed other than ".changelog/config.yml".
    57  `,
    58  		ttl("USAGE:"),
    59  		ttl("OPTIONS:"),
    60  		ttl("EXAMPLE:"),
    61  	)
    62  
    63  	cli.HelpPrinter = func(w io.Writer, templ string, data interface{}) {
    64  		cli.HelpPrinterCustom(colorable.NewColorableStdout(), templ, data, nil)
    65  	}
    66  
    67  	app := cli.NewApp()
    68  	app.Name = "git-changelog"
    69  	app.Usage = "todo usage for git-changelog"
    70  	app.Version = version(FnVersionOptions{HashAbbrevLength: 8})
    71  
    72  	app.Flags = []cli.Flag{
    73  		// init
    74  		cli.BoolFlag{
    75  			Name:  "init",
    76  			Usage: "generate the git-changelog configuration file in interactive",
    77  		},
    78  
    79  		// config
    80  		cli.StringFlag{
    81  			Name:  "config, c",
    82  			Usage: "specifies a different configuration file to pick up",
    83  			Value: ".changelog/config.yml",
    84  		},
    85  
    86  		// output
    87  		cli.StringFlag{
    88  			Name:  "output, o",
    89  			Usage: "output path and filename for the changelogs. If not specified, output to stdout",
    90  		},
    91  
    92  		cli.StringFlag{
    93  			Name:  "next-tag",
    94  			Usage: "treat unreleased commits as specified tags (EXPERIMENTAL)",
    95  		},
    96  
    97  		cli.BoolFlag{
    98  			Name:  "next-tag-now",
    99  			Usage: "assign date of 'next-tag' to current time (EXPERIMENTAL)",
   100  		},
   101  
   102  		cli.BoolFlag{
   103  			Name:  "unreleased, u",
   104  			Usage: "include unreleased commits",
   105  		},
   106  
   107  		// silent
   108  		cli.BoolFlag{
   109  			Name:  "silent",
   110  			Usage: "disable stdout output",
   111  		},
   112  
   113  		// no-color
   114  		cli.BoolFlag{
   115  			Name:   "no-color",
   116  			Usage:  "disable color output",
   117  			EnvVar: "NO_COLOR",
   118  		},
   119  
   120  		// no-emoji
   121  		cli.BoolFlag{
   122  			Name:   "no-emoji",
   123  			Usage:  "disable emoji output",
   124  			EnvVar: "NO_EMOJI",
   125  		},
   126  
   127  		// no-case
   128  		cli.BoolFlag{
   129  			Name:  "no-case",
   130  			Usage: "disable case sensitive filters",
   131  		},
   132  
   133  		// tag-filter-pattern
   134  		cli.StringFlag{
   135  			Name:  "tag-filter-pattern, p",
   136  			Usage: "Regular expression of tag filter. Is specified, only matched tags will be picked",
   137  		},
   138  
   139  		// help & version
   140  		cli.HelpFlag,
   141  		cli.VersionFlag,
   142  	}
   143  
   144  	app.Action = actionFunc
   145  
   146  	return app
   147  }
   148  
   149  func appAction(c *cli.Context) error {
   150  	wd, err := os.Getwd()
   151  	if err != nil {
   152  		fmt.Fprintln(os.Stderr, "failed to get working directory", err)
   153  		os.Exit(ExitCodeError)
   154  	}
   155  
   156  	// initializer
   157  	if c.Bool("init") {
   158  		initializer := NewInitializer(
   159  			&InitContext{
   160  				WorkingDir: wd,
   161  				Stdout:     colorable.NewColorableStdout(),
   162  				Stderr:     colorable.NewColorableStderr(),
   163  			},
   164  			fs,
   165  			NewQuestioner(
   166  				gitcmd.New(&gitcmd.Config{
   167  					Bin: "git",
   168  				}),
   169  				fs,
   170  			),
   171  			NewConfigBuilder(),
   172  			templateBuilderFactory,
   173  		)
   174  
   175  		os.Exit(initializer.Run())
   176  	}
   177  
   178  	// changelog
   179  	changelogCLI := NewCLI(
   180  		&CLIContext{
   181  			WorkingDir:       wd,
   182  			Stdout:           colorable.NewColorableStdout(),
   183  			Stderr:           colorable.NewColorableStderr(),
   184  			ConfigPath:       c.String("config"),
   185  			OutputPath:       c.String("output"),
   186  			Silent:           c.Bool("silent"),
   187  			NoColor:          c.Bool("no-color"),
   188  			NoEmoji:          c.Bool("no-emoji"),
   189  			NoCaseSensitive:  c.Bool("no-case"),
   190  			Query:            c.Args().First(),
   191  			NextTag:          c.String("next-tag"),
   192  			NextTagNow:       c.Bool("next-tag-now"),
   193  			TagFilterPattern: c.String("tag-filter-pattern"),
   194  			Unreleased:       c.Bool("unreleased"),
   195  		},
   196  		fs,
   197  		NewConfigLoader(),
   198  		NewGenerator(),
   199  	)
   200  
   201  	os.Exit(changelogCLI.Run())
   202  
   203  	return nil
   204  }
   205  
   206  func main() {
   207  	app := createApp(appAction)
   208  	app.Run(os.Args)
   209  }