Skip to content
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

Fix Vendoring Issues with Globs and Symlinks #984

Open
wants to merge 84 commits into
base: main
Choose a base branch
from
Open

Conversation

Listener430
Copy link
Collaborator

@Listener430 Listener430 commented Jan 29, 2025

what

Done:

  1. append //. at the end to github repo url (in order to clone entire repo)
  2. Removed any symlinks inside go-getter
  3. Fixed support for double star globs in excluded_paths and included_paths:
    included_paths:
      - "**/{demo-library,demo-stacks}/**/*.{tf,md}"
    excluded_paths:
      - "**/demo-library/**/*.{tfvars,tf}"
    
  4. Added test to vendoring scenario in fixtures
  5. Added depth=1 for all github downloads through custom detector
  6. Breaking change: * now correctly matches a single segment. Anyone using a single star to match multiple segments should change it to **. This should never have matched multiple segments so long as double star was supposed to work.

why

  • double star globs were not correctly matching multiple segments in all cases
  • vendoring without a shallow depth is 2x slower
  • the //. is an esoteric expression to copy all files from the root. Rather than expect users to know this, we default it where it makes sense.

references

Summary by CodeRabbit

  • New Features

    • Enhanced Git repository handling now supports multiple hosts, shallow cloning, and improved URL normalization.
    • Advanced file copying with glob pattern matching offers flexible control over file inclusion and exclusion.
    • Added URL masking to safeguard sensitive credentials.
    • New YAML configuration files for vendor components and settings.
    • New test case for validating atmos vendor pull command with glob patterns.
  • Documentation

    • Introduced a new "Vendoring with Globs" guide to help configure file selection rules more effectively.
  • Tests

    • Expanded automated test scenarios to validate improved file operations and vendor pull functionality.
    • Added tests for file copying and path exclusion/inclusion functionalities.
    • Introduced validation for file non-existence in CLI command tests.
    • Comprehensive unit tests for file copying and path management functionalities.
    • New tests for verifying file operations within the context of glob patterns.
  • Chores

    • Updated linter settings to adjust complexity thresholds and maximum lines for functions.
    • Added new dependency for enhanced testing capabilities.
  • Bug Fixes

    • Improved error handling and reporting for various operations, enhancing clarity and maintainability.

@Listener430 Listener430 added the bugfix Change that restores intended behavior label Jan 29, 2025
@Listener430 Listener430 self-assigned this Jan 29, 2025
@Listener430 Listener430 requested a review from a team as a code owner January 29, 2025 18:30
@Listener430 Listener430 requested a review from osterman January 29, 2025 18:31
Copy link
Contributor

coderabbitai bot commented Jan 29, 2025

📝 Walkthrough

Walkthrough

The changes update various components in the project. In the exec package, enhancements were made to Git URL handling by renaming detectors, adding new fields, refining URL parsing and logging, and introducing a new custom getter that removes symlinks post-clone. Several functions now receive the atmosConfig parameter by reference instead of by value. A new file providing advanced glob-based file copying was added, and comprehensive tests were introduced, including CLI test improvements that validate both file presence and non-existence. Additionally, documentation and configuration files were updated to support vendoring with glob patterns, while the cyclomatic threshold in the linter configuration was raised.

Changes

File(s) Change Summary
internal/exec/go_getter_utils.go Renamed CustomGitHubDetector to CustomGitDetector, added a source field, new CustomGitGetter type with a Get method, enhanced URL processing (logging, scheme enforcement, normalization), modularized token injection, and introduced symlink removal. Also updated RegisterCustomDetectors and DownloadDetectFormatAndParseFile signatures.
internal/exec/{vendor_model.go, validate_stacks.go, vendor_component_utils.go, vendor_model_component.go, yaml_func_include.go} Updated multiple functions to pass the atmosConfig parameter by reference instead of by value, adjusting signatures accordingly.
internal/exec/copy_glob.go New file implementing file/directory copying with advanced glob pattern matching, error handling, and functions such as copyFile, shouldExcludePath, copyDirRecursive, and others.
tests/cli_test.go, tests/test-cases/demo-globs.yaml, tests/fixtures/scenarios/vendor/vendor.yaml Introduced a new FileNotExists field and helper validation in CLI tests; added a new test case (atmos_vendor_pull_with_globs) with detailed file existence/non-existence expectations; minor formatting update in a vendor YAML file.
website/docs/core-concepts/vendor/vendor-manifest.mdx Added a new "Vendoring with Globs" section to document the use of glob patterns in vendoring configurations with examples.
pkg/utils/url_utils.go Added the MaskBasicAuth function to mask credentials in URLs.
tests/fixtures/scenarios/vendor-globs/{atmos.yaml, vendor.yaml} New configuration files defining vendoring settings with support for glob patterns.
.golangci.yml Increased the cyclomatic complexity threshold from 10 to 13.
internal/exec/copy_glob_test.go New file with unit tests for validating file copying and glob pattern matching functionalities.

