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

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"path/filepath"
     7  	"time"
     8  
     9  	"github.com/fatih/color"
    10  
    11  	changelog "github.com/rivy-go/git-changelog/internal/changelog"
    12  )
    13  
    14  // CLI ...
    15  type CLI struct {
    16  	ctx              *CLIContext
    17  	fs               FileSystem
    18  	logger           *Logger
    19  	configLoader     ConfigLoader
    20  	generator        Generator
    21  	processorFactory *ProcessorFactory
    22  }
    23  
    24  // NewCLI ...
    25  func NewCLI(
    26  	ctx *CLIContext, fs FileSystem,
    27  	configLoader ConfigLoader,
    28  	generator Generator,
    29  ) *CLI {
    30  	silent := false
    31  	if ctx.Silent || ctx.OutputPath == "" {
    32  		silent = true
    33  	}
    34  
    35  	return &CLI{
    36  		ctx:              ctx,
    37  		fs:               fs,
    38  		logger:           NewLogger(ctx.Stdout, ctx.Stderr, silent, ctx.NoEmoji),
    39  		configLoader:     configLoader,
    40  		generator:        generator,
    41  		processorFactory: NewProcessorFactory(),
    42  	}
    43  }
    44  
    45  // Run ...
    46  func (c *CLI) Run() int {
    47  	start := time.Now()
    48  
    49  	if c.ctx.NoColor {
    50  		color.NoColor = true
    51  	}
    52  
    53  	c.logger.Log(":watch: Generating changelog ...")
    54  
    55  	config, err := c.prepareConfig()
    56  	if err != nil {
    57  		c.logger.Error(err.Error())
    58  		return ExitCodeError
    59  	}
    60  
    61  	changelogConfig, err := c.createChangelogConfig(config)
    62  	if err != nil {
    63  		c.logger.Error(err.Error())
    64  		return ExitCodeError
    65  	}
    66  
    67  	w, err := c.createOutputWriter()
    68  	if err != nil {
    69  		c.logger.Error(err.Error())
    70  		return ExitCodeError
    71  	}
    72  
    73  	err = c.generator.Generate(w, c.ctx.Query, changelogConfig)
    74  	if err != nil {
    75  		c.logger.Error(err.Error())
    76  		return ExitCodeError
    77  	}
    78  
    79  	c.logger.Log(fmt.Sprintf(":sparkles: Generate of %s is completed! (%s)",
    80  		color.GreenString("\""+c.ctx.OutputPath+"\""),
    81  		color.New(color.Bold).SprintFunc()(time.Since(start).String()),
    82  	))
    83  
    84  	return ExitCodeOK
    85  }
    86  
    87  func (c *CLI) prepareConfig() (*Config, error) {
    88  	config, err := c.configLoader.Load(c.ctx.ConfigPath)
    89  	if err != nil {
    90  		return nil, err
    91  	}
    92  
    93  	err = config.Normalize(c.ctx)
    94  	if err != nil {
    95  		return nil, err
    96  	}
    97  
    98  	config.Convert(c.ctx)
    99  
   100  	return config, err
   101  }
   102  
   103  func (c *CLI) createChangelogConfig(config *Config) (*changelog.Config, error) {
   104  	processor, err := c.processorFactory.Create(config)
   105  	if err != nil {
   106  		return nil, err
   107  	}
   108  
   109  	changelogConfig := config.Convert(c.ctx)
   110  	changelogConfig.Options.Processor = processor
   111  
   112  	return changelogConfig, nil
   113  }
   114  
   115  func (c *CLI) createOutputWriter() (io.Writer, error) {
   116  	if c.ctx.OutputPath == "" {
   117  		return c.ctx.Stdout, nil
   118  	}
   119  
   120  	out := c.ctx.OutputPath
   121  	dir := filepath.Dir(out)
   122  	err := c.fs.MkdirP(dir)
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  
   127  	file, err := c.fs.Create(out)
   128  	if err != nil {
   129  		return nil, err
   130  	}
   131  
   132  	return file, nil
   133  }