diff --git a/internal/action.go b/internal/action.go index d0acfe7..0bc0cd8 100644 --- a/internal/action.go +++ b/internal/action.go @@ -1,9 +1,12 @@ package internal import ( + "embed" "errors" "fmt" + "html/template" "io" + "log" "log/slog" "net/http" "os" @@ -30,6 +33,14 @@ type Args struct { Year int } +type templateData struct { + year int + day int +} + +//go:embed templates/*.tmpl +var templateFS embed.FS + func GenerateTemplate(args Args) error { year := args.Year day := args.Day @@ -63,7 +74,38 @@ func GenerateTemplate(args Args) error { slog.Error("Unable to write input into input.txt", "err", err) } } else { - slog.Warn("Skipping downloading input") + slog.Warn("Skipping downloading input, file already exist") + } + + if args.Language == None { + slog.Warn("Skipping code template generation") + } else { + tmpl, err := loadTemplate(string(args.Language)) + if err != nil { + slog.Error("Error loading template", "err", err) + return err + } + + if _, err := os.Stat(filepath.Join(path, generateSolutionName(args.Language))); errors.Is(err, os.ErrNotExist) { + slog.Warn("Skipping code template generation, file already exist") + } + + // Create an output file + outputFile, err := os.Create(filepath.Join(path, generateSolutionName(args.Language))) + if err != nil { + log.Fatalf("Error creating file: %v", err) + } + defer outputFile.Close() + + // Execute the template with data + data := templateData{ + year: args.Year, + day: args.Day, + } + err = tmpl.Execute(outputFile, data) + if err != nil { + log.Fatalf("Error executing template: %v", err) + } } return nil @@ -73,6 +115,14 @@ func generatePath(year, day int) string { return filepath.Join(fmt.Sprint(year), fmt.Sprintf("day-%02d", day)) } +func generateSolutionName(lang Template) string { + if lang == Ruby { + return "main.rb" + } + slog.Error("unknown language", "lang", lang) + return "main.txt" +} + func prepareRequest(url string, session Session) (*http.Request, error) { req, err := http.NewRequest(http.MethodGet, url, nil) if err != nil { @@ -157,3 +207,14 @@ func writeToFile(filePath, content string) error { return nil } + +func loadTemplate(name string) (*template.Template, error) { + // Read the template content from the embedded filesystem + templateContent, err := templateFS.ReadFile("templates/" + name + ".tmpl") + if err != nil { + return nil, err + } + + // Parse the template from the content + return template.New(name).Parse(string(templateContent)) +} diff --git a/internal/templates/ruby.tmpl b/internal/templates/ruby.tmpl new file mode 100644 index 0000000..dd58ed1 --- /dev/null +++ b/internal/templates/ruby.tmpl @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require "pry" +require "minitest/autorun" + +def read_file(filename) + # Get the directory of the currently executing script + # Join the script directory with the filename + # Read the content of the file + File.read(File.join(__dir__, filename)) +end + +def solve(filename) + read_file(filename) + 0 +end + +def solve2(filename) + read_file(filename) + 0 +end + +class AoCTest < Minitest::Test + def test_solve + assert solve("test.txt") == 0 + end + + def test_solve2 + assert solve2("test.txt") == 0 + end +end + +puts 'Part1', solve('input.txt') +puts 'Part2', solve2('input.txt') diff --git a/main.go b/main.go index a6b71b1..ca5bfa1 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ import ( "log/slog" "os" "runtime" + "slices" "time" "github.com/charmbracelet/log" @@ -34,6 +35,7 @@ func main() { Flags: []cli.Flag{ &cli.StringFlag{ Name: "session", + Aliases: []string{"s"}, Usage: "Session granted by adventofcode.com when you log in", Required: false, EnvVars: []string{"AOC_SESSION"}, @@ -54,6 +56,23 @@ func main() { Value: time.Now().Year(), DefaultText: fmt.Sprint(time.Now().Year()), }, + &cli.StringFlag{ + Name: "lang", + Aliases: []string{"l"}, + Usage: "Programming language to generate the solution for", + Required: false, + Value: "none", + Action: func(ctx *cli.Context, v string) error { + if v == "" { + return nil + } + allowedValues := []string{string(internal.Ruby)} + if slices.Contains(allowedValues, v) { + return nil + } + return fmt.Errorf("Invalid language provided '%v', we currently support: %v", v, allowedValues) + }, + }, }, Action: func(ctx *cli.Context) error { handler := log.NewWithOptions(os.Stderr, log.Options{ @@ -64,7 +83,8 @@ func main() { session := internal.Session(ctx.String("session")) day := ctx.Int("day") year := ctx.Int("year") - slog.SetDefault(slog.New(handler).With("day", day, "year", year)) + lang := ctx.String("lang") + slog.SetDefault(slog.New(handler).With("day", day, "year", year, "lang", lang)) if session == "" { slog.Error("The session is required so that you can download your input and part2. see --help") return nil @@ -89,7 +109,7 @@ func main() { Session: session, Day: day, Year: year, - Language: internal.None, + Language: internal.Template(lang), } return internal.GenerateTemplate(args) },