Possibly related PRs

  • Fixed an issue with vendor.yaml source failing to accept git::ssh URI #1054: The changes in the main PR are related to those in the retrieved PR as both modify the internal/exec/go_getter_utils.go file, specifically enhancing the handling of Git repository URLs, including the addition of new schemes for URI validation.
  • fix(vendor): Remove excessive URL validation #1024: The changes in the main PR, specifically the modifications to the CustomGitDetector and its methods in go_getter_utils.go, are related to the changes in the retrieved PR, which also involves the go_getter_utils.go file, particularly in the context of URL validation and handling.
  • refactor loading and checking of atmos config #869: The changes in the main PR involve modifications to the atmosConfig parameter, specifically passing it as a pointer in various functions, which aligns with the changes in the retrieved PR that also updates checkAtmosConfig to accept a pointer to schema.AtmosConfiguration.

Suggested labels

patch


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4e640c9 and 447a305.

📒 Files selected for processing (1)
  • .golangci.yml (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .golangci.yml
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Build (ubuntu-latest, linux)
  • GitHub Check: website-deploy-preview
  • GitHub Check: Analyze (go)
  • GitHub Check: Summary

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary or @auto-summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @auto-title anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 (2)
internal/exec/go_getter_utils.go (2)

160-168: Eliminate potential duplication with existing logic.

This RegisterCustomGetters seems to mirror the RegisterCustomDetectors pattern. Consider centralizing shared logic or converting both into a unified registration function to reduce redundancy.


207-220: Consider configurable symlink removal.

Automatically stripping symlinks is helpful, but give the user control to skip or confirm. This might be vital for some use cases or compliance requirements.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 255a05a and f9b3348.

📒 Files selected for processing (1)
  • internal/exec/go_getter_utils.go (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Analyze (go)
  • GitHub Check: Summary
🔇 Additional comments (3)
internal/exec/go_getter_utils.go (3)

102-109: Check for potential unintended path expansion.

Appending //. whenever the path ends with .git or has only three parts might impact cases where the user wants to download a subdirectory. Confirm that this logic is aligned with user expectations.


188-199: Good approach for overriding the default getters.

Overriding 'git' with a custom implementation is a practical solution. Be sure to keep an eye on future expansions (like s3, gcs) if needed.


222-236: Validate error handling on symlink removal.

If removing a symlink fails due to permission errors or other reasons, you might want more detailed logging or fallback behavior. Evaluate whether to continue, warn, or halt.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 29, 2025
@osterman
Copy link
Member

Please add a test for this type of vendoring. It can be in the vendoring scenario we already have.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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)
internal/exec/go_getter_utils.go (1)

202-231: Enhance symlink handling with additional safeguards.

While the implementation is functional, consider these improvements:

  1. Pass AtmosConfig to removeSymlinks instead of using an empty config
  2. Add protection against circular symlinks
  3. Log removed symlink details for audit purposes

Here's a suggested enhancement:

 type CustomGitGetter struct {
     getter.GitGetter
+    AtmosConfig schema.AtmosConfiguration
 }

 func (c *CustomGitGetter) Get(dst string, url *url.URL) error {
     if err := c.GitGetter.Get(dst, url); err != nil {
         return err
     }
-    return removeSymlinks(dst)
+    return removeSymlinks(dst, c.AtmosConfig)
 }

-func removeSymlinks(root string) error {
+func removeSymlinks(root string, config schema.AtmosConfiguration) error {
+    visited := make(map[string]bool)
     return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
         if err != nil {
             return err
         }
         if info.Mode()&os.ModeSymlink != 0 {
+            // Check for circular symlinks
+            realPath, err := filepath.EvalSymlinks(path)
+            if err != nil {
+                return fmt.Errorf("failed to evaluate symlink %s: %w", path, err)
+            }
+            if visited[realPath] {
+                return fmt.Errorf("circular symlink detected: %s", path)
+            }
+            visited[realPath] = true
+
+            // Log symlink details before removal
+            target, _ := os.Readlink(path)
-            u.LogWarning(schema.AtmosConfiguration{}, fmt.Sprintf("Removing symlink: %s", path))
+            u.LogWarning(config, fmt.Sprintf("Removing symlink: %s -> %s", path, target))
             return os.Remove(path)
         }
         return nil
     })
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f9b3348 and ed1af3d.

📒 Files selected for processing (1)
  • internal/exec/go_getter_utils.go (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Summary
🔇 Additional comments (4)
internal/exec/go_getter_utils.go (4)

73-73: LGTM! Field addition enhances URL handling capabilities.

The addition of the source field to store the original URL is a clean enhancement.


151-157: LGTM! Clean function signature update.

The modification properly propagates the source URL to the detector while maintaining the existing detector registration logic.


171-194: LGTM! Well-documented changes with secure defaults.

The changes are well-documented and the getters map provides a comprehensive set of protocols. Good security practice to have S3 and GCS getters disabled by default.


103-109: LGTM! Clean implementation of top-level repository detection.

The logic correctly handles bare repository URLs by appending "//." when appropriate. The debug logging provides good visibility into the decision-making process.

Let's verify the URL transformation behavior:

✅ Verification successful

URL handling logic is correctly implemented and follows go-getter conventions! 💪

The code properly handles repository URLs by:

  • Detecting bare repository URLs (without subdirectories)
  • Adding "//." suffix only when needed (for .git URLs or standard org/repo formats)
  • Maintaining compatibility with go-getter's URL format requirements
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Test various GitHub URL patterns to ensure correct handling
echo "Testing URL transformations..."

# Create a test file
cat << 'EOF' > test.go
package main

import (
    "fmt"
    "os"
    u "github.com/cloudposse/atmos/pkg/utils"
)

func main() {
    detector := &CustomGitHubDetector{source: os.Args[1]}
    result, ok, err := detector.Detect(os.Args[1], "")
    fmt.Printf("Input: %s\nOutput: %s\nOK: %v\nErr: %v\n", os.Args[1], result, ok, err)
}
EOF

# Test cases
urls=(
    "github.com/org/repo.git"
    "github.com/org/repo"
    "github.com/org/repo/subdir"
)

for url in "${urls[@]}"; do
    echo "Testing URL: $url"
    go run test.go "$url"
    echo "---"
done

Length of output: 6203


Script:

#!/bin/bash
# Find the URL handling implementation
echo "Searching for URL handling implementation..."
ast-grep --pattern 'type $_ struct {
  source string
  $$$
}'

echo -e "\nSearching for Detect method implementation..."
ast-grep --pattern 'func ($_ $_) Detect($_, $_) ($_, $_, error) {
  $$$
}'

