From 54e7f1e3805ef3d6eeeac2dd6198b02bc007d513 Mon Sep 17 00:00:00 2001 From: Samuel K Date: Sat, 19 Sep 2026 16:01:20 -0600 Subject: [PATCH 1/8] feat(install): add curl install script Signed-off-by: Samuel K --- sites/docs-devsy-sh/public/install.sh | 149 ++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 sites/docs-devsy-sh/public/install.sh diff --git a/sites/docs-devsy-sh/public/install.sh b/sites/docs-devsy-sh/public/install.sh new file mode 100644 index 000000000..0f7473497 --- /dev/null +++ b/sites/docs-devsy-sh/public/install.sh @@ -0,0 +1,149 @@ +#!/bin/sh +# Install the Devsy CLI. +# +# curl -L https://devsy.sh/install.sh | sh +# +# Optional environment variables: +# DEVSY_VERSION Release tag to install (for example v1.19.0) +# instead of the latest release. +# DEVSY_INSTALL_DIR Directory to install into. Defaults to +# /usr/local/bin, or ~/.local/bin when /usr/local/bin +# is not writable and sudo is unavailable. +# DEVSY_RELEASE_BASE_URL Release download base URL, for mirrors or testing. +# Defaults to https://github.com/devsy-org/devsy/releases. +set -eu + +info() { + printf '%s\n' "$*" +} + +warn() { + printf 'warning: %s\n' "$*" >&2 +} + +fatal() { + printf 'error: %s\n' "$*" >&2 + exit 1 +} + +need() { + command -v "$1" >/dev/null 2>&1 || fatal "required command '$1' was not found; install it and re-run this script" +} + +detect_os() { + case "$(uname -s)" in + Linux) printf 'linux' ;; + Darwin) printf 'darwin' ;; + MINGW* | MSYS* | CYGWIN*) + fatal "this script supports macOS and Linux; for Windows see https://devsy.sh/docs/getting-started/install#install-devsy-cli" + ;; + *) fatal "unsupported operating system: $(uname -s)" ;; + esac +} + +detect_arch() { + case "$(uname -m)" in + x86_64 | amd64) printf 'amd64' ;; + arm64 | aarch64) printf 'arm64' ;; + *) fatal "unsupported CPU architecture: $(uname -m)" ;; + esac +} + +# sha256_of prints the file's SHA-256 digest, or fails when no +# SHA-256 tool is available. +sha256_of() { + if command -v sha256sum >/dev/null 2>&1; then + sha256sum "$1" | awk '{print $1}' + elif command -v shasum >/dev/null 2>&1; then + shasum -a 256 "$1" | awk '{print $1}' + else + return 1 + fi +} + +# maybe_verify_checksum +# Verifies the download when the release publishes checksums; otherwise +# continues with a note, matching the manual install commands in the docs. +maybe_verify_checksum() { + if [ ! -s "$3" ]; then + info "This release does not publish checksums; skipping checksum verification." + return 0 + fi + expected=$(awk -v asset="$2" '$NF == asset {print $1}' "$3" | head -n 1) + if [ -z "$expected" ]; then + warn "checksums.txt has no entry for $2; skipping checksum verification" + return 0 + fi + if ! actual=$(sha256_of "$1"); then + warn "no SHA-256 tool found (sha256sum or shasum); skipping checksum verification" + return 0 + fi + if [ "$actual" != "$expected" ]; then + fatal "checksum mismatch for $2: expected $expected, got $actual; the download may be corrupted or tampered with, aborting" + fi + info "Checksum verified." +} + +# choose_install_dir prints the directory to install into. +choose_install_dir() { + if [ -n "${DEVSY_INSTALL_DIR:-}" ]; then + printf '%s' "$DEVSY_INSTALL_DIR" + elif [ -w /usr/local/bin ] || command -v sudo >/dev/null 2>&1; then + printf '/usr/local/bin' + else + printf '%s/.local/bin' "$HOME" + fi +} + +main() { + need curl + need uname + + os=$(detect_os) + arch=$(detect_arch) + asset="devsy-$os-$arch" + + base=${DEVSY_RELEASE_BASE_URL:-https://github.com/devsy-org/devsy/releases} + version=${DEVSY_VERSION:-} + if [ -n "$version" ]; then + download_base="$base/download/$version" + else + download_base="$base/latest/download" + fi + + tmpdir=$(mktemp -d) + trap 'rm -rf "$tmpdir"' EXIT + + info "Downloading devsy ${version:-latest} for $os/$arch..." + if ! curl -fSL --connect-timeout 15 -o "$tmpdir/$asset" "$download_base/$asset"; then + fatal "download failed: $download_base/$asset (check that the release exists and your network is up)" + fi + + curl -fsSL -o "$tmpdir/checksums.txt" "$download_base/checksums.txt" 2>/dev/null || true + maybe_verify_checksum "$tmpdir/$asset" "$asset" "$tmpdir/checksums.txt" + + install_dir=$(choose_install_dir) + if [ ! -w "$install_dir" ] && command -v sudo >/dev/null 2>&1; then + sudo mkdir -p "$install_dir" + sudo install -c -m 0755 "$tmpdir/$asset" "$install_dir/devsy" || fatal "could not install to $install_dir" + else + mkdir -p "$install_dir" 2>/dev/null || true + if [ ! -w "$install_dir" ]; then + fatal "$install_dir is not writable and sudo is unavailable; set DEVSY_INSTALL_DIR to a writable directory" + fi + install -c -m 0755 "$tmpdir/$asset" "$install_dir/devsy" || fatal "could not install to $install_dir" + fi + info "Installed $install_dir/devsy" + + case ":$PATH:" in + *":$install_dir:"*) ;; + *) warn "$install_dir is not on your PATH; add it with: export PATH=\"$install_dir:\$PATH\"" ;; + esac + + if "$install_dir/devsy" --version >/dev/null 2>&1; then + info "$("$install_dir/devsy" --version)" + fi + info "Next steps: https://devsy.sh/docs/getting-started/quickstart" +} + +main "$@" From 705c228a4285cf01b6bdbe3ba66035f905c7a6bb Mon Sep 17 00:00:00 2001 From: Samuel K Date: Sat, 19 Sep 2026 16:02:08 -0600 Subject: [PATCH 2/8] test(install): add install script test package Signed-off-by: Samuel K --- hack/install_script/doc.go | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 hack/install_script/doc.go diff --git a/hack/install_script/doc.go b/hack/install_script/doc.go new file mode 100644 index 000000000..bfe3e81aa --- /dev/null +++ b/hack/install_script/doc.go @@ -0,0 +1,5 @@ +// Package installscript tests the published Devsy CLI install script +// (sites/docs-devsy-sh/public/install.sh) end to end against a fake +// release server, so the file served at https://devsy.sh/install.sh +// keeps working as releases and platforms evolve. +package installscript From 5e129f4dff337def69fccbc5f004f2ee351c1966 Mon Sep 17 00:00:00 2001 From: Samuel K Date: Sat, 19 Sep 2026 16:02:32 -0600 Subject: [PATCH 3/8] test(install): cover install script behavior end to end Signed-off-by: Samuel K --- hack/install_script/install_test.go | 283 ++++++++++++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 hack/install_script/install_test.go diff --git a/hack/install_script/install_test.go b/hack/install_script/install_test.go new file mode 100644 index 000000000..16d5b3f05 --- /dev/null +++ b/hack/install_script/install_test.go @@ -0,0 +1,283 @@ +package installscript + +import ( + "crypto/sha256" + "fmt" + "net/http" + "net/http/httptest" + "os" + "os/exec" + "path/filepath" + "runtime" + "sort" + "strings" + "testing" +) + +var scriptPath = filepath.Join("..", "..", "sites", "docs-devsy-sh", "public", "install.sh") + +const fakeBinary = "#!/bin/sh\necho 'devsy version v0.0.0-test'\n" + +// fakeRelease serves release assets and, optionally, a goreleaser-style +// checksums.txt, recording the path of every asset request. +type fakeRelease struct { + *httptest.Server + requests *[]string +} + +func newFakeRelease(t *testing.T, assets map[string]string, checksums map[string]string) *fakeRelease { + t.Helper() + requests := &[]string{} + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + parts := strings.Split(strings.TrimPrefix(r.URL.Path, "/"), "/") + name := parts[len(parts)-1] + if name == "checksums.txt" { + if checksums == nil { + http.NotFound(w, r) + return + } + names := make([]string, 0, len(checksums)) + for n := range checksums { + names = append(names, n) + } + sort.Strings(names) + var b strings.Builder + for _, n := range names { + fmt.Fprintf(&b, "%s %s\n", checksums[n], n) + } + _, _ = w.Write([]byte(b.String())) + return + } + body, ok := assets[name] + if !ok { + http.NotFound(w, r) + return + } + *requests = append(*requests, r.URL.Path) + _, _ = w.Write([]byte(body)) + })) + t.Cleanup(srv.Close) + return &fakeRelease{Server: srv, requests: requests} +} + +func checksumFor(body string) string { + return fmt.Sprintf("%x", sha256.Sum256([]byte(body))) +} + +func allAssets() map[string]string { + return map[string]string{ + "devsy-linux-amd64": fakeBinary, + "devsy-linux-arm64": fakeBinary, + "devsy-darwin-amd64": fakeBinary, + "devsy-darwin-arm64": fakeBinary, + "devsy-windows-amd64": fakeBinary, + } +} + +// runInstall executes the install script with a clean DEVSY_*/FAKE_UNAME_* +// environment plus the given extra variables, returning stdout and stderr. +func runInstall(t *testing.T, extraEnv ...string) (string, string, error) { + t.Helper() + if runtime.GOOS == "windows" { + t.Skip("install.sh is a POSIX sh script") + } + if _, err := exec.LookPath("sh"); err != nil { + t.Skip("sh not available") + } + if _, err := exec.LookPath("curl"); err != nil { + t.Skip("curl not available") + } + + var env []string + for _, kv := range os.Environ() { + key := strings.SplitN(kv, "=", 2)[0] + if strings.HasPrefix(key, "DEVSY_") || strings.HasPrefix(key, "FAKE_UNAME_") { + continue + } + env = append(env, kv) + } + env = append(env, extraEnv...) + + cmd := exec.Command("sh", scriptPath) + cmd.Env = env + var stdout, stderr strings.Builder + cmd.Stdout, cmd.Stderr = &stdout, &stderr + err := cmd.Run() + return stdout.String(), stderr.String(), err +} + +func installEnv(t *testing.T, baseURL string) []string { + t.Helper() + return []string{ + "DEVSY_INSTALL_DIR=" + t.TempDir(), + "DEVSY_RELEASE_BASE_URL=" + baseURL, + } +} + +func TestInstallsLatestForHostPlatform(t *testing.T) { + release := newFakeRelease(t, allAssets(), nil) + env := installEnv(t, release.URL) + installDir := strings.TrimPrefix(env[0], "DEVSY_INSTALL_DIR=") + + stdout, stderr, err := runInstall(t, env...) + if err != nil { + t.Fatalf("install failed: %v\nstdout: %s\nstderr: %s", err, stdout, stderr) + } + + asset := fmt.Sprintf("devsy-%s-%s", runtime.GOOS, runtime.GOARCH) + if len(*release.requests) != 1 || (*release.requests)[0] != "/latest/download/"+asset { + t.Errorf("unexpected asset requests: %v", *release.requests) + } + + installed := filepath.Join(installDir, "devsy") + content, err := os.ReadFile(installed) + if err != nil { + t.Fatalf("installed binary missing: %v", err) + } + if string(content) != fakeBinary { + t.Errorf("installed content mismatch: %q", content) + } + fi, err := os.Stat(installed) + if err != nil { + t.Fatal(err) + } + if fi.Mode().Perm() != 0o755 { + t.Errorf("installed mode = %o, want 755", fi.Mode().Perm()) + } + if !strings.Contains(stdout, "devsy version v0.0.0-test") { + t.Errorf("stdout missing installed version output:\n%s", stdout) + } +} + +func TestInstallsPinnedVersion(t *testing.T) { + release := newFakeRelease(t, allAssets(), nil) + env := append(installEnv(t, release.URL), "DEVSY_VERSION=v9.9.9") + + stdout, stderr, err := runInstall(t, env...) + if err != nil { + t.Fatalf("install failed: %v\nstdout: %s\nstderr: %s", err, stdout, stderr) + } + asset := fmt.Sprintf("devsy-%s-%s", runtime.GOOS, runtime.GOARCH) + want := "/download/v9.9.9/" + asset + if len(*release.requests) != 1 || (*release.requests)[0] != want { + t.Errorf("requests = %v, want [%s]", *release.requests, want) + } +} + +func TestVerifiesPublishedChecksum(t *testing.T) { + assets := allAssets() + checksums := map[string]string{} + for name, body := range assets { + checksums[name] = checksumFor(body) + } + release := newFakeRelease(t, assets, checksums) + + stdout, stderr, err := runInstall(t, installEnv(t, release.URL)...) + if err != nil { + t.Fatalf("install failed: %v\nstdout: %s\nstderr: %s", err, stdout, stderr) + } + if !strings.Contains(stdout, "Checksum verified.") { + t.Errorf("stdout missing checksum confirmation:\n%s", stdout) + } +} + +func TestChecksumMismatchAborts(t *testing.T) { + assets := allAssets() + checksums := map[string]string{} + for name := range assets { + checksums[name] = checksumFor("tampered") + } + release := newFakeRelease(t, assets, checksums) + env := installEnv(t, release.URL) + installDir := strings.TrimPrefix(env[0], "DEVSY_INSTALL_DIR=") + + _, stderr, err := runInstall(t, env...) + if err == nil { + t.Fatal("expected checksum mismatch to abort the install") + } + if !strings.Contains(stderr, "checksum mismatch") { + t.Errorf("stderr missing mismatch diagnosis:\n%s", stderr) + } + if _, statErr := os.Stat(filepath.Join(installDir, "devsy")); !os.IsNotExist(statErr) { + t.Error("binary was installed despite checksum mismatch") + } +} + +func TestMissingAssetFailsClearly(t *testing.T) { + release := newFakeRelease(t, map[string]string{}, nil) + + _, stderr, err := runInstall(t, installEnv(t, release.URL)...) + if err == nil { + t.Fatal("expected missing asset to fail the install") + } + if !strings.Contains(stderr, "download failed") { + t.Errorf("stderr missing download failure diagnosis:\n%s", stderr) + } +} + +// withFakeUname prepends a shimmed uname to PATH so platform detection can +// be exercised for platforms other than the test host. +func withFakeUname(t *testing.T, kernel, machine string) []string { + t.Helper() + dir := t.TempDir() + shim := "#!/bin/sh\ncase \"$1\" in\n" + + "-s) printf '%s\\n' \"$FAKE_UNAME_S\" ;;\n" + + "-m) printf '%s\\n' \"$FAKE_UNAME_M\" ;;\n" + + "*) exit 1 ;;\nesac\n" + if err := os.WriteFile(filepath.Join(dir, "uname"), []byte(shim), 0o755); err != nil { + t.Fatal(err) + } + return []string{ + "PATH=" + dir + string(os.PathListSeparator) + os.Getenv("PATH"), + "FAKE_UNAME_S=" + kernel, + "FAKE_UNAME_M=" + machine, + } +} + +func TestPlatformDetection(t *testing.T) { + for _, tc := range []struct { + name string + kernel string + machine string + wantAsset string // empty: expect a clear failure instead + wantErr string + }{ + {"linux arm64", "Linux", "aarch64", "devsy-linux-arm64", ""}, + {"macOS intel", "Darwin", "x86_64", "devsy-darwin-amd64", ""}, + {"macOS silicon", "Darwin", "arm64", "devsy-darwin-arm64", ""}, + {"windows shell", "MINGW64_NT-10.0", "x86_64", "", "for Windows see"}, + {"unsupported OS", "FreeBSD", "amd64", "", "unsupported operating system"}, + {"unsupported arch", "Linux", "riscv64", "", "unsupported CPU architecture"}, + } { + t.Run(tc.name, func(t *testing.T) { + release := newFakeRelease(t, allAssets(), nil) + env := append(installEnv(t, release.URL), withFakeUname(t, tc.kernel, tc.machine)...) + + _, stderr, err := runInstall(t, env...) + if tc.wantAsset == "" { + if err == nil { + t.Fatal("expected install to fail on this platform") + } + if !strings.Contains(stderr, tc.wantErr) { + t.Errorf("stderr missing %q:\n%s", tc.wantErr, stderr) + } + return + } + if err != nil { + t.Fatalf("install failed: %v\nstderr: %s", err, stderr) + } + if len(*release.requests) != 1 || (*release.requests)[0] != "/latest/download/"+tc.wantAsset { + t.Errorf("requests = %v, want asset %s", *release.requests, tc.wantAsset) + } + }) + } +} + +func TestScriptPassesDashSyntaxCheck(t *testing.T) { + if _, err := exec.LookPath("sh"); err != nil { + t.Skip("sh not available") + } + if out, err := exec.Command("sh", "-n", scriptPath).CombinedOutput(); err != nil { + t.Fatalf("sh -n: %v\n%s", err, out) + } +} From acc249550294f17e0f857cf5a1313f3df4c32364 Mon Sep 17 00:00:00 2001 From: Samuel K Date: Sat, 19 Sep 2026 16:02:54 -0600 Subject: [PATCH 4/8] docs(install): document the curl install script Signed-off-by: Samuel K --- .../content/docs/getting-started/install.mdx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/sites/docs-devsy-sh/content/docs/getting-started/install.mdx b/sites/docs-devsy-sh/content/docs/getting-started/install.mdx index 57f00b960..c64f90506 100644 --- a/sites/docs-devsy-sh/content/docs/getting-started/install.mdx +++ b/sites/docs-devsy-sh/content/docs/getting-started/install.mdx @@ -42,7 +42,20 @@ Devsy Desktop needs [WebView 2](https://developer.microsoft.com/en-us/microsoft- ## Install Devsy CLI -On macOS or Linux, install with [Homebrew](https://brew.sh): +On macOS or Linux, the quickest option is the install script: + +```bash +curl -L https://devsy.sh/install.sh | sh +``` + +The script detects your OS and CPU architecture, downloads the latest CLI build from [GitHub releases](https://github.com/devsy-org/devsy/releases), verifies its SHA-256 checksum when the release publishes one, and installs `devsy` into `/usr/local/bin` (or `~/.local/bin` when `/usr/local/bin` isn't writable). Re-run it any time to get the latest release. On Windows, use the PowerShell command in the Windows tab below. + +Two environment variables customize the script: + +- `DEVSY_VERSION` installs a specific release instead of the latest: `curl -L https://devsy.sh/install.sh | DEVSY_VERSION=v1.19.0 sh` +- `DEVSY_INSTALL_DIR` installs somewhere other than the default: `curl -L https://devsy.sh/install.sh | DEVSY_INSTALL_DIR="$HOME/bin" sh` + +On macOS or Linux, you can also install with [Homebrew](https://brew.sh): ```bash brew install devsy-org/homebrew-tap/devsy @@ -50,7 +63,7 @@ brew install devsy-org/homebrew-tap/devsy Upgrade later with `brew upgrade devsy`. -Otherwise, run the command for your platform below. You can also install the CLI later from Devsy Desktop. +To download a binary yourself, run the command for your platform below. You can also install the CLI later from Devsy Desktop. From 206987a0f76a7ebd9bcddfaf4f94f1ea81b6a415 Mon Sep 17 00:00:00 2001 From: Samuel K Date: Sat, 19 Sep 2026 16:03:13 -0600 Subject: [PATCH 5/8] docs(install): point update page at the install script Signed-off-by: Samuel K --- sites/docs-devsy-sh/content/docs/getting-started/update.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sites/docs-devsy-sh/content/docs/getting-started/update.mdx b/sites/docs-devsy-sh/content/docs/getting-started/update.mdx index 7bd6f5c71..f6363f563 100644 --- a/sites/docs-devsy-sh/content/docs/getting-started/update.mdx +++ b/sites/docs-devsy-sh/content/docs/getting-started/update.mdx @@ -17,4 +17,4 @@ If you installed with Homebrew, upgrade with: brew upgrade devsy ``` -Otherwise, re-run the command from [Install Devsy CLI](./install.mdx#install-devsy-cli) to download the latest version. +Otherwise, re-run the install script (`curl -L https://devsy.sh/install.sh | sh`) or the manual command from [Install Devsy CLI](./install.mdx#install-devsy-cli) to download the latest version. From 1802ac0d1533506ba828c9f8f13ce250a596acdf Mon Sep 17 00:00:00 2001 From: Samuel K Date: Sat, 19 Sep 2026 16:06:51 -0600 Subject: [PATCH 6/8] test(install): satisfy repo lint rules Signed-off-by: Samuel K --- hack/install_script/install_test.go | 33 ++++++++++++++++++----------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/hack/install_script/install_test.go b/hack/install_script/install_test.go index 16d5b3f05..571885948 100644 --- a/hack/install_script/install_test.go +++ b/hack/install_script/install_test.go @@ -25,7 +25,11 @@ type fakeRelease struct { requests *[]string } -func newFakeRelease(t *testing.T, assets map[string]string, checksums map[string]string) *fakeRelease { +func newFakeRelease( + t *testing.T, + assets map[string]string, + checksums map[string]string, +) *fakeRelease { t.Helper() requests := &[]string{} srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -74,6 +78,17 @@ func allAssets() map[string]string { } } +func hostAsset() string { + return fmt.Sprintf("devsy-%s-%s", runtime.GOOS, runtime.GOARCH) +} + +func requireSingleRequest(t *testing.T, release *fakeRelease, want string) { + t.Helper() + if len(*release.requests) != 1 || (*release.requests)[0] != want { + t.Errorf("requests = %v, want [%s]", *release.requests, want) + } +} + // runInstall executes the install script with a clean DEVSY_*/FAKE_UNAME_* // environment plus the given extra variables, returning stdout and stderr. func runInstall(t *testing.T, extraEnv ...string) (string, string, error) { @@ -90,7 +105,7 @@ func runInstall(t *testing.T, extraEnv ...string) (string, string, error) { var env []string for _, kv := range os.Environ() { - key := strings.SplitN(kv, "=", 2)[0] + key, _, _ := strings.Cut(kv, "=") if strings.HasPrefix(key, "DEVSY_") || strings.HasPrefix(key, "FAKE_UNAME_") { continue } @@ -124,10 +139,7 @@ func TestInstallsLatestForHostPlatform(t *testing.T) { t.Fatalf("install failed: %v\nstdout: %s\nstderr: %s", err, stdout, stderr) } - asset := fmt.Sprintf("devsy-%s-%s", runtime.GOOS, runtime.GOARCH) - if len(*release.requests) != 1 || (*release.requests)[0] != "/latest/download/"+asset { - t.Errorf("unexpected asset requests: %v", *release.requests) - } + requireSingleRequest(t, release, "/latest/download/"+hostAsset()) installed := filepath.Join(installDir, "devsy") content, err := os.ReadFile(installed) @@ -157,11 +169,7 @@ func TestInstallsPinnedVersion(t *testing.T) { if err != nil { t.Fatalf("install failed: %v\nstdout: %s\nstderr: %s", err, stdout, stderr) } - asset := fmt.Sprintf("devsy-%s-%s", runtime.GOOS, runtime.GOARCH) - want := "/download/v9.9.9/" + asset - if len(*release.requests) != 1 || (*release.requests)[0] != want { - t.Errorf("requests = %v, want [%s]", *release.requests, want) - } + requireSingleRequest(t, release, "/download/v9.9.9/"+hostAsset()) } func TestVerifiesPublishedChecksum(t *testing.T) { @@ -266,7 +274,8 @@ func TestPlatformDetection(t *testing.T) { if err != nil { t.Fatalf("install failed: %v\nstderr: %s", err, stderr) } - if len(*release.requests) != 1 || (*release.requests)[0] != "/latest/download/"+tc.wantAsset { + if len(*release.requests) != 1 || + (*release.requests)[0] != "/latest/download/"+tc.wantAsset { t.Errorf("requests = %v, want asset %s", *release.requests, tc.wantAsset) } }) From db186d61ad29b4372db4e57745b0f011c8c099f4 Mon Sep 17 00:00:00 2001 From: Samuel K Date: Sat, 19 Sep 2026 16:18:33 -0600 Subject: [PATCH 7/8] style(install): strip comments from install.sh Signed-off-by: Samuel K --- sites/docs-devsy-sh/public/install.sh | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/sites/docs-devsy-sh/public/install.sh b/sites/docs-devsy-sh/public/install.sh index 0f7473497..40cd8c60d 100644 --- a/sites/docs-devsy-sh/public/install.sh +++ b/sites/docs-devsy-sh/public/install.sh @@ -1,16 +1,4 @@ #!/bin/sh -# Install the Devsy CLI. -# -# curl -L https://devsy.sh/install.sh | sh -# -# Optional environment variables: -# DEVSY_VERSION Release tag to install (for example v1.19.0) -# instead of the latest release. -# DEVSY_INSTALL_DIR Directory to install into. Defaults to -# /usr/local/bin, or ~/.local/bin when /usr/local/bin -# is not writable and sudo is unavailable. -# DEVSY_RELEASE_BASE_URL Release download base URL, for mirrors or testing. -# Defaults to https://github.com/devsy-org/devsy/releases. set -eu info() { @@ -49,8 +37,6 @@ detect_arch() { esac } -# sha256_of prints the file's SHA-256 digest, or fails when no -# SHA-256 tool is available. sha256_of() { if command -v sha256sum >/dev/null 2>&1; then sha256sum "$1" | awk '{print $1}' @@ -61,9 +47,6 @@ sha256_of() { fi } -# maybe_verify_checksum -# Verifies the download when the release publishes checksums; otherwise -# continues with a note, matching the manual install commands in the docs. maybe_verify_checksum() { if [ ! -s "$3" ]; then info "This release does not publish checksums; skipping checksum verification." @@ -84,7 +67,6 @@ maybe_verify_checksum() { info "Checksum verified." } -# choose_install_dir prints the directory to install into. choose_install_dir() { if [ -n "${DEVSY_INSTALL_DIR:-}" ]; then printf '%s' "$DEVSY_INSTALL_DIR" From d0ca94c03de6826ff49b8bba187c47affe8b9957 Mon Sep 17 00:00:00 2001 From: Samuel K Date: Sat, 19 Sep 2026 16:19:54 -0600 Subject: [PATCH 8/8] style(install): strip comments from install script tests Signed-off-by: Samuel K --- hack/install_script/install_test.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/hack/install_script/install_test.go b/hack/install_script/install_test.go index 571885948..cce801c5f 100644 --- a/hack/install_script/install_test.go +++ b/hack/install_script/install_test.go @@ -18,8 +18,6 @@ var scriptPath = filepath.Join("..", "..", "sites", "docs-devsy-sh", "public", " const fakeBinary = "#!/bin/sh\necho 'devsy version v0.0.0-test'\n" -// fakeRelease serves release assets and, optionally, a goreleaser-style -// checksums.txt, recording the path of every asset request. type fakeRelease struct { *httptest.Server requests *[]string @@ -89,8 +87,6 @@ func requireSingleRequest(t *testing.T, release *fakeRelease, want string) { } } -// runInstall executes the install script with a clean DEVSY_*/FAKE_UNAME_* -// environment plus the given extra variables, returning stdout and stderr. func runInstall(t *testing.T, extraEnv ...string) (string, string, error) { t.Helper() if runtime.GOOS == "windows" { @@ -223,8 +219,6 @@ func TestMissingAssetFailsClearly(t *testing.T) { } } -// withFakeUname prepends a shimmed uname to PATH so platform detection can -// be exercised for platforms other than the test host. func withFakeUname(t *testing.T, kernel, machine string) []string { t.Helper() dir := t.TempDir() @@ -247,7 +241,7 @@ func TestPlatformDetection(t *testing.T) { name string kernel string machine string - wantAsset string // empty: expect a clear failure instead + wantAsset string wantErr string }{ {"linux arm64", "Linux", "aarch64", "devsy-linux-arm64", ""},