Skip to content

fix: Windows toolchain installation issues#2012

Merged
aknysh merged 17 commits intomainfrom
aknysh/fix-issues-on-windows-1
Jan 23, 2026
Merged

fix: Windows toolchain installation issues#2012
aknysh merged 17 commits intomainfrom
aknysh/fix-issues-on-windows-1

Conversation

@aknysh
Copy link
Member

@aknysh aknysh commented Jan 23, 2026

what

  • Fix Windows toolchain installation failures where binaries were installed without .exe extension
  • Fix GitHub release download URLs to include .exe for raw binaries on Windows (following Aqua behavior)
  • Fix archive extraction for tools like helm that have .exe binaries inside archives
  • Fix hint message to show PowerShell Invoke-Expression syntax instead of Unix eval on Windows
  • Improve .atmos.d directory detection to differentiate permission errors from not-found errors
  • Extend archive extension detection to include .tar.xz, .tar.bz2, .7z, and other formats
  • Add integration tests for Windows toolchain functionality
  • Update CLI documentation with PowerShell examples

why

Users reported multiple issues when using atmos toolchain install on Windows:

  1. Binary without .exe extension - Installing tools like terraform resulted in binaries without .exe extension, causing terraform --version to hang indefinitely
  2. Download URL missing .exe - Tools like jq that have standalone Windows binaries (e.g., jq-windows-amd64.exe) failed to download because the URL was constructed without .exe
  3. Archive extraction failures - Tools like helm that ship as archives (.tar.gz, .zip) failed because the extractor looked for windows-amd64/helm instead of windows-amd64/helm.exe
  4. Wrong shell hint - The hint message showed Unix eval $(...) syntax instead of PowerShell Invoke-Expression syntax

Architecture

Centralized Windows Extension Handling

Following Aqua's Windows support approach, Windows executables need the .exe extension to be found by os/exec.LookPath. We use a single centralized function:

// EnsureWindowsExeExtension appends .exe to the binary name on Windows if not present.
func EnsureWindowsExeExtension(binaryName string) string {
    if runtime.GOOS == "windows" && \!strings.HasSuffix(strings.ToLower(binaryName), ".exe") {
        return binaryName + ".exe"
    }
    return binaryName
}

Download URL Handling by Tool Type

Tool Type Download URL .exe Handling
github_release Automatic: Adds .exe on Windows for raw binaries (assets without archive extensions like .tar.gz, .zip)
http Manual: The asset template must include .exe in the URL if needed

This matches Aqua's behavior where .exe is added to the download URL upfront during URL construction, not as a fallback after a 404 error.

Archive Extension Detection

Extended to recognize additional formats to avoid incorrectly appending .exe to archive URLs:

var archiveExtensions = []string{
    ".tar.gz", ".tgz", ".zip", ".gz",
    ".tar.xz", ".txz", ".tar.bz2", ".tbz", ".tbz2",
    ".bz2", ".xz", ".7z", ".tar", ".pkg",
}

Archive Extraction

When extracting from archives, the .exe fallback only runs on Windows (not on Unix) to avoid masking wrong-asset errors.

Fixes Applied

File Fix
toolchain/installer/installer.go Added EnsureWindowsExeExtension() centralized function
toolchain/installer/asset.go Adds .exe to GitHub release URLs for raw binaries on Windows; extended archive detection
toolchain/installer/extract.go Uses centralized function; .exe fallback only on Windows
toolchain/install_helpers.go Platform-aware hint message for PowerShell
pkg/config/load.go Differentiate stat errors from not-found for .atmos.d directories

Test Results (Windows)

All integration tests pass on Windows:

--- PASS: TestToolchainCustomCommands_InstallAllTools (14.04s)
--- PASS: TestToolchainCustomCommands_ToolsExecutable (12.33s)
--- PASS: TestToolchainCustomCommands_PathEnvOutput (10.09s)
--- PASS: TestToolchainCustomCommands_WindowsExeExtension (8.91s)
--- PASS: TestToolchainCustomCommands_CustomCommandsLoaded (8.31s)
--- PASS: TestToolchainCustomCommands_ExecuteWithDependencies (14.50s)
PASS

references

  • Full documentation: docs/fixes/windows-atmos-d-and-toolchain-issues.md
  • Test fixture: tests/fixtures/scenarios/toolchain-custom-commands
  • Integration tests: tests/toolchain_custom_commands_test.go

