Skip to content

fix(system): add openSUSE platform support #748

Open
Houtamelo wants to merge 3 commits into
Gentleman-Programming:mainfrom
Houtamelo:main
Open

fix(system): add openSUSE platform support #748
Houtamelo wants to merge 3 commits into
Gentleman-Programming:mainfrom
Houtamelo:main

Conversation

@Houtamelo

Copy link
Copy Markdown

🔗 Linked Issue

Closes #140


🏷️ PR Type

What kind of change does this PR introduce?

  • type:bug — Bug fix (non-breaking change that fixes an issue)
  • type:feature — New feature (non-breaking change that adds functionality)
  • type:docs — Documentation only
  • type:refactor — Code refactoring (no functional changes)
  • type:chore — Build, CI, or tooling changes
  • type:breaking-change — Breaking change (fix or feature that changes existing behavior)

📝 Summary

Adds openSUSE (Tumbleweed/Leap) platform support so gentle-ai no longer exits with unsupported linux distro on openSUSE systems. Detects openSUSE distros through /etc/os-release and maps them to zypper with supported platform status.


📂 Changes

File / Area What Changed
internal/system Detects openSUSE-family distros and maps them to zypper with supported platform status
internal/installcmd Resolves zypper dependency installs and enables openSUSE paths for OpenCode --ignore-scripts consistency
e2e/ Adds an openSUSE Tumbleweed Docker E2E target and includes it in the platform matrix

🐛 Bug Fixes

The original openSUSE commit had copy-paste errors in test expectations:

  • internal/agents/opencode/adapter_test.go: openSUSE npm test missing --ignore-scripts and version pin
  • internal/installcmd/resolver_test.go: openSUSE test in TestResolveDependencyInstall had npm command instead of zypper
  • internal/installcmd/resolver_test.go: openSUSE npm test missing --ignore-scripts and version pin

All three fixed to match actual resolver output for zypper/NpmWritable=false.


🧪 Test Plan

Unit Tests

go test ./...

E2E Tests (Docker required)

sg docker -c './e2e/docker-test.sh'

Results:

  • Unit tests pass (go test ./... — 48 packages, 0 failures)
  • E2E Tier 1+2 pass (467/467)
  • gentle-ai install --dry-run reports os=linux distro=opensuse package-manager=zypper status=supported

🤖 Automated Checks

Check Status Description
Check Issue Reference PR body must contain Closes/Fixes/Resolves #N
Check Issue Has status:approved Linked issue must have been approved before work began
Check PR Has type:* Label Exactly one type:* label must be applied
Unit Tests go test ./... must pass
E2E Tests cd e2e && ./docker-test.sh must pass

✅ Contributor Checklist

  • PR is linked to an issue with status:approved
  • I have added the appropriate type:* label to this PR
  • Unit tests pass (go test ./...)
  • E2E tests pass (cd e2e && ./docker-test.sh)
  • I have updated documentation if necessary
  • My commits follow Conventional Commits format
  • My commits do not include Co-Authored-By trailers

💬 Notes for Reviewers

This is a revival of the stale PR #397, rebased onto current main with the unrelated bundled refactor (withGoInstallPathNotewithEngramPathNote) stripped. That refactor was logically separate and contained a PATH-check mismatch bug — it should be its own PR if still desired. Three test expectation bugs from the original commit were also fixed.

peplocanto and others added 3 commits June 2, 2026 11:53
# Conflicts:
#	docs/platforms.md
#	internal/installcmd/resolver.go
Both openSUSE test cases had copy-paste errors from other distros:
- adapter_test.go: missing --ignore-scripts and version pin
- resolver_test.go: wrong test body (was in TestResolveDependencyInstall
  instead of TestResolveAgentInstall) with npm command instead of zypper

Fix both to match what resolveOpenCodeInstall actually produces for
zypper/NpmWritable=false: sudo npm install -g --ignore-scripts <pinned>
Copilot AI review requested due to automatic review settings June 3, 2026 23:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds openSUSE (zypper) support across platform detection, dependency install hints/commands, and E2E coverage, while clarifying that Go is optional for normal (binary) installs.

