spruce/cmd/spruce/main.go
Dan Anglin 71d62ecaf6
refactor: add golangci-lint with code refactoring
Add golangci-lint for linting and refactor the code based on the
feedback from running it.

Changes:

- Add configuration for golangci-lint.
- Break the large function in create.go into smaller ones.
- Rename internal/templateFuncs to internal/templatefuncs to remove
  upper case letters in the package name.
- Add a mage target for lint tests.
2023-08-21 03:07:06 +01:00

124 lines
2.5 KiB
Go

package main
import (
"flag"
"fmt"
"log/slog"
"os"
"slices"
"strings"
"codeflow.dananglin.me.uk/apollo/spruce/internal/cmd"
)
const (
create string = "create"
generate string = "generate"
version string = "version"
)
var (
binaryVersion string
buildTime string
goVersion string
gitCommit string
)
func main() {
summaries := map[string]string{
create: "creates a new CV JSON file",
generate: "generates a PDF file from an existing CV JSON file",
version: "print the application's version and build information",
}
flag.Usage = spruceUsageFunc(summaries)
flag.Parse()
if flag.NArg() < 1 {
flag.Usage()
os.Exit(0)
}
subcommand := flag.Arg(0)
args := flag.Args()[1:]
logOptions := slog.HandlerOptions{
AddSource: false,
}
logger := slog.New(slog.NewTextHandler(os.Stdout, &logOptions))
slog.SetDefault(logger)
var runner cmd.Runner
switch subcommand {
case create:
runner = cmd.NewCreateCommand(create, summaries[create])
case generate:
runner = cmd.NewGenerateCommand(generate, summaries[generate])
case version:
runner = cmd.NewVersionCommand(
binaryVersion,
buildTime,
goVersion,
gitCommit,
version,
summaries[version],
)
default:
slog.Error("unknown subcommand", "subcommand", subcommand)
flag.Usage()
os.Exit(1)
}
if err := runner.Parse(args); err != nil {
slog.Error(fmt.Sprintf("unable to parse the command line flags; %v.", err))
os.Exit(1)
}
if err := runner.Run(); err != nil {
slog.Error(fmt.Sprintf("unable to run %q; %v.", runner.Name(), err))
os.Exit(1)
}
}
func spruceUsageFunc(summaries map[string]string) func() {
cmds := make([]string, len(summaries))
ind := 0
for k := range summaries {
cmds[ind] = k
ind++
}
slices.Sort(cmds)
return func() {
var builder strings.Builder
builder.WriteString("SUMMARY:\n spruce - A command-line tool for building CVs\n\n")
if binaryVersion != "" {
builder.WriteString("VERSION:\n " + binaryVersion + "\n\n")
}
builder.WriteString("USAGE:\n spruce [flags]\n spruce [command]\n\nCOMMANDS:")
for _, cmd := range cmds {
fmt.Fprintf(&builder, "\n %s\t%s", cmd, summaries[cmd])
}
builder.WriteString("\n\nFLAGS:\n -help, --help\n print the help message\n")
flag.VisitAll(func(f *flag.Flag) {
fmt.Fprintf(&builder, "\n -%s, --%s\n %s\n", f.Name, f.Name, f.Usage)
})
builder.WriteString("\nUse \"spruce [command] --help\" for more information about a command.\n")
w := flag.CommandLine.Output()
fmt.Fprint(w, builder.String())
}
}