echo -e "\nSearching for URL parsing logic..."
rg -A 5 'strings\.Contains.*"//"' --type go

Length of output: 998

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 30, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 (2)
internal/exec/copy_glob.go (1)

168-255: Consider simplifying copyToTargetWithPatterns.

The function logic is clear, but the length and multiple branches make it complex. Splitting out smaller helper functions (e.g., for handling the included vs excluded paths) might improve maintainability and ease of unit testing.

🧰 Tools
🪛 GitHub Check: Build (macos-latest, macos)

[failure] 184-184:
too many arguments in call to u.LogTrace

🪛 GitHub Check: Build (ubuntu-latest, linux)

[failure] 184-184:
too many arguments in call to u.LogTrace

tests/fixtures/scenarios/vendor/vendor.yaml (1)

54-64: Add a test case to validate the newly introduced globs.

The expanded vendor configuration is helpful for controlling which files are included or excluded. Remember to add or update an integration test verifying that only .tf and .md files are included while .tfvars files are excluded for this source.

Would you like help creating a dedicated test that specifically checks the behavior of these globs?

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ed1af3d and 5a6789e.

📒 Files selected for processing (4)
  • internal/exec/copy_glob.go (1 hunks)
  • internal/exec/vendor_model.go (1 hunks)
  • tests/fixtures/scenarios/vendor/vendor.yaml (1 hunks)
  • tests/test-cases/demo-stacks.yaml (1 hunks)
🧰 Additional context used
🪛 GitHub Check: Build (macos-latest, macos)
internal/exec/copy_glob.go

[failure] 55-55:
too many arguments in call to u.LogTrace


[failure] 64-64:
too many arguments in call to u.LogTrace


[failure] 67-67:
too many arguments in call to u.LogTrace


[failure] 78-78:
too many arguments in call to u.LogTrace


[failure] 81-81:
too many arguments in call to u.LogTrace


[failure] 87-87:
too many arguments in call to u.LogTrace


[failure] 119-119:
too many arguments in call to u.LogTrace


[failure] 157-157:
too many arguments in call to u.LogTrace


[failure] 162-162:
too many arguments in call to u.LogTrace


[failure] 184-184:
too many arguments in call to u.LogTrace

🪛 GitHub Check: Build (ubuntu-latest, linux)
internal/exec/copy_glob.go

[failure] 55-55:
too many arguments in call to u.LogTrace


[failure] 64-64:
too many arguments in call to u.LogTrace


[failure] 67-67:
too many arguments in call to u.LogTrace


[failure] 78-78:
too many arguments in call to u.LogTrace


[failure] 81-81:
too many arguments in call to u.LogTrace


[failure] 87-87:
too many arguments in call to u.LogTrace


[failure] 119-119:
too many arguments in call to u.LogTrace


[failure] 157-157:
too many arguments in call to u.LogTrace


[failure] 162-162:
too many arguments in call to u.LogTrace


[failure] 184-184:
too many arguments in call to u.LogTrace

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Summary
🔇 Additional comments (2)
internal/exec/vendor_model.go (1)

310-310: Switching to copyToTargetWithPatterns looks good.

This change aligns with the new glob-handling logic. The final code is consistent with the PR’s objective to support inclusion and exclusion patterns.

tests/test-cases/demo-stacks.yaml (1)

196-204: Enhanced Vendoring File Checks Added

The new file existence entries in the "atmos_vendor_pull" test bolster the validation of the vendoring process. They ensure that the expected files from both the demo-library and demo-stacks components are present after cloning and post-symlink removal. This aligns well with the PR objectives addressing glob functionality and symlink handling.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 (2)
internal/exec/go_getter_utils.go (2)

202-215: Consider enhancing error context.

While the implementation is solid, consider wrapping the errors with additional context to aid in debugging:

 func (c *CustomGitGetter) Get(dst string, url *url.URL) error {
 	// Normal clone
 	if err := c.GitGetter.Get(dst, url); err != nil {
-		return err
+		return fmt.Errorf("git clone failed for %s: %w", url, err)
 	}
 	// Remove symlinks
-	return removeSymlinks(dst)
+	if err := removeSymlinks(dst); err != nil {
+		return fmt.Errorf("failed to remove symlinks in %s: %w", dst, err)
+	}
+	return nil
 }

219-231: Consider adding path validation and detailed logging.

