diff --git a/cmd/enbas/main.go b/cmd/enbas/main.go index c393784..3858f4e 100644 --- a/cmd/enbas/main.go +++ b/cmd/enbas/main.go @@ -57,7 +57,8 @@ func run() error { return nil } - // If NoColor is still unspecified, check to see if the NO_COLOR environment variable is set + // If NoColor is still unspecified, + // check to see if the NO_COLOR environment variable is set if noColor == nil { noColor = new(bool) if os.Getenv("NO_COLOR") != "" { @@ -123,6 +124,12 @@ func run() error { executor.CommandFollow, executor.CommandSummaryLookup(executor.CommandFollow), ), + executor.CommandInit: executor.NewInitExecutor( + printer, + configDir, + executor.CommandInit, + executor.CommandSummaryLookup(executor.CommandInit), + ), executor.CommandLogin: executor.NewLoginExecutor( printer, config, diff --git a/internal/config/config.go b/internal/config/config.go index 17a6925..348640a 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1,3 +1,7 @@ +// SPDX-FileCopyrightText: 2024 Dan Anglin +// +// SPDX-License-Identifier: GPL-3.0-or-later + package config import ( @@ -37,17 +41,6 @@ type Integrations struct { func NewConfigFromFile(configDir string) (*Config, error) { path := configFile(configDir) - fileExists, err := utilities.FileExists(path) - if err != nil { - return nil, fmt.Errorf("unable to check if the config file exists: %w", err) - } - - if !fileExists { - if err := saveDefaultConfigToFile(configDir, path); err != nil { - return nil, fmt.Errorf("unable to save the default config to file: %w", err) - } - } - file, err := os.Open(path) if err != nil { return nil, fmt.Errorf("unable to open %s: %w", path, err) @@ -63,14 +56,18 @@ func NewConfigFromFile(configDir string) (*Config, error) { return &config, nil } -func configFile(configDir string) string { - return filepath.Join(utilities.CalculateConfigDir(configDir), configFileName) +func FileExists(configDir string) (bool, error) { + path := configFile(configDir) + + return utilities.FileExists(path) } -func saveDefaultConfigToFile(configDir, configPath string) error { - file, err := os.Create(configPath) +func SaveDefaultConfigToFile(configDir string) error { + path := configFile(configDir) + + file, err := os.Create(path) if err != nil { - return fmt.Errorf("unable to create the file at %s: %w", configPath, err) + return fmt.Errorf("unable to create the file at %s: %w", path, err) } defer file.Close() @@ -85,6 +82,10 @@ func saveDefaultConfigToFile(configDir, configPath string) error { return nil } +func configFile(configDir string) string { + return filepath.Join(utilities.CalculateConfigDir(configDir), configFileName) +} + func defaultConfig(configDir string) Config { credentialsFilePath := defaultCredentialsConfigFile(configDir) diff --git a/internal/executor/commands.go b/internal/executor/commands.go index a94673b..b16a551 100644 --- a/internal/executor/commands.go +++ b/internal/executor/commands.go @@ -12,6 +12,7 @@ const ( CommandDelete string = "delete" CommandEdit string = "edit" CommandFollow string = "follow" + CommandInit string = "init" CommandLogin string = "login" CommandMute string = "mute" CommandReject string = "reject" @@ -31,6 +32,7 @@ const ( commandDeleteSummary string = "Delete a specific resource" commandEditSummary string = "Edit a specific resource" commandFollowSummary string = "Follow a resource (e.g. an account)" + commandInitSummary string = "Create a new configuration file in the specified configuration directory" commandLoginSummary string = "Login to an account on GoToSocial" commandMuteSummary string = "Mute a resource (e.g. an account)" commandRejectSummary string = "Reject a request (e.g. a follow request)" @@ -53,6 +55,7 @@ func CommandSummaryMap() map[string]string { CommandDelete: commandDeleteSummary, CommandEdit: commandEditSummary, CommandFollow: commandFollowSummary, + CommandInit: commandInitSummary, CommandLogin: commandLoginSummary, CommandMute: commandMuteSummary, CommandReject: commandRejectSummary, diff --git a/internal/executor/init.go b/internal/executor/init.go new file mode 100644 index 0000000..8d71bc3 --- /dev/null +++ b/internal/executor/init.go @@ -0,0 +1,61 @@ +// SPDX-FileCopyrightText: 2024 Dan Anglin +// +// SPDX-License-Identifier: GPL-3.0-or-later + +package executor + +import ( + "flag" + "fmt" + + "codeflow.dananglin.me.uk/apollo/enbas/internal/config" + "codeflow.dananglin.me.uk/apollo/enbas/internal/printer" + "codeflow.dananglin.me.uk/apollo/enbas/internal/utilities" +) + +type InitExecutor struct { + *flag.FlagSet + + printer *printer.Printer + configDir string +} + +func NewInitExecutor(printer *printer.Printer, configDir, name, summary string) *InitExecutor { + initExe := InitExecutor{ + FlagSet: flag.NewFlagSet(name, flag.ExitOnError), + + printer: printer, + configDir: configDir, + } + + initExe.Usage = commandUsageFunc(name, summary, initExe.FlagSet) + + return &initExe +} + +func (i *InitExecutor) Execute() error { + if err := utilities.EnsureDirectory(i.configDir); err != nil { + return fmt.Errorf("unable to ensure that the configuration directory is present: %w", err) + } + + i.printer.PrintSuccess("The configuration directory is present.") + + fileExists, err := config.FileExists(i.configDir) + if err != nil { + return fmt.Errorf("unable to check if the config file exists: %w", err) + } + + if fileExists { + i.printer.PrintInfo("The configuration file is already present in " + i.configDir) + + return nil + } + + if err := config.SaveDefaultConfigToFile(i.configDir); err != nil { + return fmt.Errorf("unable to create a new configuration file in %s: %w", i.configDir, err) + } + + i.printer.PrintSuccess("Successfully created a new configuration file in " + i.configDir) + + return nil +} diff --git a/internal/executor/usage.go b/internal/executor/usage.go index cc5f1ff..dfd26de 100644 --- a/internal/executor/usage.go +++ b/internal/executor/usage.go @@ -6,7 +6,7 @@ package executor import ( "flag" - "fmt" + "slices" "strings" ) @@ -15,27 +15,41 @@ func commandUsageFunc(name, summary string, flagset *flag.FlagSet) func() { return func() { var builder strings.Builder - fmt.Fprintf( - &builder, - "SUMMARY:\n %s - %s\n\nUSAGE:\n enbas %s [flags]\n\nFLAGS:", - name, - summary, - name, - ) + builder.WriteString("SUMMARY:") + builder.WriteString("\n " + name + " - " + summary) + builder.WriteString("\n\nUSAGE:") + builder.WriteString("\n enbas " + name) + + flagMap := make(map[string]string) flagset.VisitAll(func(f *flag.Flag) { - fmt.Fprintf( - &builder, - "\n --%s\n %s", - f.Name, - f.Usage, - ) + flagMap[f.Name] = f.Usage }) + if len(flagMap) > 0 { + flags := make([]string, len(flagMap)) + ind := 0 + + for f := range flagMap { + flags[ind] = f + ind++ + } + + slices.Sort(flags) + + builder.WriteString(" [flags]") + builder.WriteString("\n\nFLAGS:") + + for _, value := range flags { + builder.WriteString("\n --" + value) + builder.WriteString("\n " + flagMap[value]) + } + } + builder.WriteString("\n") w := flag.CommandLine.Output() - fmt.Fprint(w, builder.String()) + _, _ = w.Write([]byte(builder.String())) } } diff --git a/internal/executor/version.go b/internal/executor/version.go index 4abdf6f..4dbf632 100644 --- a/internal/executor/version.go +++ b/internal/executor/version.go @@ -12,6 +12,7 @@ import ( type VersionExecutor struct { *flag.FlagSet + printer *printer.Printer showFullVersion bool binaryVersion string @@ -21,7 +22,7 @@ type VersionExecutor struct { } func NewVersionExecutor( - enbasPrinter *printer.Printer, + printer *printer.Printer, name, summary, binaryVersion, @@ -32,7 +33,7 @@ func NewVersionExecutor( command := VersionExecutor{ FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - printer: enbasPrinter, + printer: printer, binaryVersion: binaryVersion, buildTime: buildTime, goVersion: goVersion,