Skip to content

Commit 7f8aa30

Browse files
committed
chore: PR comments
1 parent f4adac8 commit 7f8aa30

File tree

8 files changed

+479
-163
lines changed

8 files changed

+479
-163
lines changed

cli/commands/backend/migrate/migrate.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,23 @@ func Run(ctx context.Context, l log.Logger, srcPath, dstPath string, opts *optio
5555
}
5656

5757
srcRemoteState, err := config.ParseRemoteState(ctx, l, srcModule.Execution.TerragruntOptions)
58-
if err != nil || srcRemoteState == nil {
58+
if err != nil {
5959
return err
6060
}
6161

62+
if srcRemoteState == nil {
63+
return errors.Errorf("missing remote state configuration for source module: %s", srcPath)
64+
}
65+
6266
dstRemoteState, err := config.ParseRemoteState(ctx, l, dstModule.Execution.TerragruntOptions)
63-
if err != nil || dstRemoteState == nil {
67+
if err != nil {
6468
return err
6569
}
6670

71+
if dstRemoteState == nil {
72+
return errors.Errorf("missing remote state configuration for destination module: %s", dstPath)
73+
}
74+
6775
if !opts.ForceBackendMigrate {
6876
enabled, err := srcRemoteState.IsVersionControlEnabled(ctx, l, srcModule.Execution.TerragruntOptions)
6977
if err != nil && !errors.As(err, new(backend.BucketDoesNotExistError)) {

internal/component/unit.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/gruntwork-io/terragrunt/options"
1212
"github.com/gruntwork-io/terragrunt/pkg/log"
1313
"github.com/gruntwork-io/terragrunt/tf"
14+
"github.com/gruntwork-io/terragrunt/util"
1415
)
1516

1617
const (
@@ -218,7 +219,11 @@ func (u *Unit) Dependents() Components {
218219

219220
// String renders this unit as a human-readable string for debugging.
220221
func (u *Unit) String() string {
222+
// Snapshot values under read lock to avoid data races
223+
u.rLock()
224+
path := u.path
221225
deps := make([]string, 0, len(u.dependencies))
226+
222227
for _, dep := range u.dependencies {
223228
deps = append(deps, dep.Path())
224229
}
@@ -231,30 +236,46 @@ func (u *Unit) String() string {
231236
assumeApplied = u.Execution.AssumeAlreadyApplied
232237
}
233238

239+
u.rUnlock()
240+
234241
return fmt.Sprintf(
235242
"Unit %s (excluded: %v, assume applied: %v, dependencies: [%s])",
236-
u.path, excluded, assumeApplied, strings.Join(deps, ", "),
243+
path, excluded, assumeApplied, strings.Join(deps, ", "),
237244
)
238245
}
239246

240247
// AbsolutePath returns the absolute path of the unit.
241-
// If path conversion fails, returns the original path and logs a warning.
248+
// If path conversion fails, returns the original path and logs a warning if a logger is available.
242249
func (u *Unit) AbsolutePath() string {
243250
if filepath.IsAbs(u.path) {
244251
return u.path
245252
}
246253

247254
absPath, err := filepath.Abs(u.path)
248255
if err != nil {
256+
if u.Execution != nil && u.Execution.Logger != nil {
257+
u.Execution.Logger.Warnf("Failed to convert unit path %q to absolute path: %v", u.path, err)
258+
}
259+
249260
return u.path
250261
}
251262

252263
return absPath
253264
}
254265

255266
// FindInPaths returns true if the unit is located in one of the target directories.
267+
// Paths are normalized before comparison to handle absolute/relative path mismatches.
256268
func (u *Unit) FindInPaths(targetDirs []string) bool {
257-
return slices.Contains(targetDirs, u.path)
269+
cleanUnitPath := util.CleanPath(u.path)
270+
271+
for _, dir := range targetDirs {
272+
cleanDir := util.CleanPath(dir)
273+
if util.HasPathPrefix(cleanUnitPath, cleanDir) {
274+
return true
275+
}
276+
}
277+
278+
return false
258279
}
259280

260281
// PlanFile returns plan file location if output folder is set.

internal/discovery/discovery.go

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -724,8 +724,7 @@ func (d *Discovery) skipDirIfIgnorable(_ log.Logger, path string) error {
724724
}
725725
}
726726

727-
// When the filter flag is enabled, let the filters control discovery instead of exclude patterns
728-
// When the filter flag is enabled, let the filters control discovery instead of exclude patterns
727+
// When the filter flag is enabled, let the filters control discovery instead of exclude patterns.
729728
// We also avoid early skipping for CLI exclude patterns so reporting can capture excluded units.
730729
if d.filterFlagEnabled {
731730
return nil
@@ -1288,7 +1287,12 @@ func (d *Discovery) Discover(
12881287
}
12891288

12901289
if d.graphTarget != "" {
1291-
components = d.filterGraphTarget(l, components)
1290+
var err error
1291+
1292+
components, err = d.filterGraphTarget(components)
1293+
if err != nil {
1294+
return nil, err
1295+
}
12921296
}
12931297

12941298
components = d.applyQueueFilters(opts, components)
@@ -1297,35 +1301,46 @@ func (d *Discovery) Discover(
12971301
}
12981302

12991303
// filterGraphTarget prunes components to the target path and its dependents.
1300-
func (d *Discovery) filterGraphTarget(l log.Logger, components component.Components) component.Components {
1304+
func (d *Discovery) filterGraphTarget(components component.Components) (component.Components, error) {
13011305
if d.graphTarget == "" {
1302-
return components
1306+
return components, nil
13031307
}
13041308

1305-
targetPath := canonicalizeGraphTarget(l, d.workingDir, d.graphTarget)
1309+
targetPath, err := canonicalizeGraphTarget(d.workingDir, d.graphTarget)
1310+
if err != nil {
1311+
return nil, err
1312+
}
13061313

13071314
dependentUnits := buildDependentsIndex(components)
13081315
propagateTransitiveDependents(dependentUnits)
13091316

13101317
allowed := buildAllowSet(targetPath, dependentUnits)
13111318

1312-
return filterByAllowSet(components, allowed)
1319+
return filterByAllowSet(components, allowed), nil
13131320
}
13141321

13151322
// canonicalizeGraphTarget resolves the graph target to an absolute, cleaned path.
1316-
// Falls back to a cleaned relative path on canonicalization failure, logging at debug level.
1317-
func canonicalizeGraphTarget(l log.Logger, baseDir, target string) string {
1318-
targetPath := target
1319-
if !filepath.IsAbs(targetPath) {
1320-
if abs, err := util.CanonicalPath(targetPath, baseDir); err == nil {
1321-
targetPath = abs
1322-
} else {
1323-
l.Debugf("Could not canonicalize graph target %s: %v", targetPath, err)
1324-
targetPath = filepath.Clean(targetPath)
1325-
}
1323+
// Returns an error if the path cannot be made absolute.
1324+
func canonicalizeGraphTarget(baseDir, target string) (string, error) {
1325+
// If already absolute, just clean it
1326+
if filepath.IsAbs(target) {
1327+
return filepath.Clean(target), nil
1328+
}
1329+
1330+
// Try canonical path first
1331+
if abs, err := util.CanonicalPath(target, baseDir); err == nil {
1332+
return abs, nil
1333+
}
1334+
1335+
// Fallback: join with baseDir and make absolute
1336+
joined := filepath.Join(baseDir, filepath.Clean(target))
1337+
1338+
abs, err := filepath.Abs(joined)
1339+
if err != nil {
1340+
return "", errors.Errorf("failed to resolve graph target %q relative to %q: %w", target, baseDir, err)
13261341
}
13271342

1328-
return targetPath
1343+
return abs, nil
13291344
}
13301345

13311346
// buildDependentsIndex builds an index mapping each unit path to the list of units

0 commit comments

Comments
 (0)