diff --git a/README.md b/README.md index a0f0793..e7a8578 100644 --- a/README.md +++ b/README.md @@ -89,9 +89,24 @@ code-path: path/to/code/root docs-path: path/to/docs/root code-includes: "**/*.java,**/*.gradle" doc-excludes: "**/*-old.*,**/deprecated/*.*" -embed-mappings: - - code-path: path/to/code/root/kotlin - docs-path: path/to/other/docs +``` + +For multiple independent documentation targets, use `embeddings` instead: + +```yaml +embeddings: + - name: java + code-path: path/to/code/root/java + docs-path: path/to/java/docs + code-includes: "**/*.java" + - name: kotlin + code-path: + - name: samples + path: path/to/code/root/kotlin-samples + - name: runtime + path: path/to/code/root/kotlin-runtime + docs-path: path/to/kotlin/docs + separator: "---" ``` The available fields for the configuration file are: @@ -131,7 +146,10 @@ The available fields for the configuration file are: It may be represented as a comma-separated string list or as a YAML sequence. * `fragments-path`: (Optional) Directory for code fragments. * `separator`: (Optional) Separator for fragments. - * `embed-mappings`: (Optional) A list of custom mappings, each containing `code-path` and `docs-path`. + * `embeddings`: (Optional) A list of complete embedding configurations for multiple + documentation targets. When `embeddings` is set, do not set root-level `code-path` + or `docs-path`. Define `code-path`, `docs-path`, and optional settings inside each entry. + Each entry must set a unique `name`. These settings have the same role as the command-line arguments. diff --git a/cli/cli.go b/cli/cli.go index da25d6a..a7dd473 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -21,8 +21,8 @@ package cli import ( _type "embed-code/embed-code-go/type" "flag" - "fmt" "os" + "path/filepath" "strings" "embed-code/embed-code-go/analyzing" @@ -61,14 +61,13 @@ import ( // Separator — a string that's inserted between multiple partitions of a single fragment. // The default value is "...". // -// EmbedMappings — an additional optional list of configs, which will be executed together with the -// main one. A config written here has higher priority and may overwrite the base one. +// Embeddings — independent configurations for embedding multiple documentation targets. // // Info - specifies whether info-level logs should be shown. // // Stacktrace - specifies whether error stack traces should be shown. // -// ConfigPath — a path to a yaml configuration file which contains the roots. +// ConfigPath — a path to a yaml configuration file which contains roots or embeddings. // // Mode — defines the mode of embed-code execution. type Config struct { @@ -79,17 +78,23 @@ type Config struct { DocExcludes _type.StringList `yaml:"doc-excludes"` FragmentsPath string `yaml:"fragments-path"` Separator string `yaml:"separator"` - EmbedMappings []EmbedMapping `yaml:"embed-mappings"` + Embeddings []EmbeddingConfig `yaml:"embeddings"` Info bool `yaml:"info"` Stacktrace bool `yaml:"stacktrace"` ConfigPath string Mode string } -// EmbedMapping is a pair of a source code path and a destination docs path to perform an embedding. -type EmbedMapping struct { - CodePath _type.NamedPathList `yaml:"code-path"` - DocsPath string `yaml:"docs-path"` +// EmbeddingConfig contains a complete configuration for one embedding target. +type EmbeddingConfig struct { + Name string `yaml:"name"` + CodePaths _type.NamedPathList `yaml:"code-path"` + DocsPath string `yaml:"docs-path"` + CodeIncludes _type.StringList `yaml:"code-includes"` + DocIncludes _type.StringList `yaml:"doc-includes"` + DocExcludes _type.StringList `yaml:"doc-excludes"` + FragmentsPath string `yaml:"fragments-path"` + Separator string `yaml:"separator"` } // EmbedCodeSamplesResult is result of the EmbedCodeSamples method. @@ -193,8 +198,8 @@ func FillArgsFromConfigFile(args Config) (Config, error) { if len(configFields.CodeIncludes) > 0 { args.CodeIncludes = configFields.CodeIncludes } - if len(configFields.EmbedMappings) > 0 { - args.EmbedMappings = configFields.EmbedMappings + if len(configFields.Embeddings) > 0 { + args.Embeddings = configFields.Embeddings } if len(configFields.DocIncludes) > 0 { args.DocIncludes = configFields.DocIncludes @@ -219,34 +224,50 @@ func FillArgsFromConfigFile(args Config) (Config, error) { // userArgs — a Config with user-provided args. func BuildEmbedCodeConfiguration(userArgs Config) []configuration.Configuration { embedCodeConfigs := make([]configuration.Configuration, 0) - excludedConfigs := make([]string, 0) - if len(userArgs.EmbedMappings) > 0 { - for _, mapping := range userArgs.EmbedMappings { - embedCodeConfig := configWithOptionalParams(userArgs) - embedCodeConfig.CodeRoots = mapping.CodePath - embedCodeConfig.DocumentationRoot = mapping.DocsPath - - // As the top config may overwrite those files, we need to exclude it from the embedding - excludedConfigs = append(excludedConfigs, fmt.Sprintf("%s**/*.*", mapping.DocsPath)) - embedCodeConfigs = append(embedCodeConfigs, embedCodeConfig) + if len(userArgs.Embeddings) > 0 { + for _, embedding := range userArgs.Embeddings { + embedCodeConfigs = append(embedCodeConfigs, configFromEmbedding(embedding)) } + return embedCodeConfigs } embedCodeConfig := configWithOptionalParams(userArgs) embedCodeConfig.CodeRoots = userArgs.BaseCodePaths embedCodeConfig.DocumentationRoot = userArgs.BaseDocsPath - if len(userArgs.DocExcludes) > 0 { - embedCodeConfig.DocExcludes = append(embedCodeConfig.DocExcludes, excludedConfigs...) - } else { - embedCodeConfig.DocExcludes = excludedConfigs - } embedCodeConfigs = append(embedCodeConfigs, embedCodeConfig) return embedCodeConfigs } +// Creates a new Configuration from one complete embedding config. +func configFromEmbedding(embedding EmbeddingConfig) configuration.Configuration { + embedCodeConfig := configuration.NewConfiguration() + embedCodeConfig.Name = embedding.Name + embedCodeConfig.CodeRoots = embedding.CodePaths + embedCodeConfig.DocumentationRoot = embedding.DocsPath + + if len(embedding.CodeIncludes) > 0 { + embedCodeConfig.CodeIncludes = embedding.CodeIncludes + } + if len(embedding.DocIncludes) > 0 { + embedCodeConfig.DocIncludes = embedding.DocIncludes + } + if len(embedding.DocExcludes) > 0 { + embedCodeConfig.DocExcludes = embedding.DocExcludes + } + if isNotEmpty(embedding.FragmentsPath) { + embedCodeConfig.FragmentsDir = embedding.FragmentsPath + } + embedCodeConfig.FragmentsDir = filepath.Join(embedCodeConfig.FragmentsDir, embedding.Name) + if isNotEmpty(embedding.Separator) { + embedCodeConfig.Separator = embedding.Separator + } + + return embedCodeConfig +} + // Creates a new Configuration with the filled optional properties from the user args. func configWithOptionalParams(userArgs Config) configuration.Configuration { embedCodeConfig := configuration.NewConfiguration() diff --git a/cli/cli_test.go b/cli/cli_test.go index 79033a1..726acc6 100644 --- a/cli/cli_test.go +++ b/cli/cli_test.go @@ -22,6 +22,7 @@ package cli_test import ( "embed-code/embed-code-go/cli" + "embed-code/embed-code-go/configuration" _type "embed-code/embed-code-go/type" "os" "path/filepath" @@ -65,6 +66,30 @@ var _ = Describe("CLI validation", func() { Expect(cli.ValidateConfig(config)).Error().ShouldNot(HaveOccurred()) Expect(cli.ValidateConfigFile(config)).Error().ShouldNot(HaveOccurred()) }) + + It("should pass validation when embeddings are set", func() { + config := cli.Config{ + Mode: cli.ModeCheck, + Embeddings: []cli.EmbeddingConfig{baseEmbeddingConfig()}, + } + + Expect(cli.ValidateConfig(config)).Error().ShouldNot(HaveOccurred()) + }) + + It("should store embedding fragments under a named subfolder", func() { + embedding := baseEmbeddingConfig() + embedding.FragmentsPath = "/tmp/fragments" + config := cli.Config{ + Mode: cli.ModeCheck, + Embeddings: []cli.EmbeddingConfig{embedding}, + } + + embedConfigs := cli.BuildEmbedCodeConfiguration(config) + + Expect(embedConfigs).To(HaveLen(1)) + Expect(embedConfigs[0].Name).To(Equal("docs")) + Expect(embedConfigs[0].FragmentsDir).To(Equal(filepath.Join("/tmp/fragments", "docs"))) + }) }) Context("with invalid config", func() { @@ -107,7 +132,7 @@ var _ = Describe("CLI validation", func() { Expect(cli.ValidateConfig(invalidConfig)).Error().Should(HaveOccurred()) Expect(cli.ValidateConfig(invalidConfig).Error()).Should(Equal( - "code-path and docs-path must both be set")) + "`code-path` and `docs-path` must both be set")) }) It("should fail validation when config, code and docs paths are set at the same time", func() { @@ -119,10 +144,56 @@ var _ = Describe("CLI validation", func() { "config path cannot be set when code-path, docs-path or optional params are set")) }) - It("should correctly convert embed mappings to a few configs", func() { + It("should fail validation when embeddings and root paths are set at the same time", func() { + invalidConfig := baseCliConfig() + invalidConfig.Embeddings = []cli.EmbeddingConfig{baseEmbeddingConfig()} + + Expect(cli.ValidateConfig(invalidConfig)).Error().Should(HaveOccurred()) + Expect(cli.ValidateConfig(invalidConfig).Error()).Should(Equal( + "`code-path` and `docs-path` cannot be set when `embeddings` are set")) + }) + + It("should fail validation when embeddings and root optional params are set at the same time", func() { + invalidConfig := cli.Config{ + Mode: cli.ModeCheck, + CodeIncludes: []string{"**/*.java"}, + Embeddings: []cli.EmbeddingConfig{baseEmbeddingConfig()}, + } + + Expect(cli.ValidateConfig(invalidConfig)).Error().Should(HaveOccurred()) + Expect(cli.ValidateConfig(invalidConfig).Error()).Should(Equal( + "root optional embedding options cannot be set when `embeddings` are set")) + }) + + It("should fail validation when embedding name is missed", func() { + invalidConfig := cli.Config{ + Mode: cli.ModeCheck, + Embeddings: []cli.EmbeddingConfig{baseEmbeddingConfig()}, + } + invalidConfig.Embeddings[0].Name = "" + + Expect(cli.ValidateConfig(invalidConfig)).Error().Should(HaveOccurred()) + Expect(cli.ValidateConfig(invalidConfig).Error()).Should(Equal( + "embedding #1: `name` must be set")) + }) + + It("should fail validation when embedding names are duplicated", func() { + embedding := baseEmbeddingConfig() + duplicateEmbedding := baseEmbeddingConfig() + invalidConfig := cli.Config{ + Mode: cli.ModeCheck, + Embeddings: []cli.EmbeddingConfig{embedding, duplicateEmbedding}, + } + + Expect(cli.ValidateConfig(invalidConfig)).Error().Should(HaveOccurred()) + Expect(cli.ValidateConfig(invalidConfig).Error()).Should(Equal( + "duplicate embedding names detected:\n- docs")) + }) + + It("should correctly convert embeddings to a few configs", func() { config := cli.Config{ Mode: cli.ModeCheck, - ConfigPath: "../test/resources/config_files/embedded_mappings_config.yml", + ConfigPath: "../test/resources/config_files/embeddings_config.yml", } fileConfig, err := cli.FillArgsFromConfigFile(config) @@ -130,6 +201,22 @@ var _ = Describe("CLI validation", func() { Expect(err).ToNot(HaveOccurred()) Expect(embedConfigs).To(HaveLen(3)) + Expect(embedConfigs[0].Name).To(Equal("java")) + Expect(embedConfigs[0].CodeRoots[0].Path).To(Equal("test/resources/code/java")) + Expect(embedConfigs[0].DocumentationRoot).To(Equal("test/resources/docs")) + Expect(embedConfigs[0].FragmentsDir).To(Equal( + filepath.Join(configuration.DefaultFragmentsDir, "java"))) + Expect(embedConfigs[1].Name).To(Equal("kotlin")) + Expect(embedConfigs[1].CodeRoots[0].Path).To(Equal("test/resources/code/kotlin")) + Expect(embedConfigs[1].DocumentationRoot).To(Equal("test/resources/docs/nested-dir-1")) + Expect(embedConfigs[1].FragmentsDir).To(Equal( + filepath.Join(configuration.DefaultFragmentsDir, "kotlin"))) + Expect(embedConfigs[2].Name).To(Equal("nested-java")) + Expect(embedConfigs[2].DocumentationRoot).To( + Equal("test/resources/docs/nested-dir-1/nested-dir-3")) + Expect(embedConfigs[2].FragmentsDir).To(Equal( + filepath.Join(configuration.DefaultFragmentsDir, "nested-java"))) + Expect(embedConfigs[2].Separator).To(Equal("---")) }) }) @@ -150,6 +237,15 @@ func baseCliConfig() cli.Config { } } +func baseEmbeddingConfig() cli.EmbeddingConfig { + baseConfig := baseCliConfig() + return cli.EmbeddingConfig{ + Name: "docs", + CodePaths: baseConfig.BaseCodePaths, + DocsPath: baseConfig.BaseDocsPath, + } +} + func configFilePath() string { currentDir, err := os.Getwd() if err != nil { diff --git a/cli/cli_validation.go b/cli/cli_validation.go index b2f3415..3880e0b 100644 --- a/cli/cli_validation.go +++ b/cli/cli_validation.go @@ -26,12 +26,13 @@ import ( "errors" "fmt" "log/slog" + "path/filepath" "slices" "strings" ) -// IllegalFolderNameChars the string with chars that are not allowed for the folder name. -const IllegalFolderNameChars = ` *?:"<>|` +// IllegalFolderNameChars contains characters that are not allowed in folder names. +const IllegalFolderNameChars = `/\ *?:"<>|` // IsUsingConfigFile reports whether user configs are set with file. func IsUsingConfigFile(config Config) bool { @@ -81,7 +82,7 @@ func ValidateConfigFile(userConfig Config) error { return errors.New("expected to use config file, but it does not exist") } -// Validates if mode is set to check, embed, or analyze. +// validateMode checks if mode is set to check, embed, or analyze. func validateMode(mode string) error { isModeSet := isNotEmpty(mode) if !isModeSet { @@ -92,15 +93,19 @@ func validateMode(mode string) error { isValidMode := slices.Contains(validModes, mode) if !isValidMode { - return fmt.Errorf("invalid value for mode. it must be one of — %s, %s or %s", + return fmt.Errorf("invalid value for mode. it must be one of — `%s`, `%s` or `%s`", ModeEmbed, ModeCheck, ModeAnalyze) } return nil } -// Validates if config is set correctly and does not have mutually exclusive params set. +// validateConfig checks if config is set correctly and has no mutually exclusive params. func validateConfig(config Config) error { + if len(config.Embeddings) > 0 { + return validateEmbeddingConfigs(config) + } + isCodePathsSet, err := validatePaths(config.BaseCodePaths) if err != nil { return err @@ -122,14 +127,134 @@ func validateConfig(config Config) error { isOneOfRootsSet := isCodePathsSet || isDocsPathSet if isOneOfRootsSet && !isRootsSet { - return errors.New("code-path and docs-path must both be set") + return errors.New("`code-path` and `docs-path` must both be set") } return nil } -// Reports whether at least one of optional configs is set — code-includes, doc-includes, separator -// or fragments-path. +// validateEmbeddingConfigs checks the multi-target embedding configuration. +func validateEmbeddingConfigs(config Config) error { + isCodePathsSet, err := validatePaths(config.BaseCodePaths) + if err != nil { + return err + } + isDocsPathSet, err := validatePathSet(config.BaseDocsPath) + if err != nil { + return err + } + if isCodePathsSet || isDocsPathSet { + return errors.New("`code-path` and `docs-path` cannot be set when `embeddings` are set") + } + if validateOptionalParamsSet(config) { + return errors.New("root optional embedding options cannot be set when `embeddings` are set") + } + + for i, embedding := range config.Embeddings { + if err = validateEmbeddingConfig(embedding, i); err != nil { + return err + } + } + + if err = findEmbeddingNameDuplications(config.Embeddings); err != nil { + return err + } + verifyDuplicateEmbeddingDocsPaths(config.Embeddings) + + return nil +} + +// validateEmbeddingConfig checks one embedding entry. +func validateEmbeddingConfig(embedding EmbeddingConfig, index int) error { + if isEmpty(embedding.Name) { + return fmt.Errorf("embedding #%d: `name` must be set", index+1) + } + if strings.ContainsAny(embedding.Name, IllegalFolderNameChars) { + return fmt.Errorf("embedding `%s`: `name` `%s` is not valid, "+ + "those characters are not allowed `%s`", + embedding.Name, embedding.Name, IllegalFolderNameChars) + } + + isCodePathsSet, err := validatePaths(embedding.CodePaths) + if err != nil { + return fmt.Errorf("embedding `%s`: %w", embedding.Name, err) + } + if err = findCodeSourceDuplications(embedding.CodePaths); err != nil { + return fmt.Errorf("embedding `%s`: %w", embedding.Name, err) + } + + isDocsPathSet, err := validatePathSet(embedding.DocsPath) + if err != nil { + return fmt.Errorf("embedding `%s`: %w", embedding.Name, err) + } + _, err = validatePathSet(embedding.FragmentsPath) + if err != nil { + return fmt.Errorf("embedding `%s`: %w", embedding.Name, err) + } + + isRootsSet := isCodePathsSet && isDocsPathSet + if !isRootsSet { + return fmt.Errorf("embedding `%s`: `code-path` and `docs-path` must both be set", + embedding.Name) + } + + return nil +} + +// findEmbeddingNameDuplications returns an error if multiple embeddings use the same name. +func findEmbeddingNameDuplications(embeddings []EmbeddingConfig) error { + nameCount := make(map[string]int) + for _, embedding := range embeddings { + nameCount[embedding.Name]++ + } + + var errLines []string + for name, count := range nameCount { + if count > 1 { + errLines = append(errLines, "- "+name) + } + } + + if len(errLines) > 0 { + slices.Sort(errLines) + return fmt.Errorf( + "duplicate embedding names detected:\n%s", + strings.Join(errLines, "\n"), + ) + } + return nil +} + +// verifyDuplicateEmbeddingDocsPaths logs a warning if multiple embeddings use the same docs path. +func verifyDuplicateEmbeddingDocsPaths(embeddings []EmbeddingConfig) { + docsPathEmbeddings := make(map[string][]string) + for _, embedding := range embeddings { + docsPath := filepath.Clean(embedding.DocsPath) + docsPathEmbeddings[docsPath] = append( + docsPathEmbeddings[docsPath], + embedding.Name, + ) + } + + var warnLines []string + for docsPath, names := range docsPathEmbeddings { + if len(names) > 1 { + slices.Sort(names) + warnLines = append(warnLines, fmt.Sprintf("- `%s`: %s", docsPath, strings.Join(names, ", "))) + } + } + + if len(warnLines) > 0 { + slices.Sort(warnLines) + slog.Warn( + "Multiple `embeddings` use the same `docs-path`. " + + "Make sure they are intended to process the same documentation root:\n" + + strings.Join(warnLines, "\n"), + ) + } +} + +// validateOptionalParamsSet reports whether at least one optional config is set. func validateOptionalParamsSet(config Config) bool { isCodeIncludesSet := len(config.CodeIncludes) > 0 isDocIncludesSet := len(config.DocIncludes) > 0 @@ -141,7 +266,7 @@ func validateOptionalParamsSet(config Config) bool { isSeparatorSet || isDocExcludesSet } -// Reports whether path is set or not. If it is set, checks if such path exists in a file system. +// validatePathSet reports whether path is set and checks if it exists. func validatePathSet(path string) (bool, error) { isPathSet := isNotEmpty(path) if isPathSet { @@ -160,7 +285,7 @@ func validatePathSet(path string) (bool, error) { return false, nil } -// Reports whether all paths are valid. +// validatePaths reports whether all paths are valid. // // If paths are provided, checks whether each path exists in the file system. // @@ -246,12 +371,12 @@ func verifyDuplicatePaths(pathCount map[string]int) error { return nil } -// Reports whether the given string is not empty. +// isNotEmpty reports whether the given string is not empty. func isNotEmpty(s string) bool { return !isEmpty(s) } -// Reports whether the given string is empty. +// isEmpty reports whether the given string is empty. func isEmpty(s string) bool { return strings.TrimSpace(s) == "" } diff --git a/configuration/configuration.go b/configuration/configuration.go index 3f40a9b..133a533 100644 --- a/configuration/configuration.go +++ b/configuration/configuration.go @@ -44,6 +44,9 @@ var DefaultDocIncludes = []string{"**/*.md", "**/*.html"} // // config.FragmentsDir = "foo/bar" type Configuration struct { + // Name identifies this configuration when it is built from an embeddings entry. + Name string + // CodeRoots is a list of directories with the source code to be embedded. CodeRoots _type.NamedPathList diff --git a/embedding/processor.go b/embedding/processor.go index b1e29a3..839fda0 100644 --- a/embedding/processor.go +++ b/embedding/processor.go @@ -164,13 +164,15 @@ func EmbedAll(config configuration.Configuration) EmbedAllResult { if totalEmbeddings > 0 { slog.Info( fmt.Sprintf( - "Found `%d` target documentation files with `%d` embeddings under `%s`.", + "Found `%d` target documentation files with `%d` embeddings under `%s`%s.", len(requiredDocPaths), totalEmbeddings, config.DocumentationRoot, + configNameLabel(config), ), ) } else { slog.Warn( - fmt.Sprintf("No embedding instructions were found under `%s`.", config.DocumentationRoot), + fmt.Sprintf("No embedding instructions were found under `%s`%s.", + config.DocumentationRoot, configNameLabel(config)), ) } return EmbedAllResult{ @@ -180,6 +182,13 @@ func EmbedAll(config configuration.Configuration) EmbedAllResult { } } +func configNameLabel(config configuration.Configuration) string { + if config.Name == "" { + return "" + } + return fmt.Sprintf(" for embedding `%s`", config.Name) +} + // CheckUpToDate raises an error if the documentation files are not up-to-date with code files. // // config — a configuration for embedding. diff --git a/fragmentation/fragmentation.go b/fragmentation/fragmentation.go index d5a5827..b08c666 100644 --- a/fragmentation/fragmentation.go +++ b/fragmentation/fragmentation.go @@ -218,12 +218,13 @@ func WriteFragmentFiles(config config.Configuration) WriteFragmentFilesResult { totalFragments += codeRootFragments if codeRootFiles > 0 { slog.Info( - fmt.Sprintf("Found `%d` source code files with `%d` fragments under `%s`.", - codeRootFiles, codeRootFragments, codeRoot.Path), + fmt.Sprintf("Found `%d` source code files with `%d` fragments under `%s`%s.", + codeRootFiles, codeRootFragments, codeRoot.Path, configNameLabel(config)), ) } else { slog.Warn( - fmt.Sprintf("No code fragments were found under `%s`.", codeRoot.Path), + fmt.Sprintf("No code fragments were found under `%s`%s.", + codeRoot.Path, configNameLabel(config)), ) } } @@ -234,6 +235,13 @@ func WriteFragmentFiles(config config.Configuration) WriteFragmentFilesResult { } } +func configNameLabel(config config.Configuration) string { + if config.Name == "" { + return "" + } + return fmt.Sprintf(" for embedding `%s`", config.Name) +} + // CleanFragmentFiles deletes Configuration.FragmentsDir if it exists. func CleanFragmentFiles(config config.Configuration) { exists, err := files.IsDirExist(config.FragmentsDir) diff --git a/main.go b/main.go index 11950ee..d78aabf 100644 --- a/main.go +++ b/main.go @@ -58,8 +58,8 @@ const Version = "1.1.0" // // If both options are missed, the embedding fails. // If both options are set, the embedding fails as well. -// If config file is not exists or does not contain 'code-path' and 'docs-path' fields, the -// embedding fails. +// If config file does not exist, or contains neither root 'code-path' and 'docs-path' fields nor +// 'embeddings' entries, the embedding fails. // // All possible args: // - code-path — a path to a root directory with code files; @@ -92,20 +92,20 @@ func main() { if cli.IsUsingConfigFile(userArgs) { err := cli.ValidateConfigFile(userArgs) if err != nil { - slog.Error("The provided config file is not valid.", "error", err) + logError("The provided config file is not valid", err) return } userArgs, err = cli.FillArgsFromConfigFile(userArgs) if err != nil { - slog.Error("Received an issue while reading config file: ", "error", err) + logError("Received an issue while reading config file", err) return } } err := cli.ValidateConfig(userArgs) if err != nil { - slog.Error("User arguments are not valid.", "error", err) + logError("User arguments are not valid", err) return } @@ -138,6 +138,10 @@ func configureLogging(config cli.Config) { slog.SetDefault(logger) } +func logError(message string, err error) { + slog.Error(fmt.Sprintf("%s: %v", message, err)) +} + // embedByConfig runs the embedByConfig for all configs and logs the results. func embedByConfigs(configs []configuration.Configuration) { var totalEmbeddedFiles []string diff --git a/test/resources/config_files/embedded_mappings_config.yml b/test/resources/config_files/embedded_mappings_config.yml deleted file mode 100644 index 6360c4b..0000000 --- a/test/resources/config_files/embedded_mappings_config.yml +++ /dev/null @@ -1,7 +0,0 @@ -code-path: "test/resources/code/java" -docs-path: "test/resources/docs" -embed-mappings: - - code-path: "test/resources/code/kotlin" - docs-path: "test/resources/docs/nested-dir-1" - - code-path: "test/resources/code/java" - docs-path: "test/resources/docs/nested-dir-1/nested-dir-3" diff --git a/test/resources/config_files/embeddings_config.yml b/test/resources/config_files/embeddings_config.yml new file mode 100644 index 0000000..bee4b8b --- /dev/null +++ b/test/resources/config_files/embeddings_config.yml @@ -0,0 +1,11 @@ +embeddings: + - name: "java" + code-path: "test/resources/code/java" + docs-path: "test/resources/docs" + - name: "kotlin" + code-path: "test/resources/code/kotlin" + docs-path: "test/resources/docs/nested-dir-1" + - name: "nested-java" + code-path: "test/resources/code/java" + docs-path: "test/resources/docs/nested-dir-1/nested-dir-3" + separator: "---"