Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 21 additions & 25 deletions NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -107,19 +107,19 @@ APACHE 2.0 LICENSED DEPENDENCIES

- github.com/aws/aws-sdk-go-v2/config
License: Apache-2.0
URL: https://github.com/aws/aws-sdk-go-v2/blob/config/v1.32.4/config/LICENSE.txt
URL: https://github.com/aws/aws-sdk-go-v2/blob/config/v1.32.5/config/LICENSE.txt

- github.com/aws/aws-sdk-go-v2/credentials
License: Apache-2.0
URL: https://github.com/aws/aws-sdk-go-v2/blob/credentials/v1.19.4/credentials/LICENSE.txt
URL: https://github.com/aws/aws-sdk-go-v2/blob/credentials/v1.19.5/credentials/LICENSE.txt

- github.com/aws/aws-sdk-go-v2/feature/ec2/imds
License: Apache-2.0
URL: https://github.com/aws/aws-sdk-go-v2/blob/feature/ec2/imds/v1.18.16/feature/ec2/imds/LICENSE.txt

- github.com/aws/aws-sdk-go-v2/feature/s3/manager
License: Apache-2.0
URL: https://github.com/aws/aws-sdk-go-v2/blob/feature/s3/manager/v1.20.14/feature/s3/manager/LICENSE.txt
URL: https://github.com/aws/aws-sdk-go-v2/blob/feature/s3/manager/v1.20.15/feature/s3/manager/LICENSE.txt

- github.com/aws/aws-sdk-go-v2/internal/configsources
License: Apache-2.0
Expand Down Expand Up @@ -155,7 +155,7 @@ APACHE 2.0 LICENSED DEPENDENCIES

- github.com/aws/aws-sdk-go-v2/service/s3
License: Apache-2.0
URL: https://github.com/aws/aws-sdk-go-v2/blob/service/s3/v1.93.1/service/s3/LICENSE.txt
URL: https://github.com/aws/aws-sdk-go-v2/blob/service/s3/v1.93.2/service/s3/LICENSE.txt

- github.com/aws/aws-sdk-go-v2/service/secretsmanager
License: Apache-2.0
Expand All @@ -167,7 +167,7 @@ APACHE 2.0 LICENSED DEPENDENCIES

- github.com/aws/aws-sdk-go-v2/service/ssm
License: Apache-2.0
URL: https://github.com/aws/aws-sdk-go-v2/blob/service/ssm/v1.67.6/service/ssm/LICENSE.txt
URL: https://github.com/aws/aws-sdk-go-v2/blob/service/ssm/v1.67.7/service/ssm/LICENSE.txt

- github.com/aws/aws-sdk-go-v2/service/sso
License: Apache-2.0
Expand All @@ -179,7 +179,7 @@ APACHE 2.0 LICENSED DEPENDENCIES

- github.com/aws/aws-sdk-go-v2/service/sts
License: Apache-2.0
URL: https://github.com/aws/aws-sdk-go-v2/blob/service/sts/v1.41.4/service/sts/LICENSE.txt
URL: https://github.com/aws/aws-sdk-go-v2/blob/service/sts/v1.41.5/service/sts/LICENSE.txt

- github.com/aws/smithy-go
License: Apache-2.0
Expand Down Expand Up @@ -335,7 +335,7 @@ APACHE 2.0 LICENSED DEPENDENCIES

- github.com/kubescape/go-git-url
License: Apache-2.0
URL: https://github.com/kubescape/go-git-url/blob/v0.0.30/LICENSE
URL: https://github.com/kubescape/go-git-url/blob/v0.0.31/LICENSE

- github.com/kylelemons/godebug
License: Apache-2.0
Expand Down Expand Up @@ -503,7 +503,7 @@ APACHE 2.0 LICENSED DEPENDENCIES

- google.golang.org/genproto/googleapis/rpc
License: Apache-2.0
URL: https://github.com/googleapis/go-genproto/blob/79d6a2a48846/googleapis/rpc/LICENSE
URL: https://github.com/googleapis/go-genproto/blob/ff82c1b0f217/googleapis/rpc/LICENSE

- google.golang.org/grpc
License: Apache-2.0
Expand Down Expand Up @@ -740,19 +740,19 @@ BSD LICENSED DEPENDENCIES

