mirror of
https://github.com/apricote/releaser-pleaser.git
synced 2026-01-13 13:21:00 +00:00
refactor(cmd): use factories instead of global cobra command structs (#238)
This enables us to create new commands for e2e tests.
This commit is contained in:
parent
5b5b29c0b5
commit
e6503da93a
4 changed files with 128 additions and 111 deletions
|
|
@ -7,21 +7,23 @@ import (
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/lmittmann/tint"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
var logger *slog.Logger
|
func NewRootCmd() *cobra.Command {
|
||||||
|
var cmd = &cobra.Command{
|
||||||
|
Use: "rp",
|
||||||
|
Short: "",
|
||||||
|
Long: ``,
|
||||||
|
Version: version(),
|
||||||
|
SilenceUsage: true, // Makes it harder to find the actual error
|
||||||
|
SilenceErrors: true, // We log manually with slog
|
||||||
|
}
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
cmd.AddCommand(newRunCommand())
|
||||||
Use: "rp",
|
|
||||||
Short: "",
|
return cmd
|
||||||
Long: ``,
|
|
||||||
Version: version(),
|
|
||||||
SilenceUsage: true, // Makes it harder to find the actual error
|
|
||||||
SilenceErrors: true, // We log manually with slog
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func version() string {
|
func version() string {
|
||||||
|
|
@ -66,24 +68,13 @@ func Execute() {
|
||||||
// Make sure to stop listening on signals after receiving the first signal to hand control of the signal back
|
// Make sure to stop listening on signals after receiving the first signal to hand control of the signal back
|
||||||
// to the runtime. The Go runtime implements a "force shutdown" if the signal is received again.
|
// to the runtime. The Go runtime implements a "force shutdown" if the signal is received again.
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
logger.InfoContext(ctx, "Received shutdown signal, stopping...")
|
slog.InfoContext(ctx, "Received shutdown signal, stopping...")
|
||||||
stop()
|
stop()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err := rootCmd.ExecuteContext(ctx)
|
err := NewRootCmd().ExecuteContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.ErrorContext(ctx, err.Error())
|
slog.ErrorContext(ctx, err.Error())
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
logger = slog.New(
|
|
||||||
tint.NewHandler(os.Stderr, &tint.Options{
|
|
||||||
Level: slog.LevelDebug,
|
|
||||||
TimeFormat: time.RFC3339,
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
slog.SetDefault(logger)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
|
@ -12,103 +13,104 @@ import (
|
||||||
"github.com/apricote/releaser-pleaser/internal/forge"
|
"github.com/apricote/releaser-pleaser/internal/forge"
|
||||||
"github.com/apricote/releaser-pleaser/internal/forge/github"
|
"github.com/apricote/releaser-pleaser/internal/forge/github"
|
||||||
"github.com/apricote/releaser-pleaser/internal/forge/gitlab"
|
"github.com/apricote/releaser-pleaser/internal/forge/gitlab"
|
||||||
|
"github.com/apricote/releaser-pleaser/internal/log"
|
||||||
"github.com/apricote/releaser-pleaser/internal/updater"
|
"github.com/apricote/releaser-pleaser/internal/updater"
|
||||||
"github.com/apricote/releaser-pleaser/internal/versioning"
|
"github.com/apricote/releaser-pleaser/internal/versioning"
|
||||||
)
|
)
|
||||||
|
|
||||||
var runCmd = &cobra.Command{
|
func newRunCommand() *cobra.Command {
|
||||||
Use: "run",
|
var (
|
||||||
RunE: run,
|
flagForge string
|
||||||
}
|
flagBranch string
|
||||||
|
flagOwner string
|
||||||
var (
|
flagRepo string
|
||||||
flagForge string
|
flagExtraFiles string
|
||||||
flagBranch string
|
flagUpdaters []string
|
||||||
flagOwner string
|
|
||||||
flagRepo string
|
|
||||||
flagExtraFiles string
|
|
||||||
flagUpdaters []string
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
rootCmd.AddCommand(runCmd)
|
|
||||||
runCmd.PersistentFlags().StringVar(&flagForge, "forge", "", "")
|
|
||||||
runCmd.PersistentFlags().StringVar(&flagBranch, "branch", "main", "")
|
|
||||||
runCmd.PersistentFlags().StringVar(&flagOwner, "owner", "", "")
|
|
||||||
runCmd.PersistentFlags().StringVar(&flagRepo, "repo", "", "")
|
|
||||||
runCmd.PersistentFlags().StringVar(&flagExtraFiles, "extra-files", "", "")
|
|
||||||
runCmd.PersistentFlags().StringSliceVar(&flagUpdaters, "updaters", []string{}, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
func run(cmd *cobra.Command, _ []string) error {
|
|
||||||
ctx := cmd.Context()
|
|
||||||
|
|
||||||
var err error
|
|
||||||
|
|
||||||
logger.DebugContext(ctx, "run called",
|
|
||||||
"forge", flagForge,
|
|
||||||
"branch", flagBranch,
|
|
||||||
"owner", flagOwner,
|
|
||||||
"repo", flagRepo,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var f forge.Forge
|
var cmd = &cobra.Command{
|
||||||
|
Use: "run",
|
||||||
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
|
ctx := cmd.Context()
|
||||||
|
logger := log.GetLogger(cmd.ErrOrStderr())
|
||||||
|
|
||||||
forgeOptions := forge.Options{
|
var err error
|
||||||
Repository: flagRepo,
|
|
||||||
BaseBranch: flagBranch,
|
logger.DebugContext(ctx, "run called",
|
||||||
|
"forge", flagForge,
|
||||||
|
"branch", flagBranch,
|
||||||
|
"owner", flagOwner,
|
||||||
|
"repo", flagRepo,
|
||||||
|
)
|
||||||
|
|
||||||
|
var f forge.Forge
|
||||||
|
|
||||||
|
forgeOptions := forge.Options{
|
||||||
|
Repository: flagRepo,
|
||||||
|
BaseBranch: flagBranch,
|
||||||
|
}
|
||||||
|
|
||||||
|
switch flagForge {
|
||||||
|
case "gitlab":
|
||||||
|
logger.DebugContext(ctx, "using forge GitLab")
|
||||||
|
f, err = gitlab.New(logger, &gitlab.Options{
|
||||||
|
Options: forgeOptions,
|
||||||
|
Path: fmt.Sprintf("%s/%s", flagOwner, flagRepo),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
slog.ErrorContext(ctx, "failed to create client", "err", err)
|
||||||
|
return fmt.Errorf("failed to create gitlab client: %w", err)
|
||||||
|
}
|
||||||
|
case "github":
|
||||||
|
logger.DebugContext(ctx, "using forge GitHub")
|
||||||
|
f = github.New(logger, &github.Options{
|
||||||
|
Options: forgeOptions,
|
||||||
|
Owner: flagOwner,
|
||||||
|
Repo: flagRepo,
|
||||||
|
})
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown --forge: %s", flagForge)
|
||||||
|
}
|
||||||
|
|
||||||
|
extraFiles := parseExtraFiles(flagExtraFiles)
|
||||||
|
|
||||||
|
updaterNames := parseUpdaters(flagUpdaters)
|
||||||
|
updaters := []updater.Updater{}
|
||||||
|
for _, name := range updaterNames {
|
||||||
|
switch name {
|
||||||
|
case "generic":
|
||||||
|
updaters = append(updaters, updater.Generic(extraFiles))
|
||||||
|
case "changelog":
|
||||||
|
updaters = append(updaters, updater.Changelog())
|
||||||
|
case "packagejson":
|
||||||
|
updaters = append(updaters, updater.PackageJson())
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unknown updater: %s", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
releaserPleaser := rp.New(
|
||||||
|
f,
|
||||||
|
logger,
|
||||||
|
flagBranch,
|
||||||
|
conventionalcommits.NewParser(logger),
|
||||||
|
versioning.SemVer,
|
||||||
|
extraFiles,
|
||||||
|
updaters,
|
||||||
|
)
|
||||||
|
|
||||||
|
return releaserPleaser.Run(ctx)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
switch flagForge {
|
cmd.PersistentFlags().StringVar(&flagForge, "forge", "", "")
|
||||||
case "gitlab":
|
cmd.PersistentFlags().StringVar(&flagBranch, "branch", "main", "")
|
||||||
logger.DebugContext(ctx, "using forge GitLab")
|
cmd.PersistentFlags().StringVar(&flagOwner, "owner", "", "")
|
||||||
f, err = gitlab.New(logger, &gitlab.Options{
|
cmd.PersistentFlags().StringVar(&flagRepo, "repo", "", "")
|
||||||
Options: forgeOptions,
|
cmd.PersistentFlags().StringVar(&flagExtraFiles, "extra-files", "", "")
|
||||||
Path: fmt.Sprintf("%s/%s", flagOwner, flagRepo),
|
cmd.PersistentFlags().StringSliceVar(&flagUpdaters, "updaters", []string{}, "")
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
logger.ErrorContext(ctx, "failed to create client", "err", err)
|
|
||||||
return fmt.Errorf("failed to create gitlab client: %w", err)
|
|
||||||
}
|
|
||||||
case "github":
|
|
||||||
logger.DebugContext(ctx, "using forge GitHub")
|
|
||||||
f = github.New(logger, &github.Options{
|
|
||||||
Options: forgeOptions,
|
|
||||||
Owner: flagOwner,
|
|
||||||
Repo: flagRepo,
|
|
||||||
})
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("unknown --forge: %s", flagForge)
|
|
||||||
}
|
|
||||||
|
|
||||||
extraFiles := parseExtraFiles(flagExtraFiles)
|
return cmd
|
||||||
|
|
||||||
updaterNames := parseUpdaters(flagUpdaters)
|
|
||||||
updaters := []updater.Updater{}
|
|
||||||
for _, name := range updaterNames {
|
|
||||||
switch name {
|
|
||||||
case "generic":
|
|
||||||
updaters = append(updaters, updater.Generic(extraFiles))
|
|
||||||
case "changelog":
|
|
||||||
updaters = append(updaters, updater.Changelog())
|
|
||||||
case "packagejson":
|
|
||||||
updaters = append(updaters, updater.PackageJson())
|
|
||||||
default:
|
|
||||||
return fmt.Errorf("unknown updater: %s", name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
releaserPleaser := rp.New(
|
|
||||||
f,
|
|
||||||
logger,
|
|
||||||
flagBranch,
|
|
||||||
conventionalcommits.NewParser(logger),
|
|
||||||
versioning.SemVer,
|
|
||||||
extraFiles,
|
|
||||||
updaters,
|
|
||||||
)
|
|
||||||
|
|
||||||
return releaserPleaser.Run(ctx)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseExtraFiles(input string) []string {
|
func parseExtraFiles(input string) []string {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/apricote/releaser-pleaser/cmd/rp/cmd"
|
"github.com/apricote/releaser-pleaser/cmd/rp/cmd"
|
||||||
|
_ "github.com/apricote/releaser-pleaser/internal/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
||||||
23
internal/log/log.go
Normal file
23
internal/log/log.go
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
package log
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"log/slog"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/lmittmann/tint"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetLogger(w io.Writer) *slog.Logger {
|
||||||
|
return slog.New(
|
||||||
|
tint.NewHandler(w, &tint.Options{
|
||||||
|
Level: slog.LevelDebug,
|
||||||
|
TimeFormat: time.RFC3339,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
slog.SetDefault(GetLogger(os.Stderr))
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue