spruce/internal/cmd/generate.go

99 lines
2.5 KiB
Go
Raw Permalink Normal View History

package cmd
import (
"flag"
"fmt"
"io"
"log/slog"
"os"
"path/filepath"
"time"
"codeflow.dananglin.me.uk/apollo/spruce/internal/pdf"
)
type GenerateCommand struct {
*flag.FlagSet
summary string
input string
output string
employmentHistory int
verbose bool
}
type noInputSpecifiedError struct{}
func (e noInputSpecifiedError) Error() string {
return "no input file specified, please set the --input field"
}
func NewGenerateCommand(name, summary string) *GenerateCommand {
command := GenerateCommand{
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
summary: summary,
}
command.StringVar(&command.input, "input", "", "specify the CV JSON file that you want to input to the builder.")
command.StringVar(&command.output, "output", "cv.pdf", "specify the name of the output CV file.")
command.IntVar(&command.employmentHistory, "employment-history", 10, "show employment history within these number of years.")
command.BoolVar(&command.verbose, "verbose", false, "set to true to enable verbose logging.")
command.Usage = usageFunc(command.Name(), command.summary, command.FlagSet)
return &command
}
func (c *GenerateCommand) Run() error {
if c.input == "" {
return noInputSpecifiedError{}
}
historyLimit := time.Now().AddDate(-1*c.employmentHistory, 0, 0)
tempDir, err := os.MkdirTemp("/tmp", "cv-builder-")
if err != nil {
return fmt.Errorf("unable to create a temporary directory; %w", err)
}
defer func() {
err := os.RemoveAll(tempDir)
if err != nil {
slog.Warn(fmt.Sprintf("WARN: An error occurred when removing the temporary directory; %v", err))
}
}()
pdfFileName, err := pdf.Generate(tempDir, c.input, historyLimit, c.verbose)
if err != nil {
return fmt.Errorf("unable to create the PDF file; %w", err)
}
if err := copyfile(filepath.Join(tempDir, "cv.pdf"), c.output); err != nil {
return fmt.Errorf("unable to copy %s to %s; %w", pdfFileName, c.output, err)
}
return nil
}
func copyfile(source, destination string) error {
inputFile, err := os.Open(source)
if err != nil {
return fmt.Errorf("unable to open %s; %w", source, err)
}
defer inputFile.Close()
outputFile, err := os.Create(destination)
if err != nil {
return fmt.Errorf("unable to create %s; %w", destination, err)
}
defer outputFile.Close()
_, err = io.Copy(outputFile, inputFile)
if err != nil {
return fmt.Errorf("unable to copy %s to %s; %w", source, destination, err)
}
slog.Info("File successfully copied.", "source", source, "destination", destination)
return nil
}