mirror of
https://github.com/Cheviiot/Vintner.git
synced 2026-08-03 15:57:24 +00:00
`vintner cl ...`, `vintner msbuild ...`, etc. now work without adding <dest>/bin/<arch> to PATH or relying on the same-directory symlinks `install` sets up there. wrapper.Run gained an explicit binDir parameter (empty string preserves the existing os.Executable()-based self-location for the ordinary multi-call/symlink case) so cmd/vintner's new runTool can point it at a resolved toolchain directory instead. Resolution order: VINTNER_BIN if set (same meaning as `env --bin` - point it at a <dest>/bin/<arch> directory directly, for a non-default --dest or a specific architecture), else <defaultToolchainDir>/bin/ <hostArch> - the layout a plain `vintner download && vintner install` with no --dest override produces. A missing toolchain gets a clear error pointing at both fixes, rather than bubbling up whatever wineenv.Load's env.json error looks like. Also fixed shell completion falling out of sync with the actual tool list: the bash/zsh scripts previously hand-copied tool/flag names (and had already gone stale once - --with-dxsdk was missing from the download flag completions since it was added). The tool name list is now generated from wrapper.ToolNames() instead of hand-maintained, and both scripts now complete tool names too, so `vintner <TAB>` suggests `cl`, `link`, `msbuild`, etc. alongside the management subcommands. Verified end-to-end with a minimal PATH (/usr/bin:/bin only, no toolchain dir on it at all): `vintner cl /nologo hello.c` compiled successfully, and `vintner msbuild -t:Rebuild ...` rebuilt the same real KMDF driver verified earlier this session - both via the default ~/.vintner/bin/<hostArch> resolution, no VINTNER_BIN override needed.
65 lines
2.1 KiB
Go
65 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"os/exec"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/Cheviiot/vintner/internal/wrapper"
|
|
)
|
|
|
|
// TestCompletionScriptsAreSyntacticallyValid catches the easy way to break
|
|
// these: a typo in the hand-maintained flag lists that produces invalid
|
|
// shell syntax. It shells out to bash/zsh -n rather than parsing the script
|
|
// itself, so it's testing exactly what a user's shell would see.
|
|
func TestCompletionScriptsAreSyntacticallyValid(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
shell string
|
|
script string
|
|
}{
|
|
{"bash", bashCompletionScript()},
|
|
{"zsh", zshCompletionScript()},
|
|
} {
|
|
t.Run(tc.shell, func(t *testing.T) {
|
|
if _, err := exec.LookPath(tc.shell); err != nil {
|
|
t.Skipf("%s not installed", tc.shell)
|
|
}
|
|
cmd := exec.Command(tc.shell, "-n", "/dev/stdin")
|
|
cmd.Stdin = strings.NewReader(tc.script)
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
t.Fatalf("%s -n rejected the completion script: %v\n%s", tc.shell, err, out)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestCompletionScriptsListEveryTool guards against the exact staleness bug
|
|
// found and fixed alongside this test: a hand-copied tool/flag list here
|
|
// drifting from the real set in internal/wrapper (or download.go's flags)
|
|
// as tools/flags get added. Every current tool name must appear in both
|
|
// generated scripts.
|
|
func TestCompletionScriptsListEveryTool(t *testing.T) {
|
|
bash := bashCompletionScript()
|
|
zsh := zshCompletionScript()
|
|
for _, name := range wrapper.ToolNames() {
|
|
if !strings.Contains(bash, name) {
|
|
t.Errorf("bash completion script doesn't mention tool %q", name)
|
|
}
|
|
if !strings.Contains(zsh, name+":") {
|
|
t.Errorf("zsh completion script doesn't mention tool %q", name)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRunCompletionUnknownShell(t *testing.T) {
|
|
if code := runCompletion([]string{"fish"}); code != 1 {
|
|
t.Errorf("runCompletion([\"fish\"]) = %d, want 1", code)
|
|
}
|
|
if code := runCompletion(nil); code != 1 {
|
|
t.Errorf("runCompletion(nil) = %d, want 1", code)
|
|
}
|
|
if code := runCompletion([]string{"bash", "extra"}); code != 1 {
|
|
t.Errorf("runCompletion with extra arg = %d, want 1", code)
|
|
}
|
|
}
|