Summary by CodeRabbit

  • New Features

    • Tabbed Bash/Zsh and PowerShell examples for env/shell guidance.
    • Custom toolchain commands with dependency-driven tool installation and a Terraform test component.
  • Bug Fixes

    • Improved Windows executable handling (.exe normalization for downloads/installs).
    • Safer atmos.d/.atmos.d detection with clearer "no directory found" messages and adjusted log levels.
    • Platform-aware PATH export hints in installer output.
  • Documentation

    • Added Windows toolchain troubleshooting guide; updated CLI docs for cross-platform usage.
  • Tests

    • New unit and integration tests covering custom commands, toolchain installs, Windows behaviors, and env handling.

✏️ Tip: You can customize this high-level summary in your review settings.

@aknysh aknysh requested a review from a team as a code owner January 23, 2026 04:10
@aknysh aknysh added the patch A minor, backward compatible change label Jan 23, 2026
@aknysh aknysh requested a review from a team as a code owner January 23, 2026 04:10
@github-actions github-actions bot added the size/l Large size PR label Jan 23, 2026
@aknysh aknysh self-assigned this Jan 23, 2026
@github-actions
Copy link

github-actions bot commented Jan 23, 2026

Dependency Review

✅ No vulnerabilities or license issues found.

Scanned Files

None

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 23, 2026

📝 Walkthrough

Walkthrough

Conditional loading for atmos.d/.atmos.d, centralized Windows .exe normalization across installer/asset/extract flows, platform-aware PATH hinting, many Windows-focused tests/fixtures, and updated CLI docs and snapshots.

Changes