Changes:

  • Detect openSUSE via /etc/os-release, mark as supported, and map to zypper.
  • Add zypper install hints/commands for core dependencies and update install resolver paths.
  • Expand unit tests, docs, and Docker-based E2E testing to include openSUSE; update optional-Go messaging.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
internal/system/install_deps_test.go Adds openSUSE test coverage for dependency hints/commands and expands platform matrix.
internal/system/install_deps.go Adds zypper install hints/commands for git/curl/node/go.
internal/system/guard_test.go Adds guard test for openSUSE and updates expected error message text.
internal/system/guard.go Updates unsupported-distro error message to include openSUSE.
internal/system/detect_test.go Adds openSUSE detection + profile resolution tests.
internal/system/detect.go Introduces LinuxDistroOpenSUSE, detection helper, and profile mapping to zypper.
internal/system/deps_test.go Updates dependency report expectations to include optional Go formatting.
internal/system/deps.go Clarifies Go optionality and adds formatting for optional-missing dependency output.
internal/installcmd/resolver_test.go Adds zypper resolver tests and updates “unsupported pm” cases.
internal/installcmd/resolver.go Adds zypper support for dependency installs/uv hint and includes it in linux install flows.
internal/components/gga/install_test.go Verifies GGA install path on openSUSE and updates unsupported pm case.
internal/components/engram/install_test.go Adjusts test case to treat openSUSE as a specific (expected-error) scenario.
internal/app/parity_test.go Adds parity/guard tests for openSUSE profiles.
internal/agents/opencode/adapter_test.go Adds openSUSE npm-install behavior test and updates unsupported pm case.
e2e/docker-test.sh Adds openSUSE image to the docker E2E platform list.
e2e/Dockerfile.opensuse Adds a Tumbleweed-based E2E image definition.
docs/usage.md Documents zypper hints and notes Go is optional for normal installs.
docs/rollback.md Expands rollback caveats/examples to include dnf and zypper.
docs/quickstart.md Adds openSUSE prerequisites and clarifies Go requirement for source builds only.
docs/platforms.md Lists openSUSE as supported and adds derivatives examples.
docs/non-interactive.md Adds openSUSE to the non-interactive npm/sudo matrix.
docs/docker-e2e-testing.md Documents Fedora + openSUSE Docker E2E images and commands.
docs/architecture.md Updates architecture notes to include zypper and expanded Docker E2E platforms.
PRD.md Updates supported platforms list and clarifies Go’s role and install methods.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +207 to +209
if cmds[0][0] != "sudo" || cmds[0][1] != "zypper" || cmds[0][2] != "--non-interactive" {
t.Fatalf("git opensuse command = %v, want sudo zypper --non-interactive", cmds[0])
}
Comment on lines +218 to +220
if cmds[0][0] != "sudo" || cmds[0][1] != "zypper" || cmds[0][4] != "nodejs" || cmds[0][5] != "npm" {
t.Fatalf("node opensuse command = %v, want sudo zypper --non-interactive install nodejs npm", cmds[0])
}
Comment thread e2e/Dockerfile.opensuse
@@ -0,0 +1,54 @@
# Dockerfile.opensuse — E2E test image for gentle-ai on openSUSE Tumbleweed
# Builds the binary from source and runs the E2E test suite as a non-root user.
FROM opensuse/tumbleweed:latest
Comment thread docs/quickstart.md
### All platforms

- Go 1.24+ (for building from source).
- Go 1.24+ only if you are building Gentle AI from source; it is not required for normal release-binary installs.
Comment thread internal/system/deps.go
Comment on lines +255 to +265
func formatMissingOptional(missing []string) string {
formatted := make([]string, 0, len(missing))
for _, dep := range missing {
if dep == "go" {
formatted = append(formatted, "go (only needed for local development/source builds)")
continue
}
formatted = append(formatted, dep)
}
return strings.Join(formatted, ", ")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:feature New feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for OpenSuse

4 participants