From 9355737f2c1facfdde58ac6476047f9e6ed4ec92 Mon Sep 17 00:00:00 2001 From: RaphSku Date: Sat, 19 Apr 2025 21:10:31 +0200 Subject: [PATCH 1/3] [DOCS]: Added Changelog entry for v0.2.0 [CI]: CI will trigger on PRs now [REF]: Refactored/Restructured code base to improve maintainability, removed unnecessary intermediary components like 'content' [ENH]: Added `--debug` flag to `synmake` command to get a log output when `synmake --config --debug` is being run Signed-off-by: RaphSku --- .github/workflows/ci_go.yml | 6 +- CHANGELOG.md | 12 +++- LICENSE | 2 +- cmd/generate/config/config.go | 48 +++++++++------ cmd/generate/config/config_test.go | 13 ++-- cmd/generate/generate.go | 8 ++- cmd/generate/generate_test.go | 8 ++- cmd/root.go | 80 ++++++++++++++++-------- cmd/version/version.go | 17 +++-- cmd/version/version_test.go | 13 ++-- go.mod | 4 +- internal/config/apply.go | 86 +++++++++++++++++--------- internal/config/apply_test.go | 31 ++++++---- internal/config/assembler.go | 82 ++++++++++++------------- internal/config/assembler_test.go | 77 ++--------------------- internal/config/config.go | 99 +++++++++--------------------- internal/config/config_test.go | 43 +++---------- internal/config/content.go | 36 ----------- internal/config/content_test.go | 27 -------- internal/config/example.go | 60 ++++++++++++++++++ internal/config/example_test.go | 34 ++++++++++ internal/config/file.go | 9 +++ internal/config/helper_test.go | 58 +++++++++++++++++ internal/config/parse.go | 22 +++---- internal/config/parse_test.go | 30 ++++----- internal/config/suggar.go | 5 ++ internal/config/suggar_test.go | 4 ++ internal/config/utilities.go | 5 ++ internal/logging/logger.go | 10 ++- internal/logging/logger_test.go | 15 ++++- internal/templates/help.go | 3 +- main.go | 8 +-- 32 files changed, 519 insertions(+), 436 deletions(-) delete mode 100644 internal/config/content.go delete mode 100644 internal/config/content_test.go create mode 100644 internal/config/example.go create mode 100644 internal/config/example_test.go create mode 100644 internal/config/file.go create mode 100644 internal/config/helper_test.go create mode 100644 internal/config/utilities.go diff --git a/.github/workflows/ci_go.yml b/.github/workflows/ci_go.yml index f540e5e..e5570c1 100644 --- a/.github/workflows/ci_go.yml +++ b/.github/workflows/ci_go.yml @@ -1,15 +1,13 @@ name: Go CI -on: - push: - branches: [ "main" ] +on: pull_request jobs: build: runs-on: ubuntu-latest strategy: matrix: - go-version: ['1.21', '1.22'] + go-version: ['1.24', '1.23'] steps: - uses: actions/checkout@v3 - name: Set up Go ${{ matrix.go-version }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 40d1e3a..ac7e6ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ +# Changelog + +## v0.2.0 +### Changed +- Restructured/Refactored code base and removed unnecessary intermediary components +- PHONYs will be added for every given target for now. + This will change in the future for targets that are actually files. +- New flag `debug` added for `synmake --config= --debug` that + will run synmake in `debug` mode + ## v0.1.1 -### 😁 Features +### Features - Print the version of synmake with `synmake version` - Generate example config with `synmake generate config` - Parse config and generate the Makefile with `synmake --config=` diff --git a/LICENSE b/LICENSE index 826e6e7..f937823 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [2024] [RaphSku] + Copyright [2025] [RaphSku] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/generate/config/config.go b/cmd/generate/config/config.go index 30ccf03..04cd0d3 100644 --- a/cmd/generate/config/config.go +++ b/cmd/generate/config/config.go @@ -1,36 +1,44 @@ package config import ( - "os" - c2 "github.com/RaphSku/synmake/internal/config" "github.com/spf13/cobra" "go.uber.org/zap" + "os" ) -func GetGenerateConfigCmd(logger *zap.Logger) cobra.Command { +type GenerateConfigSubCmd struct { + logger *zap.Logger +} + +func NewGenerateConfigSubCmd(logger *zap.Logger) *GenerateConfigSubCmd { + return &GenerateConfigSubCmd{ + logger: logger, + } +} + +func (gcsc *GenerateConfigSubCmd) GetGenerateConfigSubCmd() cobra.Command { generateConfigCmd := cobra.Command{ Use: "config", Short: "Generate a basic config.yaml for customization.", Long: `Generate a basic config.yaml, customize it and then apply it.`, - Run: func(cmd *cobra.Command, args []string) { - file, err := os.Create("config.yaml") - if err != nil { - logger.Error("Failed to create a config.yaml", zap.Error(err)) - os.Exit(1) - } - - content := "---\n" - defaultConfig := c2.GetConfigAsYamlString(logger) - content += defaultConfig - - _, err = file.WriteString(content) - if err != nil { - logger.Error("Failed to write to config.yaml", zap.Error(err)) - os.Exit(1) - } - }, + Run: gcsc.runGenerateConfigCmd, } return generateConfigCmd } + +func (gcsc *GenerateConfigSubCmd) runGenerateConfigCmd(cmd *cobra.Command, args []string) { + file, err := os.OpenFile("config.yaml", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) + defer file.Close() + if err != nil { + gcsc.logger.Error("Failed to create a config.yaml", zap.String("func", "runGenerateConfigCmd"), zap.Error(err)) + os.Exit(1) + } + err = c2.GenerateExampleYamlConfig(gcsc.logger, file) + if err != nil { + os.Remove(file.Name()) + gcsc.logger.Error("Failed to create a valid config.yaml", zap.String("func", "runGenerateConfigCmd"), zap.Error(err)) + os.Exit(1) + } +} diff --git a/cmd/generate/config/config_test.go b/cmd/generate/config/config_test.go index 920476e..4b5136c 100644 --- a/cmd/generate/config/config_test.go +++ b/cmd/generate/config/config_test.go @@ -9,18 +9,21 @@ import ( ) func TestIfGenerateConfigCmdIsRunning(t *testing.T) { + defer os.Remove("config.yaml") + + // --- Setup Logger logger, err := zap.NewDevelopment() assert.NoError(t, err) - cmd := GetGenerateConfigCmd(logger) + // --- Checking whether the config.yaml is being created + generateConfigCommand := NewGenerateConfigSubCmd(logger) + cmd := generateConfigCommand.GetGenerateConfigSubCmd() err = cmd.Execute() - assert.NoError(t, err, "Expected no error") - assert.FileExists(t, "config.yaml", "Expected file to be created") + assert.NoError(t, err) + assert.FileExists(t, "config.yaml") shortDescription := cmd.Short longDescription := cmd.Long assert.Greater(t, longDescription, shortDescription) - - os.Remove("config.yaml") } diff --git a/cmd/generate/generate.go b/cmd/generate/generate.go index 1dfe320..20cb42e 100644 --- a/cmd/generate/generate.go +++ b/cmd/generate/generate.go @@ -4,7 +4,13 @@ import ( "github.com/spf13/cobra" ) -func GetGenerateCmd() cobra.Command { +type GenerateConfigCmd struct{} + +func NewGenerateConfigCmd() *GenerateConfigCmd { + return &GenerateConfigCmd{} +} + +func (gcc *GenerateConfigCmd) GetGenerateConfigCmd() cobra.Command { generateCmd := cobra.Command{ Use: "generate", Short: "The command generate can be used to generate configuration files.", diff --git a/cmd/generate/generate_test.go b/cmd/generate/generate_test.go index 8ad05e1..8fc9595 100644 --- a/cmd/generate/generate_test.go +++ b/cmd/generate/generate_test.go @@ -1,13 +1,17 @@ -package generate +package generate_test import ( "testing" + "github.com/RaphSku/synmake/cmd/generate" "github.com/stretchr/testify/assert" ) func TestIfGenerateCmdIsRunning(t *testing.T) { - cmd := GetGenerateCmd() + t.Parallel() + + generateCommand := generate.NewGenerateConfigCmd() + cmd := generateCommand.GetGenerateConfigCmd() err := cmd.Execute() assert.NoError(t, err) diff --git a/cmd/root.go b/cmd/root.go index 7c8698d..fee9b13 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,12 +1,14 @@ package cmd import ( + "fmt" "os" "github.com/RaphSku/synmake/cmd/generate" "github.com/RaphSku/synmake/cmd/generate/config" "github.com/RaphSku/synmake/cmd/version" c2 "github.com/RaphSku/synmake/internal/config" + "github.com/RaphSku/synmake/internal/logging" "github.com/spf13/cobra" "go.uber.org/zap" ) @@ -17,48 +19,74 @@ type CLI struct { rootCmd *cobra.Command } -func NewCLI(logger *zap.Logger) *CLI { - var configFilePath string +func NewCLI() *CLI { + return &CLI{} +} +func (cli *CLI) Run() { rootCmd := &cobra.Command{ Use: "synmake", Short: "synmake helps you with the setup of Makefiles!", Long: `Based on a yaml config, synmake will generate a Makefile template for you!`, - Run: func(cmd *cobra.Command, args []string) { - if configFilePath != "" { - configManager := c2.NewConfigManager(logger, configFilePath) - err := configManager.Parse().Apply() - if err != nil { - logger.Error("The config file could not be parsed and applied", zap.Error(err)) - os.Exit(1) - } - } - }, + Run: cli.runSynmakeCommand, } + // --- ROOT CMD rootCmd.CompletionOptions.DisableDefaultCmd = true - rootCmd.Flags().StringVarP(&configFilePath, "config", "", "", "Specify the filepath to your config yaml.") + rootCmd.Flags().StringP("config", "", "", "Specify the filepath to your config yaml.") rootCmd.MarkFlagRequired("config") + rootCmd.Flags().BoolP("debug", "", false, "Enable debug mode to get more helpful log messages.") + cli.rootCmd = rootCmd - return &CLI{ - logger: logger, - rootCmd: rootCmd, - } -} - -func (cli *CLI) AddSubCommands() { - versionCmd := version.GetVersionCmd(cli.logger) + // --- SUB CMD + versionCmd := version.NewVersionCmd().GetVersionCmd() cli.rootCmd.AddCommand(versionCmd) - generateCmd := generate.GetGenerateCmd() + generateCmd := generate.NewGenerateConfigCmd().GetGenerateConfigCmd() cli.rootCmd.AddCommand(&generateCmd) - configCmd := config.GetGenerateConfigCmd(cli.logger) + + configCmd := config.NewGenerateConfigSubCmd(cli.logger).GetGenerateConfigSubCmd() generateCmd.AddCommand(&configCmd) -} -func (cli *CLI) Execute() { + // --- EXECUTE if err := cli.rootCmd.Execute(); err != nil { - cli.logger.Info("CLI failed to run", zap.Error(err)) + fmt.Printf("CLI failed to run due to %v\n", err) + } +} + +func (cli *CLI) runSynmakeCommand(cmd *cobra.Command, args []string) { + debugMode, _ := cmd.Flags().GetBool("debug") + cli.logger = logging.SetupZapLogger(debugMode) + configFilePath, _ := cmd.Flags().GetString("config") + + file, err := os.OpenFile(configFilePath, os.O_RDONLY, 0644) + if err != nil { + cli.logger.Error("Could not create config file", zap.String("func", "runSynmakeCommand"), zap.Error(err)) + os.Exit(1) + } + configManager, err := c2.NewConfigManager(cli.logger, file) + if err != nil { + cli.logger.Error("Failed to initialize a new config manager", zap.String("func", "runSynmakeCommand"), zap.Error(err)) + os.Exit(1) + } + defer configManager.Close() + + err = configManager.Parse() + if err != nil { + cli.logger.Error("Parsing of the config file failed", zap.String("func", "runSynmakeCommand"), zap.Error(err)) + os.Exit(1) + } + + file, err = os.OpenFile("Makefile", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) + if err != nil { + cli.logger.Error("Could not create Makefile", zap.String("func", "runSynmakeCommand"), zap.Error(err)) + os.Exit(1) + } + defer file.Close() + err = configManager.Apply(file) + if err != nil { + cli.logger.Error("The config file could not be applied", zap.String("func", "runSynmakeCommand"), zap.Error(err)) os.Exit(1) } + return } diff --git a/cmd/version/version.go b/cmd/version/version.go index bbfdfa4..c30384a 100644 --- a/cmd/version/version.go +++ b/cmd/version/version.go @@ -4,18 +4,25 @@ import ( "fmt" "github.com/spf13/cobra" - "go.uber.org/zap" ) -func GetVersionCmd(logger *zap.Logger) *cobra.Command { +type VersionCmd struct{} + +func NewVersionCmd() *VersionCmd { + return &VersionCmd{} +} + +func (vc *VersionCmd) GetVersionCmd() *cobra.Command { versionCmd := &cobra.Command{ Use: "version", Short: "Print the version number of synmake.", Long: `This will show you the version of synmake in the format: {MAJOR}-{MINOR}-{PATCH}.`, - Run: func(cmd *cobra.Command, args []string) { - fmt.Println("v0.1.1") - }, + Run: vc.runVersionCmd, } return versionCmd } + +func (vc *VersionCmd) runVersionCmd(cmd *cobra.Command, args []string) { + fmt.Println("v0.2.0") +} diff --git a/cmd/version/version_test.go b/cmd/version/version_test.go index 731d854..0aebc01 100644 --- a/cmd/version/version_test.go +++ b/cmd/version/version_test.go @@ -1,20 +1,17 @@ -package version +package version_test import ( "testing" + "github.com/RaphSku/synmake/cmd/version" "github.com/stretchr/testify/assert" - "go.uber.org/zap" ) func TestIfVersionCmdIsRunning(t *testing.T) { - logger, err := zap.NewDevelopment() - assert.NoError(t, err) + t.Parallel() - cmd := GetVersionCmd(logger) - - err = cmd.Execute() - assert.NoError(t, err) + versionCommand := version.NewVersionCmd() + cmd := versionCommand.GetVersionCmd() shortDescription := cmd.Short longDescription := cmd.Long diff --git a/go.mod b/go.mod index 726aba9..da68fe8 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,9 @@ module github.com/RaphSku/synmake -go 1.21.0 +go 1.24.2 retract ( - v0.1.0 + v0.1.0 ) require ( diff --git a/internal/config/apply.go b/internal/config/apply.go index ca107e4..a0f2c04 100644 --- a/internal/config/apply.go +++ b/internal/config/apply.go @@ -1,54 +1,84 @@ package config import ( - "os" + "io" "github.com/RaphSku/synmake/internal/templates" "go.uber.org/zap" ) -func (c *ConfigManager) Apply() error { - err := c.applyConfig() +func (cm *ConfigManager) Apply(file FileInterface) error { + err := cm.applyConfig(file) if err != nil { - c.logger.Error("config could not be applied", zap.Error(err)) - os.Exit(1) + cm.logger.Error("Config could not be applied", zap.String("func", "Apply"), zap.Error(err)) + return err } return nil } -func (c *ConfigManager) applyConfig() error { - file, err := os.Create("Makefile") - if err != nil { - c.logger.Error("error creating file", zap.Error(err)) - return err +func (cm *ConfigManager) applyConfig(w io.StringWriter) error { + content := &SuggarString{} + + var versionContent string + versionConstants := []string{} + if cm.Config.Templates.VersionCommandTemplate.Enabled { + versionContent, versionConstants = templates.GetVersionTemplate( + cm.Config.Templates.VersionCommandTemplate.Library, + cm.Config.Templates.VersionCommandTemplate.MinVersion, + ) + } + + // --- VARIABLES + cm.logger.Info("Variables will be added", zap.String("func", "applyConfig")) + variables := []string{} + if cm.Config.Templates.VersionCommandTemplate.Enabled { + for _, constant := range versionConstants { + variables = append(variables, constant) + } } - defer file.Close() + content = content.addSuggar(assembleVariables(variables)).lineBreak() + cm.logger.Info("Variables added", zap.String("func", "applyConfig")) - cnt := newContent(c.logger, c.config) - if c.config.HelpTemplate.Enabled { - cnt.assembleDefaultToContent() + // --- HELP TEMPLATE DEFAULT TARGET + if cm.Config.Templates.HelpTargetTemplate.Enabled { + cm.logger.Info("Help template default target will be added", zap.String("func", "applyConfig")) + content = content.addSuggar(assembleDefaultTarget()).lineBreak().lineBreak() + cm.logger.Info("Help template default target added", zap.String("func", "applyConfig")) } - cnt.assembleTargetsToContent() - if c.config.HelpTemplate.Enabled { - helpTemplate := templates.GetHelpTemplate() - cnt.Help = helpTemplate + + // --- PREFLIGHT + cm.logger.Info("Preflight target will be added", zap.String("func", "applyConfig")) + commands := []string{} + if cm.Config.Templates.VersionCommandTemplate.Enabled { + commands = append( + commands, + versionContent, + ) } - if c.config.VersionTemplate.Enabled { - versionTemplate, versionConstants := templates.GetVersionTemplate(c.config.VersionTemplate.Library, c.config.VersionTemplate.MinVersion) - cnt.Constants = append(cnt.Constants, versionConstants...) - cnt.Preflight = append(cnt.Preflight, versionTemplate) + content = content.addSuggar(assemblePreflightTarget(commands)) + cm.logger.Info("Preflight target added", zap.String("func", "applyConfig")) + + // --- TARGETS ADDED + cm.logger.Info("Targets will be added", zap.String("func", "applyConfig")) + content = content.addSuggar(assembleTargets(cm.Config.Targets, cm.Config.Templates.HelpTargetTemplate.Delimiter)) + cm.logger.Info("Targets added", zap.String("func", "applyConfig")) + + // --- HELP TARGET ADDED + if cm.Config.Templates.HelpTargetTemplate.Enabled { + cm.logger.Info("Help target will be added", zap.String("func", "applyConfig")) + content = content.appendString(templates.GetHelpTemplate()) + cm.logger.Info("Help target added", zap.String("func", "applyConfig")) } - cnt.assemblePhonyToContent() - content := cnt.assembleAll() - _, err = file.WriteString(content) + // --- WRITE MAKEFILE + cm.logger.Info("Writing to Makefile", zap.String("func", "applyConfig")) + _, err := w.WriteString(content.getString()) if err != nil { - c.logger.Error("error writing to file", zap.Error(err)) + cm.logger.Error("Failed to write to Makefile", zap.String("func", "applyConfig"), zap.Error(err)) return err } - - c.logger.Info("file has been created successfully") + cm.logger.Info("Makefile has been created successfully!", zap.String("func", "applyConfig")) return nil } diff --git a/internal/config/apply_test.go b/internal/config/apply_test.go index eff5e0e..5651a09 100644 --- a/internal/config/apply_test.go +++ b/internal/config/apply_test.go @@ -1,29 +1,38 @@ -package config +package config_test import ( - "os" + "bytes" "testing" + "github.com/RaphSku/synmake/internal/config" "github.com/stretchr/testify/assert" "go.uber.org/zap" ) func TestApply(t *testing.T) { + t.Parallel() + + // --- Setup Logger logger, err := zap.NewDevelopment() assert.NoError(t, err) - configString := GetConfigAsYamlString(logger) + // --- Generate example configuration for testing + configBuffer := &bytes.Buffer{} + config.GenerateExampleYamlConfig(logger, configBuffer) - file, err := os.Create("config.yaml") + // --- Initialise new config manager + configFileBuffer := NewFileBuffer("config.yaml") + configFileBuffer.Write(configBuffer.Bytes()) + cm, err := config.NewConfigManager(logger, configFileBuffer) assert.NoError(t, err) - defer file.Close() - _, err = file.WriteString(configString) + err = cm.Parse() assert.NoError(t, err) - cm := NewConfigManager(logger, "config.yaml") - cm.Apply() - assert.FileExists(t, "Makefile") + // --- Test generation of Makefile + actualMakefile := NewFileBuffer("Makefile") + err = cm.Apply(actualMakefile) + assert.NoError(t, err) - os.Remove("Makefile") - os.Remove("config.yaml") + expectedMakefileByteLength := 1646 + assert.Equal(t, expectedMakefileByteLength, len(actualMakefile.buffer.Bytes())) } diff --git a/internal/config/assembler.go b/internal/config/assembler.go index 6fc83b0..73d2711 100644 --- a/internal/config/assembler.go +++ b/internal/config/assembler.go @@ -4,39 +4,58 @@ import ( "fmt" ) -func (cnt *content) assemblePhonyToContent() { - cnt.logger.Info("preparing PHONY string") - - strs := []string{".PHONY:"} - strs = append(strs, cnt.config.Phony...) - content := cnt.concatStringsWithWhiteSpaces(strs...) - content += "\n" - cnt.Phony = content +func concatStringsWithWhiteSpaces(strs ...string) string { + result := "" + for i := range strs { + result += strs[i] + if i != len(strs)-1 { + result += " " + } + } - cnt.logger.Info("PHONY string created successfully") + return result } -func (cnt *content) assembleDefaultToContent() { - cnt.logger.Info("preparing Default string") +func assembleVariables(variables []string) SuggarString { + var content SuggarString + for i := range variables { + content.appendString(variables[i]).lineBreak() + } + + return content +} +func assembleDefaultTarget() SuggarString { var content SuggarString + content.appendString(".PHONY: default").lineBreak() content.appendString("default:").appendString(" ").appendString("help") - cnt.Default = content.getString() + return content +} + +func assemblePreflightTarget(commands []string) SuggarString { + var content SuggarString + content.appendString(".PHONY: preflight").lineBreak() + content.appendString("preflight:").lineBreak().tab() + for _, command := range commands { + content.appendString(command).lineBreak() + } - cnt.logger.Info("Default string created successfully") + return content } -func (cnt *content) assembleTargetsToContent() { - cnt.logger.Info("preparing Target string") +func assembleTargets(targetMap map[string]Target, delimiter string) SuggarString { + helpDelimiter := "" + if delimiter != "" { + helpDelimiter = delimiter + } var content SuggarString - for targetName, targetConfig := range cnt.config.Targets { - if cnt.config.HelpTemplate.Enabled { - content.appendString(cnt.config.HelpTemplate.Delimiter).appendString(" ").appendString(targetConfig.HelpDescription).lineBreak() - } + for targetName, targetConfig := range targetMap { + content.appendString(".PHONY:").appendString(" ").appendString(targetName).lineBreak() + content.appendString(helpDelimiter).appendString(" ").appendString(targetConfig.HelpDescription).lineBreak() content.appendString(targetName + ":").appendString(" ") - preTargets := cnt.concatStringsWithWhiteSpaces(targetConfig.PreTargets...) + preTargets := concatStringsWithWhiteSpaces(targetConfig.PreTargets...) content.appendString(preTargets).lineBreak().tab() for index, command := range targetConfig.Commands { if targetConfig.Display { @@ -54,26 +73,5 @@ func (cnt *content) assembleTargetsToContent() { content.lineBreak() } - cnt.Targets = content.getString() - - cnt.logger.Info("Target string created successfully") -} - -func (cnt *content) assembleAll() string { - var content SuggarString - - content.appendString(cnt.Phony).lineBreak() - for _, constant := range cnt.Constants { - content.appendString(constant) - } - content.lineBreak().lineBreak() - content.appendString(cnt.Default).lineBreak().lineBreak() - content.appendString("preflight:").lineBreak().tab() - for _, preflight := range cnt.Preflight { - content.appendString(preflight).lineBreak() - } - content.appendString(cnt.Targets) - content.appendString(cnt.Help) - - return content.getString() + return content } diff --git a/internal/config/assembler_test.go b/internal/config/assembler_test.go index 7e35226..c517b6f 100644 --- a/internal/config/assembler_test.go +++ b/internal/config/assembler_test.go @@ -4,83 +4,15 @@ import ( "testing" "github.com/stretchr/testify/assert" - "go.uber.org/zap" ) -func TestAssemblePhonyToContent(t *testing.T) { - t.Parallel() - - logger, err := zap.NewDevelopment() - assert.NoError(t, err) - - exp_phony := ".PHONY: default help\n" - - var config Config - config.Phony = []string{"default", "help"} - cnt := newContent(logger, config) - cnt.assemblePhonyToContent() - - assert.Equal(t, exp_phony, cnt.Phony) -} - -func TestDefaultToContent(t *testing.T) { - t.Parallel() - - logger, err := zap.NewDevelopment() - assert.NoError(t, err) - - exp_default := "default: help" - - var config Config - cnt := newContent(logger, config) - cnt.assembleDefaultToContent() - - assert.Equal(t, exp_default, cnt.Default) -} - func TestAssembleTargetsToContent(t *testing.T) { t.Parallel() - logger, err := zap.NewDevelopment() - assert.NoError(t, err) - - exp_target := `targetA: default preflight - echo "Test this" - -` - - var config Config - - targetA := Target{ - HelpDescription: "help test", - PreTargets: []string{"default", "preflight"}, - Commands: []string{"echo \"Test this\""}, - Display: false, - } - - config.Targets = map[string]Target{"targetA": targetA} - cnt := newContent(logger, config) - cnt.assembleTargetsToContent() - - assert.Equal(t, exp_target, cnt.Targets) -} - -func TestAssembleAll(t *testing.T) { - t.Parallel() - - logger, err := zap.NewDevelopment() - assert.NoError(t, err) - - exp_content := ` - - - - -preflight: - ` + // --- Checking whether targets are assembled correctly + exp_target := ".PHONY: targetA\n help test\ntargetA: default preflight\n\techo \"Test this\"\n\n" var config Config - config.Phony = []string{"help"} targetA := Target{ HelpDescription: "help test", PreTargets: []string{"default", "preflight"}, @@ -89,8 +21,7 @@ preflight: } config.Targets = map[string]Target{"targetA": targetA} - cnt := newContent(logger, config) - content := cnt.assembleAll() + ss := assembleTargets(config.Targets, "") - assert.Equal(t, exp_content, content) + assert.Equal(t, exp_target, ss.getString()) } diff --git a/internal/config/config.go b/internal/config/config.go index f9554f3..1ea9a20 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -1,11 +1,7 @@ package config import ( - "bytes" - "os" - "go.uber.org/zap" - "gopkg.in/yaml.v3" ) type Target struct { @@ -15,80 +11,41 @@ type Target struct { Display bool `yaml:"display"` } -type Config struct { - Phony []string `yaml:"phony"` - Targets map[string]Target `yaml:"targets"` - HelpTemplate struct { - Enabled bool `yaml:"enabled"` - Delimiter string `yaml:"delimiter"` - } `yaml:"helpTemplate"` - VersionTemplate struct { - Enabled bool `yaml:"enabled"` - Library string `yaml:"library"` - MinVersion string `yaml:"minVersion"` - } `yaml:"versionTemplate"` +type HelpTemplate struct { + Enabled bool `yaml:"enabled"` + Delimiter string `yaml:"delimiter"` } -type ConfigManager struct { - logger *zap.Logger - config Config - filePath string +type VersionTemplate struct { + Enabled bool `yaml:"enabled"` + Library string `yaml:"library"` + MinVersion string `yaml:"minVersion"` } -func NewConfigManager(logger *zap.Logger, filePath string) *ConfigManager { - return &ConfigManager{ - logger: logger, - config: Config{}, - filePath: filePath, - } +type OptionalTemplates struct { + HelpTargetTemplate HelpTemplate `yaml:"helpTemplate"` + VersionCommandTemplate VersionTemplate `yaml:"versionTemplate"` } -func GetConfigAsYamlString(logger *zap.Logger) string { - tA := Target{ - HelpDescription: "targetA just prints an output", - Commands: []string{"echo \"Hello World\"", "echo \"This is how you specify commands!\""}, - Display: false, - } - - tB := Target{ - HelpDescription: "targetB just prints an output", - PreTargets: []string{"targetA"}, - Commands: []string{"echo \"This is targetB!\"", "echo \"How are you doing?\""}, - Display: true, - } +type Config struct { + Targets map[string]Target `yaml:"targets"` + Templates OptionalTemplates `yaml:"templates"` +} - config := Config{ - Phony: []string{"default", "preflight", "targetA", "targetB", "help"}, - Targets: map[string]Target{ - "targetA": tA, - "targetB": tB, - }, - HelpTemplate: struct { - Enabled bool "yaml:\"enabled\"" - Delimiter string "yaml:\"delimiter\"" - }{ - Enabled: true, - Delimiter: "##", - }, - VersionTemplate: struct { - Enabled bool "yaml:\"enabled\"" - Library string "yaml:\"library\"" - MinVersion string "yaml:\"minVersion\"" - }{ - Enabled: true, - Library: "example", - MinVersion: "0.1.0", - }, - } +type ConfigManager struct { + logger *zap.Logger + Config Config + File FileInterface +} - var buf bytes.Buffer - encoder := yaml.NewEncoder(&buf) - encoder.SetIndent(2) - err := encoder.Encode(config) - if err != nil { - logger.Error("Config could not be marshalled", zap.Error(err)) - os.Exit(1) - } +func NewConfigManager(logger *zap.Logger, file FileInterface) (*ConfigManager, error) { + return &ConfigManager{ + logger: logger, + Config: Config{}, + File: file, + }, nil +} - return buf.String() +func (cm *ConfigManager) Close() error { + return cm.File.Close() } diff --git a/internal/config/config_test.go b/internal/config/config_test.go index ffc3ac4..dd3b5b2 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -1,49 +1,22 @@ -package config +package config_test import ( - "reflect" "testing" + "github.com/RaphSku/synmake/internal/config" "github.com/stretchr/testify/assert" "go.uber.org/zap" - "gopkg.in/yaml.v3" ) -func isEmptyStruct(s interface{}) bool { - typ := reflect.TypeOf(s) - if typ.Kind() != reflect.Struct { - return false - } +func TestConfigManagerInitNoError(t *testing.T) { + t.Parallel() - for i := 0; i < typ.NumField(); i++ { - field := typ.Field(i) - zeroValue := reflect.Zero(field.Type) - fieldValue := reflect.ValueOf(s).Field(i) - if !reflect.DeepEqual(fieldValue.Interface(), zeroValue.Interface()) { - return false - } - } - - return true -} - -func TestConfigManagerInit(t *testing.T) { - logger, err := zap.NewDevelopment() - assert.NoError(t, err) - - expFilePath := "./config.yaml" - configManager := NewConfigManager(logger, expFilePath) - assert.Equal(t, expFilePath, configManager.filePath) - assert.Equal(t, true, isEmptyStruct(configManager.config)) -} - -func TestDefaultConfigAsYAML(t *testing.T) { + // --- Logger Setup logger, err := zap.NewDevelopment() assert.NoError(t, err) - configString := GetConfigAsYamlString(logger) - var config Config - err = yaml.Unmarshal([]byte(configString), &config) + // --- Checking whether the config manager initialization throws no error + fileBuffer := NewFileBuffer("config.yaml") + _, err = config.NewConfigManager(logger, fileBuffer) assert.NoError(t, err) - assert.Equal(t, false, isEmptyStruct(config)) } diff --git a/internal/config/content.go b/internal/config/content.go deleted file mode 100644 index b3a5e0e..0000000 --- a/internal/config/content.go +++ /dev/null @@ -1,36 +0,0 @@ -package config - -import ( - "go.uber.org/zap" -) - -type content struct { - logger *zap.Logger - config Config - - Phony string - Constants []string - Default string - Preflight []string - Targets string - Help string -} - -func newContent(logger *zap.Logger, config Config) *content { - return &content{ - logger: logger, - config: config, - } -} - -func (cnt *content) concatStringsWithWhiteSpaces(strs ...string) string { - result := "" - for i := range strs { - result += strs[i] - if i != len(strs)-1 { - result += " " - } - } - - return result -} diff --git a/internal/config/content_test.go b/internal/config/content_test.go deleted file mode 100644 index 1287a98..0000000 --- a/internal/config/content_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package config - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "go.uber.org/zap" -) - -func TestContentInit(t *testing.T) { - logger, err := zap.NewDevelopment() - assert.NoError(t, err) - - var config Config - content := newContent(logger, config) - assert.Equal(t, true, isEmptyStruct(content.config)) -} - -func TestConcatenation(t *testing.T) { - logger, err := zap.NewDevelopment() - assert.NoError(t, err) - - var config Config - content := newContent(logger, config) - act_result := content.concatStringsWithWhiteSpaces([]string{"hey", "this", "is", "a", "test"}...) - assert.Equal(t, "hey this is a test", act_result) -} diff --git a/internal/config/example.go b/internal/config/example.go new file mode 100644 index 0000000..dfaf855 --- /dev/null +++ b/internal/config/example.go @@ -0,0 +1,60 @@ +package config + +import ( + "bytes" + "gopkg.in/yaml.v3" + "io" + + "go.uber.org/zap" +) + +func GenerateExampleYamlConfig(logger *zap.Logger, w io.StringWriter) error { + tA := Target{ + HelpDescription: "targetA just prints an output", + Commands: []string{"echo \"Hello World\"", "echo \"This is how you specify commands!\""}, + Display: false, + } + + tB := Target{ + HelpDescription: "targetB just prints an output", + PreTargets: []string{"targetA"}, + Commands: []string{"echo \"This is targetB!\"", "echo \"How are you doing?\""}, + Display: true, + } + + config := Config{ + Targets: map[string]Target{ + "targetA": tA, + "targetB": tB, + }, + Templates: OptionalTemplates{ + HelpTemplate{ + Enabled: true, + Delimiter: "##", + }, + VersionTemplate{ + Enabled: true, + Library: "example", + MinVersion: "0.1.0", + }, + }, + } + + buffer := &bytes.Buffer{} + encoder := yaml.NewEncoder(buffer) + encoder.SetIndent(2) + err := encoder.Encode(config) + if err != nil { + logger.Error("Config could not be marshalled", zap.String("func", "GenerateExampleYamlConfig"), zap.Error(err)) + return err + } + + yamlTemplate := YAML_DOCUMENT_SEPARATOR + buffer.String() + _, err = w.WriteString(yamlTemplate) + if err != nil { + logger.Error("Failed to write to config.yaml", zap.String("func", "GenerateExampleYamlConfig"), zap.Error(err)) + return err + } + + return nil +} diff --git a/internal/config/example_test.go b/internal/config/example_test.go new file mode 100644 index 0000000..c8a239b --- /dev/null +++ b/internal/config/example_test.go @@ -0,0 +1,34 @@ +package config_test + +import ( + "bytes" + "github.com/stretchr/testify/assert" + "gopkg.in/yaml.v3" + "io" + "testing" + + "github.com/RaphSku/synmake/internal/config" + "go.uber.org/zap" +) + +func TestDefaultConfigAsYAML(t *testing.T) { + t.Parallel() + + // --- Logger Setup + logger, err := zap.NewDevelopment() + assert.NoError(t, err) + + // --- Checking whether the generated example config can be unmarshalled + // --- and is not empty + buffer := &bytes.Buffer{} + + config.GenerateExampleYamlConfig(logger, buffer) + + data, err := io.ReadAll(buffer) + assert.NoError(t, err) + + var c config.Config + err = yaml.Unmarshal(data, &c) + assert.NoError(t, err) + assert.Equal(t, false, isEmptyStruct(c)) +} diff --git a/internal/config/file.go b/internal/config/file.go new file mode 100644 index 0000000..bc95eeb --- /dev/null +++ b/internal/config/file.go @@ -0,0 +1,9 @@ +package config + +type FileInterface interface { + Read([]byte) (int, error) + Write([]byte) (int, error) + WriteString(s string) (n int, err error) + Name() string + Close() error +} diff --git a/internal/config/helper_test.go b/internal/config/helper_test.go new file mode 100644 index 0000000..e64d3d4 --- /dev/null +++ b/internal/config/helper_test.go @@ -0,0 +1,58 @@ +package config_test + +import ( + "bytes" + "reflect" +) + +// --- HELPER FUNCTIONS +func isEmptyStruct(s interface{}) bool { + typ := reflect.TypeOf(s) + if typ.Kind() != reflect.Struct { + return false + } + + for i := 0; i < typ.NumField(); i++ { + field := typ.Field(i) + zeroValue := reflect.Zero(field.Type) + fieldValue := reflect.ValueOf(s).Field(i) + if !reflect.DeepEqual(fieldValue.Interface(), zeroValue.Interface()) { + return false + } + } + + return true +} + +// --- HELPER STRUCTS +type FileBuffer struct { + name string + buffer *bytes.Buffer +} + +func NewFileBuffer(name string) *FileBuffer { + return &FileBuffer{ + name: name, + buffer: &bytes.Buffer{}, + } +} + +func (m *FileBuffer) Read(p []byte) (int, error) { + return m.buffer.Read(p) +} + +func (m *FileBuffer) Write(p []byte) (int, error) { + return m.buffer.Write(p) +} + +func (m *FileBuffer) WriteString(s string) (int, error) { + return m.buffer.WriteString(s) +} + +func (m *FileBuffer) Name() string { + return m.name +} + +func (m *FileBuffer) Close() error { + return nil +} diff --git a/internal/config/parse.go b/internal/config/parse.go index 0ea8d76..482af2a 100644 --- a/internal/config/parse.go +++ b/internal/config/parse.go @@ -1,32 +1,32 @@ package config import ( - "os" + "io" "go.uber.org/zap" yaml "gopkg.in/yaml.v3" ) -func (c *ConfigManager) Parse() *ConfigManager { - err := c.parseConfig() +func (cm *ConfigManager) Parse() error { + err := cm.parseConfig(cm.File) if err != nil { - c.logger.Error("config file could not be parsed successfully", zap.Error(err)) - os.Exit(1) + cm.logger.Error("config file could not be parsed successfully", zap.String("func", "Parse"), zap.Error(err)) + return err } - return c + return nil } -func (c *ConfigManager) parseConfig() error { - data, err := os.ReadFile(c.filePath) +func (cm *ConfigManager) parseConfig(r io.Reader) error { + data, err := io.ReadAll(r) if err != nil { - c.logger.Error("data could not be read", zap.Error(err)) + cm.logger.Error("data could not be read", zap.String("func", "parseConfig"), zap.Error(err)) return err } - err = yaml.Unmarshal(data, &c.config) + err = yaml.Unmarshal(data, &cm.Config) if err != nil { - c.logger.Error("data could not be parsed into a valid Config", zap.Error(err)) + cm.logger.Error("data could not be parsed into a valid Config", zap.String("func", "parseConfig"), zap.Error(err)) return err } diff --git a/internal/config/parse_test.go b/internal/config/parse_test.go index 931bb64..813bd3a 100644 --- a/internal/config/parse_test.go +++ b/internal/config/parse_test.go @@ -1,31 +1,31 @@ -package config +package config_test import ( - "os" "testing" + "github.com/RaphSku/synmake/internal/config" "github.com/stretchr/testify/assert" "go.uber.org/zap" ) func TestParsing(t *testing.T) { + t.Parallel() + + // --- Setup Logger logger, err := zap.NewDevelopment() assert.NoError(t, err) - configString := GetConfigAsYamlString(logger) + // --- Generating example configuration + fileBuffer := NewFileBuffer("config.yaml") + err = config.GenerateExampleYamlConfig(logger, fileBuffer) + assert.NoError(t, err) - file, err := os.Create("config.yaml") + // Checking whether parsing works and fields are set correctly + configManager, err := config.NewConfigManager(logger, fileBuffer) assert.NoError(t, err) - defer file.Close() - _, err = file.WriteString(configString) + err = configManager.Parse() assert.NoError(t, err) - - cm := NewConfigManager(logger, "./config.yaml") - cm.Parse() - assert.Equal(t, false, isEmptyStruct(cm.config)) - assert.Equal(t, 5, len(cm.config.Phony)) - assert.Equal(t, true, cm.config.HelpTemplate.Enabled) - assert.Equal(t, "example", cm.config.VersionTemplate.Library) - - os.Remove("config.yaml") + assert.Equal(t, false, isEmptyStruct(configManager.Config)) + assert.Equal(t, true, configManager.Config.Templates.HelpTargetTemplate.Enabled) + assert.Equal(t, "example", configManager.Config.Templates.VersionCommandTemplate.Library) } diff --git a/internal/config/suggar.go b/internal/config/suggar.go index de21652..1645bbb 100644 --- a/internal/config/suggar.go +++ b/internal/config/suggar.go @@ -22,3 +22,8 @@ func (ss *SuggarString) appendString(str string) *SuggarString { ss.value += str return ss } + +func (ss *SuggarString) addSuggar(suggar SuggarString) *SuggarString { + ss.value += suggar.value + return ss +} diff --git a/internal/config/suggar_test.go b/internal/config/suggar_test.go index d2f7ec5..be62003 100644 --- a/internal/config/suggar_test.go +++ b/internal/config/suggar_test.go @@ -8,6 +8,7 @@ import ( func TestSuggarInit(t *testing.T) { t.Parallel() + var ss SuggarString assert.Equal(t, ss.value, "") @@ -18,6 +19,7 @@ func TestSuggarInit(t *testing.T) { func TestLineBreakAndTabs(t *testing.T) { t.Parallel() + var ss SuggarString ss.lineBreak().tab() @@ -26,6 +28,7 @@ func TestLineBreakAndTabs(t *testing.T) { func TestAppendString(t *testing.T) { t.Parallel() + exp_value := "Testing This" var ss SuggarString ss.appendString(exp_value) @@ -35,6 +38,7 @@ func TestAppendString(t *testing.T) { func TestChaining(t *testing.T) { t.Parallel() + value := "Test this" var ss SuggarString ss.lineBreak().appendString(value).tab() diff --git a/internal/config/utilities.go b/internal/config/utilities.go new file mode 100644 index 0000000..478e035 --- /dev/null +++ b/internal/config/utilities.go @@ -0,0 +1,5 @@ +package config + +const ( + YAML_DOCUMENT_SEPARATOR = "---\n" +) diff --git a/internal/logging/logger.go b/internal/logging/logger.go index b9ab5bd..342421c 100644 --- a/internal/logging/logger.go +++ b/internal/logging/logger.go @@ -7,7 +7,7 @@ import ( "go.uber.org/zap/zapcore" ) -func SetupZapLogger() *zap.Logger { +func SetupZapLogger(debugMode bool) *zap.Logger { logLevel := zapcore.InfoLevel encoderConfig := zap.NewProductionEncoderConfig() @@ -24,7 +24,11 @@ func SetupZapLogger() *zap.Logger { zap.Fields(zap.String("service", "synmake")), } - logger := zap.New(core, loggerOptions...) + if debugMode { + logger := zap.New(core, loggerOptions...) + logger = logger.Named("synmake") + return logger + } - return logger + return zap.NewNop() } diff --git a/internal/logging/logger_test.go b/internal/logging/logger_test.go index 54672f4..61a20f8 100644 --- a/internal/logging/logger_test.go +++ b/internal/logging/logger_test.go @@ -7,9 +7,20 @@ import ( "go.uber.org/zap/zapcore" ) -func TestLoggerSetup(t *testing.T) { - logger := SetupZapLogger() +func TestLoggerWithDebugModeSetup(t *testing.T) { + t.Parallel() + + logger := SetupZapLogger(true) assert.Equal(t, zapcore.InfoLevel, logger.Level()) + assert.Equal(t, "synmake", logger.Name()) +} + +func TestLoggerWithoutDebugModeSetup(t *testing.T) { + t.Parallel() + + logger := SetupZapLogger(false) + + assert.Equal(t, zapcore.Level(6), logger.Level()) assert.Equal(t, "", logger.Name()) } diff --git a/internal/templates/help.go b/internal/templates/help.go index 2b51531..d10b28e 100644 --- a/internal/templates/help.go +++ b/internal/templates/help.go @@ -1,7 +1,8 @@ package templates func GetHelpTemplate() string { - content := `help: + content := `.PHONY: help +help: @echo "----------------------------------" @echo "Welcome to make! Enjoy the flight." @echo "Makefile - make [\033[38;5;154mtarget\033[0m]" diff --git a/main.go b/main.go index 04b6f05..e811806 100644 --- a/main.go +++ b/main.go @@ -2,13 +2,9 @@ package main import ( "github.com/RaphSku/synmake/cmd" - "github.com/RaphSku/synmake/internal/logging" ) func main() { - logger := logging.SetupZapLogger() - - cli := cmd.NewCLI(logger) - cli.AddSubCommands() - cli.Execute() + cli := cmd.NewCLI() + cli.Run() } From 2119e56594ae95347ae15e5f8afbd5bdb4cd4041 Mon Sep 17 00:00:00 2001 From: RaphSku Date: Sun, 20 Apr 2025 15:45:47 +0200 Subject: [PATCH 2/3] [FIX]: Behavior of delimiter, when help template is disabled, the default delimiter should be used [DOCS]: Adjusted README.md Signed-off-by: RaphSku --- README.md | 70 +++++++++++++++++------------------- internal/config/apply.go | 6 +++- internal/config/assembler.go | 7 +--- 3 files changed, 38 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index fc67b82..840869c 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,19 @@ # synmake -![Version](https://img.shields.io/badge/version-v0.1.1-orange) +![Version](https://img.shields.io/badge/version-v0.2.0-orange) ![CI](https://github.com/RaphSku/synmake/workflows/Go%20CI/badge.svg) ## What is synmake? -You will not need synmake, when you have to write a simple Makefiles but synmake should rather help you in times where you cannot remember, e.g. how to setup a preflight check for checking the minimum required version of a tool or how to print a help window that describes the available targets. +You will not need synmake, when you have to write a simple Makefile but synmake should rather help you in times where you cannot remember, e.g. how to setup a preflight check for checking the minimum required version of a tool or how to print a help window that describes the available targets. Nowadays, the majority of people are used to writing YAML. synmake allows you to write the specification in YAML and is doing the generation of the Makefile for you. ## How to install synmake -You can either install synmake via Go1.21+ with the following command: +You can install synmake with the following command: ```bash go install github.com/RaphSku/synmake@latest ``` -Alternatively, check the release page and install the binary. There are binaries provided for Windows, MacOS and Linux. - ## How to use synmake -If you want to check which version you are using, just check with +To print synmake's version, use ```bash synmake version ``` @@ -28,16 +26,15 @@ Adjust it to your needs and then you can simply generate your Makefile via synmake --config= ``` The Makefile will be created in the directory in which you ran this command. +If something goes wrong, you can enable debugging with +```bash +synmake --config= --debug +``` ## Understanding the config schema -The config file might look like this: +An example configuration file might look like this: ```yaml -phony: - - default - - preflight - - targetA - - targetB - - help +--- targets: targetA: helpDescription: targetA just prints an output @@ -53,31 +50,28 @@ targets: - echo "This is targetB!" - echo "How are you doing?" display: true -helpTemplate: - enabled: true - delimiter: '##' -versionTemplate: - enabled: true - library: example - minVersion: 0.1.0 +templates: + helpTemplate: + enabled: true + delimiter: '##' + versionTemplate: + enabled: true + library: example + minVersion: 0.1.0 ``` -1. Phony Targets: - -The phony section lists the names of phony targets (targets that are not actual files or commands) such as default, preflight, targetA, targetB, and help. - -2. Targets: - -Each target (targetA, targetB) has a helpDescription field providing a brief description of what the target does. -The commands field lists the commands to be executed when the target is invoked. -The display field specifies whether the commands should be displayed when running a target. If you specify `Display` as false, the commands will be shown, as well as the resulting output. -For targetB, there is a preTargets field that specifies dependencies on other targets (targetA in this case). -3. Help and Version Templates: +### Targets +Each key under targets specifies a new target where you can specify 3 attributes: +- `helpDescription` -> This field describes the target and will be added above the target as documentation. If you have set + `helpTemplate.enabled` to `true`, the `helpTemplate.delimiter` will override the default comment delimiter which is `#`. +- `commands` -> Here you can specify the commands that should be appear under the given target. +- `display` -> If `display` is `true`, the commands will be printed when you run the given target, otherwise they are + supressed by the command modifier `@`. -The helpTemplate section configures the help template: -enabled specifies whether the help template is enabled or not (true/false). -delimiter specifies the delimiter used in the help template. -The versionTemplate section configures the version template: -enabled specifies whether the version template is enabled or not (true/false). -library specifies the library or module used for checking the version. -minVersion specifies the minimum version required for the library/module. +### Templates +Templates are additional helper targets that can be optionally added to the Makefile. Currently, 2 templates are available: +- `helpTemplate` -> It adds a help target to the Makefile, such that when you run `make`, a help description is shown + with all the available targets and their help description. +- `versionTemplate` -> The version template can be used to check the version of a given tool, this is especially helpful for + preflight checks before a given target is being run. `versionTemplate.library` specifies the tool and `minVersion` the minimum + version that the tool has to satisfy. diff --git a/internal/config/apply.go b/internal/config/apply.go index a0f2c04..81046bd 100644 --- a/internal/config/apply.go +++ b/internal/config/apply.go @@ -61,7 +61,11 @@ func (cm *ConfigManager) applyConfig(w io.StringWriter) error { // --- TARGETS ADDED cm.logger.Info("Targets will be added", zap.String("func", "applyConfig")) - content = content.addSuggar(assembleTargets(cm.Config.Targets, cm.Config.Templates.HelpTargetTemplate.Delimiter)) + delimiter := "#" + if cm.Config.Templates.HelpTargetTemplate.Enabled { + delimiter = cm.Config.Templates.HelpTargetTemplate.Delimiter + } + content = content.addSuggar(assembleTargets(cm.Config.Targets, delimiter)) cm.logger.Info("Targets added", zap.String("func", "applyConfig")) // --- HELP TARGET ADDED diff --git a/internal/config/assembler.go b/internal/config/assembler.go index 73d2711..acd6474 100644 --- a/internal/config/assembler.go +++ b/internal/config/assembler.go @@ -45,15 +45,10 @@ func assemblePreflightTarget(commands []string) SuggarString { } func assembleTargets(targetMap map[string]Target, delimiter string) SuggarString { - helpDelimiter := "" - if delimiter != "" { - helpDelimiter = delimiter - } - var content SuggarString for targetName, targetConfig := range targetMap { content.appendString(".PHONY:").appendString(" ").appendString(targetName).lineBreak() - content.appendString(helpDelimiter).appendString(" ").appendString(targetConfig.HelpDescription).lineBreak() + content.appendString(delimiter).appendString(" ").appendString(targetConfig.HelpDescription).lineBreak() content.appendString(targetName + ":").appendString(" ") preTargets := concatStringsWithWhiteSpaces(targetConfig.PreTargets...) content.appendString(preTargets).lineBreak().tab() From 358561f96728ab948817dac7732bbd93224a369f Mon Sep 17 00:00:00 2001 From: RaphSku Date: Fri, 16 May 2025 11:18:50 +0200 Subject: [PATCH 3/3] [CLEANUP]: Cleaning up go.mod file Signed-off-by: RaphSku --- go.mod | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/go.mod b/go.mod index da68fe8..54bac07 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,7 @@ module github.com/RaphSku/synmake go 1.24.2 -retract ( - v0.1.0 -) +retract v0.1.0 require ( github.com/spf13/cobra v1.8.0