-
Notifications
You must be signed in to change notification settings - Fork 549
feat(system): add NixOS support and nix package manager integration #975
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
ff664d8
bd3a2ac
edcffd8
6798ae2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ package cli | |
| import ( | ||
| "os" | ||
| "path/filepath" | ||
| "runtime" | ||
| "strings" | ||
| "testing" | ||
|
|
||
|
|
@@ -501,7 +502,11 @@ func TestRunInstallMacOSEngramStillUsesBrew(t *testing.T) { | |
| func TestRunInstallBetaEngramUsesMainGoInstallAndInstalledBinary(t *testing.T) { | ||
| home := t.TempDir() | ||
| gobin := filepath.Join(home, "go-bin") | ||
| betaEngram := filepath.Join(gobin, "engram") | ||
| betaEngramName := "engram" | ||
| if runtime.GOOS == "windows" { | ||
| betaEngramName += ".exe" | ||
| } | ||
| betaEngram := filepath.Join(gobin, betaEngramName) | ||
|
|
||
| restoreCommand := runCommand | ||
| restoreLookPath := cmdLookPath | ||
|
|
@@ -554,5 +559,61 @@ func TestRunInstallBetaEngramUsesMainGoInstallAndInstalledBinary(t *testing.T) { | |
| } | ||
| } | ||
|
|
||
| // TestRunInstallNixOSEngramUsesGoInstall verifies NixOS uses go install. | ||
| func TestRunInstallNixOSEngramUsesGoInstall(t *testing.T) { | ||
| home := t.TempDir() | ||
| restoreHome := osUserHomeDir | ||
| restoreCommand := runCommand | ||
| restoreLookPath := cmdLookPath | ||
| restoreGoEnv := goEnv | ||
| t.Cleanup(func() { | ||
| osUserHomeDir = restoreHome | ||
| runCommand = restoreCommand | ||
| cmdLookPath = restoreLookPath | ||
| goEnv = restoreGoEnv | ||
| }) | ||
|
|
||
| osUserHomeDir = func() (string, error) { return home, nil } | ||
| cmdLookPath = missingBinaryLookPath | ||
| gobin := filepath.Join(home, "go-bin") | ||
| goEnv = func(keys ...string) (map[string]string, error) { | ||
| return map[string]string{"GOBIN": gobin, "GOPATH": filepath.Join(home, "go")}, nil | ||
| } | ||
| recorder := &commandRecorder{} | ||
| runCommand = recorder.record | ||
|
|
||
| // DownloadFn should NOT be called for NixOS (go install handles it). | ||
| origDownloadFn := engramDownloadFn | ||
| engramDownloadFn = func(profile system.PlatformProfile) (string, error) { | ||
| t.Error("DownloadLatestBinary should NOT be called on NixOS (go install handles it)") | ||
| return "", nil | ||
| } | ||
| t.Cleanup(func() { engramDownloadFn = origDownloadFn }) | ||
|
|
||
| detection := linuxDetectionResult(system.LinuxDistroNixOS, "nix") | ||
| result, err := RunInstall( | ||
| []string{"--agent", "opencode", "--component", "engram"}, | ||
| detection, | ||
| ) | ||
| if err != nil { | ||
| t.Fatalf("RunInstall() error = %v", err) | ||
| } | ||
| if !result.Verify.Ready { | ||
| t.Fatalf("verification ready = false") | ||
| } | ||
|
|
||
| // Must use go install. | ||
| commands := recorder.get() | ||
| foundGoInstall := false | ||
| for _, cmd := range commands { | ||
| if strings.Contains(cmd, "go install github.com/Gentleman-Programming/engram/cmd/engram@latest") { | ||
| foundGoInstall = true | ||
| } | ||
| } | ||
| if !foundGoInstall { | ||
| t.Fatalf("expected go install on NixOS, got commands: %v", commands) | ||
| } | ||
| } | ||
|
Comment on lines
+562
to
+616
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win Add coverage for the This test only exercises the happy path where 🤖 Prompt for AI Agents |
||
|
|
||
| // Make sure the engram package's DownloadLatestBinary is accessible. | ||
| var _ = engram.DownloadLatestBinary | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -260,7 +260,7 @@ func resolveGGAInstall(profile system.PlatformProfile) (CommandSequence, error) | |
| {"brew", "tap", "Gentleman-Programming/homebrew-tap"}, | ||
| {"brew", "reinstall", "gga"}, | ||
| }, nil | ||
| case "apt", "pacman", "dnf": | ||
| case "apt", "pacman", "dnf", "nix": | ||
| const tmpDir = "/tmp/gentleman-guardian-angel" | ||
| return CommandSequence{ | ||
| {"rm", "-rf", tmpDir}, | ||
|
|
@@ -402,6 +402,12 @@ func resolveEngramInstall(profile system.PlatformProfile) (CommandSequence, erro | |
| {"brew", "tap", "Gentleman-Programming/homebrew-tap"}, | ||
| {"brew", "install", "engram"}, | ||
| }, nil | ||
| case "nix": | ||
| // NixOS requires installing from source via go install because pre-built release | ||
| // binaries fail to run natively due to hardcoded dynamic linker paths. | ||
| return CommandSequence{ | ||
| {"go", "install", "github.com/Gentleman-Programming/engram/cmd/engram@latest"}, | ||
| }, nil | ||
|
Comment on lines
+405
to
+410
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
rg -n 'validateGoForModuleInstall' -g '*.go'Repository: Gentleman-Programming/gentle-ai Length of output: 169 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '--- resolver.go outline ---'
ast-grep outline internal/installcmd/resolver.go --view expanded || true
echo
echo '--- relevant symbols and strings ---'
rg -n 'validateGo|go install|1\.24|NixOS|nix' internal/installcmd -g '*.go' || true
echo
echo '--- resolver.go around nix branch ---'
sed -n '320,440p' internal/installcmd/resolver.goRepository: Gentleman-Programming/gentle-ai Length of output: 8844 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo '--- resolveEngramInstall usages ---'
rg -n 'resolveEngramInstall\(' -g '*.go' .
echo
echo '--- ResolveComponentInstall / dependency paths ---'
sed -n '180,245p' internal/installcmd/resolver.go
echo
echo '--- preflight helpers around validateGoForModuleInstall ---'
sed -n '110,180p' internal/installcmd/resolver.go
echo
echo '--- engram-related tests ---'
sed -n '600,635p' internal/installcmd/resolver_test.goRepository: Gentleman-Programming/gentle-ai Length of output: 7196 Add the Go preflight to the Nix install path. 🤖 Prompt for AI Agents |
||
| default: | ||
| return nil, fmt.Errorf( | ||
| "engram on %q/%q uses direct binary download — use engram.DownloadLatestBinary() instead of CommandSequence", | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
Repository: Gentleman-Programming/gentle-ai
Length of output: 306
🏁 Script executed:
Repository: Gentleman-Programming/gentle-ai
Length of output: 7629
Propagate
goInstallBinDirFromGoEnv()failures hereinternal/cli/run.go:805-815If
go envcan’t resolve the install bin dir, this branch silently leavesengramCommandas"engram"even though the binary was just installed outsidePATH. The follow-upengram setupcall can then fail with no useful hint. Return an error or warn like the beta install path does.🤖 Prompt for AI Agents