fpf-cli 1.0.0 → 1.1.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 +49 -73
- package/fpf +209 -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,65 @@ 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
|
+
## Supported Managers
|
|
82
40
|
|
|
83
|
-
|
|
84
|
-
|
|
41
|
+
- Linux: `apt`, `dnf`, `pacman`, `zypper`, `emerge`
|
|
42
|
+
- Cross-platform: `snap`, `flatpak`
|
|
43
|
+
- Dev: `npm`, `bun`
|
|
44
|
+
- macOS: `brew`
|
|
85
45
|
|
|
86
|
-
|
|
87
|
-
fpf -U
|
|
46
|
+
(`winget` intentionally not included.)
|
|
88
47
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
48
|
+
## Manager Override Flags
|
|
49
|
+
|
|
50
|
+
- `-ap` apt
|
|
51
|
+
- `-dn` dnf
|
|
52
|
+
- `-pm` pacman
|
|
53
|
+
- `-zy` zypper
|
|
54
|
+
- `-em` emerge
|
|
55
|
+
- `-br` brew
|
|
56
|
+
- `-sn` snap
|
|
57
|
+
- `-fp` flatpak
|
|
58
|
+
- `-np` npm
|
|
59
|
+
- `-bn` bun
|
|
60
|
+
- `-m, --manager <name>` full manager name
|
|
61
|
+
|
|
62
|
+
## Common Options
|
|
63
|
+
|
|
64
|
+
- `-l, --list-installed` list installed packages
|
|
65
|
+
- `-R, --remove` remove selected packages
|
|
66
|
+
- `-U, --update` run update/upgrade flow
|
|
67
|
+
- `-h, --help` show help
|
|
92
68
|
|
|
93
69
|
## Keybinds
|
|
94
70
|
|
|
95
|
-
- `ctrl-h`
|
|
96
|
-
- `ctrl-k`
|
|
71
|
+
- `ctrl-h` help in preview
|
|
72
|
+
- `ctrl-k` keybinds in preview
|
|
97
73
|
- `ctrl-/` toggle preview
|
|
98
|
-
- `ctrl-n`
|
|
99
|
-
- `ctrl-b`
|
|
74
|
+
- `ctrl-n` next selected item
|
|
75
|
+
- `ctrl-b` previous selected item
|
|
100
76
|
|
|
101
77
|
## Notes
|
|
102
78
|
|
|
103
|
-
-
|
|
104
|
-
-
|
|
79
|
+
- Requires: `bash` + `fzf`
|
|
80
|
+
- Root managers (`apt`, `dnf`, `pacman`, `zypper`, `emerge`, `snap`) use `sudo` when needed.
|
package/fpf
CHANGED
|
@@ -202,8 +202,60 @@ 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
|
+
os="$(uname -s)"
|
|
208
|
+
|
|
209
|
+
if [[ "${os}" == "Darwin" ]]; then
|
|
210
|
+
local found=0
|
|
211
|
+
if command_exists brew; then
|
|
212
|
+
printf "brew\n"
|
|
213
|
+
found=1
|
|
214
|
+
fi
|
|
215
|
+
if command_exists bun; then
|
|
216
|
+
printf "bun\n"
|
|
217
|
+
found=1
|
|
218
|
+
fi
|
|
219
|
+
if [[ "${found}" -eq 1 ]]; then
|
|
220
|
+
return
|
|
221
|
+
fi
|
|
222
|
+
fi
|
|
223
|
+
|
|
224
|
+
printf "%s\n" "$(detect_default_manager)"
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
join_manager_labels() {
|
|
228
|
+
local out=""
|
|
229
|
+
local mgr
|
|
230
|
+
|
|
231
|
+
for mgr in "$@"; do
|
|
232
|
+
[[ -n "${mgr}" ]] || continue
|
|
233
|
+
if [[ -n "${out}" ]]; then
|
|
234
|
+
out+=", "
|
|
235
|
+
fi
|
|
236
|
+
out+="$(manager_label "${mgr}")"
|
|
237
|
+
done
|
|
238
|
+
|
|
239
|
+
printf "%s" "${out}"
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
join_manager_labels_with_ids() {
|
|
243
|
+
local out=""
|
|
244
|
+
local mgr
|
|
245
|
+
|
|
246
|
+
for mgr in "$@"; do
|
|
247
|
+
[[ -n "${mgr}" ]] || continue
|
|
248
|
+
if [[ -n "${out}" ]]; then
|
|
249
|
+
out+=", "
|
|
250
|
+
fi
|
|
251
|
+
out+="$(manager_label "${mgr}") (${mgr})"
|
|
252
|
+
done
|
|
253
|
+
|
|
254
|
+
printf "%s" "${out}"
|
|
255
|
+
}
|
|
256
|
+
|
|
205
257
|
build_help_file() {
|
|
206
|
-
local
|
|
258
|
+
local default_managers="$1"
|
|
207
259
|
|
|
208
260
|
cat >"${HELP_FILE}" <<EOF
|
|
209
261
|
${SCRIPT_NAME} - ultimate fuzzy package finder
|
|
@@ -215,8 +267,8 @@ Syntax:
|
|
|
215
267
|
Default behavior:
|
|
216
268
|
Fuzzy-search available packages and install selected items.
|
|
217
269
|
|
|
218
|
-
Detected default manager:
|
|
219
|
-
$
|
|
270
|
+
Detected default manager(s):
|
|
271
|
+
${default_managers}
|
|
220
272
|
|
|
221
273
|
Action options:
|
|
222
274
|
-l, --list-installed Fuzzy-search installed packages and show details
|
|
@@ -349,7 +401,7 @@ join_query() {
|
|
|
349
401
|
return
|
|
350
402
|
fi
|
|
351
403
|
|
|
352
|
-
for part in "${QUERY_PARTS[@]}"; do
|
|
404
|
+
for part in "${QUERY_PARTS[@]-}"; do
|
|
353
405
|
if [[ -z "${query}" ]]; then
|
|
354
406
|
query="${part}"
|
|
355
407
|
else
|
|
@@ -475,8 +527,7 @@ manager_search_entries() {
|
|
|
475
527
|
if bun search "${effective_query}" >/dev/null 2>&1; then
|
|
476
528
|
bun search "${effective_query}" 2>/dev/null |
|
|
477
529
|
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
|
|
530
|
+
elif command_exists npm; then
|
|
480
531
|
npm search "${effective_query}" --searchlimit=500 --parseable 2>/dev/null |
|
|
481
532
|
awk -F'\t' 'NF >= 2 { print $1 "\t" $2 }'
|
|
482
533
|
fi
|
|
@@ -548,8 +599,7 @@ manager_installed_entries() {
|
|
|
548
599
|
elif bun pm ls >/dev/null 2>&1; then
|
|
549
600
|
bun pm ls 2>/dev/null |
|
|
550
601
|
awk 'NR > 1 && NF > 0 { print $1 "\tglobal" }'
|
|
551
|
-
|
|
552
|
-
if command_exists npm; then
|
|
602
|
+
elif command_exists npm; then
|
|
553
603
|
npm ls -g --depth=0 --parseable 2>/dev/null |
|
|
554
604
|
awk -F'/' 'NR > 1 { print $NF "\tglobal" }'
|
|
555
605
|
fi
|
|
@@ -807,17 +857,16 @@ confirm_action() {
|
|
|
807
857
|
}
|
|
808
858
|
|
|
809
859
|
run_fuzzy_selector() {
|
|
810
|
-
local
|
|
811
|
-
local
|
|
812
|
-
local
|
|
813
|
-
local header_line="$4"
|
|
860
|
+
local query="$1"
|
|
861
|
+
local input_file="$2"
|
|
862
|
+
local header_line="$3"
|
|
814
863
|
local preview_cmd
|
|
815
864
|
|
|
816
|
-
preview_cmd="$
|
|
865
|
+
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
866
|
|
|
818
867
|
fzf -q "${query}" -e -m \
|
|
819
868
|
--delimiter=$'\t' \
|
|
820
|
-
--with-nth=1,2 \
|
|
869
|
+
--with-nth=1,2,3 \
|
|
821
870
|
--preview="${preview_cmd}" \
|
|
822
871
|
--preview-window=55%:wrap:border-sharp \
|
|
823
872
|
--layout=reverse \
|
|
@@ -830,24 +879,27 @@ run_fuzzy_selector() {
|
|
|
830
879
|
--bind=ctrl-h:preview:"cat ${HELP_FILE}" \
|
|
831
880
|
--bind='ctrl-/:change-preview-window(hidden|)' \
|
|
832
881
|
--bind=ctrl-n:next-selected,ctrl-b:prev-selected \
|
|
833
|
-
--bind='focus:transform-preview-label:echo
|
|
882
|
+
--bind='focus:transform-preview-label:echo {1}: {2}' \
|
|
834
883
|
<"${input_file}"
|
|
835
884
|
}
|
|
836
885
|
|
|
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
886
|
main() {
|
|
843
887
|
ensure_tmp_root
|
|
844
888
|
|
|
845
889
|
parse_args "$@"
|
|
846
890
|
|
|
847
891
|
local detected_manager
|
|
848
|
-
|
|
892
|
+
local detected_managers=()
|
|
893
|
+
while IFS= read -r detected_manager; do
|
|
894
|
+
[[ -n "${detected_manager}" ]] || continue
|
|
895
|
+
detected_managers+=("${detected_manager}")
|
|
896
|
+
done < <(detect_default_managers)
|
|
897
|
+
|
|
898
|
+
local default_managers_display
|
|
899
|
+
default_managers_display="$(join_manager_labels_with_ids "${detected_managers[@]-}")"
|
|
900
|
+
[[ -n "${default_managers_display}" ]] || default_managers_display="None"
|
|
849
901
|
|
|
850
|
-
build_help_file "${
|
|
902
|
+
build_help_file "${default_managers_display}"
|
|
851
903
|
build_keybind_file
|
|
852
904
|
|
|
853
905
|
if [[ "${ACTION}" == "help" ]]; then
|
|
@@ -855,21 +907,39 @@ main() {
|
|
|
855
907
|
exit 0
|
|
856
908
|
fi
|
|
857
909
|
|
|
858
|
-
local
|
|
910
|
+
local managers=()
|
|
859
911
|
if [[ -n "${MANAGER_OVERRIDE}" ]]; then
|
|
860
|
-
|
|
912
|
+
managers+=("$(normalize_manager "${MANAGER_OVERRIDE}")")
|
|
913
|
+
else
|
|
914
|
+
for detected_manager in "${detected_managers[@]-}"; do
|
|
915
|
+
[[ -n "${detected_manager}" ]] || continue
|
|
916
|
+
managers+=("${detected_manager}")
|
|
917
|
+
done
|
|
918
|
+
fi
|
|
919
|
+
|
|
920
|
+
if [[ "${#managers[@]}" -eq 0 ]]; then
|
|
921
|
+
die "Unable to auto-detect supported package managers. Use --manager."
|
|
861
922
|
fi
|
|
862
923
|
|
|
863
|
-
|
|
864
|
-
|
|
924
|
+
local manager
|
|
925
|
+
for manager in "${managers[@]-}"; do
|
|
926
|
+
manager_supported "${manager}" || die "Unsupported manager: ${manager}"
|
|
927
|
+
manager_command_ready "${manager}" || die "Manager command(s) for '${manager}' not found on this system"
|
|
928
|
+
done
|
|
929
|
+
|
|
930
|
+
local manager_display
|
|
931
|
+
manager_display="$(join_manager_labels "${managers[@]-}")"
|
|
865
932
|
|
|
866
933
|
local query
|
|
867
934
|
query="$(join_query)"
|
|
868
935
|
|
|
869
936
|
if [[ "${ACTION}" == "update" ]]; then
|
|
870
|
-
log "Using manager: $
|
|
871
|
-
if confirm_action "Run update/upgrade for ${
|
|
872
|
-
|
|
937
|
+
log "Using manager(s): ${manager_display}"
|
|
938
|
+
if confirm_action "Run update/upgrade for ${manager_display}?"; then
|
|
939
|
+
for manager in "${managers[@]-}"; do
|
|
940
|
+
log "Updating with $(manager_label "${manager}")"
|
|
941
|
+
manager_update "${manager}"
|
|
942
|
+
done
|
|
873
943
|
else
|
|
874
944
|
log "Update canceled"
|
|
875
945
|
fi
|
|
@@ -878,34 +948,64 @@ main() {
|
|
|
878
948
|
|
|
879
949
|
command_exists fzf || die "fzf is required"
|
|
880
950
|
|
|
881
|
-
local source_file
|
|
882
951
|
local display_file
|
|
883
|
-
source_file="$(mktemp "${TMP_ROOT}/source.XXXXXX")"
|
|
884
952
|
display_file="$(mktemp "${TMP_ROOT}/display.XXXXXX")"
|
|
953
|
+
: >"${display_file}"
|
|
885
954
|
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
955
|
+
local source_file
|
|
956
|
+
local marked_file
|
|
957
|
+
for manager in "${managers[@]-}"; do
|
|
958
|
+
source_file="$(mktemp "${TMP_ROOT}/source.XXXXXX")"
|
|
959
|
+
|
|
960
|
+
if [[ "${ACTION}" == "list" || "${ACTION}" == "remove" ]]; then
|
|
961
|
+
manager_installed_entries "${manager}" >"${source_file}" || true
|
|
962
|
+
if [[ -s "${source_file}" ]]; then
|
|
963
|
+
awk -F'\t' -v mgr="${manager}" '
|
|
964
|
+
NF >= 1 {
|
|
965
|
+
desc = $2
|
|
966
|
+
if (desc == "") desc = "-"
|
|
967
|
+
print mgr "\t" $1 "\t" desc
|
|
968
|
+
}
|
|
969
|
+
' "${source_file}" >>"${display_file}"
|
|
970
|
+
fi
|
|
971
|
+
rm -f "${source_file}"
|
|
972
|
+
continue
|
|
973
|
+
fi
|
|
974
|
+
|
|
975
|
+
marked_file="$(mktemp "${TMP_ROOT}/marked.XXXXXX")"
|
|
976
|
+
manager_search_entries "${manager}" "${query}" >"${source_file}" || true
|
|
977
|
+
if [[ -s "${source_file}" ]]; then
|
|
978
|
+
mark_installed_packages "${manager}" "${source_file}" "${marked_file}"
|
|
979
|
+
awk -F'\t' -v mgr="${manager}" '
|
|
980
|
+
NF >= 1 {
|
|
981
|
+
desc = $2
|
|
982
|
+
if (desc == "") desc = "-"
|
|
983
|
+
print mgr "\t" $1 "\t" desc
|
|
984
|
+
}
|
|
985
|
+
' "${marked_file}" >>"${display_file}"
|
|
986
|
+
fi
|
|
987
|
+
rm -f "${source_file}" "${marked_file}"
|
|
988
|
+
done
|
|
989
|
+
|
|
990
|
+
if [[ -s "${display_file}" ]]; then
|
|
991
|
+
sort -u "${display_file}" -o "${display_file}"
|
|
892
992
|
fi
|
|
893
993
|
|
|
894
994
|
if [[ ! -s "${display_file}" ]]; then
|
|
895
|
-
rm -f "${
|
|
896
|
-
die "No packages found for manager '${
|
|
995
|
+
rm -f "${display_file}"
|
|
996
|
+
die "No packages found for manager(s) '${manager_display}' and query '${query}'"
|
|
897
997
|
fi
|
|
898
998
|
|
|
899
999
|
local header
|
|
900
1000
|
case "${ACTION}" in
|
|
901
1001
|
search)
|
|
902
|
-
header="Select package(s) to install with ${
|
|
1002
|
+
header="Select package(s) to install with ${manager_display} (TAB to multi-select)"
|
|
903
1003
|
;;
|
|
904
1004
|
list)
|
|
905
|
-
header="Select installed package(s) to inspect"
|
|
1005
|
+
header="Select installed package(s) to inspect from ${manager_display}"
|
|
906
1006
|
;;
|
|
907
1007
|
remove)
|
|
908
|
-
header="Select installed package(s) to remove"
|
|
1008
|
+
header="Select installed package(s) to remove from ${manager_display}"
|
|
909
1009
|
;;
|
|
910
1010
|
*)
|
|
911
1011
|
header="Select package(s)"
|
|
@@ -913,47 +1013,97 @@ main() {
|
|
|
913
1013
|
esac
|
|
914
1014
|
|
|
915
1015
|
local selected
|
|
916
|
-
selected="$(run_fuzzy_selector "${
|
|
1016
|
+
selected="$(run_fuzzy_selector "${query}" "${display_file}" "${header}" || true)"
|
|
917
1017
|
|
|
918
|
-
rm -f "${
|
|
1018
|
+
rm -f "${display_file}"
|
|
919
1019
|
|
|
920
1020
|
if [[ -z "${selected}" ]]; then
|
|
921
1021
|
log "No package selected"
|
|
922
1022
|
exit 0
|
|
923
1023
|
fi
|
|
924
1024
|
|
|
925
|
-
local
|
|
1025
|
+
local selected_managers=()
|
|
1026
|
+
local selected_packages=()
|
|
1027
|
+
local selected_line
|
|
1028
|
+
local selected_manager
|
|
926
1029
|
local selected_pkg
|
|
927
|
-
while IFS= read -r
|
|
928
|
-
[[ -n "${
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
1030
|
+
while IFS= read -r selected_line; do
|
|
1031
|
+
[[ -n "${selected_line}" ]] || continue
|
|
1032
|
+
IFS=$'\t' read -r selected_manager selected_pkg _ <<<"${selected_line}"
|
|
1033
|
+
[[ -n "${selected_manager}" && -n "${selected_pkg}" ]] || continue
|
|
1034
|
+
selected_managers+=("${selected_manager}")
|
|
1035
|
+
selected_packages+=("${selected_pkg}")
|
|
1036
|
+
done <<<"${selected}"
|
|
1037
|
+
|
|
1038
|
+
if [[ "${#selected_packages[@]}" -eq 0 ]]; then
|
|
933
1039
|
log "No package selected"
|
|
934
1040
|
exit 0
|
|
935
1041
|
fi
|
|
936
1042
|
|
|
1043
|
+
local unique_managers=()
|
|
1044
|
+
local candidate_manager
|
|
1045
|
+
local already_seen
|
|
1046
|
+
local existing_manager
|
|
1047
|
+
for candidate_manager in "${selected_managers[@]-}"; do
|
|
1048
|
+
already_seen=0
|
|
1049
|
+
for existing_manager in "${unique_managers[@]-}"; do
|
|
1050
|
+
if [[ "${existing_manager}" == "${candidate_manager}" ]]; then
|
|
1051
|
+
already_seen=1
|
|
1052
|
+
break
|
|
1053
|
+
fi
|
|
1054
|
+
done
|
|
1055
|
+
if [[ "${already_seen}" -eq 0 ]]; then
|
|
1056
|
+
unique_managers+=("${candidate_manager}")
|
|
1057
|
+
fi
|
|
1058
|
+
done
|
|
1059
|
+
|
|
1060
|
+
local selected_manager_display
|
|
1061
|
+
selected_manager_display="$(join_manager_labels "${unique_managers[@]-}")"
|
|
1062
|
+
|
|
1063
|
+
local idx
|
|
1064
|
+
local mgr_packages=()
|
|
1065
|
+
|
|
937
1066
|
case "${ACTION}" in
|
|
938
1067
|
search)
|
|
939
|
-
if confirm_action "Install ${#
|
|
940
|
-
|
|
1068
|
+
if confirm_action "Install ${#selected_packages[@]} package(s) with ${selected_manager_display}?"; then
|
|
1069
|
+
for manager in "${unique_managers[@]-}"; do
|
|
1070
|
+
mgr_packages=()
|
|
1071
|
+
for idx in "${!selected_packages[@]-}"; do
|
|
1072
|
+
if [[ "${selected_managers[$idx]}" == "${manager}" ]]; then
|
|
1073
|
+
mgr_packages+=("${selected_packages[$idx]}")
|
|
1074
|
+
fi
|
|
1075
|
+
done
|
|
1076
|
+
if [[ "${#mgr_packages[@]}" -gt 0 ]]; then
|
|
1077
|
+
log "Installing ${#mgr_packages[@]} package(s) with $(manager_label "${manager}")"
|
|
1078
|
+
manager_install "${manager}" "${mgr_packages[@]-}"
|
|
1079
|
+
fi
|
|
1080
|
+
done
|
|
941
1081
|
else
|
|
942
1082
|
log "Install canceled"
|
|
943
1083
|
fi
|
|
944
1084
|
;;
|
|
945
1085
|
remove)
|
|
946
|
-
if confirm_action "Remove ${#
|
|
947
|
-
|
|
1086
|
+
if confirm_action "Remove ${#selected_packages[@]} package(s) with ${selected_manager_display}?"; then
|
|
1087
|
+
for manager in "${unique_managers[@]-}"; do
|
|
1088
|
+
mgr_packages=()
|
|
1089
|
+
for idx in "${!selected_packages[@]-}"; do
|
|
1090
|
+
if [[ "${selected_managers[$idx]}" == "${manager}" ]]; then
|
|
1091
|
+
mgr_packages+=("${selected_packages[$idx]}")
|
|
1092
|
+
fi
|
|
1093
|
+
done
|
|
1094
|
+
if [[ "${#mgr_packages[@]}" -gt 0 ]]; then
|
|
1095
|
+
log "Removing ${#mgr_packages[@]} package(s) with $(manager_label "${manager}")"
|
|
1096
|
+
manager_remove "${manager}" "${mgr_packages[@]-}"
|
|
1097
|
+
fi
|
|
1098
|
+
done
|
|
948
1099
|
else
|
|
949
1100
|
log "Remove canceled"
|
|
950
1101
|
fi
|
|
951
1102
|
;;
|
|
952
1103
|
list)
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
manager_show_info "${manager}" "${pkg}" || true
|
|
1104
|
+
for idx in "${!selected_packages[@]-}"; do
|
|
1105
|
+
printf "\n=== %s (%s) ===\n" "${selected_packages[$idx]}" "$(manager_label "${selected_managers[$idx]}")"
|
|
1106
|
+
manager_show_info "${selected_managers[$idx]}" "${selected_packages[$idx]}" || true
|
|
957
1107
|
done
|
|
958
1108
|
;;
|
|
959
1109
|
esac
|