- golang.org/x/crypto
License: BSD-3-Clause
URL: https://cs.opensource.google/go/x/crypto/+/v0.45.0:LICENSE
URL: https://cs.opensource.google/go/x/crypto/+/v0.46.0:LICENSE

- golang.org/x/exp
License: BSD-3-Clause
URL: https://cs.opensource.google/go/x/exp/+/054e65f0:LICENSE
URL: https://cs.opensource.google/go/x/exp/+/8475f288:LICENSE

- golang.org/x/mod/semver
License: BSD-3-Clause
URL: https://cs.opensource.google/go/x/mod/+/v0.30.0:LICENSE
URL: https://cs.opensource.google/go/x/mod/+/v0.31.0:LICENSE

- golang.org/x/net
License: BSD-3-Clause
URL: https://cs.opensource.google/go/x/net/+/v0.47.0:LICENSE
URL: https://cs.opensource.google/go/x/net/+/v0.48.0:LICENSE

- golang.org/x/oauth2
License: BSD-3-Clause
Expand Down Expand Up @@ -792,7 +792,7 @@ BSD LICENSED DEPENDENCIES

- google.golang.org/protobuf
License: BSD-3-Clause
URL: https://github.com/protocolbuffers/protobuf-go/blob/v1.36.10/LICENSE
URL: https://github.com/protocolbuffers/protobuf-go/blob/v1.36.11/LICENSE

- gopkg.in/op/go-logging.v1
License: BSD-3-Clause
Expand All @@ -816,7 +816,7 @@ BSD LICENSED DEPENDENCIES

- mvdan.cc/xurls/v2
License: BSD-3-Clause
URL: https://github.com/mvdan/xurls/blob/v2.5.0/LICENSE
URL: https://github.com/mvdan/xurls/blob/v2.6.0/LICENSE


================================================================================
Expand Down Expand Up @@ -937,7 +937,7 @@ MOZILLA PUBLIC LICENSE (MPL) 2.0 DEPENDENCIES

- github.com/terraform-docs/terraform-config-inspect/tfconfig
License: MPL-2.0
URL: https://github.com/terraform-docs/terraform-config-inspect/blob/9c1f178932fa/LICENSE
URL: https://github.com/terraform-docs/terraform-config-inspect/blob/5b88c7ed5b63/LICENSE


================================================================================
Expand Down Expand Up @@ -994,7 +994,7 @@ MIT LICENSED DEPENDENCIES

- github.com/BurntSushi/toml
License: MIT
URL: https://github.com/BurntSushi/toml/blob/v1.4.0/COPYING
URL: https://github.com/BurntSushi/toml/blob/v1.5.0/COPYING

- github.com/HdrHistogram/hdrhistogram-go
License: MIT
Expand Down Expand Up @@ -1098,7 +1098,7 @@ MIT LICENSED DEPENDENCIES

- github.com/charmbracelet/colorprofile
License: MIT
URL: https://github.com/charmbracelet/colorprofile/blob/v0.3.3/LICENSE
URL: https://github.com/charmbracelet/colorprofile/blob/v0.4.1/LICENSE

- github.com/charmbracelet/glamour
License: MIT
Expand All @@ -1122,7 +1122,7 @@ MIT LICENSED DEPENDENCIES

- github.com/charmbracelet/x/ansi
License: MIT
URL: https://github.com/charmbracelet/x/blob/ansi/v0.11.2/ansi/LICENSE
URL: https://github.com/charmbracelet/x/blob/ansi/v0.11.3/ansi/LICENSE

- github.com/charmbracelet/x/cellbuf
License: MIT
Expand All @@ -1142,7 +1142,7 @@ MIT LICENSED DEPENDENCIES

- github.com/clipperhouse/displaywidth
License: MIT
URL: https://github.com/clipperhouse/displaywidth/blob/v0.6.0/LICENSE
URL: https://github.com/clipperhouse/displaywidth/blob/v0.6.1/LICENSE

- github.com/clipperhouse/stringish
License: MIT
Expand Down Expand Up @@ -1514,7 +1514,7 @@ MIT LICENSED DEPENDENCIES

- github.com/sagikazarmark/locafero
License: MIT
URL: https://github.com/sagikazarmark/locafero/blob/v0.11.0/LICENSE
URL: https://github.com/sagikazarmark/locafero/blob/v0.12.0/LICENSE

