Resolve Windows rooted search paths with Go
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Configuration Discovery Review Findings
|
||||
|
||||
Status: findings 1–4 complete; finding 5 remains open.
|
||||
Status: complete. All five findings have been addressed in separate commits.
|
||||
|
||||
Reviewed commit: `e50fee2`, including the discovery implementation commits after
|
||||
`424c897`. The review compared the implementation with the
|
||||
@@ -185,7 +185,15 @@ code, not a new Windows support promise or native-platform release gate.
|
||||
|
||||
## 5. Preserve Drive-Root-Relative Windows Path Meaning
|
||||
|
||||
Priority: P3. Status: open. Algorithmic audit: correctness finding.
|
||||
Priority: P3. Status: complete. Algorithmic audit: correctness finding.
|
||||
|
||||
**Completed:** drive-root-relative Windows paths now use `filepath.Abs` alongside
|
||||
drive-relative paths, preserving native host interpretation. Windows regression
|
||||
tests compare candidates and loaded files with explicit `File` for relative,
|
||||
drive-root-relative (both separators), drive-relative, and absolute paths, through
|
||||
both `Paths` and `SearchDirectory`. Existing Unix path/short-circuit tests and
|
||||
`./scripts/check.sh` passed. The Windows engine test binary cross-compiled; no
|
||||
native Windows execution or new release gate was introduced.
|
||||
|
||||
**Location:** [discovery.go](../../internal/engine/discovery.go),
|
||||
`absoluteCandidate`, lines 380–391; also used for literal directory searches.
|
||||
@@ -257,8 +265,8 @@ ordinary file acquisition. It did not benchmark or reopen those choices.
|
||||
No unplanned quadratic algorithm or other actionable asymptotic regression was
|
||||
identified. Findings 4 and 5 record the additional ordinary correctness issues
|
||||
found while examining those algorithms; findings 1–3 were carried forward from
|
||||
the earlier review. Existing configuration-tree algorithms outside the discovery changes
|
||||
were not re-audited as new feature work.
|
||||
the earlier review. Existing configuration-tree algorithms outside the discovery
|
||||
changes were not re-audited as new feature work.
|
||||
|
||||
## Review Validation
|
||||
|
||||
@@ -278,3 +286,13 @@ were not re-audited as new feature work.
|
||||
helper regression overlay described in finding 4. It collected no timing or
|
||||
allocation measurements. Findings 4 and 5 are platform-specific correctness
|
||||
findings, not claims of a native Windows validation run.
|
||||
|
||||
## Completed Remediation Validation
|
||||
|
||||
All five fixes include focused regression coverage and per-issue completion
|
||||
markers above. The final `./scripts/check.sh` and `go test -race ./...` passed
|
||||
with Go 1.26.10 on Linux. The Windows engine tests also cross-compiled with
|
||||
`GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go test -c`, with the binary kept outside
|
||||
the repository. No native Windows or macOS run was performed or made a gate.
|
||||
The implementation preserves the public API, candidate ordering, optional
|
||||
absence, and existing composition/version/ownership contracts.
|
||||
|
||||
@@ -370,7 +370,9 @@ func (iterator *searchCandidateIterator) absoluteCandidate(path string) (string,
|
||||
if filepath.IsAbs(path) {
|
||||
return filepath.Clean(path), nil
|
||||
}
|
||||
if filepath.VolumeName(path) != "" {
|
||||
// Drive-relative and drive-root-relative Windows paths need native
|
||||
// resolution; joining a rooted path to the whole working directory changes it.
|
||||
if filepath.VolumeName(path) != "" || runtime.GOOS == "windows" && len(path) > 0 && os.IsPathSeparator(path[0]) {
|
||||
return filepath.Abs(path)
|
||||
}
|
||||
working, err := iterator.helpers.workingDir()
|
||||
|
||||
@@ -4,6 +4,8 @@ package engine
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -30,3 +32,60 @@ func TestWindowsSearchRejectsReservedComponentsBeforeAcquisition(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWindowsSearchPathsMatchHostAbsoluteResolution(t *testing.T) {
|
||||
root := t.TempDir()
|
||||
file := writeImportFile(t, root, "settings/config.yml", "value: selected\n")
|
||||
working := t.TempDir()
|
||||
t.Chdir(working)
|
||||
relative, err := filepath.Rel(working, file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
volume := filepath.VolumeName(file)
|
||||
rooted := strings.TrimPrefix(file, volume)
|
||||
for _, entry := range []struct {
|
||||
name string
|
||||
path string
|
||||
}{
|
||||
{"relative", relative},
|
||||
{"drive root relative", rooted},
|
||||
{"slash root relative", filepath.ToSlash(rooted)},
|
||||
{"drive relative", volume + relative},
|
||||
{"absolute", file},
|
||||
} {
|
||||
t.Run(entry.name, func(t *testing.T) {
|
||||
want, err := filepath.Abs(entry.path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
explicit, err := testLoad[discoveryLoadConfig](File(entry.path))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, search := range []Search{
|
||||
Paths(entry.path),
|
||||
SearchDirectory(filepath.Dir(entry.path), DirectorySearchOptions{
|
||||
Filenames: []FilenameGroup{CustomFilenames(filepath.Base(entry.path))},
|
||||
}),
|
||||
} {
|
||||
iterator, diagnostics := newSearchCandidateIterator(search, "", discoveryDirectoryHelpers{})
|
||||
if len(diagnostics) != 0 {
|
||||
t.Fatal(diagnostics)
|
||||
}
|
||||
candidate, ok, err := iterator.next()
|
||||
if err != nil || !ok || candidate != want {
|
||||
t.Fatalf("candidate = %q, %v, %v; want %q", candidate, ok, err, want)
|
||||
}
|
||||
result, err := testLoad[discoveryLoadConfig](SearchConfig("", search))
|
||||
if err != nil || result.Config.Value != explicit.Config.Value {
|
||||
t.Fatalf("searched path = %#v, %v; explicit value %q", result, err, explicit.Config.Value)
|
||||
}
|
||||
sources := result.Sources()
|
||||
if len(sources) != 1 || sources[0].Path != explicit.Sources()[0].Path {
|
||||
t.Fatalf("searched source = %#v; explicit source %#v", sources, explicit.Sources())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user