fpf-cli 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -73
- package/fpf +241 -59
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,40 +1,10 @@
|
|
|
1
|
-
#
|
|
1
|
+
# fpf-cli (`fpf`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Simple fuzzy package finder for people who live in the terminal.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Search packages with `fzf`, preview details, and install/remove/update from one place.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
- Linux distro managers: `apt`, `dnf`, `pacman`, `zypper`, `emerge`
|
|
10
|
-
- Cross-platform app managers: `snap`, `flatpak`
|
|
11
|
-
- Dev package managers: `npm`, `bun`
|
|
12
|
-
- macOS: `brew`
|
|
13
|
-
|
|
14
|
-
`winget` is intentionally not supported.
|
|
15
|
-
|
|
16
|
-
## Features
|
|
17
|
-
|
|
18
|
-
- Auto-detects default manager from OS + distro
|
|
19
|
-
- Supports manager override with one or two-letter flags
|
|
20
|
-
- Unified fuzzy UI for search/install/list/remove
|
|
21
|
-
- Multi-select installs/removals with safety confirmation
|
|
22
|
-
- Shared keybinds and preview pane behavior across managers
|
|
23
|
-
|
|
24
|
-
## Requirements
|
|
25
|
-
|
|
26
|
-
- `bash`
|
|
27
|
-
- `fzf`
|
|
28
|
-
- One or more supported package managers from the list above
|
|
29
|
-
|
|
30
|
-
## Usage
|
|
31
|
-
|
|
32
|
-
```bash
|
|
33
|
-
fpf [manager option] [action option] [query]
|
|
34
|
-
fpf -m|--manager <name> [action option] [query]
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Default action is `search + install` using auto-detected manager.
|
|
7
|
+

|
|
38
8
|
|
|
39
9
|
## Install
|
|
40
10
|
|
|
@@ -46,59 +16,67 @@ npm install -g fpf-cli
|
|
|
46
16
|
bun add -g fpf-cli
|
|
47
17
|
```
|
|
48
18
|
|
|
49
|
-
|
|
19
|
+
## Quick Start
|
|
50
20
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
- `-h`, `--help` - show help
|
|
21
|
+
```bash
|
|
22
|
+
# Search + install (default action)
|
|
23
|
+
fpf ripgrep
|
|
55
24
|
|
|
56
|
-
|
|
25
|
+
# List installed packages
|
|
26
|
+
fpf -l
|
|
57
27
|
|
|
58
|
-
|
|
59
|
-
-
|
|
60
|
-
- `-pm`, `--pacman`
|
|
61
|
-
- `-zy`, `--zypper`
|
|
62
|
-
- `-em`, `--emerge`
|
|
63
|
-
- `-br`, `--brew`
|
|
64
|
-
- `-sn`, `--snap`
|
|
65
|
-
- `-fp`, `--flatpak`
|
|
66
|
-
- `-np`, `--npm`
|
|
67
|
-
- `-bn`, `--bun`
|
|
68
|
-
- `-ad`, `--auto` (force auto-detection)
|
|
69
|
-
- `-m`, `--manager <name>` (explicit manager by name)
|
|
28
|
+
# Remove packages
|
|
29
|
+
fpf -R
|
|
70
30
|
|
|
71
|
-
|
|
31
|
+
# Update packages
|
|
32
|
+
fpf -U
|
|
33
|
+
```
|
|
72
34
|
|
|
73
|
-
|
|
74
|
-
# Auto-detected manager search/install
|
|
75
|
-
fpf ripgrep
|
|
35
|
+
By default, `fpf` auto-detects your package manager.
|
|
76
36
|
|
|
77
|
-
|
|
78
|
-
fpf -dn nginx
|
|
37
|
+
On macOS, default auto mode uses both `brew` and `bun` together.
|
|
79
38
|
|
|
80
|
-
|
|
81
|
-
fpf -ap -l openssl
|
|
39
|
+
On Linux, default auto mode uses your distro manager plus installed cross-platform managers (`snap`, `flatpak`, `brew`, `npm`, `bun`).
|
|
82
40
|
|
|
83
|
-
|
|
84
|
-
fpf -br -R wget
|
|
41
|
+
## Supported Managers
|
|
85
42
|
|
|
86
|
-
|
|
87
|
-
|
|
43
|
+
- Linux: `apt`, `dnf`, `pacman`, `zypper`, `emerge`
|
|
44
|
+
- Cross-platform: `snap`, `flatpak`
|
|
45
|
+
- Dev: `npm`, `bun`
|
|
46
|
+
- macOS: `brew`
|
|
88
47
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
48
|
+
(`winget` intentionally not included.)
|
|
49
|
+
|
|
50
|
+
## Manager Override Flags
|
|
51
|
+
|
|
52
|
+
- `-ap` apt
|
|
53
|
+
- `-dn` dnf
|
|
54
|
+
- `-pm` pacman
|
|
55
|
+
- `-zy` zypper
|
|
56
|
+
- `-em` emerge
|
|
57
|
+
- `-br` brew
|
|
58
|
+
- `-sn` snap
|
|
59
|
+
- `-fp` flatpak
|
|
60
|
+
- `-np` npm
|
|
61
|
+
- `-bn` bun
|
|
62
|
+
- `-m, --manager <name>` full manager name
|
|
63
|
+
|
|
64
|
+
## Common Options
|
|
65
|
+
|
|
66
|
+
- `-l, --list-installed` list installed packages
|
|
67
|
+
- `-R, --remove` remove selected packages
|
|
68
|
+
- `-U, --update` run update/upgrade flow
|
|
69
|
+
- `-h, --help` show help
|
|
92
70
|
|
|
93
71
|
## Keybinds
|
|
94
72
|
|
|
95
|
-
- `ctrl-h`
|
|
96
|
-
- `ctrl-k`
|
|
73
|
+
- `ctrl-h` help in preview
|
|
74
|
+
- `ctrl-k` keybinds in preview
|
|
97
75
|
- `ctrl-/` toggle preview
|
|
98
|
-
- `ctrl-n`
|
|
99
|
-
- `ctrl-b`
|
|
76
|
+
- `ctrl-n` next selected item
|
|
77
|
+
- `ctrl-b` previous selected item
|
|
100
78
|
|
|
101
79
|
## Notes
|
|
102
80
|
|
|
103
|
-
-
|
|
104
|
-
-
|
|
81
|
+
- Requires: `bash` + `fzf`
|
|
82
|
+
- Root managers (`apt`, `dnf`, `pacman`, `zypper`, `emerge`, `snap`) use `sudo` when needed.
|
package/fpf
CHANGED
|
@@ -202,8 +202,92 @@ detect_default_manager() {
|
|
|
202
202
|
die "Unable to auto-detect a supported package manager. Use --manager."
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
detect_default_managers() {
|
|
206
|
+
local os
|
|
207
|
+
local emitted=""
|
|
208
|
+
local primary_manager=""
|
|
209
|
+
|
|
210
|
+
add_detected_manager() {
|
|
211
|
+
local manager_name="$1"
|
|
212
|
+
[[ -n "${manager_name}" ]] || return
|
|
213
|
+
case " ${emitted} " in
|
|
214
|
+
*" ${manager_name} "*)
|
|
215
|
+
return
|
|
216
|
+
;;
|
|
217
|
+
esac
|
|
218
|
+
if manager_command_ready "${manager_name}"; then
|
|
219
|
+
printf "%s\n" "${manager_name}"
|
|
220
|
+
emitted+=" ${manager_name}"
|
|
221
|
+
fi
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
os="$(uname -s)"
|
|
225
|
+
|
|
226
|
+
if [[ "${os}" == "Darwin" ]]; then
|
|
227
|
+
add_detected_manager "brew"
|
|
228
|
+
add_detected_manager "bun"
|
|
229
|
+
if [[ -n "${emitted}" ]]; then
|
|
230
|
+
return
|
|
231
|
+
fi
|
|
232
|
+
fi
|
|
233
|
+
|
|
234
|
+
if [[ "${os}" == "Linux" ]]; then
|
|
235
|
+
primary_manager="$(detect_default_manager)"
|
|
236
|
+
add_detected_manager "${primary_manager}"
|
|
237
|
+
|
|
238
|
+
add_detected_manager "snap"
|
|
239
|
+
add_detected_manager "flatpak"
|
|
240
|
+
add_detected_manager "brew"
|
|
241
|
+
add_detected_manager "npm"
|
|
242
|
+
add_detected_manager "bun"
|
|
243
|
+
|
|
244
|
+
if [[ -n "${emitted}" ]]; then
|
|
245
|
+
return
|
|
246
|
+
fi
|
|
247
|
+
fi
|
|
248
|
+
|
|
249
|
+
primary_manager="$(detect_default_manager)"
|
|
250
|
+
add_detected_manager "${primary_manager}"
|
|
251
|
+
|
|
252
|
+
if [[ -n "${emitted}" ]]; then
|
|
253
|
+
return
|
|
254
|
+
fi
|
|
255
|
+
|
|
256
|
+
die "Unable to auto-detect supported package managers. Use --manager."
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
join_manager_labels() {
|
|
260
|
+
local out=""
|
|
261
|
+
local mgr
|
|
262
|
+
|
|
263
|
+
for mgr in "$@"; do
|
|
264
|
+
[[ -n "${mgr}" ]] || continue
|
|
265
|
+
if [[ -n "${out}" ]]; then
|
|
266
|
+
out+=", "
|
|
267
|
+
fi
|
|
268
|
+
out+="$(manager_label "${mgr}")"
|
|
269
|
+
done
|
|
270
|
+
|
|
271
|
+
printf "%s" "${out}"
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
join_manager_labels_with_ids() {
|
|
275
|
+
local out=""
|
|
276
|
+
local mgr
|
|
277
|
+
|
|
278
|
+
for mgr in "$@"; do
|
|
279
|
+
[[ -n "${mgr}" ]] || continue
|
|
280
|
+
if [[ -n "${out}" ]]; then
|
|
281
|
+
out+=", "
|
|
282
|
+
fi
|
|
283
|
+
out+="$(manager_label "${mgr}") (${mgr})"
|
|
284
|
+
done
|
|
285
|
+
|
|
286
|
+
printf "%s" "${out}"
|
|
287
|
+
}
|
|
288
|
+
|
|
205
289
|
build_help_file() {
|
|
206
|
-
local
|
|
290
|
+
local default_managers="$1"
|
|
207
291
|
|
|
208
292
|
cat >"${HELP_FILE}" <<EOF
|
|
209
293
|
${SCRIPT_NAME} - ultimate fuzzy package finder
|
|
@@ -215,8 +299,8 @@ Syntax:
|
|
|
215
299
|
Default behavior:
|
|
216
300
|
Fuzzy-search available packages and install selected items.
|
|
217
301
|
|
|
218
|
-
Detected default manager:
|
|
219
|
-
$
|
|
302
|
+
Detected default manager(s):
|
|
303
|
+
${default_managers}
|
|
220
304
|
|
|
221
305
|
Action options:
|
|
222
306
|
-l, --list-installed Fuzzy-search installed packages and show details
|
|
@@ -349,7 +433,7 @@ join_query() {
|
|
|
349
433
|
return
|
|
350
434
|
fi
|
|
351
435
|
|
|
352
|
-
for part in "${QUERY_PARTS[@]}"; do
|
|
436
|
+
for part in "${QUERY_PARTS[@]-}"; do
|
|
353
437
|
if [[ -z "${query}" ]]; then
|
|
354
438
|
query="${part}"
|
|
355
439
|
else
|
|
@@ -475,8 +559,7 @@ manager_search_entries() {
|
|
|
475
559
|
if bun search "${effective_query}" >/dev/null 2>&1; then
|
|
476
560
|
bun search "${effective_query}" 2>/dev/null |
|
|
477
561
|
awk 'NR > 1 && NF > 0 { name=$1; $1=""; sub(/^[[:space:]]+/, "", $0); if ($0 == "") $0="-"; print name "\t" $0 }'
|
|
478
|
-
|
|
479
|
-
if command_exists npm; then
|
|
562
|
+
elif command_exists npm; then
|
|
480
563
|
npm search "${effective_query}" --searchlimit=500 --parseable 2>/dev/null |
|
|
481
564
|
awk -F'\t' 'NF >= 2 { print $1 "\t" $2 }'
|
|
482
565
|
fi
|
|
@@ -548,8 +631,7 @@ manager_installed_entries() {
|
|
|
548
631
|
elif bun pm ls >/dev/null 2>&1; then
|
|
549
632
|
bun pm ls 2>/dev/null |
|
|
550
633
|
awk 'NR > 1 && NF > 0 { print $1 "\tglobal" }'
|
|
551
|
-
|
|
552
|
-
if command_exists npm; then
|
|
634
|
+
elif command_exists npm; then
|
|
553
635
|
npm ls -g --depth=0 --parseable 2>/dev/null |
|
|
554
636
|
awk -F'/' 'NR > 1 { print $NF "\tglobal" }'
|
|
555
637
|
fi
|
|
@@ -807,17 +889,16 @@ confirm_action() {
|
|
|
807
889
|
}
|
|
808
890
|
|
|
809
891
|
run_fuzzy_selector() {
|
|
810
|
-
local
|
|
811
|
-
local
|
|
812
|
-
local
|
|
813
|
-
local header_line="$4"
|
|
892
|
+
local query="$1"
|
|
893
|
+
local input_file="$2"
|
|
894
|
+
local header_line="$3"
|
|
814
895
|
local preview_cmd
|
|
815
896
|
|
|
816
|
-
preview_cmd="$
|
|
897
|
+
preview_cmd='bash -c '\''mgr="$1"; pkg="$2"; case "$mgr" in apt) apt-cache show "$pkg" 2>/dev/null; printf "\n"; dpkg -L "$pkg" 2>/dev/null ;; dnf) dnf info "$pkg" 2>/dev/null; printf "\n"; rpm -ql "$pkg" 2>/dev/null ;; pacman) pacman -Si "$pkg" 2>/dev/null; printf "\n"; pacman -Fl "$pkg" 2>/dev/null | awk "{print \$2}" ;; zypper) zypper --non-interactive info "$pkg" 2>/dev/null ;; emerge) emerge --search --color=n "$pkg" 2>/dev/null ;; brew) brew info "$pkg" 2>/dev/null ;; snap) snap info "$pkg" 2>/dev/null ;; flatpak) flatpak info "$pkg" 2>/dev/null || flatpak remote-info flathub "$pkg" 2>/dev/null ;; npm) npm view "$pkg" 2>/dev/null ;; bun) bun info "$pkg" 2>/dev/null || npm view "$pkg" 2>/dev/null ;; esac'\'' _ {1} {2}'
|
|
817
898
|
|
|
818
899
|
fzf -q "${query}" -e -m \
|
|
819
900
|
--delimiter=$'\t' \
|
|
820
|
-
--with-nth=1,2 \
|
|
901
|
+
--with-nth=1,2,3 \
|
|
821
902
|
--preview="${preview_cmd}" \
|
|
822
903
|
--preview-window=55%:wrap:border-sharp \
|
|
823
904
|
--layout=reverse \
|
|
@@ -830,24 +911,27 @@ run_fuzzy_selector() {
|
|
|
830
911
|
--bind=ctrl-h:preview:"cat ${HELP_FILE}" \
|
|
831
912
|
--bind='ctrl-/:change-preview-window(hidden|)' \
|
|
832
913
|
--bind=ctrl-n:next-selected,ctrl-b:prev-selected \
|
|
833
|
-
--bind='focus:transform-preview-label:echo
|
|
914
|
+
--bind='focus:transform-preview-label:echo {1}: {2}' \
|
|
834
915
|
<"${input_file}"
|
|
835
916
|
}
|
|
836
917
|
|
|
837
|
-
collect_selected_packages() {
|
|
838
|
-
local selected_lines="$1"
|
|
839
|
-
printf "%s\n" "${selected_lines}" | awk -F'\t' 'NF > 0 { print $1 }'
|
|
840
|
-
}
|
|
841
|
-
|
|
842
918
|
main() {
|
|
843
919
|
ensure_tmp_root
|
|
844
920
|
|
|
845
921
|
parse_args "$@"
|
|
846
922
|
|
|
847
923
|
local detected_manager
|
|
848
|
-
|
|
924
|
+
local detected_managers=()
|
|
925
|
+
while IFS= read -r detected_manager; do
|
|
926
|
+
[[ -n "${detected_manager}" ]] || continue
|
|
927
|
+
detected_managers+=("${detected_manager}")
|
|
928
|
+
done < <(detect_default_managers)
|
|
849
929
|
|
|
850
|
-
|
|
930
|
+
local default_managers_display
|
|
931
|
+
default_managers_display="$(join_manager_labels_with_ids "${detected_managers[@]-}")"
|
|
932
|
+
[[ -n "${default_managers_display}" ]] || default_managers_display="None"
|
|
933
|
+
|
|
934
|
+
build_help_file "${default_managers_display}"
|
|
851
935
|
build_keybind_file
|
|
852
936
|
|
|
853
937
|
if [[ "${ACTION}" == "help" ]]; then
|
|
@@ -855,21 +939,39 @@ main() {
|
|
|
855
939
|
exit 0
|
|
856
940
|
fi
|
|
857
941
|
|
|
858
|
-
local
|
|
942
|
+
local managers=()
|
|
859
943
|
if [[ -n "${MANAGER_OVERRIDE}" ]]; then
|
|
860
|
-
|
|
944
|
+
managers+=("$(normalize_manager "${MANAGER_OVERRIDE}")")
|
|
945
|
+
else
|
|
946
|
+
for detected_manager in "${detected_managers[@]-}"; do
|
|
947
|
+
[[ -n "${detected_manager}" ]] || continue
|
|
948
|
+
managers+=("${detected_manager}")
|
|
949
|
+
done
|
|
861
950
|
fi
|
|
862
951
|
|
|
863
|
-
|
|
864
|
-
|
|
952
|
+
if [[ "${#managers[@]}" -eq 0 ]]; then
|
|
953
|
+
die "Unable to auto-detect supported package managers. Use --manager."
|
|
954
|
+
fi
|
|
955
|
+
|
|
956
|
+
local manager
|
|
957
|
+
for manager in "${managers[@]-}"; do
|
|
958
|
+
manager_supported "${manager}" || die "Unsupported manager: ${manager}"
|
|
959
|
+
manager_command_ready "${manager}" || die "Manager command(s) for '${manager}' not found on this system"
|
|
960
|
+
done
|
|
961
|
+
|
|
962
|
+
local manager_display
|
|
963
|
+
manager_display="$(join_manager_labels "${managers[@]-}")"
|
|
865
964
|
|
|
866
965
|
local query
|
|
867
966
|
query="$(join_query)"
|
|
868
967
|
|
|
869
968
|
if [[ "${ACTION}" == "update" ]]; then
|
|
870
|
-
log "Using manager: $
|
|
871
|
-
if confirm_action "Run update/upgrade for ${
|
|
872
|
-
|
|
969
|
+
log "Using manager(s): ${manager_display}"
|
|
970
|
+
if confirm_action "Run update/upgrade for ${manager_display}?"; then
|
|
971
|
+
for manager in "${managers[@]-}"; do
|
|
972
|
+
log "Updating with $(manager_label "${manager}")"
|
|
973
|
+
manager_update "${manager}"
|
|
974
|
+
done
|
|
873
975
|
else
|
|
874
976
|
log "Update canceled"
|
|
875
977
|
fi
|
|
@@ -878,34 +980,64 @@ main() {
|
|
|
878
980
|
|
|
879
981
|
command_exists fzf || die "fzf is required"
|
|
880
982
|
|
|
881
|
-
local source_file
|
|
882
983
|
local display_file
|
|
883
|
-
source_file="$(mktemp "${TMP_ROOT}/source.XXXXXX")"
|
|
884
984
|
display_file="$(mktemp "${TMP_ROOT}/display.XXXXXX")"
|
|
985
|
+
: >"${display_file}"
|
|
885
986
|
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
987
|
+
local source_file
|
|
988
|
+
local marked_file
|
|
989
|
+
for manager in "${managers[@]-}"; do
|
|
990
|
+
source_file="$(mktemp "${TMP_ROOT}/source.XXXXXX")"
|
|
991
|
+
|
|
992
|
+
if [[ "${ACTION}" == "list" || "${ACTION}" == "remove" ]]; then
|
|
993
|
+
manager_installed_entries "${manager}" >"${source_file}" || true
|
|
994
|
+
if [[ -s "${source_file}" ]]; then
|
|
995
|
+
awk -F'\t' -v mgr="${manager}" '
|
|
996
|
+
NF >= 1 {
|
|
997
|
+
desc = $2
|
|
998
|
+
if (desc == "") desc = "-"
|
|
999
|
+
print mgr "\t" $1 "\t" desc
|
|
1000
|
+
}
|
|
1001
|
+
' "${source_file}" >>"${display_file}"
|
|
1002
|
+
fi
|
|
1003
|
+
rm -f "${source_file}"
|
|
1004
|
+
continue
|
|
1005
|
+
fi
|
|
1006
|
+
|
|
1007
|
+
marked_file="$(mktemp "${TMP_ROOT}/marked.XXXXXX")"
|
|
1008
|
+
manager_search_entries "${manager}" "${query}" >"${source_file}" || true
|
|
1009
|
+
if [[ -s "${source_file}" ]]; then
|
|
1010
|
+
mark_installed_packages "${manager}" "${source_file}" "${marked_file}"
|
|
1011
|
+
awk -F'\t' -v mgr="${manager}" '
|
|
1012
|
+
NF >= 1 {
|
|
1013
|
+
desc = $2
|
|
1014
|
+
if (desc == "") desc = "-"
|
|
1015
|
+
print mgr "\t" $1 "\t" desc
|
|
1016
|
+
}
|
|
1017
|
+
' "${marked_file}" >>"${display_file}"
|
|
1018
|
+
fi
|
|
1019
|
+
rm -f "${source_file}" "${marked_file}"
|
|
1020
|
+
done
|
|
1021
|
+
|
|
1022
|
+
if [[ -s "${display_file}" ]]; then
|
|
1023
|
+
sort -u "${display_file}" -o "${display_file}"
|
|
892
1024
|
fi
|
|
893
1025
|
|
|
894
1026
|
if [[ ! -s "${display_file}" ]]; then
|
|
895
|
-
rm -f "${
|
|
896
|
-
die "No packages found for manager '${
|
|
1027
|
+
rm -f "${display_file}"
|
|
1028
|
+
die "No packages found for manager(s) '${manager_display}' and query '${query}'"
|
|
897
1029
|
fi
|
|
898
1030
|
|
|
899
1031
|
local header
|
|
900
1032
|
case "${ACTION}" in
|
|
901
1033
|
search)
|
|
902
|
-
header="Select package(s) to install with ${
|
|
1034
|
+
header="Select package(s) to install with ${manager_display} (TAB to multi-select)"
|
|
903
1035
|
;;
|
|
904
1036
|
list)
|
|
905
|
-
header="Select installed package(s) to inspect"
|
|
1037
|
+
header="Select installed package(s) to inspect from ${manager_display}"
|
|
906
1038
|
;;
|
|
907
1039
|
remove)
|
|
908
|
-
header="Select installed package(s) to remove"
|
|
1040
|
+
header="Select installed package(s) to remove from ${manager_display}"
|
|
909
1041
|
;;
|
|
910
1042
|
*)
|
|
911
1043
|
header="Select package(s)"
|
|
@@ -913,47 +1045,97 @@ main() {
|
|
|
913
1045
|
esac
|
|
914
1046
|
|
|
915
1047
|
local selected
|
|
916
|
-
selected="$(run_fuzzy_selector "${
|
|
1048
|
+
selected="$(run_fuzzy_selector "${query}" "${display_file}" "${header}" || true)"
|
|
917
1049
|
|
|
918
|
-
rm -f "${
|
|
1050
|
+
rm -f "${display_file}"
|
|
919
1051
|
|
|
920
1052
|
if [[ -z "${selected}" ]]; then
|
|
921
1053
|
log "No package selected"
|
|
922
1054
|
exit 0
|
|
923
1055
|
fi
|
|
924
1056
|
|
|
925
|
-
local
|
|
1057
|
+
local selected_managers=()
|
|
1058
|
+
local selected_packages=()
|
|
1059
|
+
local selected_line
|
|
1060
|
+
local selected_manager
|
|
926
1061
|
local selected_pkg
|
|
927
|
-
while IFS= read -r
|
|
928
|
-
[[ -n "${
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
1062
|
+
while IFS= read -r selected_line; do
|
|
1063
|
+
[[ -n "${selected_line}" ]] || continue
|
|
1064
|
+
IFS=$'\t' read -r selected_manager selected_pkg _ <<<"${selected_line}"
|
|
1065
|
+
[[ -n "${selected_manager}" && -n "${selected_pkg}" ]] || continue
|
|
1066
|
+
selected_managers+=("${selected_manager}")
|
|
1067
|
+
selected_packages+=("${selected_pkg}")
|
|
1068
|
+
done <<<"${selected}"
|
|
1069
|
+
|
|
1070
|
+
if [[ "${#selected_packages[@]}" -eq 0 ]]; then
|
|
933
1071
|
log "No package selected"
|
|
934
1072
|
exit 0
|
|
935
1073
|
fi
|
|
936
1074
|
|
|
1075
|
+
local unique_managers=()
|
|
1076
|
+
local candidate_manager
|
|
1077
|
+
local already_seen
|
|
1078
|
+
local existing_manager
|
|
1079
|
+
for candidate_manager in "${selected_managers[@]-}"; do
|
|
1080
|
+
already_seen=0
|
|
1081
|
+
for existing_manager in "${unique_managers[@]-}"; do
|
|
1082
|
+
if [[ "${existing_manager}" == "${candidate_manager}" ]]; then
|
|
1083
|
+
already_seen=1
|
|
1084
|
+
break
|
|
1085
|
+
fi
|
|
1086
|
+
done
|
|
1087
|
+
if [[ "${already_seen}" -eq 0 ]]; then
|
|
1088
|
+
unique_managers+=("${candidate_manager}")
|
|
1089
|
+
fi
|
|
1090
|
+
done
|
|
1091
|
+
|
|
1092
|
+
local selected_manager_display
|
|
1093
|
+
selected_manager_display="$(join_manager_labels "${unique_managers[@]-}")"
|
|
1094
|
+
|
|
1095
|
+
local idx
|
|
1096
|
+
local mgr_packages=()
|
|
1097
|
+
|
|
937
1098
|
case "${ACTION}" in
|
|
938
1099
|
search)
|
|
939
|
-
if confirm_action "Install ${#
|
|
940
|
-
|
|
1100
|
+
if confirm_action "Install ${#selected_packages[@]} package(s) with ${selected_manager_display}?"; then
|
|
1101
|
+
for manager in "${unique_managers[@]-}"; do
|
|
1102
|
+
mgr_packages=()
|
|
1103
|
+
for idx in "${!selected_packages[@]-}"; do
|
|
1104
|
+
if [[ "${selected_managers[$idx]}" == "${manager}" ]]; then
|
|
1105
|
+
mgr_packages+=("${selected_packages[$idx]}")
|
|
1106
|
+
fi
|
|
1107
|
+
done
|
|
1108
|
+
if [[ "${#mgr_packages[@]}" -gt 0 ]]; then
|
|
1109
|
+
log "Installing ${#mgr_packages[@]} package(s) with $(manager_label "${manager}")"
|
|
1110
|
+
manager_install "${manager}" "${mgr_packages[@]-}"
|
|
1111
|
+
fi
|
|
1112
|
+
done
|
|
941
1113
|
else
|
|
942
1114
|
log "Install canceled"
|
|
943
1115
|
fi
|
|
944
1116
|
;;
|
|
945
1117
|
remove)
|
|
946
|
-
if confirm_action "Remove ${#
|
|
947
|
-
|
|
1118
|
+
if confirm_action "Remove ${#selected_packages[@]} package(s) with ${selected_manager_display}?"; then
|
|
1119
|
+
for manager in "${unique_managers[@]-}"; do
|
|
1120
|
+
mgr_packages=()
|
|
1121
|
+
for idx in "${!selected_packages[@]-}"; do
|
|
1122
|
+
if [[ "${selected_managers[$idx]}" == "${manager}" ]]; then
|
|
1123
|
+
mgr_packages+=("${selected_packages[$idx]}")
|
|
1124
|
+
fi
|
|
1125
|
+
done
|
|
1126
|
+
if [[ "${#mgr_packages[@]}" -gt 0 ]]; then
|
|
1127
|
+
log "Removing ${#mgr_packages[@]} package(s) with $(manager_label "${manager}")"
|
|
1128
|
+
manager_remove "${manager}" "${mgr_packages[@]-}"
|
|
1129
|
+
fi
|
|
1130
|
+
done
|
|
948
1131
|
else
|
|
949
1132
|
log "Remove canceled"
|
|
950
1133
|
fi
|
|
951
1134
|
;;
|
|
952
1135
|
list)
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
manager_show_info "${manager}" "${pkg}" || true
|
|
1136
|
+
for idx in "${!selected_packages[@]-}"; do
|
|
1137
|
+
printf "\n=== %s (%s) ===\n" "${selected_packages[$idx]}" "$(manager_label "${selected_managers[$idx]}")"
|
|
1138
|
+
manager_show_info "${selected_managers[$idx]}" "${selected_packages[$idx]}" || true
|
|
957
1139
|
done
|
|
958
1140
|
;;
|
|
959
1141
|
esac
|