- github.com/sahilm/fuzzy
License: MIT
Expand All @@ -1536,10 +1536,6 @@ MIT LICENSED DEPENDENCIES
License: MIT
URL: https://github.com/sirupsen/logrus/blob/dd1b4c2e81af/LICENSE

- github.com/sourcegraph/conc
License: MIT
URL: https://github.com/sourcegraph/conc/blob/5f936abd7ae8/LICENSE

- github.com/spf13/cast
License: MIT
URL: https://github.com/spf13/cast/blob/v1.10.0/LICENSE
Expand All @@ -1562,7 +1558,7 @@ MIT LICENSED DEPENDENCIES

- github.com/terraform-docs/terraform-docs
License: MIT
URL: https://github.com/terraform-docs/terraform-docs/blob/v0.20.0/LICENSE
URL: https://github.com/terraform-docs/terraform-docs/blob/v0.21.0/LICENSE

- github.com/tidwall/gjson
License: MIT
Expand Down
200 changes: 200 additions & 0 deletions docs/fixes/path-resolution-regression.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
# Issue #1858: Path Resolution Regression Fix

## Summary

Fixed a regression introduced in v1.201.0 where relative paths in `atmos.yaml` were resolved incorrectly. The fix
implements correct base path resolution semantics that allow users to run `atmos` from anywhere inside a repository.

## Issue Description

