-
-
Notifications
You must be signed in to change notification settings - Fork 108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refine Atmos Configuration Handling to Support Imports, Remote Imports, and Configuration Directories #808
base: main
Are you sure you want to change the base?
Conversation
📝 WalkthroughWalkthroughThe pull request introduces comprehensive enhancements to the Atmos CLI's configuration management system, focusing on flexible configuration loading, import handling, and environment variable management. The changes enable more robust configuration discovery, support for importing configurations from multiple sources (local and remote), and improved path resolution mechanisms. Key improvements include dynamic base path computation, recursive configuration imports, and better error handling during configuration loading. Changes
Assessment against linked issues
Possibly related PRs
Suggested reviewers✨ Finishing Touches
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🧹 Outside diff range and nitpick comments (7)
examples/demo-atmos.d/atmos.yaml (3)
4-11
: Document security-sensitive settingsCritical settings like
apply_auto_approve
andauto_generate_backend_file
would benefit from inline documentation explaining their security implications.Consider adding comments:
components: terraform: base_path: "components/terraform" + # Disable auto-approve for safety in production environments apply_auto_approve: false deploy_run_init: true init_run_reconfigure: true + # Disable auto-generation of backend files to prevent unauthorized state access auto_generate_backend_file: false
12-19
: Consider expanding name pattern flexibilityThe current name pattern only supports {stage}. Consider supporting additional variables for better organization.
Consider expanding:
- name_pattern: "{stage}" + name_pattern: "{org}-{stage}-{component}"
20-29
: Clean up formatting and enhance documentationThe vendor configuration contains helpful examples but needs formatting cleanup.
Apply these changes:
-vendor: +vendor: # Single file - base_path: "./vendor.yaml" + base_path: "./vendor.yaml" # Default configuration # Directory with multiple files #base_path: "./vendor" # Absolute path #base_path: "vendor.d/vendor1.yaml"🧰 Tools
🪛 yamllint (1.29.0-1)
[error] 20-20: trailing spaces
(trailing-spaces)
[error] 23-23: trailing spaces
(trailing-spaces)
[error] 26-26: trailing spaces
(trailing-spaces)
examples/demo-atmos.d/custom-import/atmos.yaml (2)
26-35
: Consider moving configuration examples to documentationWhile the commented examples are helpful, they might be better suited in the documentation, keeping the configuration file cleaner.
- # Single file base_path: "./vendor.yaml" - - # Directory with multiple files - #base_path: "./vendor" - - # Absolute path - #base_path: "vendor.d/vendor1.yaml"🧰 Tools
🪛 yamllint (1.29.0-1)
[error] 26-26: trailing spaces
(trailing-spaces)
[error] 29-29: trailing spaces
(trailing-spaces)
[error] 32-32: trailing spaces
(trailing-spaces)
36-38
: Consider environment-specific log configurationsThe current logging setup is good for development, but you might want to add environment-specific configurations for production use.
Example addition:
logs: file: "${ATMOS_LOG_FILE:-/dev/stderr}" level: "${ATMOS_LOG_LEVEL:-Info}"pkg/schema/schema.go (1)
29-29
: Add field documentation.Consider adding a documentation comment to describe the purpose and usage of the
Import
field, following Go's documentation conventions.Add this documentation above the field:
+ // Import specifies a list of paths from which to import additional configurations. + // Supports local files, directories (using glob patterns), and remote URLs. Import []string `yaml:"import" json:"import" mapstructure:"import"`pkg/config/config.go (1)
231-232
: Combine the return statement for clarityThe return statement is unnecessarily split across two lines.
Consider writing it on a single line:
-return cliConfig, - err +return cliConfig, err
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (10)
examples/demo-atmos.d/atmos.d/configs.d/config1.yaml
(1 hunks)examples/demo-atmos.d/atmos.d/configs.d/sub/config2.yaml
(1 hunks)examples/demo-atmos.d/atmos.yaml
(1 hunks)examples/demo-atmos.d/custom-import/atmos.yaml
(1 hunks)examples/demo-atmos.d/custom-import/configs.d/config1.yaml
(1 hunks)examples/demo-atmos.d/custom-import/configs.d/sub/config2.yaml
(1 hunks)examples/demo-atmos.d/custom-import/extra-config.yaml
(1 hunks)pkg/config/config.go
(3 hunks)pkg/schema/schema.go
(1 hunks)pkg/utils/glob_utils.go
(2 hunks)
✅ Files skipped from review due to trivial changes (5)
- examples/demo-atmos.d/atmos.d/configs.d/config1.yaml
- examples/demo-atmos.d/atmos.d/configs.d/sub/config2.yaml
- examples/demo-atmos.d/custom-import/configs.d/config1.yaml
- examples/demo-atmos.d/custom-import/configs.d/sub/config2.yaml
- examples/demo-atmos.d/custom-import/extra-config.yaml
🧰 Additional context used
🪛 yamllint (1.29.0-1)
examples/demo-atmos.d/atmos.yaml
[error] 20-20: trailing spaces
(trailing-spaces)
[error] 23-23: trailing spaces
(trailing-spaces)
[error] 26-26: trailing spaces
(trailing-spaces)
[warning] 38-38: wrong indentation: expected 2 but found 0
(indentation)
[warning] 41-41: wrong indentation: expected 4 but found 2
(indentation)
examples/demo-atmos.d/custom-import/atmos.yaml
[error] 26-26: trailing spaces
(trailing-spaces)
[error] 29-29: trailing spaces
(trailing-spaces)
[error] 32-32: trailing spaces
(trailing-spaces)
[warning] 44-44: wrong indentation: expected 2 but found 0
(indentation)
[warning] 47-47: wrong indentation: expected 4 but found 2
(indentation)
🔇 Additional comments (6)
examples/demo-atmos.d/atmos.yaml (1)
30-33
: Add validation for log levels
Consider adding validation to ensure only valid log levels (Debug, Info, Warning, Error) are accepted.
examples/demo-atmos.d/custom-import/atmos.yaml (3)
7-9
: Consider adding URL validation for remote configurations
While loading from remote URLs provides flexibility, it could pose security risks. Consider implementing URL validation and HTTPS enforcement.
Would you like me to propose a validation pattern for secure URL handling?
18-24
: Strong stack configuration, warrior! 💪
The stack configuration is well-structured with clear inclusion/exclusion patterns and a simple naming convention.
11-16
: Verify backend file management strategy
Setting auto_generate_backend_file: false
means you'll need to manage backend configurations manually. This is a valid choice but requires careful consideration.
Run this check to ensure consistent backend configuration across components:
✅ Verification successful
Setting auto_generate_backend_file: false
is appropriate for this setup
The configuration choice is valid as there's no existing Terraform component directory at the specified path, indicating this is likely a new project setup. Manual backend management is a reasonable approach when starting fresh, allowing for more controlled and explicit backend configuration as the project evolves.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check for existing backend configurations
fd -e tf -e hcl . components/terraform -x grep -l 'backend'
Length of output: 167
Script:
#!/bin/bash
# First, let's verify if the components/terraform directory exists and check the directory structure
fd --type d terraform
# Then, let's search for backend configurations across all Terraform files in the repository
fd -e tf -e hcl . -x grep -l 'backend'
# Also check for any Terraform component references in the atmos configuration
fd -g "*.yaml" -x grep -A 5 -B 5 "terraform:"
Length of output: 33961
Script:
#!/bin/bash
# Let's check for backend configurations in the actual Terraform components
fd -t f -e tf . examples/demo-atmos.d/custom-import/components/terraform -x grep -l 'backend'
# Also check for any backend configuration files
fd -t f -g "*.backend.tf" -g "backend.tf" examples/demo-atmos.d/custom-import/components/terraform
# Check if there are any existing backend configurations in the component directory
ls -la examples/demo-atmos.d/custom-import/components/terraform/
Length of output: 709
pkg/utils/glob_utils.go (2)
7-7
: LGTM! Clean import addition, warrior!
The sort package import is well-placed and necessary for the new functionality.
Line range hint 19-48
: Verify caching behavior for dynamic configurations, brave one!
The caching mechanism using sync.Map could prevent picking up new configuration files added to atmos.d during runtime. Additionally, we should verify that the error handling aligns with the requirement to log non-existent paths as warnings.
Let's verify the implementation:
✅ Verification successful
Cache invalidation is not a concern, brave warrior!
The caching mechanism in GetGlobMatches
is pattern-based, which means:
- Each unique glob pattern gets its own cache entry
- When a new file is added that matches an existing pattern, it will be discovered on the next process restart
- The cache is process-scoped (using
sync.Map
), so it's automatically cleared between runs - Error handling correctly returns both the error and logs the non-existent paths
The implementation aligns perfectly with the requirements:
- Cache is scoped to the current process, preventing stale state between runs
- Error handling returns descriptive errors for non-existent paths:
failed to find a match for the import '%s' ('%s' + '%s')
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for warning logs related to non-existent paths and cache invalidation
# Search for warning log implementations
rg -A 2 "failed to find a match for the import" .
# Check if there's any cache invalidation mechanism
rg -A 5 "getGlobMatchesSyncMap" .
# Look for any warning level log statements
rg -A 2 "Warning|WARN|warn" .
Length of output: 47400
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (2)
pkg/config/config.go
(3 hunks)pkg/schema/schema.go
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- pkg/schema/schema.go
🔇 Additional comments (1)
pkg/config/config.go (1)
231-232
: LGTM! Clean error handling.
The multi-line error return improves readability.
…correct command structure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (3)
examples/demo-atmos.d/custom-import/atmos.yaml (2)
26-34
: Clean up trailing spacesRemove trailing spaces from lines 26, 29, and 32 for better maintainability.
-vendor: +vendor: # Single file -base_path: "./vendor.yaml" +base_path: "./vendor.yaml" # Directory with multiple files -#base_path: "./vendor" +#base_path: "./vendor"🧰 Tools
🪛 yamllint (1.29.0-1)
[error] 26-26: trailing spaces
(trailing-spaces)
[error] 29-29: trailing spaces
(trailing-spaces)
[error] 32-32: trailing spaces
(trailing-spaces)
36-38
: Logging configuration is good but could be enhancedCurrent configuration is solid. Consider adding:
- Log rotation settings
- Format specification
- Additional log destinations for production environments
pkg/config/config.go (1)
401-444
: Consider adding rate limiting and path validationThe import processing is robust, but consider these enhancements:
- Add rate limiting for remote downloads to prevent abuse
- Validate import paths before processing to ensure they're safe
func processImports(cliConfig schema.CliConfiguration, v *viper.Viper) error { + // Add rate limiting for remote downloads + rateLimiter := time.NewTicker(time.Second) + defer rateLimiter.Stop() + for _, importPath := range cliConfig.Import { if importPath == "" { continue } + // Basic path validation + if strings.Contains(importPath, "..") { + u.LogWarning(cliConfig, fmt.Sprintf("Warning: skipping potentially unsafe import path '%s'", importPath)) + continue + }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (4)
examples/demo-atmos.d/atmos.d/config1.yaml
(1 hunks)examples/demo-atmos.d/atmos.d/sub/config2.yaml
(1 hunks)examples/demo-atmos.d/custom-import/atmos.yaml
(1 hunks)pkg/config/config.go
(3 hunks)
✅ Files skipped from review due to trivial changes (2)
- examples/demo-atmos.d/atmos.d/config1.yaml
- examples/demo-atmos.d/atmos.d/sub/config2.yaml
🧰 Additional context used
🪛 yamllint (1.29.0-1)
examples/demo-atmos.d/custom-import/atmos.yaml
[error] 26-26: trailing spaces
(trailing-spaces)
[error] 29-29: trailing spaces
(trailing-spaces)
[error] 32-32: trailing spaces
(trailing-spaces)
🔇 Additional comments (7)
examples/demo-atmos.d/custom-import/atmos.yaml (4)
11-16
: Terraform security settings look good!
The Terraform component configuration follows security best practices:
apply_auto_approve: false
prevents unintended infrastructure changesauto_generate_backend_file: false
ensures explicit backend configuration
18-24
: Stack configuration structure is well-organized!
Good use of:
- Explicit path inclusions/exclusions
- Clear naming pattern
- Logical directory structure
43-47
: Command configuration looks good!
The test command is well-defined with clear description and steps.
7-9
: Verify security measures for remote configuration imports
The remote URL import capability could pose security risks. Ensure that:
- HTTPS is enforced for remote URLs
- URL validation is implemented
- Content verification is performed before applying configurations
Consider implementing:
- URL allowlist/blocklist
- SSL certificate validation
- Content integrity checks (e.g., checksums)
pkg/config/config.go (3)
231-232
: Clean error handling format!
The multi-line error return improves readability while maintaining functionality.
239-250
: Validate path to prevent directory traversal
While the implementation correctly handles the atmos.d directory existence, consider adding path validation as suggested in the past review to prevent potential path traversal attacks.
446-464
: Add safeguards to remote downloads
The download function needs the safeguards mentioned in the past review:
- Context timeout
- File size limits
- Temporary directory cleanup
…onfig and processImports
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (4)
pkg/config/config.go (4)
231-232
: Consider using idiomatic Go error handling.While splitting the return statement improves readability, consider using the more idiomatic Go style:
- return cliConfig, - err + return cliConfig, fmt.Errorf("failed to unmarshal config: %w", err)
239-256
: Strong implementation with robust security measures!The atmos.d directory support is well-implemented with proper path validation and error handling. The path traversal prevention is particularly noteworthy.
Consider adding more context to the error message:
- return cliConfig, fmt.Errorf("invalid atmos.d path: attempted directory traversal") + return cliConfig, fmt.Errorf("invalid atmos.d path '%s': attempted directory traversal outside base path '%s'", atmosDPath, basePath)
257-269
: Consider adding debug logging for configuration merging.The import processing logic is sound, but adding debug logs would help troubleshoot configuration issues.
err = v.Unmarshal(&cliConfig) if err != nil { + u.LogTrace(cliConfig, fmt.Sprintf("Failed to unmarshal merged config: %v", err)) return cliConfig, err } + u.LogTrace(cliConfig, "Successfully merged and unmarshaled imported configurations")
407-459
: Consider parallel processing for multiple imports.The implementation is robust with proper error handling and path validation. However, processing imports sequentially might be slow for many imports.
Consider using a worker pool for parallel processing:
func processImports(cliConfig schema.CliConfiguration, v *viper.Viper) error { + type importResult struct { + path string + err error + } + workers := make(chan struct{}, 4) // Limit concurrent downloads + results := make(chan importResult) + for _, importPath := range cliConfig.Import { - if importPath == "" { - continue - } + go func(imp string) { + workers <- struct{}{} // Acquire worker + defer func() { <-workers }() // Release worker + + if imp == "" { + results <- importResult{"", nil} + return + } + // ... rest of the import processing logic ... + }(importPath) }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (1)
pkg/config/config.go
(3 hunks)
🔇 Additional comments (1)
pkg/config/config.go (1)
461-479
: Past review comment about remote download safeguards is still applicable.
The previous review comment suggesting context timeout, file size limits, and temporary directory cleanup remains valid.
…andle cleanup on error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (1)
pkg/config/config.go (1)
232-233
: Combine the return statement into a single lineThe return statement is split across two lines. Merging it into one line enhances readability.
Apply this diff:
- return cliConfig, - err + return cliConfig, err
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
📒 Files selected for processing (1)
pkg/config/config.go
(3 hunks)
🔇 Additional comments (4)
pkg/config/config.go (4)
240-257
: Good handling of the 'import' key and path security
The logic for setting the default Import
path when it's empty is well-implemented. Ensuring the path doesn't escape the intended directory adds a valuable security check.
259-270
: Import processing added effectively
The addition of import processing and re-unmarshalling is correctly handled. Error checks are appropriately placed.
417-426
: Consider validating remote URLs for security
Currently, any URL starting with "http://" or "https://" is accepted. Validating these URLs against an allowlist can prevent unintended or malicious imports.
464-484
: Add a file size limit check in downloadRemoteConfig
While the context timeout is set, the function lacks a file size limit check. This could allow the download of excessively large files, leading to resource exhaustion.
Update documentation for Atmos CLI Configuration schema and examples |
Update documentation for Atmos CLI Configuration |
@haitham911 please resolve the conflicts |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
♻️ Duplicate comments (3)
pkg/config/con.go (3)
687-687
:⚠️ Potential issueAvoid using dynamic format strings with
fmt.Errorf
At line 687, using
fmt.Errorf(errorMessage)
with a dynamic string can cause unexpected behavior. It's safer to useerrors.New(errorMessage)
instead.Suggested fix:
-return fmt.Errorf(errorMessage) +return errors.New(errorMessage)🧰 Tools
🪛 golangci-lint (1.62.2)
687-687: printf: non-constant format string in call to fmt.Errorf
(govet)
800-800
: 🛠️ Refactor suggestionEnsure the result of
strings.HasSuffix
is usedAt line 800, the result of
strings.HasSuffix(existingFile, ".yaml")
isn't effectively used. Let's verify the condition to ensure it's working as intended.🧰 Tools
🪛 golangci-lint (1.62.2)
800-800: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
865-865
:⚠️ Potential issueAvoid using dynamic format strings with
fmt.Sprintf
At line 865, using
fmt.Sprintf
with a dynamic format string might lead to runtime errors ifpath
orerr.Error()
contain formatting verbs. Let's use format specifiers safely.Suggested fix:
-u.LogWarning(atmosConfig, fmt.Sprintf("error closing file '"+path+"'. "+err.Error())) +u.LogWarning(atmosConfig, fmt.Sprintf("error closing file '%s'. %v", path, err))🧰 Tools
🪛 golangci-lint (1.62.2)
865-865: printf: non-constant format string in call to fmt.Sprintf
(govet)
🧹 Nitpick comments (10)
pkg/config/base-path.go (1)
3-3
: Add proper function documentation.The function lacks proper documentation. Let's add a clear description of its purpose, parameters, and return values.
+// BasePathComputing computes the base path for Atmos configurations. +// It checks for the --base-path CLI argument and updates ATMOS_BASE_PATH environment variable. +// If a relative path is provided, it is converted to an absolute path. +// Returns the computed base path or an empty string if no base path is set or on error. func (cl *ConfigLoader) BasePathComputing() string {pkg/config/imports.go (1)
73-75
: Consider enhancingisRemoteImport
function for robustness.Using
url.Parse
and checking the scheme inisRemoteImport
can make the function more robust against different URL formats and edge cases.Apply this diff:
func isRemoteImport(importPath string) bool { - return strings.HasPrefix(importPath, "http://") || strings.HasPrefix(importPath, "https://") + parsedURL, err := url.Parse(strings.TrimSpace(importPath)) + if err != nil { + return false + } + return parsedURL.Scheme == "http" || parsedURL.Scheme == "https" }pkg/config/imports_test.go (2)
76-76
: Use a unique temporary directory fortempDir
in tests.Currently, the test uses
"./test"
as thetempDir
, which can cause conflicts in concurrent test runs. It's better to use a unique temporary directory.Apply this diff:
- resolvedPaths, err := configLoader.processImports(imports, "./test", 0, 10) + resolvedPaths, err := configLoader.processImports(imports, t.TempDir(), 0, 10)
134-136
: Prefert.TempDir()
overos.MkdirTemp
in tests.Using
t.TempDir()
simplifies temporary directory management in tests and ensures cleanup. Replaceos.MkdirTemp
and manual cleanup witht.TempDir()
.Apply this diff:
- tempDir, err := os.MkdirTemp("", "config-test") - assert.NoError(t, err) - defer os.RemoveAll(tempDir) + tempDir := t.TempDir()Also applies to: 144-146, 154-156
pkg/config/homedir/home.go (2)
118-121
: Useerrors.Is
for error comparisonWhen checking errors from
cmd.Run()
, directly comparingerr
toexec.ErrNotFound
might not handle wrapped errors correctly. Usingerrors.Is(err, exec.ErrNotFound)
ensures proper error handling.
164-164
: Update error message to match variables checkedThe error message mentions
USERPROFILE
, but onlyHOMEDRIVE
andHOMEPATH
are checked here. Let's adjust the message to reflect this accurately.pkg/config/con.go (1)
453-454
: Remove duplicate commentThe comment for
applyUserPreferences
is duplicated. Removing the redundant line will keep the code clean.pkg/config/con_test.go (3)
151-186
: Consider splitting this test function for better maintainability.This test function is handling multiple test cases (single file, multiple files, directory). Consider splitting it into separate test functions for better clarity:
TestLoadExplicitConfigsWithSingleFile
TestLoadExplicitConfigsWithMultipleFiles
TestLoadExplicitConfigsFromDirectory
61-101
: Consider adding more edge cases to the config file search test.The test could be enhanced with additional cases:
- Empty directory
- Directory with unsupported file extensions
- Directory with subdirectories containing config files
19-271
: Strong test coverage with room for enhancement!The test suite provides comprehensive coverage of the configuration loading functionality. Consider:
- Adding more edge cases for error scenarios
- Testing concurrent access to configuration
- Adding benchmarks for performance-critical operations
Would you like me to help generate additional test cases or benchmarks?
🧰 Tools
🪛 golangci-lint (1.62.2)
244-244: Error return value of
w.Write
is not checked(errcheck)
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
pkg/config/base-path.go
(1 hunks)pkg/config/con.go
(1 hunks)pkg/config/con_test.go
(1 hunks)pkg/config/homedir/LICENSE
(1 hunks)pkg/config/homedir/home.go
(1 hunks)pkg/config/homedir/home_test.go
(1 hunks)pkg/config/imports.go
(1 hunks)pkg/config/imports_test.go
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- pkg/config/homedir/LICENSE
🧰 Additional context used
🪛 golangci-lint (1.62.2)
pkg/config/imports_test.go
161-161: ineffectual assignment to err
(ineffassign)
pkg/config/con.go
542-542: Error return value of cl.deepMergeConfig
is not checked
(errcheck)
687-687: printf: non-constant format string in call to fmt.Errorf
(govet)
865-865: printf: non-constant format string in call to fmt.Sprintf
(govet)
800-800: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
pkg/config/con_test.go
244-244: Error return value of w.Write
is not checked
(errcheck)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Summary
🔇 Additional comments (4)
pkg/config/base-path.go (1)
3-10
: Add unit tests for the new functionality.Ensure comprehensive test coverage for the BasePathComputing method.
Create a test file with cases for:
- Valid absolute path
- Valid relative path
- Invalid path
- Empty path
- Environment variable setting
- Error conditions
Would you like me to generate a comprehensive test suite for this functionality?
pkg/config/homedir/home_test.go (1)
1-129
: Tests look solidThe test cases cover various scenarios effectively.
pkg/config/con_test.go (2)
1-17
: Clean and well-organized imports!The package declaration and imports are properly structured and follow Go conventions.
244-244
: Unchecked error fromw.Write
The return value of
w.Write([]byte("mock content"))
should be checked for errors.🧰 Tools
🪛 golangci-lint (1.62.2)
244-244: Error return value of
w.Write
is not checked(errcheck)
pkg/config/base-path.go
Outdated
func (cl *ConfigLoader) BasePathComputing() string { | ||
// Is --base-path Provided? | ||
// If --base-path arg is provided | ||
// Yes --> "Set base_path to --base-path (resolve absolute if relative)" | ||
// Update ATMOS_BASE_PATH with absolute path | ||
|
||
return "" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation needed: BasePathComputing is currently a stub.
Greetings, warrior! The current implementation returns an empty string and doesn't fulfill the requirements outlined in the comments. Here's what needs to be implemented:
- Parse and validate the --base-path CLI argument
- Convert relative paths to absolute paths
- Update the ATMOS_BASE_PATH environment variable
- Return the computed base path
Here's a suggested implementation structure:
+import (
+ "os"
+ "path/filepath"
+)
+
func (cl *ConfigLoader) BasePathComputing() string {
- // Is --base-path Provided?
- // If --base-path arg is provided
- // Yes --> "Set base_path to --base-path (resolve absolute if relative)"
- // Update ATMOS_BASE_PATH with absolute path
+ if basePath := cl.getBasePathFromCLI(); basePath != "" {
+ absPath, err := filepath.Abs(basePath)
+ if err != nil {
+ cl.logger.Error("Failed to resolve absolute path", "error", err)
+ return ""
+ }
+
+ if err := os.Setenv("ATMOS_BASE_PATH", absPath); err != nil {
+ cl.logger.Error("Failed to set ATMOS_BASE_PATH", "error", err)
+ return ""
+ }
+
+ return absPath
+ }
return ""
}
Committable suggestion skipped: line range outside the PR's diff.
🛠️ Refactor suggestion
Add error handling and validation.
The function should include proper error handling for various scenarios:
- Invalid paths
- Permission issues
- Environment variable setting failures
Consider returning an error along with the string to properly handle and communicate failures:
-func (cl *ConfigLoader) BasePathComputing() string {
+func (cl *ConfigLoader) BasePathComputing() (string, error) {
if basePath := cl.getBasePathFromCLI(); basePath != "" {
absPath, err := filepath.Abs(basePath)
if err != nil {
- cl.logger.Error("Failed to resolve absolute path", "error", err)
- return ""
+ return "", fmt.Errorf("failed to resolve absolute path: %w", err)
}
+ if _, err := os.Stat(absPath); err != nil {
+ return "", fmt.Errorf("invalid base path: %w", err)
+ }
+
if err := os.Setenv("ATMOS_BASE_PATH", absPath); err != nil {
- cl.logger.Error("Failed to set ATMOS_BASE_PATH", "error", err)
- return ""
+ return "", fmt.Errorf("failed to set ATMOS_BASE_PATH: %w", err)
}
- return absPath
+ return absPath, nil
}
- return ""
+ return "", nil
}
Committable suggestion skipped: line range outside the PR's diff.
pkg/config/imports.go
Outdated
} | ||
err := client.Get() | ||
if err != nil { | ||
os.RemoveAll(tempDir) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prevent unintended deletion of temporary files on download failure.
When a download error occurs in downloadRemoteConfig
, the function removes the entire tempDir
, which may contain other configuration files. This could lead to data loss if multiple remote imports are being processed. It's safer to remove only the temporary file associated with the failed download.
Apply this diff to fix the issue:
- os.RemoveAll(tempDir)
+ os.Remove(tempFile)
Committable suggestion skipped: line range outside the PR's diff.
"local.yaml", | ||
server.URL + "/config.yaml", | ||
} | ||
resolved, err := cl.processImports(importPaths, tempDir, 11, 10) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle the error returned by processImports
in the test.
In TestProcessImportNested
, the error returned by processImports
when the max depth is exceeded is not checked. To properly validate the expected behavior, the test should assert that an error is returned.
Apply this diff:
resolved, err := cl.processImports(importPaths, tempDir, 11, 10)
- assert.Nil(t, resolved, "no resolved paths should be returned on depth limit breach")
+ assert.Error(t, err, "should return an error when maxDepth is exceeded")
+ assert.Nil(t, resolved, "no resolved paths should be returned on depth limit breach")
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
resolved, err := cl.processImports(importPaths, tempDir, 11, 10) | |
resolved, err := cl.processImports(importPaths, tempDir, 11, 10) | |
assert.Error(t, err, "should return an error when maxDepth is exceeded") | |
assert.Nil(t, resolved, "no resolved paths should be returned on depth limit breach") |
🧰 Tools
🪛 golangci-lint (1.62.2)
161-161: ineffectual assignment to err
(ineffassign)
func Dir() (string, error) { | ||
if !DisableCache { | ||
cacheLock.RLock() | ||
cached := homedirCache | ||
cacheLock.RUnlock() | ||
if cached != "" { | ||
return cached, nil | ||
} | ||
} | ||
|
||
cacheLock.Lock() | ||
defer cacheLock.Unlock() | ||
|
||
var result string | ||
var err error | ||
if runtime.GOOS == "windows" { | ||
result, err = dirWindows() | ||
} else { | ||
// Unix-like system, so just assume Unix | ||
result, err = dirUnix() | ||
} | ||
|
||
if err != nil { | ||
return "", err | ||
} | ||
homedirCache = result | ||
return result, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid updating the cache when caching is disabled
Even when DisableCache
is true, Dir()
updates homedirCache
, which could lead to unintended caching. Let's guard the cache update with if !DisableCache
to ensure proper behavior.
if found { | ||
u.LogTrace(cl.atmosConfig, fmt.Sprintf("merge import paths: %v", resolvedPaths)) | ||
} | ||
cl.deepMergeConfig() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check the error returned by cl.deepMergeConfig()
At line 542, the error from cl.deepMergeConfig()
isn't checked. This might hide issues if the merge fails. Let's handle the error to catch any problems.
Suggested fix:
- cl.deepMergeConfig()
+ if err := cl.deepMergeConfig(); err != nil {
+ return err
+ }
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
cl.deepMergeConfig() | |
if err := cl.deepMergeConfig(); err != nil { | |
return err | |
} |
🧰 Tools
🪛 golangci-lint (1.62.2)
542-542: Error return value of cl.deepMergeConfig
is not checked
(errcheck)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (9)
pkg/config/imports.go (3)
18-36
: Validate URL scheme before download attempt.The function should validate the URL scheme before attempting the download. This would prevent unnecessary network calls for invalid URLs.
func (cl *ConfigLoader) downloadRemoteConfig(url string, tempDir string) (string, error) { + parsedURL, err := url.Parse(url) + if err != nil || (parsedURL.Scheme != "http" && parsedURL.Scheme != "https") { + return "", fmt.Errorf("invalid URL scheme '%s': %v", url, err) + } // uniq name for the temp file fileName := fmt.Sprintf("atmos-%d.yaml", time.Now().UnixNano())
37-40
: Add directory existence check.The function should verify that tempDir exists before proceeding. This would prevent cryptic errors later in the process.
if tempDir == "" { return nil, fmt.Errorf("tempDir required to process imports") } +if _, err := os.Stat(tempDir); os.IsNotExist(err) { + return nil, fmt.Errorf("tempDir '%s' does not exist", tempDir) +}
89-91
: Add basic YAML validation before parsing.Consider adding basic YAML validation before attempting to parse the configuration to provide more helpful error messages.
v := viper.New() v.SetConfigType("yaml") +// Basic YAML validation +content, err := os.ReadFile(tempFile) +if err != nil { + return nil, fmt.Errorf("failed to read config file '%s': %v", tempFile, err) +} +if len(content) == 0 { + return nil, fmt.Errorf("config file '%s' is empty", tempFile) +} found, _, err := cl.loadConfigFile(cl.atmosConfig, tempFile, v)pkg/config/con.go (6)
46-134
: Consider adding flowchart documentation.The
LoadConfig
method implements a well-structured multi-stage configuration loading process. Consider adding a link to the flowchart documentation in the method's comments to help future maintainers understand the loading stages and their relationships.
684-688
: Use errors.New for static error messages.Replace
fmt.Errorf
witherrors.New
when the error message is pre-formatted and doesn't require any formatting verbs.Apply this change:
- return fmt.Errorf(errorMessage) + return errors.New(errorMessage)🧰 Tools
🪛 golangci-lint (1.62.2)
687-687: printf: non-constant format string in call to fmt.Errorf
(govet)
862-867
: Improve error message formatting.Use proper format verbs instead of string concatenation for better error message handling.
Apply this change:
- u.LogWarning(atmosConfig, fmt.Sprintf("error closing file '"+path+"'. "+err.Error())) + u.LogWarning(atmosConfig, fmt.Sprintf("error closing file '%s': %v", path, err))🧰 Tools
🪛 golangci-lint (1.62.2)
865-865: printf: non-constant format string in call to fmt.Sprintf
(govet)
800-802
: Remove redundant HasSuffix check.The
HasSuffix
check is unnecessary as the condition is already handled by the extension comparison.Apply this change:
- } else if ext == ".yml" && strings.HasSuffix(existingFile, ".yaml") { + } else if ext == ".yml" { continue // Keep .yaml priority }🧰 Tools
🪛 golangci-lint (1.62.2)
800-800: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
299-301
: Enhance error context in error wrapping.Consider adding more context when wrapping errors to help with debugging. Include relevant values that led to the error.
Apply this change:
- return fmt.Errorf("error loading configs from ATMOS_CLI_CONFIG_PATH: %w", err) + return fmt.Errorf("error loading configs from ATMOS_CLI_CONFIG_PATH '%s': %w", cl.atmosConfig.CliConfigPath, err)
523-523
: Use more specific temporary directory prefix.Consider using a more specific prefix for the temporary directory to better identify its purpose.
Apply this change:
- tempDir, err := os.MkdirTemp("", "atmos-import-*") + tempDir, err := os.MkdirTemp("", "atmos-config-import-*")
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
pkg/config/con.go
(1 hunks)pkg/config/imports.go
(1 hunks)
🧰 Additional context used
🪛 golangci-lint (1.62.2)
pkg/config/con.go
542-542: Error return value of cl.deepMergeConfig
is not checked
(errcheck)
687-687: printf: non-constant format string in call to fmt.Errorf
(govet)
865-865: printf: non-constant format string in call to fmt.Sprintf
(govet)
800-800: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Summary
🔇 Additional comments (3)
pkg/config/imports.go (1)
72-75
: Clean and focused implementation!The helper function is well-scoped and handles the common HTTP(S) schemes appropriately.
pkg/config/con.go (2)
22-34
: Well-structured type declarations!The
MaximumImportLvL
constant effectively prevents infinite import loops, and theConfigLoader
struct is cleanly organized with clear field purposes.
542-542
:⚠️ Potential issueCheck error from deepMergeConfig.
The error returned by
deepMergeConfig()
should be checked to ensure proper error propagation.Apply this fix:
- cl.deepMergeConfig() + if err := cl.deepMergeConfig(); err != nil { + return err + }Likely invalid or redundant comment.
🧰 Tools
🪛 golangci-lint (1.62.2)
542-542: Error return value of
cl.deepMergeConfig
is not checked(errcheck)
localPath := filepath.Join(basePath, importPath) | ||
paths, err := cl.SearchAtmosConfigFileDir(localPath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add path traversal protection.
The function should ensure that the resolved path doesn't escape the base directory through path traversal.
localPath := filepath.Join(basePath, importPath)
+// Ensure the resolved path is still under basePath
+if !strings.HasPrefix(filepath.Clean(localPath), filepath.Clean(basePath)) {
+ return nil, fmt.Errorf("import path '%s' attempts to escape base directory", importPath)
+}
paths, err := cl.SearchAtmosConfigFileDir(localPath)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
localPath := filepath.Join(basePath, importPath) | |
paths, err := cl.SearchAtmosConfigFileDir(localPath) | |
localPath := filepath.Join(basePath, importPath) | |
// Ensure the resolved path is still under basePath | |
if !strings.HasPrefix(filepath.Clean(localPath), filepath.Clean(basePath)) { | |
return nil, fmt.Errorf("import path '%s' attempts to escape base directory", importPath) | |
} | |
paths, err := cl.SearchAtmosConfigFileDir(localPath) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (5)
pkg/config/config.go (3)
280-306
: Consider consolidating error handling for directory checks.The implementation correctly handles both
atmos.d
and.atmos.d
directories with proper path traversal protection. However, the error handling pattern is repeated.Consider consolidating the directory checks:
- atmosDPath := filepath.Join(basePath, "atmos.d") - if !strings.HasPrefix(atmosDPath, basePath) { - u.LogWarning(atmosConfig, "invalid atmos.d path: attempted directory traversal") - } - _, err = os.Stat(atmosDPath) - if err == nil { - atmosConfig.Import = []string{"atmos.d/**/*.yaml", "atmos.d/**/*.yml"} - } else if !os.IsNotExist(err) { - return atmosConfig, err - } - atmosDPath = filepath.Join(atmosDPath, ".atmos.d") - _, err = os.Stat(atmosDPath) - if err == nil { - cliImport := []string{".atmos.d/**/*.yaml", ".atmos.d/**/*.yml"} - atmosConfig.Import = append(atmosConfig.Import, cliImport...) - } else if !os.IsNotExist(err) { - return atmosConfig, err - } + for _, dir := range []string{"atmos.d", ".atmos.d"} { + atmosDPath := filepath.Join(basePath, dir) + if !strings.HasPrefix(atmosDPath, basePath) { + u.LogWarning(atmosConfig, fmt.Sprintf("invalid %s path: attempted directory traversal", dir)) + continue + } + _, err = os.Stat(atmosDPath) + if err == nil { + patterns := []string{fmt.Sprintf("%s/**/*.yaml", dir), fmt.Sprintf("%s/**/*.yml", dir)} + if atmosConfig.Import == nil { + atmosConfig.Import = patterns + } else { + atmosConfig.Import = append(atmosConfig.Import, patterns...) + } + } else if !os.IsNotExist(err) { + return atmosConfig, err + } + }
465-537
: Consider adding rate limiting for remote imports.The import processing implementation is robust with proper URL validation and temporary file cleanup. However, when processing multiple remote imports, there's no rate limiting mechanism in place.
Consider adding rate limiting:
+var importLimiter = make(chan struct{}, 3) // Allow 3 concurrent downloads + func processImports(atmosConfig schema.AtmosConfiguration, v *viper.Viper) error { + defer func() { + // Cleanup any remaining tokens + for len(importLimiter) > 0 { + <-importLimiter + } + }() + for _, importPath := range atmosConfig.Import { if importPath == "" { continue } if strings.HasPrefix(importPath, "http://") || strings.HasPrefix(importPath, "https://") { + importLimiter <- struct{}{} // Acquire token tempDir, tempFile, err := downloadRemoteConfig(importPath) + <-importLimiter // Release token
539-558
: Consider enhancing logging for remote downloads.The remote config downloading implementation is secure with proper timeout handling and cleanup. However, it could benefit from additional logging to help with troubleshooting.
Consider adding debug logging:
func downloadRemoteConfig(url string) (string, string, error) { + u.LogDebug(fmt.Sprintf("Downloading remote config from %s", url)) tempDir, err := os.MkdirTemp("", "atmos-import-*") if err != nil { return "", "", err } tempFile := filepath.Join(tempDir, "atmos.yaml") + u.LogDebug(fmt.Sprintf("Using temporary file %s", tempFile)) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() client := &getter.Client{ Ctx: ctx, Src: url, Dst: tempFile, Mode: getter.ClientModeFile, } err = client.Get() if err != nil { + u.LogDebug(fmt.Sprintf("Failed to download from %s: %v", url, err)) os.RemoveAll(tempDir) return "", "", fmt.Errorf("failed to download remote config: %w", err) } + u.LogDebug(fmt.Sprintf("Successfully downloaded config from %s", url)) return tempDir, tempFile, nil }pkg/config/utils.go (2)
787-830
: Consider enhancing error messages for better debugging.The ProcessConfigFile implementation is robust with proper handling of both single files and directories. However, the error messages could be more descriptive.
Consider enhancing error messages:
func ProcessConfigFile(config interface{}, configPath string, v *viper.Viper) (bool, string, error) { absPath, err := filepath.Abs(configPath) if err != nil { - return false, "", fmt.Errorf("unable to get absolute path for %s: %w", configPath, err) + return false, "", fmt.Errorf("failed to resolve absolute path for config file %s: %w", configPath, err) } info, err := os.Stat(absPath) if os.IsNotExist(err) { return false, "", nil } else if err != nil { - return false, "", fmt.Errorf("error accessing config file (%s): %w", absPath, err) + return false, "", fmt.Errorf("failed to access config file %s (permissions or I/O error): %w", absPath, err) }
832-843
: Consider adding directory existence validation.The GetHomeDir implementation correctly retrieves the user's home directory with proper error handling. However, it could benefit from additional validation.
Consider adding directory validation:
func GetHomeDir() (string, error) { homeDir, err := os.UserHomeDir() if err != nil { return "", fmt.Errorf("unable to determine home directory: %w", err) } if homeDir == "" { return "", fmt.Errorf("home directory not found") } + // Validate that the directory exists and is accessible + info, err := os.Stat(homeDir) + if err != nil { + return "", fmt.Errorf("home directory %s is not accessible: %w", homeDir, err) + } + if !info.IsDir() { + return "", fmt.Errorf("home directory %s is not a directory", homeDir) + } return homeDir, nil }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
go.sum
is excluded by!**/*.sum
📒 Files selected for processing (8)
.github/workflows/test.yml
(1 hunks)go.mod
(2 hunks)internal/exec/helmfile.go
(1 hunks)internal/exec/terraform.go
(1 hunks)pkg/config/config.go
(6 hunks)pkg/config/utils.go
(2 hunks)pkg/schema/schema.go
(1 hunks)pkg/utils/glob_utils.go
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
- .github/workflows/test.yml
- go.mod
- pkg/utils/glob_utils.go
- internal/exec/terraform.go
- pkg/schema/schema.go
- internal/exec/helmfile.go
🧰 Additional context used
📓 Learnings (1)
pkg/config/config.go (2)
Learnt from: osterman
PR: cloudposse/atmos#808
File: pkg/config/config.go:478-483
Timestamp: 2024-12-02T21:26:32.337Z
Learning: In the 'atmos' project, when reviewing Go code like `pkg/config/config.go`, avoid suggesting file size checks after downloading remote configs if such checks aren't implemented elsewhere in the codebase.
Learnt from: osterman
PR: cloudposse/atmos#887
File: internal/exec/stack_processor_utils.go:380-380
Timestamp: 2024-12-25T20:28:47.526Z
Learning: Windows path handling often requires `filepath.Join` to ensure correct separators and comparisons. Insufficient tests can break cross-platform compatibility, so migrating from `path.Join` to `filepath.Join` needs thorough testing on Windows before merging.
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Summary
🔇 Additional comments (1)
pkg/config/config.go (1)
144-158
: LGTM! Clean implementation of configuration loading hierarchy.The configuration loading logic follows a clear precedence order and properly handles the
ATMOS_CLI_CONFIG_PATH
environment variable. The error handling is thorough and the early return pattern is well applied.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
cmd/root.go (1)
Line range hint
26-46
: Add examples to help text for the new configuration features.Greetings, commander! The command's help text could be enhanced to showcase the new configuration capabilities. Consider adding examples to the
Long
description:Long: `Atmos is a universal tool for DevOps and cloud automation used for provisioning, managing and orchestrating workflows across various toolchains`, + Example: ` # Use a custom base path for configuration + atmos --base-path /path/to/config + + # The base path will be used to locate: + # - atmos.yaml configuration file + # - atmos.d directory for additional configurations + # - imported configurations and remote sources`,
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
cmd/root.go
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Summary
🔇 Additional comments (2)
cmd/root.go (2)
157-157
: Implementation approved with minor suggestions.The new flag is well-implemented and strategically positioned to support the enhanced configuration management features. The code is clean, follows best practices, and integrates smoothly with the existing codebase.
157-157
: Enhance the flag description and consider adding path validation.The flag implementation is solid, warrior! However, let's make it even more battle-ready:
- Expand the description to provide more context:
- RootCmd.PersistentFlags().String("base-path", "", "Base path for Atmos configuration files. If not set, Atmos will use the default path.") + RootCmd.PersistentFlags().String("base-path", "", "Base path for Atmos configuration files and atmos.d directory. If not set, Atmos will use the current directory. The path can be absolute or relative to the current working directory.")
- Consider adding path validation in the
PersistentPreRun
function to ensure the path exists and is accessible.Let's verify if path validation is implemented elsewhere:
pkg/config/ReadMe.md
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename to README.md
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (5)
pkg/config/con_test.go (1)
217-217
:⚠️ Potential issueHandle potential write error in mock server.
The error from
w.Write
should be checked to ensure proper test behavior.-w.Write([]byte("mock content")) +if _, err := w.Write([]byte("mock content")); err != nil { + t.Fatalf("Failed to write mock content: %v", err) +}🧰 Tools
🪛 golangci-lint (1.62.2)
217-217: Error return value of
w.Write
is not checked(errcheck)
pkg/config/con.go (4)
534-534
:⚠️ Potential issueCheck the error returned by
cl.deepMergeConfig()
The error returned by
cl.deepMergeConfig()
is not being checked, which could lead to unhandled errors if the merge fails.Apply this change to handle the error:
- cl.deepMergeConfig() + if err := cl.deepMergeConfig(); err != nil { + return err + }🧰 Tools
🪛 golangci-lint (1.62.2)
534-534: Error return value of
cl.deepMergeConfig
is not checked(errcheck)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
679-679
:⚠️ Potential issueAvoid using dynamic format strings in
fmt.Errorf
Using a dynamic string with
fmt.Errorf
may cause unexpected behavior if the message contains formatting verbs. Consider usingerrors.New(errorMessage)
instead.Apply this change:
- return fmt.Errorf(errorMessage) + return errors.New(errorMessage)🧰 Tools
🪛 golangci-lint (1.62.2)
679-679: printf: non-constant format string in call to fmt.Errorf
(govet)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
792-792
:⚠️ Potential issueUnused result of
strings.HasSuffix
The result of
strings.HasSuffix(existingFile, ".yaml")
is computed but not used, which may indicate a logical error or unnecessary computation.Consider using the result in a condition or removing the call if it's unnecessary.
- } else if ext == ".yml" && strings.HasSuffix(existingFile, ".yaml") { + } else if ext == ".yml" && /* condition using HasSuffix result */ { + // Handle the case when existingFile ends with .yaml + }🧰 Tools
🪛 golangci-lint (1.62.2)
792-792: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
857-857
:⚠️ Potential issueAvoid using dynamic format strings in
fmt.Sprintf
Using a dynamic string with
fmt.Sprintf
can lead to runtime errors if the string contains unintended formatting verbs. It's safer to use format specifiers explicitly.Apply this change:
- u.LogWarning(atmosConfig, fmt.Sprintf("error closing file '"+path+"'. "+err.Error())) + u.LogWarning(atmosConfig, fmt.Sprintf("error closing file '%s'. %v", path, err))🧰 Tools
🪛 golangci-lint (1.62.2)
857-857: printf: non-constant format string in call to fmt.Sprintf
(govet)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
🧹 Nitpick comments (6)
pkg/config/con_test.go (2)
19-35
: Consider adding specific merge value assertions.While the test verifies the merge operation succeeds, it would be more robust to assert specific expected values in the merged configuration.
Consider adding assertions like:
expectedConfig := schema.AtmosConfiguration{ // Add expected merged values here } assert.Equal(t, expectedConfig, cl.atmosConfig, "Merged configuration does not match expected values")
93-95
: Enhance error message clarity.The error message could be more descriptive about the expected file priority.
-t.Errorf("Expected 1 config files, got %d", len(got)) +t.Errorf("Expected exactly 1 config file (highest priority .yaml file), got %d files", len(got))cmd/root.go (1)
157-158
: Enhance flag descriptions with more details and examples.The new flags look solid, warrior! However, their descriptions could be more battle-ready. Consider enhancing them to better guide our users:
- RootCmd.PersistentFlags().String("base-path", "", "Base path for Atmos configuration files.") - RootCmd.PersistentFlags().StringSlice("config", []string{}, "Paths to configuration files") + RootCmd.PersistentFlags().String("base-path", "", "Base path for Atmos configuration files (e.g., '/path/to/atmos/config'). Used as the root for resolving relative paths in configuration.") + RootCmd.PersistentFlags().StringSlice("config", []string{}, "Paths to configuration files. Accepts multiple paths (e.g., '--config path1.yaml --config path2.yaml') and supports glob patterns for atmos.d directory (e.g., './atmos.d/*.yaml')")This will make it crystal clear to our users how to wield these powerful configuration options! 💪
pkg/config/con.go (3)
444-445
: Remove duplicate function commentThe function
applyUserPreferences
has duplicate comments, which is redundant.Consider removing the duplicate line to improve readability:
-// applyUserPreferences applies user-specific configuration preferences.
🧰 Tools
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
446-446
: Simplify function commentThere's an extra blank line after the function comment for
applyUserPreferences
, which can be removed for better readability.-// applyUserPreferences applies user-specific configuration preferences. - func (cl *ConfigLoader) applyUserPreferences() error {🧰 Tools
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
49-51
: Simplify log level checkThe log level check in
LoadConfig
can be simplified by converting the log level to lowercase to make the comparison case-insensitive.- logsLevelEnvVar := os.Getenv("ATMOS_LOGS_LEVEL") - if logsLevelEnvVar == u.LogLevelDebug || logsLevelEnvVar == u.LogLevelTrace { + logsLevelEnvVar := strings.ToLower(os.Getenv("ATMOS_LOGS_LEVEL")) + if logsLevelEnvVar == u.LogLevelDebug || logsLevelEnvVar == u.LogLevelTrace { cl.debug = true }🧰 Tools
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
cmd/root.go
(1 hunks)internal/exec/utils.go
(1 hunks)pkg/config/README.md
(1 hunks)pkg/config/con.go
(1 hunks)pkg/config/con_test.go
(1 hunks)pkg/schema/schema.go
(2 hunks)
✅ Files skipped from review due to trivial changes (1)
- pkg/config/README.md
🚧 Files skipped from review as they are similar to previous changes (1)
- pkg/schema/schema.go
🧰 Additional context used
🪛 golangci-lint (1.62.2)
pkg/config/con.go
534-534: Error return value of cl.deepMergeConfig
is not checked
(errcheck)
679-679: printf: non-constant format string in call to fmt.Errorf
(govet)
857-857: printf: non-constant format string in call to fmt.Sprintf
(govet)
792-792: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
pkg/config/con_test.go
217-217: Error return value of w.Write
is not checked
(errcheck)
🪛 GitHub Actions: Tests
pkg/config/con.go
[error] Invalid file path detected during git checkout process
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Summary
🔇 Additional comments (7)
internal/exec/utils.go (2)
210-217
: LGTM! The changes enhance configuration path handling.The additions correctly extract the
base-path
andconfig
flag values, following the established error handling pattern. This aligns with the PR's objective to support flexible configuration paths.
210-217
: Verify integration with configuration loading.Let's ensure these new flags are properly integrated with the configuration loading logic.
Run the following script to verify the usage of these flags:
✅ Verification successful
Integration verified successfully!
The new flags are properly integrated with the configuration loading logic in
pkg/config/con.go
. The implementation follows a clean separation of concerns and maintains consistent error handling.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the integration of new flags with configuration loading. # Test: Search for usage of base-path and config flags in configuration loading code echo "Searching for base-path flag usage..." rg -A 5 'base-path.*GetString|BasePathFromArg' echo "Searching for config flag usage..." rg -A 5 'config.*GetStringSlice|AtmosConfigPathFromArg'Length of output: 1862
pkg/config/con_test.go (2)
1-17
: Clean and well-organized imports!The imports are properly structured and include all necessary testing packages.
106-107
: Excellent use of test utilities!The tests properly use
t.TempDir()
with appropriate cleanup usingdefer
, which is a robust pattern for handling temporary test files.Also applies to: 129-130
cmd/root.go (1)
157-158
: Verify flag handling in configuration loading.Let's ensure our new flags are properly integrated with the configuration loading system:
✅ Verification successful
Flags are properly integrated with configuration loading system
The flags are correctly integrated with:
- Proper flag definition and persistence
- Consistent retrieval across commands
- Validation of provided values
- Error handling for invalid inputs
- Integration with configuration loading pipeline
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify the integration of new flags with configuration loading # Check if the flags are properly handled in the configuration loading code echo "Checking flag handling implementation..." rg -A 10 "InitCliConfig|LoadConfig" --type go # Look for any potential validation of these flags echo "Checking flag validation..." rg -A 5 "base-path|config.*flag" --type go # Verify error handling for these flags echo "Checking error handling..." rg -A 5 "ErrInvalidConfig|ErrInvalidPath" --type goLength of output: 55393
pkg/config/con.go (2)
49-51
: Ensure environment variable names are consistentDouble-check that
ATMOS_LOGS_LEVEL
is the correct name of the environment variable for setting the log level.Please verify that the environment variable is correctly named and documented.
🧰 Tools
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
155-161
: 🛠️ Refactor suggestionHandle possible errors when reading embedded config data
In
loadEmbeddedConfig
, consider handling potential errors when creating the reader fromembeddedConfigData
.Ensure that
bytes.NewReader
doesn't fail silently:reader := bytes.NewReader(embeddedConfigData) +if reader == nil { + return fmt.Errorf("failed to create reader for embedded config data") +}Likely invalid or redundant comment.
🧰 Tools
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
// Determine if dirPath is a directory or a pattern | ||
isDir := false | ||
if stat, err := os.Stat(dirPath); err == nil && stat.IsDir() { | ||
isDir = true | ||
} | ||
// Normalize dirPath to include patterns if it's a directory | ||
var patterns []string | ||
|
||
if isDir { | ||
// For directories, append a default pattern to match all files | ||
patterns = []string{filepath.Join(dirPath, "*.yaml"), filepath.Join(dirPath, "*.yml")} | ||
|
||
} else { | ||
|
||
ext := filepath.Ext(dirPath) | ||
if ext == "" { | ||
impYaml := dirPath + ".yaml" | ||
impYml := dirPath + ".yml" | ||
patterns = append(patterns, impYaml, impYml) | ||
} else { | ||
patterns = append(patterns, dirPath) | ||
} | ||
|
||
} | ||
|
||
// sort fileExtension in ascending order to prioritize .yaml over .yml | ||
var atmosFilePaths []string | ||
for _, pattern := range patterns { | ||
filePaths, err := u.GetGlobMatches(pattern) | ||
if err == nil { | ||
atmosFilePaths = append(atmosFilePaths, filePaths...) | ||
} | ||
|
||
} | ||
if atmosFilePaths == nil { | ||
return nil, fmt.Errorf("no files matching name `atmos` with extensions [.yaml,.yml] found in the provided directory: %s", dirPath) | ||
} | ||
var atmosFilePathsABS []string | ||
for _, path := range atmosFilePaths { | ||
absPath, err := filepath.Abs(path) | ||
if err != nil { | ||
u.LogWarning(cl.atmosConfig, fmt.Sprintf("error getting absolute path for file '%s'. %v", path, err)) | ||
continue | ||
} | ||
atmosFilePathsABS = append(atmosFilePathsABS, absPath) | ||
} | ||
|
||
atmosFilePathsABS = cl.detectPriorityFiles(atmosFilePathsABS) | ||
atmosFilePathsABS = cl.sortFilesByDepth(atmosFilePathsABS) | ||
return atmosFilePathsABS, nil | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle errors returned by os.Stat
and u.GetGlobMatches
In the SearchAtmosConfigFileDir
method, errors returned by os.Stat
and u.GetGlobMatches
are not properly handled, which might lead to unexpected behavior.
Ensure to handle these errors appropriately. For example:
+if err != nil {
+ return nil, fmt.Errorf("error accessing directory '%s': %w", dirPath, err)
+}
Committable suggestion skipped: line range outside the PR's diff.
🧰 Tools
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
go.mod (1)
Line range hint
3-3
: Invalid Go version specified.The Go version
1.23.5
is invalid as it does not exist. The latest stable version of Go is 1.22.Apply this diff to fix the version:
-go 1.23.5 +go 1.22
♻️ Duplicate comments (4)
pkg/config/con.go (4)
537-537
:⚠️ Potential issueCheck the error returned by
cl.deepMergeConfig()
At line 537, the error returned by
cl.deepMergeConfig()
is not checked. This might hide issues if the merge fails.Apply this change:
+if err := cl.deepMergeConfig(); err != nil { + return err +}🧰 Tools
🪛 golangci-lint (1.62.2)
537-537: Error return value of
cl.deepMergeConfig
is not checked(errcheck)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
682-682
:⚠️ Potential issueAvoid using dynamic format strings in
fmt.Errorf
At line 682, using
fmt.Errorf(errorMessage)
with a dynamic string can lead to unexpected behavior if the message contains formatting verbs.Change to:
-return fmt.Errorf(errorMessage) +return errors.New(errorMessage)🧰 Tools
🪛 golangci-lint (1.62.2)
682-682: printf: non-constant format string in call to fmt.Errorf
(govet)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
795-795
:⚠️ Potential issueUnused result of
strings.HasSuffix
At line 795, the result of
strings.HasSuffix(existingFile, ".yaml")
is computed but not used.If you intend to check the suffix, use the result in a condition.
🧰 Tools
🪛 golangci-lint (1.62.2)
795-795: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
860-860
:⚠️ Potential issueAvoid dynamic format strings in
fmt.Sprintf
At line 860, using a dynamic string in
fmt.Sprintf
can cause runtime errors if formatting verbs are present.Modify the statement:
-u.LogWarning(atmosConfig, fmt.Sprintf("error closing file '"+path+"'. "+err.Error())) +u.LogWarning(atmosConfig, fmt.Sprintf("error closing file '%s'. %v", path, err))🧰 Tools
🪛 golangci-lint (1.62.2)
860-860: printf: non-constant format string in call to fmt.Sprintf
(govet)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
🧹 Nitpick comments (4)
pkg/config/con.go (1)
892-908
: Remove unused functionfindGitTopLevel
The function
findGitTopLevel
defined at lines 892-908 is unused.Consider removing it to improve maintainability:
-// findGitTopLevel finds the top-level directory of a Git repository -func findGitTopLevel(startDir string) (string, error) { - // function implementation -}🧰 Tools
🪛 golangci-lint (1.62.2)
892-892: func
findGitTopLevel
is unused(unused)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
pkg/config/base-path.go (3)
66-95
: Enhance maintainability with constants and documentation.Well met, warrior! The search paths and patterns should be defined as constants at the package level for better maintainability. Also, let's add godoc comments to explain the method's purpose and return values.
+// Common file patterns for Atmos configuration +const ( + AtmosConfigFile = "atmos" + AtmosHiddenConfig = ".atmos" + AtmosDirPattern = "atmos.d/**/*.yaml" + AtmosDirPatternYml = "atmos.d/**/*.yml" +) +// infraBasePath searches for Atmos configuration files in the current working directory +// and its parent directories, including the Git repository root if available. +// Returns the directory containing the configuration file and true if found, +// otherwise returns empty string and false. func (cl *ConfigLoader) infraBasePath(cwd string) (string, bool) {
97-117
: Consider caching the Git root path.Hail, warrior! The Git root path is unlikely to change during execution. Consider caching the result to avoid repeated filesystem operations.
+var ( + cachedGitRoot string + rootFound bool +) + func GetGitRoot(startPath string) (string, error) { + if rootFound { + return cachedGitRoot, nil + } // Open the repository starting from the given path repo, err := git.PlainOpenWithOptions(startPath, &git.PlainOpenOptions{ DetectDotGit: true, }) if err != nil { + rootFound = true // Cache negative result return "", fmt.Errorf("failed to open Git repository: %w", err) } // Get the worktree to extract the repository's root directory worktree, err := repo.Worktree() if err != nil { + rootFound = true // Cache negative result return "", fmt.Errorf("failed to get worktree: %w", err) } // Return the absolute path to the root directory rootPath, err := filepath.Abs(worktree.Filesystem.Root()) if err != nil { + rootFound = true // Cache negative result return "", fmt.Errorf("failed to resolve absolute path: %w", err) } + cachedGitRoot = rootPath + rootFound = true return rootPath, nil }
62-64
: Address TODO comment regarding ATMOS_BASE_PATH.Greetings, warrior! The TODO comment suggests we should set the ATMOS_BASE_PATH environment variable. This is important for consistency across the application.
- // TODO : Update ATMOS_BASE_PATH with absolute path is that mean set env ATMOS_BASE_PATH=base_path //Set base_path to absolute path of ./ - return "./", nil + absPath, err := filepath.Abs("./") + if err != nil { + return "", fmt.Errorf("failed to resolve current directory: %w", err) + } + if err := os.Setenv("ATMOS_BASE_PATH", absPath); err != nil { + return "", fmt.Errorf("failed to set ATMOS_BASE_PATH: %w", err) + } + return absPath, nilWould you like me to create an issue to track this enhancement?
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
go.sum
is excluded by!**/*.sum
📒 Files selected for processing (3)
go.mod
(2 hunks)pkg/config/base-path.go
(1 hunks)pkg/config/con.go
(1 hunks)
🧰 Additional context used
🪛 golangci-lint (1.62.2)
pkg/config/con.go
537-537: Error return value of cl.deepMergeConfig
is not checked
(errcheck)
892-892: func findGitTopLevel
is unused
(unused)
682-682: printf: non-constant format string in call to fmt.Errorf
(govet)
860-860: printf: non-constant format string in call to fmt.Sprintf
(govet)
795-795: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
🪛 GitHub Actions: Tests
pkg/config/con.go
[error] Invalid file path detected during git checkout process
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Summary
🔇 Additional comments (1)
go.mod (1)
8-8
: LGTM! Dependencies align with PR objectives.The new dependencies enhance the project's capabilities:
github.com/adrg/xdg
: Provides XDG Base Directory support for better configuration managementgithub.com/go-git/go-billy/v5
: Adds virtual filesystem abstraction for handling remote importsThese additions align well with the PR's goal of improving configuration handling and supporting remote imports.
Also applies to: 25-25
pkg/config/base-path.go
Outdated
if cl.atmosConfig.BasePath != "" { | ||
//Is base_path Absolute? | ||
absPath, err := filepath.Abs(configAndStacksInfo.BasePath) | ||
if err == nil { | ||
return absPath, nil | ||
} | ||
//Resolve base_path relative to current working directory |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect error handling logic.
Hold fast, warrior! The error handling logic here is inverted. We're proceeding with the absolute path only if there's no error, but then continuing with an alternative path resolution without properly handling the original error.
if cl.atmosConfig.BasePath != "" {
//Is base_path Absolute?
absPath, err := filepath.Abs(configAndStacksInfo.BasePath)
- if err == nil {
+ if err != nil {
+ return "", fmt.Errorf("failed to resolve base path from config: %w", err)
+ }
+ if _, err := os.Stat(absPath); err == nil {
return absPath, nil
}
//Resolve base_path relative to current working directory
Committable suggestion skipped: line range outside the PR's diff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let’s move to tests/fixturess/scennarios. Remove the demo prefix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (9)
pkg/config/imports_test.go (3)
15-19
: Consider adding input validationThe helper function could benefit from validating its inputs to ensure robustness.
func setupTestFile(content, tempDir string, filename string) (string, error) { + if content == "" || tempDir == "" || filename == "" { + return "", fmt.Errorf("content, tempDir, and filename must not be empty") + } filePath := filepath.Join(tempDir, filename) err := os.WriteFile(filePath, []byte(content), 0644) return filePath, err }
21-95
: Enhance error case testingWhile the test covers the happy path well, consider adding specific test cases for error scenarios.
func TestProcessImports(t *testing.T) { // ... existing setup ... + t.Run("Test invalid file permissions", func(t *testing.T) { + invalidDir := filepath.Join(baseDir, "invalid") + err := os.MkdirAll(invalidDir, 0000) + assert.NoError(t, err) + defer os.Chmod(invalidDir, 0755) + + imports := []string{filepath.Join("invalid", "**", "*")} + _, err = configLoader.processImports(imports, baseDir, 0, 10) + assert.Error(t, err, "should error on permission denied") + }) }
97-165
: Improve test cleanup and organizationConsider using subtests more consistently and improving cleanup practices.
func TestProcessImportNested(t *testing.T) { - baseDir, err := os.MkdirTemp("", "config-test") + baseDir := t.TempDir() // Uses testing.T's cleanup mechanism assert.NoError(t, err) - defer os.RemoveAll(baseDir) // ... rest of the test ... t.Run("Test mixed imports with depth limit", func(t *testing.T) { - tempDir, err := os.MkdirTemp("", "config-test") + tempDir := t.TempDir() assert.NoError(t, err) - defer os.RemoveAll(tempDir) importPaths := []string{ "local.yaml", server.URL + "/config.yaml", } resolved, err := cl.processImports(importPaths, tempDir, 11, 10) + assert.Error(t, err, "should return an error when maxDepth is exceeded") assert.Nil(t, resolved, "no resolved paths should be returned on depth limit breach") }) }🧰 Tools
🪛 golangci-lint (1.62.2)
161-161: ineffectual assignment to err
(ineffassign)
pkg/config/base_path.go (3)
41-41
: Fix the repeated word in error message.The error message contains “from from” and a slight grammar mismatch. Consider correcting it to improve clarity.
Apply this diff:
- return "", fmt.Errorf("Error base path from from atmos config can not resolving relative path:%w", err) + return "", fmt.Errorf("Error base path from atmos config cannot resolve relative path: %w", err)
43-47
: Return validated path to stay consistent.The call to
resolveAndValidatePath
at line 43 returns the absolute path, but the function ultimately returnsrelativePath
. This may cause discrepancies if the validated path differs. Consider returning the validated path for consistency.- _, err = cl.resolveAndValidatePath(relativePath, source) + validated, err := cl.resolveAndValidatePath(relativePath, source)- return relativePath, nil + return validated, nil
76-97
: Log the absolute path for consistency.You log the original path while returning the absolute path. This can be confusing when debugging. Logging the absolute path might help diagnose issues more easily.
pkg/config/base_path_test.go (3)
27-31
: Remove the unused variable assignment.The static analysis hint is correct:
expectedPath
is reassigned but never used. Removing it will help keep the code clean.- expectedPath, _ = filepath.Abs("invalid/path")
🧰 Tools
🪛 golangci-lint (1.62.2)
28-28: ineffectual assignment to expectedPath
(ineffassign)
33-33
: Correct the spelling in the code comment.The comment says "test base pat not directory" instead of "test base path not directory."
- // test base pat not directory + // test base path not directory
88-91
: Avoid using os.Exit during tests.Using
os.Exit
in a unit test can stop the entire test suite. Consider usingt.Fatalf
for consistency.- fmt.Printf("Failed to get the current working directory: %v\n", err) - os.Exit(1) + t.Fatalf("Failed to get the current working directory: %v", err)
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
pkg/config/base_path.go
(1 hunks)pkg/config/base_path_test.go
(1 hunks)pkg/config/imports_test.go
(1 hunks)
🧰 Additional context used
🪛 golangci-lint (1.62.2)
pkg/config/imports_test.go
161-161: ineffectual assignment to err
(ineffassign)
pkg/config/base_path_test.go
28-28: ineffectual assignment to expectedPath
(ineffassign)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Summary
🔇 Additional comments (4)
pkg/config/imports_test.go (2)
1-13
: Clean and well-organized imports!The package structure and imports are well-organized and contain all necessary dependencies for testing.
161-161
: Handle the error returned byprocessImports
in the testThe error returned by
processImports
when the max depth is exceeded should be checked.🧰 Tools
🪛 golangci-lint (1.62.2)
161-161: ineffectual assignment to err
(ineffassign)
pkg/config/base_path.go (1)
135-155
: Looks good.This function properly locates and returns the Git repository’s root using go-git.
pkg/config/base_path_test.go (1)
70-114
: Overall test coverage is excellent.These tests thoroughly validate relative and absolute path scenarios, environment variable usage, and directory structures.
pkg/config/base_path.go
Outdated
cl.logging(fmt.Sprintf("base path from infra %s: %s", "atmos.d", filePath)) | ||
filePaths = cl.sortFilesByDepth(filePaths) | ||
return filepath.Dir(filePaths[0]), true | ||
} | ||
gitTopLevel, err := GetGitRoot(cwd) | ||
if err == nil { | ||
dirAbs, found := cl.SearchConfigFilePath(filepath.Join(gitTopLevel, "atmos")) | ||
if found { | ||
cl.logging(fmt.Sprintf("base path from infra %s: %s", "git root", filePath)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Use correct variable when logging from “atmos.d” or “git root.”
Here, filePath
is never reassigned after the .atmos
check, so logging it at lines 117 and 125 may be inaccurate. Consider logging the first matched file path or the directory path stored in new variables such as filePaths[0]
or dirAbs
.
- cl.logging(fmt.Sprintf("base path from infra %s: %s", "atmos.d", filePath))
+ cl.logging(fmt.Sprintf("base path from infra %s: %s", "atmos.d", filePaths[0]))
- cl.logging(fmt.Sprintf("base path from infra %s: %s", "git root", filePath))
+ cl.logging(fmt.Sprintf("base path from infra %s: %s", "git root", dirAbs))
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
cl.logging(fmt.Sprintf("base path from infra %s: %s", "atmos.d", filePath)) | |
filePaths = cl.sortFilesByDepth(filePaths) | |
return filepath.Dir(filePaths[0]), true | |
} | |
gitTopLevel, err := GetGitRoot(cwd) | |
if err == nil { | |
dirAbs, found := cl.SearchConfigFilePath(filepath.Join(gitTopLevel, "atmos")) | |
if found { | |
cl.logging(fmt.Sprintf("base path from infra %s: %s", "git root", filePath)) | |
cl.logging(fmt.Sprintf("base path from infra %s: %s", "atmos.d", filePaths[0])) | |
filePaths = cl.sortFilesByDepth(filePaths) | |
return filepath.Dir(filePaths[0]), true | |
} | |
gitTopLevel, err := GetGitRoot(cwd) | |
if err == nil { | |
dirAbs, found := cl.SearchConfigFilePath(filepath.Join(gitTopLevel, "atmos")) | |
if found { | |
cl.logging(fmt.Sprintf("base path from infra %s: %s", "git root", dirAbs)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
pkg/config/base_path.go (1)
112-112
:⚠️ Potential issueUse correct variable in logging, valiant coder! ⚔️
The logging statement uses
filePath
which is undefined in this scope. It should usedirAbs
instead.- cl.logging(fmt.Sprintf("base path from infra %s: %s", "git root", filePath)) + cl.logging(fmt.Sprintf("base path from infra %s: %s", "git root", dirAbs))
🧹 Nitpick comments (4)
pkg/config/base_path_test.go (1)
13-48
: Fix ineffectual assignment and typo in comment.The test function is well-structured with good error cases, but has a few minor issues:
Apply these changes:
- // test base pat not directory + // test base path not directory- expectedPath, _ = filepath.Abs("invalid/path") - result, err = configLoader.BasePathComputing(info) + result, err = configLoader.BasePathComputing(info)The
expectedPath
assignment on line 28 is not used in the test, so it can be removed.🧰 Tools
🪛 golangci-lint (1.62.2)
28-28: ineffectual assignment to expectedPath
(ineffassign)
pkg/config/base_path.go (3)
26-26
: Remove duplicate comment line, fellow warrior! 🗑️The comment "Check base path from configuration" appears twice consecutively.
- // Check base path from configuration
13-61
: Strong base path resolution strategy! 💪The hierarchical checking of base path sources (CLI -> ENV -> config -> inferred) provides good flexibility while maintaining clear precedence.
Consider adding a constant or documentation that explicitly states this precedence order to help users understand how their configuration will be resolved.
82-82
: Log the resolved absolute path, brave one! 🎯The logging statement uses the original
path
instead of the resolvedabsPath
.- cl.logging(fmt.Sprintf("base path from %s: %s", source, path)) + cl.logging(fmt.Sprintf("base path from %s: %s", source, absPath))
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
pkg/config/base_path.go
(1 hunks)pkg/config/base_path_test.go
(1 hunks)
🧰 Additional context used
🪛 golangci-lint (1.62.2)
pkg/config/base_path_test.go
28-28: ineffectual assignment to expectedPath
(ineffassign)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Summary
🔇 Additional comments (4)
pkg/config/base_path_test.go (2)
1-11
: LGTM! Clean and well-organized imports.The imports are appropriate for the test requirements, using standard libraries and the necessary testing frameworks.
50-68
: Strong test implementation for environment variable handling!The test demonstrates good practices with proper cleanup of both temporary directory and environment variables. The assertions are clear and meaningful.
pkg/config/base_path.go (2)
1-11
: Clean and well-organized imports, warrior! 🛡️The package structure and import organization follow Go best practices.
122-142
: Excellent Git root resolution implementation, champion! 🏆The function is well-documented, handles errors appropriately, and effectively uses the go-git library.
// test base_path Set in Configuration | ||
func TestBasePathComputingWithBasePathSetInConfiguration(t *testing.T) { | ||
tempDir, err := os.MkdirTemp("", "config-test") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
defer os.RemoveAll(tempDir) | ||
configLoader := &ConfigLoader{} | ||
configLoader.atmosConfig.BasePath = tempDir | ||
info := schema.ConfigAndStacksInfo{ | ||
BasePathFromArg: "", | ||
} | ||
expectedPath, _ := filepath.Abs(tempDir) | ||
result, err := configLoader.BasePathComputing(info) | ||
assert.NoError(t, err) | ||
assert.Equal(t, expectedPath, result) | ||
// test base pat not abs directory | ||
// change pwd to temp | ||
startingDir, err := os.Getwd() | ||
if err != nil { | ||
fmt.Printf("Failed to get the current working directory: %v\n", err) | ||
os.Exit(1) // Exit with a non-zero code to indicate failure | ||
} | ||
defer func() { | ||
// Change back to the original working directory after the test | ||
if err := os.Chdir(startingDir); err != nil { | ||
t.Fatalf("Failed to change back to the starting directory: %v", err) | ||
} | ||
}() | ||
err = os.Chdir(tempDir) | ||
if err != nil { | ||
t.Fatalf("Failed to change directory to %q: %v", tempDir, err) | ||
} | ||
// dir under temp | ||
subDirTemp := filepath.Join(tempDir, "sub-dir") | ||
err = os.Mkdir(subDirTemp, 0755) | ||
if err != nil { | ||
t.Fatalf("Failed to create directory %q: %v", subDirTemp, err) | ||
} | ||
expectedPath, _ = filepath.Abs(subDirTemp) | ||
|
||
configLoader.atmosConfig.BasePath = "sub-dir" | ||
result, err = configLoader.BasePathComputing(info) | ||
assert.NoError(t, err) | ||
assert.Equal(t, expectedPath, result) | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Improve error handling and test practices.
While the test is comprehensive, there are several areas for improvement:
- Fix the comment formatting and typo:
- // test base_path Set in Configuration
+ // test base_path set in configuration
- Replace
os.Exit(1)
witht.Fatal
:
- fmt.Printf("Failed to get the current working directory: %v\n", err)
- os.Exit(1) // Exit with a non-zero code to indicate failure
+ t.Fatalf("Failed to get the current working directory: %v", err)
- Consider using helper functions to reduce the repetitive error handling code and improve readability. For example:
func createTestDir(t *testing.T, parent, name string) string {
t.Helper()
path := filepath.Join(parent, name)
if err := os.Mkdir(path, 0755); err != nil {
t.Fatalf("Failed to create directory %q: %v", path, err)
}
return path
}
This would simplify the test setup and make it more maintainable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
pkg/config/con.go (4)
25-25
: Follow Go naming conventions for constants.The constant
MaximumImportLvL
should be renamed tomaximumImportLevel
ormaxImportLevel
for better readability and consistency with Go naming conventions.-const MaximumImportLvL = 10 +const maxImportLevel = 10🧰 Tools
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
693-697
: Useerrors.New
for static error messages.When creating an error with a static message, use
errors.New
instead offmt.Errorf
.- errorMessage := fmt.Sprintf("\nno stack manifests found in the provided "+ - "paths:\n%s\n\nCheck if `base_path`, 'stacks.base_path', 'stacks.included_paths' and 'stacks.excluded_paths' are correctly set in CLI config "+ - "files or ENV vars.", j) - return fmt.Errorf(errorMessage) + return fmt.Errorf("\nno stack manifests found in the provided paths:\n%s\n\nCheck if `base_path`, 'stacks.base_path', 'stacks.included_paths' and 'stacks.excluded_paths' are correctly set in CLI config files or ENV vars", j)🧰 Tools
🪛 golangci-lint (1.62.2)
696-696: printf: non-constant format string in call to fmt.Errorf
(govet)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
906-922
: Remove unused functionfindGitTopLevel
.The function
findGitTopLevel
is not used anywhere in the codebase. Consider removing it or documenting why it's kept for future use.🧰 Tools
🪛 golangci-lint (1.62.2)
906-906: func
findGitTopLevel
is unused(unused)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
874-874
: Use proper string formatting in warning message.Replace string concatenation with proper formatting using
fmt.Sprintf
.- u.LogWarning(atmosConfig, fmt.Sprintf("error closing file '"+path+"'. "+err.Error())) + u.LogWarning(atmosConfig, fmt.Sprintf("error closing file '%s': %v", path, err))🧰 Tools
🪛 golangci-lint (1.62.2)
874-874: printf: non-constant format string in call to fmt.Sprintf
(govet)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
pkg/config/base_path.go
(1 hunks)pkg/config/con.go
(1 hunks)pkg/config/imports.go
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- pkg/config/base_path.go
- pkg/config/imports.go
🧰 Additional context used
🪛 golangci-lint (1.62.2)
pkg/config/con.go
532-532: Error return value of cl.deepMergeConfig
is not checked
(errcheck)
906-906: func findGitTopLevel
is unused
(unused)
696-696: printf: non-constant format string in call to fmt.Errorf
(govet)
874-874: printf: non-constant format string in call to fmt.Sprintf
(govet)
809-809: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
🪛 GitHub Actions: Tests
pkg/config/con.go
[error] Invalid file path detected during git checkout process
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Summary
🔇 Additional comments (2)
pkg/config/con.go (2)
532-532
:⚠️ Potential issueHandle the error returned by
deepMergeConfig
.The error returned by
deepMergeConfig
should be checked to ensure proper error handling.- cl.deepMergeConfig() + if err := cl.deepMergeConfig(); err != nil { + return err + }Likely invalid or redundant comment.
🧰 Tools
🪛 golangci-lint (1.62.2)
532-532: Error return value of
cl.deepMergeConfig
is not checked(errcheck)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
809-809
:⚠️ Potential issueAddress unused HasSuffix result.
The result of
strings.HasSuffix
is computed but not used. This might indicate a logical error.- } else if ext == ".yml" && strings.HasSuffix(existingFile, ".yaml") { + } else if ext == ".yml" { + // If you need to check for .yaml suffix, use the result + if strings.HasSuffix(existingFile, ".yaml") { + continue // Skip if it's a .yml file but has .yaml suffix + }Likely invalid or redundant comment.
🧰 Tools
🪛 golangci-lint (1.62.2)
809-809: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (5)
pkg/config/base_path_test.go (3)
33-33
: Fix typo in comment.- // test base pat not directory + // test base path not directory
70-70
: Fix typo and formatting in comment.-// test base_path Set in Configuration +// test base_path set in configuration
118-118
: Fix typo in comment.-// test base path form "!repo-root" +// test base path from "!repo-root"pkg/config/base_path.go (1)
26-26
: Remove duplicate comment.- // Check base path from configuration
pkg/config/con.go (1)
874-874
: Simplify string formatting.No need to use
fmt.Sprintf
when the argument is already a string.- u.LogWarning(atmosConfig, fmt.Sprintf("%s", "error closing file '"+path+"'. "+err.Error())) + u.LogWarning(atmosConfig, fmt.Sprintf("error closing file '%s': %v", path, err))🧰 Tools
🪛 golangci-lint (1.62.2)
874-874: S1025: the argument is already a string, there's no need to use fmt.Sprintf
(gosimple)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
pkg/config/base_path.go
(1 hunks)pkg/config/base_path_test.go
(1 hunks)pkg/config/con.go
(1 hunks)
🧰 Additional context used
🪛 golangci-lint (1.62.2)
pkg/config/base_path_test.go
28-28: ineffectual assignment to expectedPath
(ineffassign)
pkg/config/con.go
532-532: Error return value of cl.deepMergeConfig
is not checked
(errcheck)
906-906: func findGitTopLevel
is unused
(unused)
874-874: S1025: the argument is already a string, there's no need to use fmt.Sprintf
(gosimple)
696-696: printf: non-constant format string in call to fmt.Errorf
(govet)
809-809: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
🪛 GitHub Actions: Tests
pkg/config/con.go
[error] Invalid file path detected during git checkout process
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Summary
🔇 Additional comments (9)
pkg/config/base_path_test.go (2)
13-48
: Well-structured test cases covering all scenarios!The test suite comprehensively covers various base path computation scenarios:
- Base path from CLI argument
- Base path from environment variable
- Base path from configuration
- Base path from repo root
Good job on including both positive and negative test cases, and proper cleanup using
defer
.Also applies to: 51-68, 71-116, 119-134
🧰 Tools
🪛 golangci-lint (1.62.2)
28-28: ineffectual assignment to expectedPath
(ineffassign)
89-92
:⚠️ Potential issueReplace os.Exit(1) with t.Fatal in test.
Using
os.Exit(1)
in tests is not recommended as it prevents proper test cleanup and reporting.Apply this diff to fix the issue:
- fmt.Printf("Failed to get the current working directory: %v\n", err) - os.Exit(1) // Exit with a non-zero code to indicate failure + t.Fatalf("Failed to get the current working directory: %v", err)Likely invalid or redundant comment.
pkg/config/base_path.go (3)
13-72
: Well-structured base path resolution with clear priority!The
BasePathComputing
function implements a clear priority order for resolving the base path:
- CLI argument
- Environment variable
- Configuration
- Inferred path
Good job on the comprehensive error handling and path validation.
133-152
: Clean Git root resolution implementation!The
GetGitRoot
function:
- Uses proper error wrapping
- Provides clear error messages
- Returns absolute paths
123-124
:⚠️ Potential issueFix incorrect variable in logging statement.
The logging statement uses
filePath
which is not updated in this code path. It should usedirAbs
instead.- cl.debugLogging(fmt.Sprintf("base path from infra %s: %s", "git root", filePath)) + cl.debugLogging(fmt.Sprintf("base path from infra %s: %s", "git root", dirAbs))Likely invalid or redundant comment.
pkg/config/con.go (4)
48-144
: Well-structured configuration loading process!The
LoadConfig
function implements a clear and systematic approach to loading configurations:
- Schema defaults
- Embedded config
- Explicit configs
- System configs
- User preferences
- Additional configs
Good job on the comprehensive error handling and configuration merging strategy.
🧰 Tools
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
696-696
:⚠️ Potential issueUse errors.New for static error messages.
Using
fmt.Errorf
with a non-constant format string could lead to issues if the string contains format verbs.- return fmt.Errorf(errorMessage) + return errors.New(errorMessage)Likely invalid or redundant comment.
🧰 Tools
🪛 golangci-lint (1.62.2)
696-696: printf: non-constant format string in call to fmt.Errorf
(govet)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
532-532
:⚠️ Potential issueCheck error returned by deepMergeConfig.
The error from
deepMergeConfig
should be checked and handled appropriately.- cl.deepMergeConfig() + if err := cl.deepMergeConfig(); err != nil { + return fmt.Errorf("failed to merge config after imports: %w", err) + }Likely invalid or redundant comment.
🧰 Tools
🪛 golangci-lint (1.62.2)
532-532: Error return value of
cl.deepMergeConfig
is not checked(errcheck)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
809-809
:⚠️ Potential issueUse HasSuffix result in condition.
The result of
HasSuffix
is computed but not used.- } else if ext == ".yml" && strings.HasSuffix(existingFile, ".yaml") { + } else if ext == ".yml" { + if strings.HasSuffix(existingFile, ".yaml") { + continue // Skip .yml if .yaml exists + }Likely invalid or redundant comment.
🧰 Tools
🪛 golangci-lint (1.62.2)
809-809: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
info.BasePathFromArg = "invalid/path" | ||
expectedPath, _ = filepath.Abs("invalid/path") | ||
result, err = configLoader.BasePathComputing(info) | ||
assert.Error(t, err) | ||
assert.Equal(t, "", result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove ineffectual assignment.
The expectedPath
variable is assigned but never used in the error case.
Apply this diff to fix the issue:
- expectedPath, _ = filepath.Abs("invalid/path")
result, err = configLoader.BasePathComputing(info)
assert.Error(t, err)
assert.Equal(t, "", result)
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
info.BasePathFromArg = "invalid/path" | |
expectedPath, _ = filepath.Abs("invalid/path") | |
result, err = configLoader.BasePathComputing(info) | |
assert.Error(t, err) | |
assert.Equal(t, "", result) | |
info.BasePathFromArg = "invalid/path" | |
result, err = configLoader.BasePathComputing(info) | |
assert.Error(t, err) | |
assert.Equal(t, "", result) |
🧰 Tools
🪛 golangci-lint (1.62.2)
28-28: ineffectual assignment to expectedPath
(ineffassign)
func findGitTopLevel(startDir string) (string, error) { | ||
// Open the current directory as a billy filesystem | ||
fs := osfs.New(startDir) | ||
// Create a filesystem-based storage for Git (this allows us to traverse Git config) | ||
storer := filesystem.NewStorage(fs, nil) | ||
// Create a new repository from the storage | ||
repo, err := git.Open(storer, fs) | ||
if err != nil { | ||
return "", fmt.Errorf("not a git repository: %w", err) | ||
} | ||
// Get the repository's top-level directory from the configuration | ||
worktree, err := repo.Worktree() | ||
if err != nil { | ||
return "", fmt.Errorf("failed to get worktree: %w", err) | ||
} | ||
return worktree.Filesystem.Root(), nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Remove unused function findGitTopLevel.
The function findGitTopLevel
is not used anywhere in the codebase. Either remove it or use it to replace similar functionality in getGitRepoRoot
.
-// findGitTopLevel finds the top-level directory of a Git repository
-func findGitTopLevel(startDir string) (string, error) {
- // Open the current directory as a billy filesystem
- fs := osfs.New(startDir)
- // Create a filesystem-based storage for Git (this allows us to traverse Git config)
- storer := filesystem.NewStorage(fs, nil)
- // Create a new repository from the storage
- repo, err := git.Open(storer, fs)
- if err != nil {
- return "", fmt.Errorf("not a git repository: %w", err)
- }
- // Get the repository's top-level directory from the configuration
- worktree, err := repo.Worktree()
- if err != nil {
- return "", fmt.Errorf("failed to get worktree: %w", err)
- }
- return worktree.Filesystem.Root(), nil
-}
🧰 Tools
🪛 golangci-lint (1.62.2)
906-906: func findGitTopLevel
is unused
(unused)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
pkg/config/con.go (4)
25-25
: Consider renaming constant for consistency with Go naming conventions.The constant
MaximumImportLvL
should be renamed tomaximumImportLevel
ormaxImportLevel
for better readability and consistency with Go naming conventions.-const MaximumImportLvL = 10 +const maxImportLevel = 10🧰 Tools
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
27-37
: Add documentation for struct types.Consider adding documentation comments for both structs to explain their purpose and fields. This will improve code maintainability and help other developers understand the code better.
+// Imports represents a configuration import with its path and nesting level type Imports struct { Path string Level int } +// ConfigLoader handles the loading and management of Atmos configuration +// from various sources including files, environment variables, and defaults type ConfigLoader struct { viper *viper.Viper atmosConfig schema.AtmosConfiguration configFound bool debug bool AtmosConfigPaths []string }🧰 Tools
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
950-966
: Remove or utilize unused function findGitTopLevel.The
findGitTopLevel
function is well-implemented but currently unused. Consider either removing it or replacing the similar functionality ingetGitRepoRoot
with this implementation.🧰 Tools
🪛 golangci-lint (1.62.2)
950-950: func
findGitTopLevel
is unused(unused)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
918-918
: Simplify string formatting.The argument is already a string, making
fmt.Sprintf
unnecessary here.- u.LogWarning(atmosConfig, fmt.Sprintf("%s", "error closing file '"+path+"'. "+err.Error())) + u.LogWarning(atmosConfig, "error closing file '"+path+"'. "+err.Error())🧰 Tools
🪛 golangci-lint (1.62.2)
918-918: S1025: the argument is already a string, there's no need to use fmt.Sprintf
(gosimple)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
pkg/config/con.go
(1 hunks)
🧰 Additional context used
🪛 golangci-lint (1.62.2)
pkg/config/con.go
576-576: Error return value of cl.deepMergeConfig
is not checked
(errcheck)
238-238: func (*ConfigLoader).loadSystemAndUserConfigs
is unused
(unused)
950-950: func findGitTopLevel
is unused
(unused)
918-918: S1025: the argument is already a string, there's no need to use fmt.Sprintf
(gosimple)
740-740: printf: non-constant format string in call to fmt.Errorf
(govet)
853-853: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
🪛 GitHub Actions: Tests
pkg/config/con.go
[error] Invalid file path detected during git checkout process
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Summary
🔇 Additional comments (4)
pkg/config/con.go (4)
853-854
:⚠️ Potential issueFix unused HasSuffix result in condition.
The result of
strings.HasSuffix
is computed but not used in the condition, which might indicate a logical error.- } else if ext == ".yml" && strings.HasSuffix(existingFile, ".yaml") { + } else if ext == ".yml" && !strings.HasSuffix(existingFile, ".yaml") { continue // Keep .yaml priorityLikely invalid or redundant comment.
🧰 Tools
🪛 golangci-lint (1.62.2)
853-853: SA4017: HasSuffix doesn't have side effects and its return value is ignored
(staticcheck)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
576-576
:⚠️ Potential issueHandle error returned by deepMergeConfig.
The error returned by
deepMergeConfig
is not being checked, which could lead to silent failures.- cl.deepMergeConfig() + if err := cl.deepMergeConfig(); err != nil { + u.LogWarning(cl.atmosConfig, fmt.Sprintf("failed to merge configuration: %v", err)) + continue + }Likely invalid or redundant comment.
🧰 Tools
🪛 golangci-lint (1.62.2)
576-576: Error return value of
cl.deepMergeConfig
is not checked(errcheck)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
740-741
:⚠️ Potential issueImprove error message formatting.
The error message uses string concatenation which could lead to formatting issues. Use
fmt.Errorf
with proper formatting verbs.- return fmt.Errorf(errorMessage) + return fmt.Errorf("no stack manifests found in the provided paths:\n%s\n\nCheck if `base_path`, 'stacks.base_path', 'stacks.included_paths' and 'stacks.excluded_paths' are correctly set in CLI config files or ENV vars", j)Likely invalid or redundant comment.
🧰 Tools
🪛 golangci-lint (1.62.2)
740-740: printf: non-constant format string in call to fmt.Errorf
(govet)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
238-238
: Verify usage of loadSystemAndUserConfigs method.The
loadSystemAndUserConfigs
method appears to contain important configuration loading logic but is currently unused. Either remove it if it's no longer needed or integrate it into the configuration loading flow.✅ Verification successful
Confirmed: loadSystemAndUserConfigs method is unused
The method is indeed unused in the codebase. No calls to this method were found, and it's not required by any interfaces. Consider either integrating it into the configuration loading flow or removing it to maintain code cleanliness.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for any usage of loadSystemAndUserConfigs rg -l "loadSystemAndUserConfigs" --type goLength of output: 60
Script:
#!/bin/bash # Search for method calls and context echo "=== Method calls ===" rg "loadSystemAndUserConfigs" -B 2 -A 2 --type go echo -e "\n=== Potential interface definitions ===" ast-grep --pattern 'type $_ interface { $$$ loadSystemAndUserConfigs($$$) $$$ }'Length of output: 640
🧰 Tools
🪛 golangci-lint (1.62.2)
238-238: func
(*ConfigLoader).loadSystemAndUserConfigs
is unused(unused)
🪛 GitHub Actions: Tests
[error] Invalid file path detected during git checkout process
what
atmos.d
convention foratmos.yaml
configuration, allowing automatic inclusion of configuration files from the atmos.d directory.import
key inside `atmos.yaml, allowing users to define a list of locations (local files, directories using glob patterns, and remote URLs) to import configurations from.ATMOS_CLI_CONFIG_PATH
andATMOS_BASE_PATH
before running terraform and helm cmdexamples/demo-env
that shows exposed env variablesexamples/demo-atmos-cli-imports
for custom inclusion of configuration files from the atmos.d directoryexamples/demo-atmos.d
for automatic inclusion of configuration files from the atmos.d directorywhy
Simplifies configuration management, enabling overrides at multiple levels of processing, making it easier to include additional configurations without explicit declarations.
Details
Load Config
3 Stages
Base Path
references
Summary by CodeRabbit
Release Notes
New Features
Configuration Improvements
CLI Enhancements
--base-path
flag for specifying Atmos configuration file locations.--config
flag for defining multiple configuration file paths.Compatibility
Documentation