Skip to content

Commit 7a524ea

Browse files
authored
Merge pull request #177 from snyk/fix/support-uvlock-target-file-in-subfolder
fix: support uv lock target files in subfolders
2 parents 6d63a31 + 699e79d commit 7a524ea

File tree

5 files changed

+70
-23
lines changed

5 files changed

+70
-23
lines changed

internal/commands/ostest/routing.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ type FlowConfig struct {
133133
Unmanaged bool
134134
TargetPackage string
135135
AllProjects bool
136+
FileFlag string
136137
}
137138

138139
func doesPathExist(path string) (bool, error) {
@@ -161,6 +162,7 @@ func ParseFlowConfig(cfg configuration.Configuration) (*FlowConfig, error) {
161162
reachabilityFilter := cfg.GetString(flags.FlagReachabilityFilter)
162163
unmanaged := cfg.GetBool(flags.FlagUnmanaged)
163164
allProjects := cfg.GetBool(flags.FlagAllProjects)
165+
fileFlag := cfg.GetString(flags.FlagFile)
164166

165167
experimentalFlagSet := cfg.GetBool(configuration.FLAG_EXPERIMENTAL)
166168
experimentalUvSupport := experimentalFlagSet && cfg.GetBool(constants.EnableExperimentalUvSupportEnvVar)
@@ -204,6 +206,7 @@ func ParseFlowConfig(cfg configuration.Configuration) (*FlowConfig, error) {
204206
Unmanaged: unmanaged,
205207
TargetPackage: targetPackage,
206208
AllProjects: allProjects,
209+
FileFlag: fileFlag,
207210
}, nil
208211
}
209212

@@ -217,7 +220,7 @@ func ShouldUseLegacyFlow(ctx context.Context, fc *FlowConfig, inputDirs []string
217220
}
218221

219222
// Check if UV support should trigger, only if env var is set and uv.lock exists.
220-
uvSupportWithLockFile := fc.ExperimentalUvSupport && util.HasUvLockFileInAnyDir(inputDirs, fc.AllProjects, logger)
223+
uvSupportWithLockFile := fc.ExperimentalUvSupport && util.HasUvLockFileInAnyDir(inputDirs, fc.FileFlag, fc.AllProjects, logger)
221224

222225
hasNewFeatures := fc.RiskScoreTest || fc.Reachability || fc.SBOM != "" || fc.ReachabilityFilter != "" || uvSupportWithLockFile
223226
useLegacy := fc.ForceLegacyTest || fc.RequiresLegacy || !hasNewFeatures

internal/commands/ostest/workflow_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ func TestOSWorkflow_FlagCombinations(t *testing.T) {
652652
tempDir := util.CreateTempDirWithUvLock(t)
653653
config.Set(configuration.INPUT_DIRECTORY, []string{tempDir})
654654
config.Set(configuration.FLAG_EXPERIMENTAL, true)
655+
config.Set(flags.FlagFile, "")
655656
config.Set(constants.EnableExperimentalUvSupportEnvVar, true)
656657
mockEngine.EXPECT().
657658
InvokeWithConfig(common.DepGraphWorkflowID, gomock.Any()).

internal/common/depgraph.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ func GetDepGraph(ictx workflow.InvocationContext, inputDir string) ([]RawDepGrap
4444

4545
depGraphConfig := config.Clone()
4646
experimentalFlagSet := config.GetBool(configuration.FLAG_EXPERIMENTAL)
47-
allProjectsFlagSet := config.GetBool(flags.FlagAllProjects)
47+
allProjects := config.GetBool(flags.FlagAllProjects)
48+
fileFlag := config.GetString(flags.FlagFile)
4849
experimentalUvSupportEnabled := experimentalFlagSet && config.GetBool(constants.EnableExperimentalUvSupportEnvVar)
49-
uvLockExists := util.HasUvLockFile(inputDir, allProjectsFlagSet, logger)
50+
uvLockExists := util.HasUvLockFile(inputDir, fileFlag, allProjects, logger)
5051

5152
if experimentalUvSupportEnabled && uvLockExists {
5253
logger.Info().Msg("Experimental uv support enabled and uv.lock found, using SBOM resolution in depgraph workflow")

internal/util/uv.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,30 @@ var ExcludedUVLockFileDirs = map[string]bool{
1919
".build": true,
2020
}
2121

22-
// HasUvLockFile checks if the specified directory contains a uv.lock file.
22+
// HasUvLockFile checks if the specified directory contains a uv.lock file or the target file if provided.
2323
// If allProjects is true, the function will check if the directory contains a uv.lock file recursively.
2424
// Otherwise, it will only check if the directory contains a uv.lock file.
25-
func HasUvLockFile(dir string, allProjects bool, logger *zerolog.Logger) bool {
25+
func HasUvLockFile(dir, targetFile string, allProjects bool, logger *zerolog.Logger) bool {
2626
if allProjects {
2727
return HasUvLockFileRecursive(dir, logger)
2828
}
29-
return HasUvLockFileSingle(dir, logger)
29+
return HasUvLockFileSingle(dir, targetFile, logger)
3030
}
3131

32-
// HasUvLockFileSingle checks if the specified directory contains a uv.lock file.
33-
func HasUvLockFileSingle(dir string, logger *zerolog.Logger) bool {
34-
uvLockPath := filepath.Join(dir, constants.UvLockFileName)
32+
// HasUvLockFileSingle checks if the specified directory contains a uv.lock file or the target file if provided.
33+
// If targetFile is an absolute path, it will be used directly; otherwise, it will be joined with dir.
34+
func HasUvLockFileSingle(dir, targetFile string, logger *zerolog.Logger) bool {
35+
var uvLockPath string
36+
if targetFile != "" {
37+
if filepath.IsAbs(targetFile) {
38+
uvLockPath = targetFile
39+
} else {
40+
uvLockPath = filepath.Join(dir, targetFile)
41+
}
42+
} else {
43+
uvLockPath = filepath.Join(dir, constants.UvLockFileName)
44+
}
45+
3546
_, err := os.Stat(uvLockPath)
3647
if err == nil {
3748
return true
@@ -95,9 +106,9 @@ func HasUvLockFileRecursive(dir string, logger *zerolog.Logger) bool {
95106
}
96107

97108
// HasUvLockFileInAnyDir checks if any of the input directories contains a uv.lock file.
98-
func HasUvLockFileInAnyDir(inputDirs []string, allProjects bool, logger *zerolog.Logger) bool {
109+
func HasUvLockFileInAnyDir(inputDirs []string, targetFile string, allProjects bool, logger *zerolog.Logger) bool {
99110
for _, inputDir := range inputDirs {
100-
if HasUvLockFile(inputDir, allProjects, logger) {
111+
if HasUvLockFile(inputDir, targetFile, allProjects, logger) {
101112
return true
102113
}
103114
}

internal/util/uv_test.go

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func TestHasUvLockFile(t *testing.T) {
2323
tmpDir := t.TempDir()
2424
createUvLockFile(t, tmpDir, "project1")
2525

26-
result := util.HasUvLockFile(tmpDir, false, &nopLogger)
26+
result := util.HasUvLockFile(tmpDir, "", false, &nopLogger)
2727
assert.False(t, result)
2828
})
2929

@@ -33,7 +33,7 @@ func TestHasUvLockFile(t *testing.T) {
3333
tmpDir := t.TempDir()
3434
createUvLockFile(t, tmpDir, "project1")
3535

36-
result := util.HasUvLockFile(tmpDir, true, &nopLogger)
36+
result := util.HasUvLockFile(tmpDir, "", true, &nopLogger)
3737
assert.True(t, result)
3838
})
3939
}
@@ -48,23 +48,54 @@ func TestHasUvLockFileSingle(t *testing.T) {
4848
tmpDir := t.TempDir()
4949
createUvLockFile(t, tmpDir)
5050

51-
result := util.HasUvLockFileSingle(tmpDir, &nopLogger)
51+
result := util.HasUvLockFileSingle(tmpDir, "", &nopLogger)
52+
assert.True(t, result)
53+
})
54+
55+
t.Run("returns true when uv.lock exists with target file", func(t *testing.T) {
56+
t.Parallel()
57+
58+
tmpDir := t.TempDir()
59+
createUvLockFile(t, tmpDir)
60+
61+
result := util.HasUvLockFileSingle(tmpDir, "uv.lock", &nopLogger)
62+
assert.True(t, result)
63+
})
64+
65+
t.Run("returns true when uv.lock exists with target file in subdirectory", func(t *testing.T) {
66+
t.Parallel()
67+
68+
tmpDir := t.TempDir()
69+
createUvLockFile(t, tmpDir, "subdir")
70+
71+
result := util.HasUvLockFileSingle(tmpDir, "subdir/uv.lock", &nopLogger)
72+
assert.True(t, result)
73+
})
74+
75+
t.Run("returns true when uv.lock exists with target file in subdirectory and giving absolute path", func(t *testing.T) {
76+
t.Parallel()
77+
78+
tmpDir := t.TempDir()
79+
createUvLockFile(t, tmpDir, "subdir")
80+
absolutePath := filepath.Join(tmpDir, "subdir", constants.UvLockFileName)
81+
82+
result := util.HasUvLockFileSingle(tmpDir, absolutePath, &nopLogger)
5283
assert.True(t, result)
5384
})
5485

5586
t.Run("returns false when uv.lock does not exist", func(t *testing.T) {
5687
t.Parallel()
5788
dir := t.TempDir()
5889

59-
result := util.HasUvLockFileSingle(dir, &nopLogger)
90+
result := util.HasUvLockFileSingle(dir, "", &nopLogger)
6091
assert.False(t, result)
6192
})
6293

6394
t.Run("returns false when directory does not exist", func(t *testing.T) {
6495
t.Parallel()
6596
dir := filepath.Join(t.TempDir(), "nonexistent")
6697

67-
result := util.HasUvLockFileSingle(dir, &nopLogger)
98+
result := util.HasUvLockFileSingle(dir, "", &nopLogger)
6899
assert.False(t, result)
69100
})
70101

@@ -75,7 +106,7 @@ func TestHasUvLockFileSingle(t *testing.T) {
75106
err := os.WriteFile(uvLockPath, []byte("# test"), 0o600)
76107
require.NoError(t, err)
77108

78-
result := util.HasUvLockFileSingle(dir, nil)
109+
result := util.HasUvLockFileSingle(dir, "", nil)
79110
assert.True(t, result)
80111
})
81112
}
@@ -155,7 +186,7 @@ func TestHasUvLockFileInAnyDir(t *testing.T) {
155186
err := os.WriteFile(uvLockPath, []byte("# test"), 0o600)
156187
require.NoError(t, err)
157188

158-
result := util.HasUvLockFileInAnyDir([]string{dir1, dir2}, false, &nopLogger)
189+
result := util.HasUvLockFileInAnyDir([]string{dir1, dir2}, "", false, &nopLogger)
159190
assert.True(t, result)
160191
})
161192

@@ -168,7 +199,7 @@ func TestHasUvLockFileInAnyDir(t *testing.T) {
168199
err := os.WriteFile(uvLockPath, []byte("# test"), 0o600)
169200
require.NoError(t, err)
170201

171-
result := util.HasUvLockFileInAnyDir([]string{dir1, dir2}, false, &nopLogger)
202+
result := util.HasUvLockFileInAnyDir([]string{dir1, dir2}, "", false, &nopLogger)
172203
assert.True(t, result)
173204
})
174205

@@ -185,7 +216,7 @@ func TestHasUvLockFileInAnyDir(t *testing.T) {
185216
err = os.WriteFile(uvLockPath2, []byte("# test"), 0o600)
186217
require.NoError(t, err)
187218

188-
result := util.HasUvLockFileInAnyDir([]string{dir1, dir2}, false, &nopLogger)
219+
result := util.HasUvLockFileInAnyDir([]string{dir1, dir2}, "", false, &nopLogger)
189220
assert.True(t, result)
190221
})
191222

@@ -194,14 +225,14 @@ func TestHasUvLockFileInAnyDir(t *testing.T) {
194225
dir1 := t.TempDir()
195226
dir2 := t.TempDir()
196227

197-
result := util.HasUvLockFileInAnyDir([]string{dir1, dir2}, false, &nopLogger)
228+
result := util.HasUvLockFileInAnyDir([]string{dir1, dir2}, "", false, &nopLogger)
198229
assert.False(t, result)
199230
})
200231

201232
t.Run("returns false for empty directory list", func(t *testing.T) {
202233
t.Parallel()
203234

204-
result := util.HasUvLockFileInAnyDir([]string{}, false, &nopLogger)
235+
result := util.HasUvLockFileInAnyDir([]string{}, "", false, &nopLogger)
205236
assert.False(t, result)
206237
})
207238

@@ -214,7 +245,7 @@ func TestHasUvLockFileInAnyDir(t *testing.T) {
214245
err := os.WriteFile(uvLockPath, []byte("# test"), 0o600)
215246
require.NoError(t, err)
216247

217-
result := util.HasUvLockFileInAnyDir([]string{nonExistentDir, dir1}, false, &nopLogger)
248+
result := util.HasUvLockFileInAnyDir([]string{nonExistentDir, dir1}, "", false, &nopLogger)
218249
assert.True(t, result)
219250
})
220251
}

0 commit comments

Comments
 (0)