Cohort / File(s) Summary
Config loading
pkg/config/load.go
Only attempt loading atmos.d and .atmos.d when directories exist; log explicit absence and use debug-level logging on load errors.
Windows exe normalization
toolchain/installer/installer.go, toolchain/installer/asset.go, toolchain/installer/extract.go
Add windowsExeExt and EnsureWindowsExeExtension; normalize binary names for install/extract and append .exe for raw GitHub-release binaries when appropriate.
Installer hints & helpers
toolchain/install.go, toolchain/install_helpers.go, toolchain/install_helpers_test.go
Replace hard-coded PATH hint with getPlatformPathHint() (PowerShell vs Bash/Zsh) and add platform-aware tests (note: duplicated test block present).
Extractor behavior
toolchain/installer/extract.go
If a configured source file is missing, on Windows try the same path with .exe, adjust destination path, and continue extraction when found.
Asset URL handling
toolchain/installer/asset.go, toolchain/installer/asset_test.go
Detect archive extensions (archiveExtensions/hasArchiveExtension) and append .exe for raw binary assets on Windows only when no extension and not an archive; add tests for archive/non-archive cases.
Installer tests
toolchain/installer/installer_test.go, toolchain/exec_test.go
Add tests for EnsureWindowsExeExtension and update tests to use it for expected binary names.
New integration tests & fixtures
tests/toolchain_custom_commands_test.go, tests/fixtures/scenarios/toolchain-custom-commands/...
Add integration tests validating tool installation, executability, PATH/env outputs, custom command loading/execution, Windows .exe handling; include scenario fixtures and Terraform component/stack.
Config load error tests
pkg/config/load_error_paths_test.go, pkg/config/load_error_paths_unix_test.go
Add tests for missing/exists/both/file-not-directory and Unix permission/stat error paths to ensure graceful handling without panics.
Snapshots
tests/snapshots/TestCLICommands_Valid_Log_Level_in_Config_File.stderr.golden, tests/snapshots/TestCLICommands_atmos_describe_configuration.stderr.golden
Update golden outputs to reflect explicit "No atmos.d/.atmos.d directory found" messages and additional atmos.d discovery debug logs.
Docs & website updates
docs/fixes/windows-atmos-d-and-toolchain-issues.md, website/docs/cli/commands/auth/auth-env.mdx, website/docs/cli/commands/env.mdx
Add Windows troubleshooting doc; update CLI docs with Bash/Zsh and PowerShell tabbed examples and env-loading snippets.
Test snapshots & fixtures
tests/snapshots/*, tests/fixtures/*
Add/replace fixtures and snapshots for the new scenarios and updated logging behavior.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant CLI as Atmos CLI
participant Installer as Toolchain Installer
participant Asset as Release Resolver
participant FS as Filesystem / Extractor
CLI->>Installer: request install (tool, version)
Installer->>Asset: render asset name & build URL (hasArchiveExtension, EnsureWindowsExeExtension)
Asset-->>Installer: asset URL / type (raw vs archive)
Installer->>FS: download & extract if archive
FS->>FS: locate binary (try name; on Windows try name + .exe)
FS-->>Installer: installed binary path
Installer-->>CLI: print success summary (getPlatformPathHint())

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • osterman
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and accurately describes the main focus of the PR: fixing Windows-specific toolchain installation issues, which aligns with the comprehensive changes across multiple files.
Docstring Coverage ✅ Passed Docstring coverage is 95.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch aknysh/fix-issues-on-windows-1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
website/docs/cli/commands/env.mdx (1)

41-70: Quote eval to avoid word-splitting in shell examples.
Unquoted eval $(...) can break when values contain spaces or special characters.

🔧 Suggested update
- eval $(atmos env)
+ eval "$(atmos env)"
@@
- eval $(atmos env --profile ci)
+ eval "$(atmos env --profile ci)"
@@
- ATMOS_PROFILE=ci eval $(atmos env)
+ ATMOS_PROFILE=ci eval "$(atmos env)"
🧹 Nitpick comments (4)
tests/snapshots/TestCLICommands_atmos_describe_configuration.stderr.golden (1)

8-24: Observation: Multiple directory loads per command.

The snapshot shows atmos.d being discovered/loaded 10 times during a single command execution. This is existing behavior now made visible by the new logging. Not a concern for this PR, but could be a future optimization opportunity if config loading performance becomes a consideration.

toolchain/installer/download.go (1)

189-213: Consider improving error message clarity.

The error on line 212 references assetURL and fallbackURL but doesn't mention the .exe variants that were actually attempted. This could confuse debugging.

🔧 Suggested improvement
-	return "", fmt.Errorf("%w: tried %s and %s: %w", ErrHTTPRequest, assetURL, fallbackURL, ErrHTTP404)
+	return "", fmt.Errorf("%w: tried %s.exe and %s.exe: %w", ErrHTTPRequest, assetURL, fallbackURL, ErrHTTP404)
tests/toolchain_custom_commands_test.go (2)

328-336: Consider using t.Skip or a dedicated TODO test marker.

The soft failure pattern here means CI passes even when the feature doesn't work. If toolchain PATH injection isn't yet implemented, consider:

  • Using t.Skip("Pending: toolchain PATH injection not implemented")
  • Or marking this as an expected failure with a tracking issue

The current approach risks the incomplete behavior being forgotten.

♻️ Alternative approach
 			// The command should succeed if toolchain integration works.
 			if err != nil {
-				t.Logf("Command failed: %v", err)
-				t.Logf("This may indicate that toolchain tools are not in PATH for custom commands")
-				// Don't fail - document current behavior.
-				// Once the toolchain PATH injection is implemented, change to require.NoError.
+				// TODO: Remove skip once toolchain PATH injection is implemented.
+				t.Skipf("Pending implementation: toolchain tools not in PATH for custom commands (error: %v)", err)
 			} else {
 				assert.Contains(t, strings.ToLower(string(output)), strings.ToLower(tc.expectedOutput),
 					"Output should contain %q", tc.expectedOutput)

346-349: Fragile path calculation.

The "../../../.." assumes the fixture is always exactly 4 levels deep from repo root. If the fixture directory structure changes, this breaks silently.

A more robust approach would find the repo root by locating go.mod:

♻️ More robust alternative
// findRepoRoot walks up from cwd to find go.mod.
func findRepoRoot(t *testing.T) string {
	t.Helper()
	dir, err := os.Getwd()
	require.NoError(t, err)
	for {
		if _, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil {
			return dir
		}
		parent := filepath.Dir(dir)
		if parent == dir {
			t.Fatal("could not find repo root (go.mod)")
		}
		dir = parent
	}
}

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 23, 2026
@codecov
Copy link

codecov bot commented Jan 23, 2026

Codecov Report

❌ Patch coverage is 67.30769% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.36%. Comparing base (8e2cc18) to head (678ab3f).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
toolchain/installer/extract.go 30.00% 7 Missing ⚠️
pkg/config/load.go 80.00% 2 Missing and 2 partials ⚠️
toolchain/install_helpers.go 50.00% 2 Missing and 1 partial ⚠️
toolchain/installer/installer.go 57.14% 2 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2012      +/-   ##
==========================================
- Coverage   75.38%   75.36%   -0.02%     
==========================================
  Files         792      792              
  Lines       73356    73396      +40     
==========================================
+ Hits        55299    55318      +19     
- Misses      14553    14566      +13     
- Partials     3504     3512       +8     
Flag Coverage Δ
unittests 75.36% <67.30%> (-0.02%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
toolchain/install.go 76.27% <100.00%> (ø)
toolchain/installer/asset.go 98.21% <100.00%> (+0.13%) ⬆️
toolchain/install_helpers.go 55.93% <50.00%> (-0.44%) ⬇️
toolchain/installer/installer.go 77.22% <57.14%> (-0.24%) ⬇️
pkg/config/load.go 78.19% <80.00%> (-0.50%) ⬇️
toolchain/installer/extract.go 67.47% <30.00%> (-1.38%) ⬇️

... and 4 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@aknysh
Copy link
Member Author

aknysh commented Jan 23, 2026

@coderabbitai full review please

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 23, 2026

@aknysh I'll perform a comprehensive review of all the changes in this PR.


🧠 Learnings used
Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: The atmos toolchain XDG compliance implementation is complete with GetXDGCacheDir() and GetXDGTempCacheDir() functions in toolchain/xdg_cache.go, updated installer.go and toolchain_clean.go to use these helpers, and changed cache paths from ~/.cache/tools-cache to ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain when XDG_CACHE_HOME is not set).

Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: errors/errors.go:184-203
Timestamp: 2025-12-13T06:10:13.688Z
Learning: cloudposse/atmos: For toolchain work, duplicate/unused error sentinels in errors/errors.go should be cleaned up in a separate refactor PR and not block feature PRs; canonical toolchain sentinels live under toolchain/registry with re-exports in toolchain/errors.go.

Learnt from: aknysh
Repo: cloudposse/atmos PR: 944
File: go.mod:206-206
Timestamp: 2025-01-17T00:18:57.769Z
Learning: For indirect dependencies with license compliance issues in the cloudposse/atmos repository, the team prefers to handle them in follow-up PRs rather than blocking the current changes, as these issues often require deeper investigation of the dependency tree.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1466
File: website/docs/cli/commands/toolchain/usage.mdx:117-121
Timestamp: 2025-09-08T01:25:44.958Z
Learning: XDG Base Directory Specification compliance implementation for atmos toolchain is complete: created toolchain/xdg_cache.go with GetXDGCacheDir() and GetXDGTempCacheDir() functions, updated toolchain/installer.go and cmd/toolchain_clean.go to use these XDG helpers, and changed all cache paths from hardcoded ~/.cache/tools-cache to XDG-compliant ${XDG_CACHE_HOME}/atmos-toolchain (or ~/.cache/atmos-toolchain fallback).

Learnt from: Listener430
Repo: cloudposse/atmos PR: 934
File: tests/fixtures/scenarios/docs-generate/README.md.gotmpl:99-118
Timestamp: 2025-01-25T03:51:57.689Z
Learning: For the cloudposse/atmos repository, changes to template contents should be handled in dedicated PRs and are typically considered out of scope for PRs focused on other objectives.

Learnt from: osterman
Repo: cloudposse/atmos PR: 1686
File: docs/prd/tool-dependencies-integration.md:58-64
Timestamp: 2025-12-13T06:07:37.766Z
Learning: cloudposse/atmos: For PRD docs (docs/prd/*.md), markdownlint issues like MD040/MD010/MD034 can be handled in a separate documentation cleanup commit and should not block the current PR.
✅ Actions performed

Full review triggered.

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: 4

🤖 Fix all issues with AI agents
In `@pkg/config/load.go`:
- Around line 1042-1063: The code currently treats any os.Stat error as "not
found" for atmosDPath and dotAtmosDPath, hiding permission/IO errors; update
both checks around os.Stat(atmosDPath) and os.Stat(dotAtmosDPath) to distinguish
os.IsNotExist(err) (log.Trace "No ... directory found" and continue) from other
errors (log.Error or log.Warn with the error details and the path), and only
call stat.IsDir() when err == nil; keep the existing call to
loadAtmosConfigsFromDirectory(searchPattern, dst, "atmos.d"/".atmos.d")
unchanged.

In `@tests/fixtures/scenarios/toolchain-custom-commands/atmos.yaml`:
- Around line 45-47: The fixtures use a hard-coded Unix path in logs.file (value
"/dev/stderr") which will fail on Windows; update the fixture by either removing
the logs.file key entirely or setting logs.file to an empty string so atmos
falls back to platform-appropriate defaults (i.e., change the logs.file entry in
the atmo.yaml fixture).

In `@toolchain/installer/asset.go`:
- Around line 71-73: The block comment in asset.go that starts "On Windows, add
.exe to raw binary asset names that don't have an archive extension." and ends
with the URL "See: https://aquaproj.github.io/docs/reference/windows-support/"
is missing a terminal period; update that trailing sentence to end with a period
so the comment finishes with proper punctuation (e.g., add a period after the
URL) -- locate this comment near the Windows/asset logic in the asset.go file
(the comment above the raw binary asset handling) and amend it accordingly.
- Around line 84-92: Update hasArchiveExtension to recognize additional archive
suffixes so Windows assets aren't misdetected and `.exe` isn't appended;
specifically, extend the strings.HasSuffix checks in hasArchiveExtension
(asset.go) to include multi-part and other common archive extensions such as
".tar.xz", ".tar.bz2", ".tar.zst" as well as single-part extensions like ".7z",
".xz", ".bz2", ".rar", ".deb", and ".rpm", making sure to check longer
multi-part suffixes before shorter ones (e.g., ".tar.xz" before ".xz") against
the lower variable.
🧹 Nitpick comments (2)
docs/fixes/windows-atmos-d-and-toolchain-issues.md (1)

61-65: Optional: Add language specifier to fenced code block.

These code blocks would benefit from a language specifier for syntax highlighting consistency. Based on learnings, this can be addressed in a separate documentation cleanup commit.

📝 Suggested fix
-```
+```text
 Asset template: jq-{{.OS}}-{{.Arch}}
 On Windows:     https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-windows-amd64.exe  ✅
 On Linux:       https://github.com/jqlang/jq/releases/download/jq-1.7.1/jq-linux-amd64       ✅
tests/toolchain_custom_commands_test.go (1)

232-236: Use the getBinaryPath helper for consistency instead of hardcoding the path structure.

The test path at line 233 and the getBinaryPath helper at line 366 actually construct identical paths. Both produce toolsDir/bin/jqlang/jq/1.7.1/jq.exe. Consider using getBinaryPath to reduce duplication and future-proof against path structure changes.

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

🤖 Fix all issues with AI agents
In `@toolchain/installer/asset.go`:
- Around line 71-76: The code unconditionally calls EnsureWindowsExeExtension
for any asset that lacks an archive extension, causing names like
"installer.msi" to become "installer.msi.exe"; change the conditional in the
asset name handling so EnsureWindowsExeExtension is only called when the asset
has no file extension at all (use filepath.Ext or an equivalent file-extension
check) — update the logic around hasArchiveExtension and
EnsureWindowsExeExtension to check that filepath.Ext(assetName) == "" before
appending .exe to assetName.
🧹 Nitpick comments (2)
pkg/config/load_error_paths_test.go (2)

129-139: Prefer t.Setenv for test-scoped env isolation.
You can replace the manual unset with an empty t.Setenv, which still yields an empty os.Getenv result while preserving automatic cleanup.

🛠️ Suggested tweak
-	os.Unsetenv("ATMOS_CLI_CONFIG_PATH")
+	t.Setenv("ATMOS_CLI_CONFIG_PATH", "")
Based on learnings, prefer `t.Setenv` for env setup/teardown in tests.

92-112: Avoid swallowing errors in the Getwd error-path test.
Right now the test can pass without exercising the error path. Consider asserting on err when directory removal succeeds, or t.Skip when it can’t be reproduced.

As per coding guidelines, tests should assert behavior rather than silently discarding errors.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jan 23, 2026
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/config/load_error_paths_test.go (1)

393-397: Tautological test - error silenced without assertion.

The _ = err pattern means this test always passes regardless of behavior. Either assert on the error (e.g., check for max depth error) or document why no assertion is needed.

Per coding guidelines: "Avoid tautological tests."

Suggested fix
 	// This should eventually hit max import depth
 	err = mergeConfig(v, tempDir, "atmos.yaml", true)
-	// May error on max depth or may complete - testing the path exists
-	_ = err
+	// Circular imports should trigger max depth error.
+	assert.Error(t, err, "Expected error from circular import")
🧹 Nitpick comments (1)
pkg/config/load_error_paths_test.go (1)

489-572: Good scenario coverage.

Tests cover the key permutations well. Optional enhancement: consider asserting that viper actually contains the loaded values (e.g., v.GetString("settings.test_value")) to verify the config was processed, not just that no panic occurred.

Example assertion
// After loadAtmosDFromDirectory call:
assert.Equal(t, "from_atmos_d", v.GetString("settings.test_value"))

@aknysh aknysh requested a review from osterman January 23, 2026 17:28
osterman
osterman previously approved these changes Jan 23, 2026
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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/config/load_error_paths_test.go (1)

393-397: Test discards result without assertion.

Line 396 uses _ = err which makes this a no-op. The test should either assert that an error occurs (circular import should hit max depth) or assert success. As-is, it doesn't verify any behavior.

Suggested fix
 	// This should eventually hit max import depth
 	err = mergeConfig(v, tempDir, "atmos.yaml", true)
-	// May error on max depth or may complete - testing the path exists
-	_ = err
+	// Circular imports should trigger max depth error
+	assert.Error(t, err, "circular import should hit max depth limit")
🤖 Fix all issues with AI agents
In `@toolchain/installer/extract.go`:
- Around line 238-253: The current os.Stat check for src treats any error on the
.exe probe as "not found" and returns ErrToolNotFound, which hides other errors;
modify the logic in the block that computes srcWithExe so that after calling
os.Stat(srcWithExe) you distinguish os.IsNotExist(exeErr) versus other errors —
if not exist then return ErrToolNotFound as before, but if exeErr is non-nil and
not IsNotExist, return or wrap exeErr as ErrFileOperation (preserving the
original error); ensure you still set src = srcWithExe and call
EnsureWindowsExeExtension(dst) only when the .exe Stat succeeds.
🧹 Nitpick comments (2)
pkg/config/load_error_paths_test.go (2)

226-226: Hardcoded path with forward slashes.

Per coding guidelines, prefer filepath.Join() even for non-existent paths. This keeps tests consistent cross-platform.

Suggested fix
-	_, err := readConfigFileContent("/nonexistent/path/atmos.yaml")
+	_, err := readConfigFileContent(filepath.Join(string(os.PathSeparator), "nonexistent", "path", "atmos.yaml"))

445-445: Same hardcoded path pattern.

Consider using filepath.Join() for consistency.

Suggested fix
-	err := mergeConfigFile("/nonexistent/path/config.yaml", v)
+	err := mergeConfigFile(filepath.Join(string(os.PathSeparator), "nonexistent", "path", "config.yaml"), v)

@aknysh aknysh requested a review from osterman January 23, 2026 19:11
@aknysh aknysh merged commit 34d6675 into main Jan 23, 2026
57 checks passed
@aknysh aknysh deleted the aknysh/fix-issues-on-windows-1 branch January 23, 2026 19:19
@github-actions
Copy link

These changes were released in v1.204.1-rc.5.

aknysh added a commit that referenced this pull request Jan 25, 2026
Add .exe handling to buildHTTPAssetURL() for HTTP type tools (like kubectl
from dl.k8s.io) to match existing behavior in buildGitHubReleaseURL().
This fixes HTTP 404 errors on Windows when downloading raw binaries.

Added comprehensive test fixture in tests/fixtures/scenarios/windows-test/
with .tool-versions, .atmos.d custom commands, and Terraform components
for Windows testing.

Related: #2002, #2012

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
aknysh added a commit that referenced this pull request Jan 25, 2026
…2027)

* WIP: Windows toolchain HTTP type .exe fix and test fixture

Add .exe handling to buildHTTPAssetURL() for HTTP type tools (like kubectl
from dl.k8s.io) to match existing behavior in buildGitHubReleaseURL().
This fixes HTTP 404 errors on Windows when downloading raw binaries.

Added comprehensive test fixture in tests/fixtures/scenarios/windows-test/
with .tool-versions, .atmos.d custom commands, and Terraform components
for Windows testing.

Related: #2002, #2012

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

* updates

* fix toolchain installation, improve errors, improve registries detection, add test fixtures and tests

* address comments, add tests, fix platform detection in Aqua registry

* address comments, add tests, fix platform detection in Aqua registry

* updates

* address comments, add tests, fix platform detection in Aqua registry

* update docs

* address comments

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch A minor, backward compatible change size/xl Extra large size PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants