Skip to content

Commit 6abb400

Browse files
authored
Merge pull request #2221 from dgageot/board/docker-agent-issue-1655-deep-analysis-aac731b8
fix: resolve relative paths against CWD when parentDir is empty
2 parents 0dbc1be + 40dd442 commit 6abb400

4 files changed

Lines changed: 144 additions & 6 deletions

File tree

pkg/rag/manager.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,12 +574,25 @@ func (m *Manager) readFile(path string) (string, error) {
574574
return string(data), nil
575575
}
576576

577-
// GetAbsolutePaths converts doc paths to absolute paths
577+
// GetAbsolutePaths converts doc paths to absolute paths relative to basePath.
578+
// If basePath is empty (e.g. for OCI/URL sources), relative paths are resolved
579+
// against the current working directory.
578580
func GetAbsolutePaths(basePath string, docPaths []string) []string {
579581
var absPaths []string
580582
for _, p := range docPaths {
581583
if filepath.IsAbs(p) {
582584
absPaths = append(absPaths, p)
585+
continue
586+
}
587+
if basePath == "" {
588+
slog.Debug("Resolving relative path with empty basePath, using working directory", "path", p)
589+
abs, err := filepath.Abs(p)
590+
if err != nil {
591+
slog.Warn("Failed to resolve absolute path, using as-is", "path", p, "error", err)
592+
absPaths = append(absPaths, p)
593+
} else {
594+
absPaths = append(absPaths, abs)
595+
}
583596
} else {
584597
absPaths = append(absPaths, filepath.Join(basePath, p))
585598
}

pkg/rag/manager_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package rag
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func TestGetAbsolutePaths_WithBasePath(t *testing.T) {
13+
result := GetAbsolutePaths("/base", []string{"relative/file.go", "/absolute/file.go"})
14+
assert.Equal(t, []string{"/base/relative/file.go", "/absolute/file.go"}, result)
15+
}
16+
17+
func TestGetAbsolutePaths_EmptyBasePath(t *testing.T) {
18+
// When basePath is empty (OCI/URL sources), relative paths should be
19+
// resolved against the current working directory instead of producing
20+
// broken paths like "relative/file.go".
21+
cwd, err := os.Getwd()
22+
require.NoError(t, err)
23+
24+
result := GetAbsolutePaths("", []string{"relative/file.go", "/absolute/file.go"})
25+
26+
assert.Equal(t, filepath.Join(cwd, "relative", "file.go"), result[0])
27+
assert.Equal(t, "/absolute/file.go", result[1])
28+
}
29+
30+
func TestGetAbsolutePaths_NilInput(t *testing.T) {
31+
result := GetAbsolutePaths("/base", nil)
32+
assert.Nil(t, result)
33+
}

pkg/rag/strategy/helpers.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@ func ResolveDatabasePath(dbCfg latest.RAGDatabaseConfig, parentDir, defaultName
6060

6161
// If it's a relative file path, make it absolute
6262
if !filepath.IsAbs(dbStr) {
63+
if parentDir == "" {
64+
slog.Debug("Resolving relative database path with empty parentDir, using working directory", "path", dbStr)
65+
abs, err := filepath.Abs(dbStr)
66+
if err != nil {
67+
return "", fmt.Errorf("failed to resolve absolute path for %q: %w", dbStr, err)
68+
}
69+
return abs, nil
70+
}
6371
return filepath.Join(parentDir, dbStr), nil
6472
}
6573

@@ -165,12 +173,23 @@ func GetParamPtr[T any](params map[string]any, key string) *T {
165173
}
166174
}
167175

168-
// makeAbsolute makes a path absolute relative to parentDir
169-
func makeAbsolute(path, parentDir string) string {
170-
if filepath.IsAbs(path) {
171-
return path
176+
// makeAbsolute makes a path absolute relative to parentDir.
177+
// If parentDir is empty (e.g. for OCI/URL sources), the path is resolved
178+
// against the current working directory.
179+
func makeAbsolute(p, parentDir string) string {
180+
if filepath.IsAbs(p) {
181+
return p
182+
}
183+
if parentDir == "" {
184+
slog.Debug("Resolving relative path with empty parentDir, using working directory", "path", p)
185+
abs, err := filepath.Abs(p)
186+
if err != nil {
187+
slog.Warn("Failed to resolve absolute path, using as-is", "path", p, "error", err)
188+
return p
189+
}
190+
return abs
172191
}
173-
return filepath.Join(parentDir, path)
192+
return filepath.Join(parentDir, p)
174193
}
175194

176195
// EmitEvent sends an event to the events channel using non-blocking send

pkg/rag/strategy/helpers_test.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package strategy
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
11+
"github.com/docker/docker-agent/pkg/config/latest"
12+
)
13+
14+
// newDBConfig creates a RAGDatabaseConfig for testing via YAML unmarshaling.
15+
func newDBConfig(t *testing.T, value string) latest.RAGDatabaseConfig {
16+
t.Helper()
17+
var cfg latest.RAGDatabaseConfig
18+
err := cfg.UnmarshalYAML(func(v any) error {
19+
p, ok := v.(*string)
20+
if !ok {
21+
return nil
22+
}
23+
*p = value
24+
return nil
25+
})
26+
require.NoError(t, err)
27+
return cfg
28+
}
29+
30+
func TestMakeAbsolute_WithParentDir(t *testing.T) {
31+
assert.Equal(t, "/parent/relative.go", makeAbsolute("relative.go", "/parent"))
32+
assert.Equal(t, "/absolute/file.go", makeAbsolute("/absolute/file.go", "/parent"))
33+
}
34+
35+
func TestMakeAbsolute_EmptyParentDir(t *testing.T) {
36+
cwd, err := os.Getwd()
37+
require.NoError(t, err)
38+
39+
result := makeAbsolute("relative.go", "")
40+
assert.Equal(t, filepath.Join(cwd, "relative.go"), result)
41+
}
42+
43+
func TestResolveDatabasePath_EmptyParentDir(t *testing.T) {
44+
cwd, err := os.Getwd()
45+
require.NoError(t, err)
46+
47+
result, err := ResolveDatabasePath(newDBConfig(t, "./my.db"), "", "default")
48+
require.NoError(t, err)
49+
assert.Equal(t, filepath.Join(cwd, "my.db"), result)
50+
}
51+
52+
func TestResolveDatabasePath_AbsolutePathIgnoresParentDir(t *testing.T) {
53+
result, err := ResolveDatabasePath(newDBConfig(t, "/absolute/my.db"), "/parent", "default")
54+
require.NoError(t, err)
55+
assert.Equal(t, "/absolute/my.db", result)
56+
}
57+
58+
func TestResolveDatabasePath_RelativeWithParentDir(t *testing.T) {
59+
result, err := ResolveDatabasePath(newDBConfig(t, "./my.db"), "/parent", "default")
60+
require.NoError(t, err)
61+
assert.Equal(t, "/parent/my.db", result)
62+
}
63+
64+
func TestMergeDocPaths_EmptyParentDir(t *testing.T) {
65+
cwd, err := os.Getwd()
66+
require.NoError(t, err)
67+
68+
result := MergeDocPaths([]string{"shared.go"}, []string{"extra.go"}, "")
69+
assert.Equal(t, []string{
70+
filepath.Join(cwd, "shared.go"),
71+
filepath.Join(cwd, "extra.go"),
72+
}, result)
73+
}

0 commit comments

Comments
 (0)