The symlink removal implementation could be enhanced with additional safety checks and logging:

 func removeSymlinks(root string) error {
+	// Validate root path
+	if _, err := os.Stat(root); err != nil {
+		return fmt.Errorf("invalid root path %s: %w", root, err)
+	}
+
 	return filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
 		if err != nil {
 			return err
 		}
 		if info.Mode()&os.ModeSymlink != 0 {
-			u.LogWarning(schema.AtmosConfiguration{}, fmt.Sprintf("Removing symlink: %s", path))
+			target, err := os.Readlink(path)
+			if err != nil {
+				return fmt.Errorf("failed to read symlink %s: %w", path, err)
+			}
+			u.LogWarning(schema.AtmosConfiguration{}, fmt.Sprintf("Removing symlink: %s -> %s", path, target))
 			// It's a symlink, remove it
-			return os.Remove(path)
+			if err := os.Remove(path); err != nil {
+				return fmt.Errorf("failed to remove symlink %s: %w", path, err)
+			}
 		}
 		return nil
 	})
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4fdffa3 and b8d7a5a.

📒 Files selected for processing (2)
  • internal/exec/go_getter_utils.go (4 hunks)
  • internal/exec/vendor_model.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/exec/vendor_model.go
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Summary
🔇 Additional comments (2)
internal/exec/go_getter_utils.go (2)

71-74: LGTM! Smart handling of top-level repository cloning.

The addition of the source field and the logic to append "//." for top-level repositories is a solid improvement. This ensures proper cloning behavior when no subdirectory is specified.

Also applies to: 103-109


151-155: LGTM! Well-documented parameter addition.

The addition of the source parameter and the detailed comments explaining its purpose make the code's intent clear and maintainable.

Also applies to: 171-175

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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)
internal/exec/copy_glob.go (1)

47-92: ⚠️ Potential issue

Fix LogTrace calls to match the updated function signature.

Based on the pipeline failures and past review comments, the LogTrace calls need to be updated.

Apply this fix to all LogTrace calls in the function:

-    u.LogTrace(atmosConfig, fmt.Sprintf("Error computing relative path for %q: %v", srcPath, err))
+    u.LogTrace(fmt.Sprintf("Error computing relative path for %q: %v", srcPath, err))
🧹 Nitpick comments (4)
internal/exec/copy_glob.go (3)

16-45: Consider handling errors from deferred Close() calls.

While the implementation is solid, it's good practice to handle errors from Close() operations, especially for the destination file where data corruption could occur.