**GitHub Issue**: [#1858](https://github.com/cloudposse/atmos/issues/1858)

**Symptoms**:

- After upgrading from `v1.200.0` to `v1.201.0`, `atmos validate stacks` fails with:
```text
The atmos.yaml CLI config file specifies the directory for Atmos stacks as stacks, but the directory does not exist.
```

- This occurs when `ATMOS_CLI_CONFIG_PATH` points to a subdirectory (e.g., `./rootfs/usr/local/etc/atmos`) while the
`stacks/` and `components/` directories are at the repository root.

**Example Configuration**:

```yaml
# Located at ./rootfs/usr/local/etc/atmos/atmos.yaml
base_path: ""
stacks:
base_path: "stacks"
components:
terraform:
base_path: "components/terraform"
```

## Root Cause

Commit `2aad133f6` ("fix: resolve ATMOS_BASE_PATH relative to CLI config directory") introduced a new
`resolveAbsolutePath()` function that resolves **all** relative paths relative to `CliConfigPath` (the directory
containing `atmos.yaml`).

This was intended to fix a legitimate issue where `ATMOS_BASE_PATH="../../.."` wasn't working correctly when running
from component subdirectories. However, the change was too broad and affected all relative paths, not just those
explicitly referencing the config directory.

## Solution

Implemented correct base path resolution semantics as defined in the PRD (`docs/prd/base-path-resolution-semantics.md`):

### Base Path Resolution Rules

| `base_path` value | Resolves to | Rationale |
| -------------------- | ------------------------------------------------------ | -------------------------------------------------- |
| `""` (empty/unset) | Git repo root, fallback to dirname(atmos.yaml) | Smart default - most users want repo root |
| `"."` | CWD | Explicit "where I'm standing" |
| `"./foo"` | CWD/foo | Explicit CWD-relative path |
| `"foo"` or `"foo/bar"` | Git repo root/foo, fallback to dirname(atmos.yaml)/foo | Simple relative paths anchor to repo root |
| `"../foo"` | dirname(atmos.yaml)/../foo | Parent traversal navigates from config location |
| `"/absolute/path"` | /absolute/path (unchanged) | Absolute paths are explicit |

### Key Semantic Distinctions

1. **`.` vs `""`**: These are NOT the same
- `"."` = explicit CWD (user wants current working directory)
- `""` = smart default (repo root with fallback)

2. **`./foo` vs `foo`**: These are NOT the same
- `"./foo"` = CWD/foo (explicit CWD-relative)
- `"foo"` = repo root/foo (anchored to repo root)

3. **`../foo`**: Always relative to atmos.yaml location
- Used for navigating from config location to elsewhere in repo
- Common pattern: config in subdirectory, `base_path: "../.."` to reach repo root

### Code Change

```go
func resolveBasePath(path string, cliConfigPath string) (string, error) {
// Absolute paths unchanged.
if filepath.IsAbs(path) {
return path, nil
}

// Explicit CWD: "." or "./...".
if path == "." || strings.HasPrefix(path, "./") {
return filepath.Abs(path)
}

// Parent traversal: "../..." - relative to atmos.yaml dir.
if strings.HasPrefix(path, "../") {
return filepath.Abs(filepath.Join(cliConfigPath, path))
}

// Empty or simple relative: try git root, fallback to atmos.yaml dir.
gitRoot, err := getGitRoot()
if err == nil && gitRoot != "" {
if path == "" {
return gitRoot, nil
}
return filepath.Join(gitRoot, path), nil
}

// Fallback: relative to atmos.yaml dir.
if path == "" {
return filepath.Abs(cliConfigPath)
}
return filepath.Abs(filepath.Join(cliConfigPath, path))
}
```

## Test Coverage

Added comprehensive tests in `pkg/config/config_test.go`:

1. **`TestResolveBasePath`**: Unit tests for the path resolution logic covering:

- Absolute paths remain unchanged
- Empty path resolves to git repo root (or atmos.yaml dir if not in git repo)
- Dot path (`.`) resolves to CWD
- Paths starting with `./` resolve to CWD
- Paths starting with `../` resolve relative to atmos.yaml dir
- Simple relative paths resolve to git repo root (or atmos.yaml dir if not in git repo)

2. **`TestCliConfigPathRegression`**: Integration tests for issue #1858 scenario:

- Config in subdirectory with `base_path: ..`
- Empty `base_path` with nested config should resolve paths relative to git repo root

## Test Fixtures

Added test fixture in `tests/fixtures/scenarios/`:

- **`cli-config-path/`**: Tests the `base_path: ..` scenario where atmos.yaml is in a subdirectory and uses parent
directory traversal to reference the repo root

## Manual Testing

You can manually verify the fix using the test fixture at `tests/fixtures/scenarios/cli-config-path/`.

### Fixture Structure

```text
tests/fixtures/scenarios/cli-config-path/
├── components/
│ └── terraform/
│ └── test-component/
│ └── main.tf
├── config/
│ └── atmos.yaml # Config in subdirectory with base_path: ".."
└── stacks/
└── dev.yaml
```

The `config/atmos.yaml` uses `base_path: ".."` to reference the parent directory (repo root), while `stacks` and
`components/terraform` are simple relative paths that should resolve relative to the git repo root.

### Test Commands

Run these commands from the fixture directory:

```bash
# Navigate to the test fixture
cd tests/fixtures/scenarios/cli-config-path

# Set ATMOS_CLI_CONFIG_PATH to point to the config subdirectory
export ATMOS_CLI_CONFIG_PATH=./config

# Test 1: Validate stacks (this was failing in v1.201.0)
atmos validate stacks
# Expected: "✓ All stacks validated successfully"

# Test 2: List stacks
atmos list stacks
# Expected: "dev"

# Test 3: List components
atmos list components
# Expected: "test-component dev terraform real true false"

# Test 4: Describe component
atmos describe component test-component -s dev
# Expected: Component configuration output (not an error)

# Test 5: Describe config (verify path resolution)
atmos describe config | grep -E "(base_path|stacks_base_absolute|terraform_dir_absolute)"
# Expected: Paths should point to repo root, not inside config/
```

### Expected vs. Broken Behavior

| Command | v1.200.0 (Working) | v1.201.0 (Broken) | This Fix |
| ----------------------- | ------------------ | ------------------------------------ | ------------------ |
| `atmos validate stacks` | ✅ Success | ❌ "stacks directory does not exist" | ✅ Success |
| `atmos list stacks` | ✅ Shows "dev" | ❌ Error | ✅ Shows "dev" |
| `atmos list components` | ✅ Shows component | ❌ Error | ✅ Shows component |

## Related PRs/Commits

- **Commit `2aad133f6`**: "fix: resolve ATMOS_BASE_PATH relative to CLI config directory" (introduced the regression)
- **PR #1774**: "Path-based component resolution for all commands" (contained the breaking commit)
- **PR #1868**: Initial fix attempt (reverted to inconsistent CWD behavior)
- **PRD**: `docs/prd/base-path-resolution-semantics.md` (defines correct semantics)
Loading
Loading