v3.1.0 d676137

install_next_test.sh RawHistoryFolder

1#!/bin/sh
2set -eu
3
4ROOT=$(CDPATH='' cd -- "$(dirname -- "$0")/.." && pwd)
5PASS=0
6FAIL=0
7SHA=0123456789abcdef0123456789abcdef01234567
8
9fail() {
10    echo "not ok - $1"
11    FAIL=$((FAIL + 1))
12}
13
14pass() {
15    echo "ok - $1"
16    PASS=$((PASS + 1))
17}
18
19run_case() {
20    shift
21    case_dir=$(mktemp -d)
22    mkdir -p "$case_dir/bin" "$case_dir/home" "$case_dir/install"
23
24    cat >"$case_dir/bin/uname" <<'EOF'
25#!/bin/sh
26[ "$1" = "-s" ] && echo Linux || echo x86_64
27EOF
28    cat >"$case_dir/bin/id" <<'EOF'
29#!/bin/sh
30[ "$1" = "-u" ] && { echo 1000; exit 0; }
31exec /usr/bin/id "$@"
32EOF
33    cat >"$case_dir/bin/curl" <<EOF
34#!/bin/sh
35printf '%s\n' "\$*" >>'$case_dir/curl.log'
36case "\$*" in
37  *api.github.com/repos/bnema/gordon/commits/next*) printf '%s\n' '{"sha":"$SHA"}' ;;
38  *codeload.github.com/bnema/gordon/tar.gz/$SHA*) : >'$case_dir/source.tar.gz' ;;
39  *) exit 90 ;;
40esac
41EOF
42    cat >"$case_dir/bin/tar" <<EOF
43#!/bin/sh
44printf '%s\n' "\$*" >>'$case_dir/tar.log'
45case "\$1" in
46  -tzf) printf '%s\n' 'gordon-$SHA/' 'gordon-$SHA/go.mod' 'gordon-$SHA/main.go' ;;
47  -tvzf) printf '%s\n' 'drwxr-xr-x root/root 0 date gordon-$SHA/' '-rw-r--r-- root/root 0 date gordon-$SHA/go.mod' '-rw-r--r-- root/root 0 date gordon-$SHA/main.go' ;;
48  -xzf)
49    while [ "\$#" -gt 0 ]; do
50      if [ "\$1" = -C ]; then
51        shift
52        mkdir -p "\$1/gordon-$SHA"
53        printf 'module example\n\ngo 1.27\n' >"\$1/gordon-$SHA/go.mod"
54        : >"\$1/gordon-$SHA/main.go"
55        exit 0
56      fi
57      shift
58    done
59    ;;
60esac
61EOF
62    cat >"$case_dir/bin/go" <<EOF
63#!/bin/sh
64printf '%s\n' "GOOS=\${GOOS-} GOARCH=\${GOARCH-} GOTOOLCHAIN=\${GOTOOLCHAIN-} \$*" >>'$case_dir/go.log'
65if [ "\$1 \$2" = 'env GOVERSION' ]; then echo go1.27.1; exit 0; fi
66if [ "\$1" = build ]; then
67  while [ "\$#" -gt 0 ]; do [ "\$1" = -o ] && { shift; : >"\$1"; chmod 755 "\$1"; exit 0; }; shift; done
68fi
69exit 91
70EOF
71    cat >"$case_dir/bin/install" <<EOF
72#!/bin/sh
73printf '%s\n' "\$*" >>'$case_dir/install.log'
74cp "\$3" "\$4"
75EOF
76    cat >"$case_dir/bin/mv" <<EOF
77#!/bin/sh
78printf '%s\n' "\$*" >>'$case_dir/mv.log'
79[ "\$1" = -f ] && shift
80/bin/mv "\$1" "\$2"
81EOF
82    chmod +x "$case_dir/bin/"*
83    mkdir -p "$case_dir/tmp"
84
85    if (PATH="$case_dir/bin:/usr/bin:/bin" HOME="$case_dir/home" SHELL=/bin/bash TMPDIR="$case_dir/tmp" GORDON_UPDATE_PATH=0 "$@") >"$case_dir/out" 2>&1; then
86        status=0
87    else
88        status=$?
89    fi
90}
91
92test_next_build() {
93    run_case next-build env GORDON_CHANNEL=next sh "$ROOT/install.sh"
94    [ "$status" -eq 0 ] || { cat "$case_dir/out"; fail "next channel builds pinned source"; return; }
95    if grep -q "commits/next" "$case_dir/curl.log" &&
96        grep -q "codeload.github.com/bnema/gordon/tar.gz/$SHA" "$case_dir/curl.log" &&
97        grep -q -- "-X main.version=next-$SHA" "$case_dir/go.log" &&
98        grep -q "GOOS=linux GOARCH=amd64 GOTOOLCHAIN=local" "$case_dir/go.log" &&
99        grep -q "UNVERIFIED DEVELOPMENT BUILD" "$case_dir/out" &&
100        [ -x "$case_dir/home/.local/bin/gordon" ]; then
101        pass "next channel builds pinned source"
102    else
103        fail "next channel builds pinned source"
104    fi
105}
106
107test_conflicts() {
108    run_case version-conflict env GORDON_CHANNEL=next GORDON_VERSION=v1.2.3 sh "$ROOT/install.sh"
109    if [ "$status" -ne 0 ] && grep -q "GORDON_VERSION cannot be used" "$case_dir/out"; then
110        pass "next rejects GORDON_VERSION"
111    else
112        fail "next rejects GORDON_VERSION"
113    fi
114
115    run_case prerelease-conflict env GORDON_CHANNEL=next GORDON_PRERELEASE=1 sh "$ROOT/install.sh"
116    if [ "$status" -ne 0 ] && grep -q "GORDON_PRERELEASE cannot be used" "$case_dir/out"; then
117        pass "next rejects GORDON_PRERELEASE"
118    else
119        fail "next rejects GORDON_PRERELEASE"
120    fi
121}
122
123test_go_version() {
124    run_case old-go env GORDON_CHANNEL=next MOCK_GO_VERSION=unused sh "$ROOT/install.sh"
125    # Replace the mock after setup, then run once more in the same fixture.
126    cat >"$case_dir/bin/go" <<'EOF'
127#!/bin/sh
128[ "$1 $2" = 'env GOVERSION' ] && { echo go1.26.9; exit 0; }
129exit 91
130EOF
131    chmod +x "$case_dir/bin/go"
132    if (PATH="$case_dir/bin:/usr/bin:/bin" HOME="$case_dir/home" SHELL=/bin/bash TMPDIR="$case_dir/tmp" GORDON_UPDATE_PATH=0 GORDON_CHANNEL=next sh "$ROOT/install.sh") >"$case_dir/out" 2>&1; then status=0; else status=$?; fi
133    if [ "$status" -ne 0 ] && grep -q "requires Go 1.27 or newer" "$case_dir/out"; then
134        pass "next enforces go.mod Go version"
135    else
136        fail "next enforces go.mod Go version"
137    fi
138}
139
140test_default_and_path_modes() {
141    run_case default-dir env GORDON_CHANNEL=next sh "$ROOT/install.sh"
142    if [ "$status" -eq 0 ] && [ -x "$case_dir/home/.local/bin/gordon" ] &&
143        grep -q "export PATH='${case_dir}/home/.local/bin':\$PATH" "$case_dir/out"; then
144        pass "default install is user-local and prints current-shell instruction"
145    else
146        fail "default install is user-local and prints current-shell instruction"
147    fi
148
149    run_case path-present env GORDON_CHANNEL=next sh "$ROOT/install.sh"
150    if (PATH="$case_dir/bin:$case_dir/home/.local/bin:/usr/bin:/bin" HOME="$case_dir/home" SHELL=/bin/bash TMPDIR="$case_dir/tmp" GORDON_UPDATE_PATH=0 GORDON_CHANNEL=next sh "$ROOT/install.sh") >"$case_dir/out" 2>&1; then status=0; else status=$?; fi
151    if [ "$status" -eq 0 ] && ! grep -q "Add Gordon to the current shell" "$case_dir/out"; then
152        pass "existing PATH needs no update"
153    else
154        fail "existing PATH needs no update"
155    fi
156
157    run_case forced-no env GORDON_CHANNEL=next GORDON_UPDATE_PATH=0 sh "$ROOT/install.sh"
158    if [ "$status" -eq 0 ] && [ ! -e "$case_dir/home/.bashrc" ]; then
159        pass "forced no does not modify shell config"
160    else
161        fail "forced no does not modify shell config"
162    fi
163
164    run_case invalid-update env GORDON_CHANNEL=next GORDON_UPDATE_PATH=maybe sh "$ROOT/install.sh"
165    if [ "$status" -ne 0 ] && grep -q "must be 0 or 1" "$case_dir/out"; then
166        pass "invalid PATH mode is rejected"
167    else
168        fail "invalid PATH mode is rejected"
169    fi
170
171    run_case unsafe-dir env GORDON_CHANNEL=next GORDON_INSTALL_DIR="/tmp/unsafe
172path" sh "$ROOT/install.sh"
173    if [ "$status" -ne 0 ] && grep -q "unsafe control character" "$case_dir/out"; then
174        pass "control characters in install directory are rejected"
175    else
176        fail "control characters in install directory are rejected"
177    fi
178
179    run_case trailing-newline env GORDON_CHANNEL=next GORDON_INSTALL_DIR="/tmp/unsafe
180" sh "$ROOT/install.sh"
181    if [ "$status" -ne 0 ] && grep -q "unsafe control character" "$case_dir/out"; then
182        pass "trailing newline in install directory is rejected"
183    else
184        fail "trailing newline in install directory is rejected"
185    fi
186}
187
188test_shell_updates() {
189    for shell in bash zsh fish; do
190        run_case "shell-$shell" env GORDON_CHANNEL=next GORDON_UPDATE_PATH=1 SHELL="/usr/bin/$shell" sh "$ROOT/install.sh"
191        case "$shell" in
192            bash) config=$case_dir/home/.bashrc; expected="export PATH='${case_dir}/home/.local/bin':\$PATH" ;;
193            zsh) config=$case_dir/home/.zshrc; expected="export PATH='${case_dir}/home/.local/bin':\$PATH" ;;
194            fish) config=$case_dir/home/.config/fish/config.fish; expected="fish_add_path '${case_dir}/home/.local/bin'" ;;
195        esac
196        if [ "$status" -eq 0 ] && grep -Fq "$expected" "$config"; then
197            pass "$shell PATH update"
198        else
199            fail "$shell PATH update"
200        fi
201    done
202
203    run_case idempotent env GORDON_CHANNEL=next GORDON_UPDATE_PATH=1 SHELL=/bin/bash sh "$ROOT/install.sh"
204    first_case=$case_dir
205    if (PATH="$case_dir/bin:/usr/bin:/bin" HOME="$case_dir/home" SHELL=/bin/bash TMPDIR="$case_dir/tmp" GORDON_UPDATE_PATH=1 GORDON_CHANNEL=next sh "$ROOT/install.sh") >>"$case_dir/out" 2>&1 &&
206        [ "$(grep -c '^# >>> Gordon installer PATH >>>$' "$case_dir/home/.bashrc")" -eq 1 ]; then
207        pass "PATH marker block is idempotent"
208    else
209        cat "$first_case/out"
210        fail "PATH marker block is idempotent"
211    fi
212
213    run_case unsupported env GORDON_CHANNEL=next GORDON_UPDATE_PATH=1 SHELL=/bin/ksh sh "$ROOT/install.sh"
214    if [ "$status" -eq 0 ] && grep -q "unsupported or missing SHELL" "$case_dir/out"; then
215        pass "unsupported shell gets manual instructions"
216    else
217        fail "unsupported shell gets manual instructions"
218    fi
219}
220
221test_explicit_global_override() {
222    run_case home-bin env GORDON_CHANNEL=next sh "$ROOT/install.sh"
223    if (PATH="$case_dir/bin:/usr/bin:/bin" HOME="$case_dir/home" SHELL=/bin/bash TMPDIR="$case_dir/tmp" GORDON_UPDATE_PATH=1 GORDON_INSTALL_DIR="$case_dir/home/bin" GORDON_CHANNEL=next sh "$ROOT/install.sh") >"$case_dir/out" 2>&1; then status=0; else status=$?; fi
224    if [ "$status" -eq 0 ] && [ -x "$case_dir/home/bin/gordon" ] &&
225        grep -Fq "export PATH='${case_dir}/home/bin':\$PATH" "$case_dir/home/.bashrc"; then
226        pass "HOME bin override is installed and added to PATH"
227    else
228        fail "HOME bin override is installed and added to PATH"
229    fi
230
231    run_case global env GORDON_CHANNEL=next sh "$ROOT/install.sh"
232    if (PATH="$case_dir/bin:/usr/bin:/bin" HOME="$case_dir/home" SHELL=/bin/bash TMPDIR="$case_dir/tmp" GORDON_UPDATE_PATH=0 GORDON_INSTALL_DIR="$case_dir/install" GORDON_CHANNEL=next sh "$ROOT/install.sh") >"$case_dir/out" 2>&1; then status=0; else status=$?; fi
233    if [ "$status" -eq 0 ] && [ -x "$case_dir/install/gordon" ]; then
234        pass "explicit global install override is preserved"
235    else
236        fail "explicit global install override is preserved"
237    fi
238
239    run_case sudo-default env SUDO_USER=test-user GORDON_CHANNEL=next sh "$ROOT/install.sh"
240    if [ "$status" -ne 0 ] && grep -q "Refusing a default user-local install" "$case_dir/out" && [ ! -e "$case_dir/home/.local/bin/gordon" ]; then
241        pass "sudo default install is refused"
242    else
243        fail "sudo default install is refused"
244    fi
245}
246
247test_next_build
248test_conflicts
249test_go_version
250test_default_and_path_modes
251test_shell_updates
252test_explicit_global_override
253printf '%s passed, %s failed\n' "$PASS" "$FAIL"
254[ "$FAIL" -eq 0 ]

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 7

Tags 106

↑↓ moveenter openesc close