Here's how you could improve the error handling:

 func copyFile(atmosConfig schema.AtmosConfiguration, src, dst string) error {
     sourceFile, err := os.Open(src)
     if err != nil {
         return fmt.Errorf("opening source file %q: %w", src, err)
     }
-    defer sourceFile.Close()
+    defer func() {
+        if cerr := sourceFile.Close(); cerr != nil && err == nil {
+            err = fmt.Errorf("closing source file %q: %w", src, cerr)
+        }
+    }()
 
     if err := os.MkdirAll(filepath.Dir(dst), os.ModePerm); err != nil {
         return fmt.Errorf("creating destination directory for %q: %w", dst, err)
     }
 
     destinationFile, err := os.Create(dst)
     if err != nil {
         return fmt.Errorf("creating destination file %q: %w", dst, err)
     }
-    defer destinationFile.Close()
+    defer func() {
+        if cerr := destinationFile.Close(); cerr != nil && err == nil {
+            err = fmt.Errorf("closing destination file %q: %w", dst, cerr)
+        }
+    }()

139-166: Consider extracting pattern suffixes as constants.

The pattern matching logic is well-implemented, but the magic strings could be made more maintainable.

Consider this improvement:

+const (
+    singleLevelGlob = "/*"
+    recursiveGlob   = "/**"
+)
+
 func getMatchesForPattern(atmosConfig schema.AtmosConfiguration, sourceDir, pattern string) ([]string, error) {
     fullPattern := filepath.Join(sourceDir, pattern)
     matches, err := u.GetGlobMatches(fullPattern)
     if err != nil {
         return nil, fmt.Errorf("error getting glob matches for %q: %w", fullPattern, err)
     }
     if len(matches) == 0 {
-        if strings.HasSuffix(pattern, "/*") {
-            recursivePattern := strings.TrimSuffix(pattern, "/*") + "/**"
+        if strings.HasSuffix(pattern, singleLevelGlob) {
+            recursivePattern := strings.TrimSuffix(pattern, singleLevelGlob) + recursiveGlob

168-255: Consider pre-allocating the map with an estimated size.

The implementation is solid, but the map allocation could be optimized when processing inclusion patterns.

Consider this optimization:

     if len(s.IncludedPaths) > 0 {
-        filesToCopy := make(map[string]struct{})
+        // Pre-allocate map with estimated size based on number of patterns
+        filesToCopy := make(map[string]struct{}, len(s.IncludedPaths)*10)

This pre-allocation helps avoid map resizing during population, potentially improving performance when dealing with many files.

internal/exec/go_getter_utils.go (1)

202-233: Consider adding progress logging for symlink removal.

The symlink removal implementation is solid, but for better observability, consider adding debug logging for the number of symlinks removed.

Here's a suggested enhancement:

 func removeSymlinks(root string) error {
+    removedCount := 0
     err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
         if err != nil {
             return err
         }
         if info.Mode()&os.ModeSymlink != 0 {
-            return os.Remove(path)
+            if err := os.Remove(path); err != nil {
+                return err
+            }
+            removedCount++
             return nil
         }
         return nil
     })
+    if removedCount > 0 {
+        u.LogDebug(fmt.Sprintf("Removed %d symlinks from %s", removedCount, root))
+    }
     return err
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b8d7a5a and 06f5f3b.

📒 Files selected for processing (2)
  • internal/exec/copy_glob.go (1 hunks)
  • internal/exec/go_getter_utils.go (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Summary
🔇 Additional comments (5)
internal/exec/copy_glob.go (2)

3-13: LGTM! Well-organized imports with clear purpose.

The imports are appropriately chosen for file operations and include an optimized copy library with a clear explanatory comment.


94-137: LGTM! Excellent symlink handling implementation.

The function properly implements the PR objective of removing symlinks by explicitly skipping them during the copy process. The error handling is comprehensive and the recursive logic is sound.

internal/exec/go_getter_utils.go (3)

71-74: LGTM! Clean struct extension.

The addition of the source field to CustomGitHubDetector is a well-structured change that maintains backward compatibility.


171-194: LGTM! Well-documented client configuration.

The client configuration is clear and the comments explaining the source parameter's importance are helpful.


219-233: Consider adding test coverage for symlink removal.

The symlink removal functionality would benefit from unit tests to verify its behavior.

Would you like me to generate unit tests for the removeSymlinks function to ensure it handles various scenarios correctly?

Co-authored-by: Erik Osterman (CEO @ Cloud Posse) <erik@cloudposse.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

🧹 Nitpick comments (1)
internal/exec/vendor_model_component.go (1)

209-212: Create a constant for the error wrapping format

Multiple occurrences of fmt.Errorf("%w", Err...) follow the same pattern and could use the wrapErrFmt constant for consistency.

Apply this diff:

-			return fmt.Errorf("%w", ErrLocalMixinURIEmpty)
+			return fmt.Errorf(wrapErrFmt, ErrLocalMixinURIEmpty, nil)

-		return fmt.Errorf("%w", ErrLocalMixinNotImplemented)
+		return fmt.Errorf(wrapErrFmt, ErrLocalMixinNotImplemented, nil)

Or, define a simpler format for unwrapped errors:

+const simpleErrFmt = "%w"

-			return fmt.Errorf("%w", ErrLocalMixinURIEmpty)
+			return fmt.Errorf(simpleErrFmt, ErrLocalMixinURIEmpty)

-		return fmt.Errorf("%w", ErrLocalMixinNotImplemented)
+		return fmt.Errorf(simpleErrFmt, ErrLocalMixinNotImplemented)
🧰 Tools
🪛 GitHub Check: golangci

[failure] 211-211: [golangci] internal/exec/vendor_model_component.go#L211
add-constant: string literal "%w" appears, at least, 4 times, create a named constant for it (revive)

🛑 Comments failed to post (1)
internal/exec/vendor_model.go (1)

250-250: 🛠️ Refactor suggestion

Use the predefined error constants instead of dynamic errors

The code currently creates dynamic errors with errors.New(), but the project has defined static error constants in vendor_model_component.go that should be used for consistency.

Apply this diff to use the predefined error constants:

-				err:  fmt.Errorf(wrapErrFmt, errors.New("failed to create temp directory"), err),
+				err:  fmt.Errorf(wrapErrFmt, ErrCreateTempDir, err),

-				err:  fmt.Errorf(wrapErrFmt, errors.New("failed to set temp directory permissions"), err),
+				err:  fmt.Errorf(wrapErrFmt, ErrSetTempDirPermissions, err),

-					err:  fmt.Errorf(wrapErrFmt, errors.New("failed to download package"), err),
+					err:  fmt.Errorf(wrapErrFmt, ErrDownloadPackage, err),

-					err:  fmt.Errorf(wrapErrFmt, errors.New("failed to process OCI image"), err),
+					err:  fmt.Errorf(wrapErrFmt, ErrProcessOCIImage, err),

-					err:  fmt.Errorf(wrapErrFmt, errors.New("failed to copy package"), err),
+					err:  fmt.Errorf(wrapErrFmt, ErrCopyPackage, err),

-				err:  fmt.Errorf(wrapErrFmt, errors.New("failed to copy package"), err),
+				err:  fmt.Errorf(wrapErrFmt, ErrCopyPackage, err),

Note: You'll need to define ErrSetTempDirPermissions in the error variables section in vendor_model_component.go.

Also applies to: 256-256, 267-267, 275-275, 291-291, 303-303

🧰 Tools
🪛 GitHub Check: golangci

[failure] 250-250: [golangci] internal/exec/vendor_model.go#L250
do not define dynamic errors, use wrapped static errors instead: "errors.New("failed to create temp directory")" (err113)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

🧹 Nitpick comments (2)
internal/exec/vendor_model_component.go (2)

138-138: Consider defining a constant for permission value

The permission value 0o700 is a magic number that should be defined as a constant for better maintainability.

+ const tempDirPermissions os.FileMode = 0o700
- if err := os.Chmod(tempDir, 0o700); err != nil {
+ if err := os.Chmod(tempDir, tempDirPermissions); err != nil {
🧰 Tools
🪛 GitHub Check: golangci

[failure] 138-138: [golangci] internal/exec/vendor_model_component.go#L138
add-constant: avoid magic numbers like '0o700', create a named constant for it (revive)


170-170: Error handling improvements

Good refactoring of error handling to use standardized error variables with consistent formatting patterns (%w: %v). For the local mixin errors, consider also defining static error variables instead of inline error creation.

+ var (
+     ErrEmptyMixinURI = errors.New("local mixin URI cannot be empty")
+     ErrMixinNotImplemented = errors.New("local mixin installation not implemented")
+ )

  // Later in the code:
- return errors.New("local mixin URI cannot be empty")
+ return ErrEmptyMixinURI

- return errors.New("local mixin installation not implemented")
+ return ErrMixinNotImplemented

Also applies to: 175-176, 193-194, 203-205

🧰 Tools
🪛 GitHub Check: golangci

[failure] 170-170: [golangci] internal/exec/vendor_model_component.go#L170
add-constant: string literal "%w: %v" appears, at least, 4 times, create a named constant for it (revive)

🛑 Comments failed to post (1)
internal/exec/vendor_model.go (1)

255-257: ⚠️ Potential issue

Fix error wrapping format

The fmt.Errorf calls are using incorrect formatting. When using wrapErrFmt which is defined as "%w", you should only provide one argument to wrap. The code is providing two arguments.

Apply this fix to all similar occurrences:

- err: fmt.Errorf(wrapErrFmt, errors.New("failed to create temp directory"), err),
+ err: fmt.Errorf("%w: %v", errors.New("failed to create temp directory"), err),

Or alternatively change the wrapErrFmt constant:

- const wrapErrFmt = "%w"
+ const wrapErrFmt = "%w: %v"

Also applies to: 262-264, 274-276, 283-285, 300-302, 313-315

🧰 Tools
🪛 golangci-lint (1.62.2)

256-256: printf: fmt.Errorf call needs 1 arg but has 2 args

(govet)

🪛 GitHub Check: golangci

[failure] 256-256: [golangci] internal/exec/vendor_model.go#L256
printf: fmt.Errorf call needs 1 arg but has 2 args (govet)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

🛑 Comments failed to post (2)
internal/exec/vendor_model.go (2)

23-25: 🛠️ Refactor suggestion

Consider refining the wrapErrFmt.
Currently set to "%w", but it's used with multiple error arguments below, causing format mismatches. A format string like "%w: %v" would be more appropriate for chaining.


254-254: ⚠️ Potential issue

Incorrect usage of fmt.Errorf with multiple arguments.
Each call uses %w but passes two errors, conflicting with the single format specifier. Below is a possible fix adjusting to "%w: %v".

- err:  fmt.Errorf(wrapErrFmt, ErrCreateTempDir, err),
+ err:  fmt.Errorf("%w: %v", ErrCreateTempDir, err),

- err:  fmt.Errorf(wrapErrFmt, ErrSetTempDirPermissions, err),
+ err:  fmt.Errorf("%w: %v", ErrSetTempDirPermissions, err),

- err:  fmt.Errorf(wrapErrFmt, ErrDownloadPackage, err),
+ err:  fmt.Errorf("%w: %v", ErrDownloadPackage, err),

- err:  fmt.Errorf(wrapErrFmt, ErrProcessOCIImage, err),
+ err:  fmt.Errorf("%w: %v", ErrProcessOCIImage, err),

- err:  fmt.Errorf(wrapErrFmt, ErrCopyPackage, err),
+ err:  fmt.Errorf("%w: %v", ErrCopyPackage, err),

- err:  fmt.Errorf(wrapErrFmt, ErrCopyPackageToTarget, err),
+ err:  fmt.Errorf("%w: %v", ErrCopyPackageToTarget, err),

Also applies to: 260-260, 271-271, 279-279, 295-295, 307-307

🧰 Tools
🪛 golangci-lint (1.62.2)

254-254: printf: fmt.Errorf call needs 1 arg but has 2 args

(govet)

🪛 GitHub Check: golangci

[failure] 254-254: [golangci] internal/exec/vendor_model.go#L254
printf: fmt.Errorf call needs 1 arg but has 2 args (govet)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

🧹 Nitpick comments (1)
internal/exec/vendor_model.go (1)

319-326: Inconsistent parameter passing in ExecuteInstall.

ExecuteInstall still accepts atmosConfig as a value but passes it as a pointer to downloadComponentAndInstall.

For consistency, update the function signature to use a pointer parameter:

-func ExecuteInstall(installer pkgVendor, dryRun bool, atmosConfig schema.AtmosConfiguration) tea.Cmd {
+func ExecuteInstall(installer pkgVendor, dryRun bool, atmosConfig *schema.AtmosConfiguration) tea.Cmd {

And then update line 321 to pass the pointer directly:

-    return downloadAndInstall(installer.atmosPackage, dryRun, atmosConfig)
+    return downloadAndInstall(installer.atmosPackage, dryRun, *atmosConfig)

Or alternatively, update downloadAndInstall to also accept a pointer.

🛑 Comments failed to post (2)
internal/exec/vendor_utils.go (1)

430-430: 💡 Verification agent

🧩 Analysis chain

Undefined error variable in error formatting.

The error variable ErrFailedToInitializeTUIModelWithDetails is referenced but not defined in the provided code.

Fix this by adding the missing error variable definition:

+var ErrFailedToInitializeTUIModelWithDetails = fmt.Errorf("failed to initialize TUI model with details")

This should be added in a central error definitions file or at the top of this file.


🏁 Script executed:

#!/bin/bash
# Check if the error variable is defined elsewhere in the codebase
rg -g "*.go" "ErrFailedToInitializeTUIModelWithDetails" --no-filename

Length of output: 147


Undefined error variable detected in internal/exec/vendor_utils.go – please define ErrFailedToInitializeTUIModelWithDetails.

The rg search confirms that the variable is referenced at line 430 but isn't defined elsewhere in the repository. Please add the following definition, either in a central error definitions file or at the top of the file:

  • Location: Internal/exec/vendor_utils.go (or a central errors file)
  • Suggested fix:
+var ErrFailedToInitializeTUIModelWithDetails = fmt.Errorf("failed to initialize TUI model with details")
📝 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.

package exec

import (
	"fmt"
	// other imports...
)

// Add the missing error variable definition here (or in a central errors file)
var ErrFailedToInitializeTUIModelWithDetails = fmt.Errorf("failed to initialize TUI model with details")

// ... rest of the file code ...

func someFunctionThatCallsTUIModel(err error) error {
	// Existing logic
	return fmt.Errorf("%w: %v", ErrFailedToInitializeTUIModelWithDetails, err)
}

// ... rest of the file ...
🧰 Tools
🪛 GitHub Check: golangci

[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails) (typecheck)


[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails) (typecheck)


[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails (typecheck)


[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails) (typecheck)


[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails) (typecheck)


[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails) (typecheck)


[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails) (typecheck)


[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails) (typecheck)


[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails) (typecheck)


[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails) (typecheck)


[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails) (typecheck)


[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails) (typecheck)


[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails) (typecheck)


[failure] 430-430: [golangci] internal/exec/vendor_utils.go#L430
undefined: ErrFailedToInitializeTUIModelWithDetails) (typecheck)

🪛 GitHub Check: Build (macos-latest, macos)

[failure] 430-430:
undefined: ErrFailedToInitializeTUIModelWithDetails

🪛 GitHub Check: Build (ubuntu-latest, linux)

[failure] 430-430:
undefined: ErrFailedToInitializeTUIModelWithDetails

internal/exec/vendor_model.go (1)

329-331: 💡 Verification agent

🧩 Analysis chain

Undefined error variable.

The error variable ErrNoValidInstallerPackage is referenced but not defined in the provided code.

Define the missing error variable in a central error definitions file or at the top of this file:

+var ErrNoValidInstallerPackage = fmt.Errorf("no valid installer package")

🏁 Script executed:

#!/bin/bash
# Check if the error variable is defined elsewhere
rg -g "*.go" "ErrNoValidInstallerPackage" --no-filename

Length of output: 109


Attention: The error variable ErrNoValidInstallerPackage remains undefined. The shell search confirmed that aside from its usage in internal/exec/vendor_model.go (lines 329-331), there’s no definition anywhere in the repository. Please define it—either at the top of this file or in a centralized error definitions file—to ensure proper error handling. For example:

var ErrNoValidInstallerPackage = fmt.Errorf("no valid installer package")
🧰 Tools
🪛 GitHub Check: golangci

[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage


[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage


[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage


[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage


[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage


[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage


[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage


[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage


[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage


[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage


[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage


[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage


[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage


[failure] 330-330: [golangci] internal/exec/vendor_model.go#L330
undefined: ErrNoValidInstallerPackage

🪛 GitHub Check: Build (macos-latest, macos)

[failure] 330-330:
undefined: ErrNoValidInstallerPackage

🪛 GitHub Check: Build (ubuntu-latest, linux)

[failure] 330-330:
undefined: ErrNoValidInstallerPackage

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 1

🧹 Nitpick comments (1)
internal/exec/error.go (1)

8-14: Constants look good but could use documentation.

The constants are well-defined with descriptive names, but adding documentation comments would enhance code readability and maintainability.

 const (
+	// progressWidth defines the width of the progress bar in characters
 	progressWidth               = 30
+	// getterTimeout defines the maximum time allowed for downloading packages
 	getterTimeout               = 10 * time.Minute
+	// componentTempDirPermissions defines file permissions for temporary directories (owner read/write/execute only)
 	componentTempDirPermissions = 0o700
+	// wrapErrFmtWithDetails defines the format string for wrapping errors with additional details
 	wrapErrFmtWithDetails       = "%w: %v"
+	// timeFormatBase defines the base for time format conversions
 	timeFormatBase              = 10
 )
🛑 Comments failed to post (1)
internal/exec/error.go (1)

24-28: 🛠️ Refactor suggestion

Duplicate error messages detected.

The error variables ErrFailedToInitializeTUIModel and ErrFailedToInitializeTUIModelWithDetails have identical error messages. This creates potential confusion during error handling. Consider either:

  1. Using different messages for each error type
  2. Consolidating into a single error variable if they serve the same purpose
  3. Creating a function that can wrap additional details if that's the intended difference
 var (
 	ErrDownloadPackage                       = errors.New("failed to download package")
 	ErrProcessOCIImage                       = errors.New("failed to process OCI image")
 	ErrCopyPackage                           = errors.New("failed to copy package")
 	ErrCreateTempDir                         = errors.New("failed to create temp directory")
 	ErrUnknownPackageType                    = errors.New("unknown package type")
 	ErrLocalMixinURICannotBeEmpty            = errors.New("local mixin URI cannot be empty")
 	ErrLocalMixinInstallationNotImplemented  = errors.New("local mixin installation not implemented")
 	ErrFailedToInitializeTUIModel            = errors.New("failed to initialize TUI model: verify terminal capabilities and permissions")
 	ErrSetTempDirPermissions                 = errors.New("failed to set temp directory permissions")
 	ErrCopyPackageToTarget                   = errors.New("failed to copy package to target")
 	ErrNoValidInstallerPackage               = errors.New("no valid installer package provided")
-	ErrFailedToInitializeTUIModelWithDetails = errors.New("failed to initialize TUI model: verify terminal capabilities and permissions")
+	// If you need both errors, use different messages
+	ErrFailedToInitializeTUIModelWithDetails = errors.New("failed to initialize TUI model with extended information: verify terminal capabilities and permissions")
 )
📝 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.

 var (
 	ErrDownloadPackage                       = errors.New("failed to download package")
 	ErrProcessOCIImage                       = errors.New("failed to process OCI image")
 	ErrCopyPackage                           = errors.New("failed to copy package")
 	ErrCreateTempDir                         = errors.New("failed to create temp directory")
 	ErrUnknownPackageType                    = errors.New("unknown package type")
 	ErrLocalMixinURICannotBeEmpty            = errors.New("local mixin URI cannot be empty")
 	ErrLocalMixinInstallationNotImplemented  = errors.New("local mixin installation not implemented")
 	ErrFailedToInitializeTUIModel            = errors.New("failed to initialize TUI model: verify terminal capabilities and permissions")
 	ErrSetTempDirPermissions                 = errors.New("failed to set temp directory permissions")
 	ErrCopyPackageToTarget                   = errors.New("failed to copy package to target")
 	ErrNoValidInstallerPackage               = errors.New("no valid installer package provided")
 	// If you need both errors, use different messages
 	ErrFailedToInitializeTUIModelWithDetails = errors.New("failed to initialize TUI model with extended information: verify terminal capabilities and permissions")
 )

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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)
internal/exec/vendor_model.go (1)

23-26: Add period at the end of comment

The comment on line 24 should end with a period to follow code formatting standards.

-	// WrapErrFmt is defined in error.go as wrapErrFmtWithDetails ("%w: %v")
+	// WrapErrFmt is defined in error.go as wrapErrFmtWithDetails ("%w: %v").
🧰 Tools
🪛 GitHub Check: golangci

[failure] 24-24: [golangci] internal/exec/vendor_model.go#L24
Comment should end in a period (godot)

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c7764b8 and 225b0f1.

📒 Files selected for processing (1)
  • internal/exec/vendor_model.go (10 hunks)
🧰 Additional context used
🪛 GitHub Check: golangci
internal/exec/vendor_model.go

[failure] 24-24: [golangci] internal/exec/vendor_model.go#L24
Comment should end in a period (godot)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build (windows-latest, windows)
  • GitHub Check: Summary
🔇 Additional comments (7)
internal/exec/vendor_model.go (7)

84-84: Good improvement: passing atmosConfig as pointer

Changing the function to receive a pointer to atmosConfig instead of a value copy improves performance for larger structs by avoiding unnecessary copying.


110-110: Dereferencing pointer correctly

The code correctly dereferences the atmosConfig pointer when assigning to the model struct.


255-256: Consistent error handling improvements

Using the standard wrapErrFmtWithDetails format for all error messages improves consistency and makes errors more traceable by preserving the original error information.

Also applies to: 261-262, 272-273, 280-281, 296-297, 302-303, 308-309


259-259: Using named constant instead of magic number

Good practice replacing the hardcoded permission value with the tempDirPermissions constant, which improves code readability and maintainability.


329-330: Simplified error wrapping

The error handling has been simplified and a helpful comment has been added to explain the approach.


324-324: Consistent passing of atmosConfig as a pointer

This change aligns with the overall pattern in this PR of passing atmosConfig by reference rather than by value, improving consistency across the codebase.


306-306:

✅ Verification successful

Verifying the new pattern-based file copying functionality

The change from copyToTarget to copyToTargetWithPatterns appears to implement the glob pattern support mentioned in the PR objectives. This supports the new functionality for handling included_paths and excluded_paths with glob patterns.


🏁 Script executed:

#!/bin/bash
# Find the implementation of copyToTargetWithPatterns to confirm it supports glob patterns
rg -g "*.go" --no-ignore -A 5 "func copyToTargetWithPatterns"

Length of output: 365


Glob Pattern File Copying Verified

The implementation of copyToTargetWithPatterns in internal/exec/copy_glob.go confirms that the new functionality supports glob patterns for handling included_paths and excluded_paths. The call on line 306 in internal/exec/vendor_model.go is correctly updated to use this function.

  • Verified the function definition and signature in internal/exec/copy_glob.go.
  • Confirmed that the changes align with the PR objectives for glob pattern support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugfix Change that restores intended behavior no-release Do not create a new release (wait for additional code changes) size/xl
Projects
None yet
4 participants