Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33ebf89748 |
No files matched your search
@@ -130,8 +130,8 @@ package (pacman backend with paru or yay, see below) and a space on every other
|
||||
|
||||
One line, whitespace-separated tokens; `N` is the number in brackets. Numbers are
|
||||
stable for the whole session (rows that leave the list leave a gap). Every token
|
||||
of a line is validated first: a line with an unknown token or a number that is not
|
||||
listed prints an error, runs nothing, and the prompt comes back.
|
||||
of a line is checked for syntax first: an unknown token rejects the line. A number
|
||||
that is not listed prints an error and the remaining commands still run.
|
||||
|
||||
| token | action |
|
||||
|-------|--------|
|
||||
@@ -147,7 +147,10 @@ listed prints an error, runs nothing, and the prompt comes back.
|
||||
| `h`, `?` | help |
|
||||
| end of input | abort without upgrading (exit 2) |
|
||||
|
||||
Several tokens may share a line (`1? 3- 4+`); they run left to right. With `--all`
|
||||
Several tokens may share a line (`1? 3- 4+`); they run left to right. Consecutive
|
||||
`N+` commands are processed together: selected packages required by another selected
|
||||
package are recorded as dependencies, regardless of their order. `*+` works the same
|
||||
way. With `--all`
|
||||
trusted packages are listed too, marked with `=`. When purges leave nothing to upgrade the
|
||||
session ends by itself (exit 0).
|
||||
|
||||
|
||||
+5
-2
@@ -125,6 +125,9 @@ Refreshing package lists... done.
|
||||
```
|
||||
|
||||
Command grammar (one line, whitespace-separated tokens, each `N` is the number in brackets):
|
||||
Unknown tokens reject the line; nonexistent numbers report an error and are skipped.
|
||||
Consecutive `N+` commands and `*+` trust the selected dependency roots, recording
|
||||
other selected packages in their closures as dependencies regardless of input order.
|
||||
|
||||
| token | action |
|
||||
|--------|---------------------------------------------------------------------------|
|
||||
@@ -153,8 +156,8 @@ On AUR rows `N?`, `N+` and `Nx` act through pacman like on any installed package
|
||||
`pacman -Qi` with `<helper> -Sia PKG`; `N-` excludes the row through the helper's `--ignore`.
|
||||
|
||||
Numbers are stable for the whole session (removed rows leave a gap, never renumber).
|
||||
All tokens of a line are validated first: an unknown token or a number that is not listed
|
||||
prints an error, runs nothing of that line and re-prompts. EOF on stdin aborts without
|
||||
Syntax is validated first; an unknown token rejects the line. Numbers that are not listed
|
||||
print an error and are skipped while the remaining commands run. EOF on stdin aborts without
|
||||
upgrading (exit 2) so a piped run can never upgrade by accident unless it sends an empty
|
||||
line. When purges leave no row at all, the session ends ("Nothing left to upgrade.", exit 0).
|
||||
|
||||
|
||||
+40
-18
@@ -6,7 +6,7 @@
|
||||
# and zypper: list what would be upgraded, interrogate every package, remember the
|
||||
# ones you trust, then run the native upgrade (with per-run exclusions).
|
||||
#
|
||||
# Version: 0.1.0
|
||||
# Version: 0.2.0
|
||||
#
|
||||
# Specification: docs/DESIGN.md. Single file, bash >= 4.3, no runtime dependency
|
||||
# beyond the distro's package manager and coreutils/sed/grep (awk only on the apt
|
||||
@@ -23,7 +23,7 @@ export LC_ALL=C DEBIAN_FRONTEND=noninteractive
|
||||
# never read from or written to a file (no HISTFILE; `history -r`/`-w`/`-a` are never used).
|
||||
unset HISTFILE
|
||||
|
||||
readonly SU_VERSION=0.1.0
|
||||
readonly SU_VERSION=0.2.0
|
||||
readonly SU_PROG=skeptical-updater
|
||||
readonly SU_STATE_HEADER='# skeptical-updater trusted packages. Columns: backend package reason added(UTC ISO-8601)'
|
||||
readonly SU_PROMPT_HELP='<enter> upgrade | N? what is it | N?? full info | N- exclude this run | Nx purge now | N+ trust forever'
|
||||
@@ -2712,9 +2712,28 @@ session_purge() {
|
||||
}
|
||||
|
||||
session_trust() { # session_trust IDX...
|
||||
local i now
|
||||
now=$(now_utc)
|
||||
local i j d now covered
|
||||
local -a selected=() roots=()
|
||||
local -A seen=() reach=()
|
||||
for i in "$@"; do
|
||||
[[ -z ${seen[$i]+x} ]] || continue
|
||||
seen[$i]=1
|
||||
selected+=("$i")
|
||||
done
|
||||
for i in "${selected[@]}"; do
|
||||
closure_of "${R_NAME[i]}"
|
||||
for d in ${CLOSURE[@]+"${CLOSURE[@]}"}; do reach["$i,$d"]=1; done
|
||||
done
|
||||
for i in "${selected[@]}"; do
|
||||
covered=0
|
||||
for j in "${selected[@]}"; do
|
||||
[[ $i != "$j" && -n ${reach[$j,${R_NAME[i]}]+x} ]] || continue
|
||||
if [[ -z ${reach[$i,${R_NAME[j]}]+x} ]] || ((j < i)); then covered=1; break; fi
|
||||
done
|
||||
((covered)) || roots+=("$i")
|
||||
done
|
||||
now=$(now_utc)
|
||||
for i in "${roots[@]}"; do
|
||||
trust_pkg "${R_NAME[i]}" "$now"
|
||||
R_EXCL[i]=0
|
||||
done
|
||||
@@ -2747,10 +2766,10 @@ session_toggle_all() {
|
||||
SESSION_PROCEED=0
|
||||
UPGRADE_FAILED_MSG= # set by <be>_upgrade when the failing step is not the package manager's own
|
||||
|
||||
# session_line LINE: validate every token first (a typo never executes half a line), then run them
|
||||
session_line() {
|
||||
local tok n op i
|
||||
local -a toks=()
|
||||
local -a toks=() batch=()
|
||||
local -A initial=()
|
||||
local re='^([0-9]{1,6})(\?\?|\?|-|x|\+)$'
|
||||
read -r -a toks <<<"$1" || true
|
||||
if ((${#toks[@]} == 0)); then
|
||||
@@ -2758,13 +2777,7 @@ session_line() {
|
||||
return 0
|
||||
fi
|
||||
for tok in "${toks[@]}"; do
|
||||
if [[ $tok =~ $re ]]; then
|
||||
n=$((10#${BASH_REMATCH[1]}))
|
||||
if ! num_row "$n"; then
|
||||
err "no package [$n] in the list (l to redraw)"
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
if [[ ! $tok =~ $re ]]; then
|
||||
case $tok in
|
||||
'*+' | '*-' | l | q | h | '?') ;;
|
||||
*)
|
||||
@@ -2774,15 +2787,23 @@ session_line() {
|
||||
esac
|
||||
fi
|
||||
done
|
||||
for ((n = 1; n <= N_MAX; n++)); do
|
||||
if num_row "$n"; then initial[$n]=$REPLY; fi
|
||||
done
|
||||
for tok in "${toks[@]}"; do
|
||||
if [[ $tok =~ $re ]]; then
|
||||
n=$((10#${BASH_REMATCH[1]}))
|
||||
op=${BASH_REMATCH[2]}
|
||||
if ! num_row "$n"; then
|
||||
err "package [$n] has left the list; ignoring the rest of the line"
|
||||
return 0
|
||||
if [[ -z ${initial[$n]+x} ]] || ((R_GONE[${initial[$n]:-0}])); then
|
||||
err "no package [$n] in the list (l to redraw)"
|
||||
continue
|
||||
fi
|
||||
i=$REPLY
|
||||
i=${initial[$n]}
|
||||
if [[ $op == + ]]; then
|
||||
batch+=("$i")
|
||||
continue
|
||||
fi
|
||||
if ((${#batch[@]})); then session_trust "${batch[@]}"; batch=(); fi
|
||||
case $op in
|
||||
'?') print_info "${R_NAME[i]}" "${R_OLD[i]}" || true ;;
|
||||
'??') print_full_info "${R_NAME[i]}" "${R_OLD[i]}" || true ;;
|
||||
@@ -2802,9 +2823,9 @@ session_line() {
|
||||
exit 0
|
||||
fi
|
||||
;;
|
||||
+) session_trust "$i" ;;
|
||||
esac
|
||||
else
|
||||
if ((${#batch[@]})); then session_trust "${batch[@]}"; batch=(); fi
|
||||
case $tok in
|
||||
'*+')
|
||||
local -a idx=()
|
||||
@@ -2823,6 +2844,7 @@ session_line() {
|
||||
esac
|
||||
fi
|
||||
done
|
||||
if ((${#batch[@]})); then session_trust "${batch[@]}"; fi
|
||||
}
|
||||
|
||||
cmd_interactive() {
|
||||
|
||||
@@ -292,11 +292,49 @@ UPGRADE='apt-get -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--forc
|
||||
run skup --no-refresh <<<$'*+\nl\nq'
|
||||
assert_success
|
||||
assert_line 'trusted su-dummy-a (+1 dependency: su-dummy-b)'
|
||||
assert_line 'trusted su-dummy-b'
|
||||
assert_line 'trusted su-dummy-c'
|
||||
assert_line '3 upgradable, 3 trusted (hidden, use --all to show), 0 to review:'
|
||||
run cut -f2,3 "$STATE_FILE"
|
||||
assert_line "su-dummy-b${T}user"
|
||||
assert_line "su-dummy-b${T}dep:su-dummy-a"
|
||||
}
|
||||
|
||||
@test "consecutive trust commands keep dependencies under their selected root in either order" {
|
||||
for line in '1+ 2+ 3+' '2+ 3+ 1+'; do
|
||||
rm -rf "$STATE"
|
||||
run skup --no-refresh <<<"$line"$'\nq'
|
||||
assert_success
|
||||
assert_line 'trusted su-dummy-a (+1 dependency: su-dummy-b)'
|
||||
assert_line 'trusted su-dummy-c'
|
||||
refute_output --partial 'no package ['
|
||||
run cut -f2,3 "$STATE_FILE"
|
||||
assert_line "su-dummy-a${T}user"
|
||||
assert_line "su-dummy-b${T}dep:su-dummy-a"
|
||||
assert_line "su-dummy-c${T}user"
|
||||
done
|
||||
}
|
||||
|
||||
@test "invalid numbers do not stop other commands on the line" {
|
||||
run skup --no-refresh <<<$'9+ 2- 0? 3+\nq'
|
||||
assert_success
|
||||
assert_output --partial 'no package [9] in the list'
|
||||
assert_output --partial 'no package [0] in the list'
|
||||
assert_line 'excluded from this run: su-dummy-b'
|
||||
assert_line 'trusted su-dummy-c'
|
||||
}
|
||||
|
||||
@test "a package removed by a purge does not stop later commands" {
|
||||
FAKE_APT_AUTO_ORPHANS=su-dummy-a:su-dummy-b run skup --no-refresh <<<$'1x 2? 3-\ny\nq'
|
||||
assert_success
|
||||
assert_output --partial 'no package [2] in the list'
|
||||
assert_line 'excluded from this run: su-dummy-c'
|
||||
}
|
||||
|
||||
@test "trusting a dependency and its root with --all keeps the dependency implicit" {
|
||||
run skup --no-refresh --all <<<$'2+ 1+\nq'
|
||||
assert_success
|
||||
run cut -f2,3 "$STATE_FILE"
|
||||
assert_line "su-dummy-a${T}user"
|
||||
assert_line "su-dummy-b${T}dep:su-dummy-a"
|
||||
}
|
||||
|
||||
@test "*- excludes every listed package; *- again re-includes them" {
|
||||
|
||||
Reference in new issue
Block a user