From c67573e45f06915a464dead65fa8d3be26b4dd0c Mon Sep 17 00:00:00 2001 From: Daniel Thau Date: Wed, 8 Apr 2020 17:05:29 -0400 Subject: [PATCH] pmm: add yay support --- ReleaseNotes.md | 4 + src/slash-bedrock/etc/bedrock.conf | 11 ++ src/slash-bedrock/libexec/pmm | 34 +++- .../share/pmm/package_managers/pacman | 10 +- .../share/pmm/package_managers/yay | 168 ++++++++++++++++++ 5 files changed, 213 insertions(+), 14 deletions(-) create mode 100644 src/slash-bedrock/share/pmm/package_managers/yay diff --git a/ReleaseNotes.md b/ReleaseNotes.md index 52ca4329..03e0a956 100644 --- a/ReleaseNotes.md +++ b/ReleaseNotes.md @@ -1,3 +1,7 @@ +# 0.7.14beta12 + +- Add pmm yay support + # 0.7.14beta11 - Fix Path handling in crossfs ini filter diff --git a/src/slash-bedrock/etc/bedrock.conf b/src/slash-bedrock/etc/bedrock.conf index d57df45b..70c7da7f 100644 --- a/src/slash-bedrock/etc/bedrock.conf +++ b/src/slash-bedrock/etc/bedrock.conf @@ -482,6 +482,17 @@ ignore-non-system-package-managers = true # stratum. See `brl hide --help` and `brl show --help`. # +# +# Some package managers such as yay recommend against running as root. If pmm +# is called as root, pmm will call such package managers with this user via +# `sudo`. +# +# sudo sets $SUDO_USER accordingly and is thus a good general default if pmm is +# called via sudo. If you do not use this, consider setting it either your +# primary user or a dedicated unprivileged user. +# +unprivileged-user = $SUDO_USER + # # Most package managers support only a subset of available operations. If a # given package manager is unable to fulfill an operation, it is skipped. diff --git a/src/slash-bedrock/libexec/pmm b/src/slash-bedrock/libexec/pmm index 5a16da23..35f9d738 100755 --- a/src/slash-bedrock/libexec/pmm +++ b/src/slash-bedrock/libexec/pmm @@ -61,6 +61,18 @@ color[\"strat\"] = \"${color_strat}\" color[\"sub\"] = \"${color_sub}\" color[\"warn\"] = \"${color_warn}\"" +# Check if running as root user +if [ "$(id -u)" -eq 0 ]; then + initialize_awk_variables="${initialize_awk_variables} +am_root=1" +fi + +# +# Gather unprivileged user +# +initialize_awk_variables="${initialize_awk_variables} +unprivileged_user=\"$(cfg_value "pmm" "unprivileged-user" | sed -e "s/['\"\\]/\\\&/" -e "s/^x//")\"" + # # Check if warnings are desired when skipping package managers. # @@ -130,10 +142,6 @@ cfg_ignore_non_system_package_managers=1" if [ "${cfg_cache_package_manager_list}" = "true" ]; then initialize_awk_variables="${initialize_awk_variables} cfg_cache_package_manager_list=1" - if [ "$(id -u)" -eq 0 ]; then - initialize_awk_variables="${initialize_awk_variables} -am_root=1" - fi fi fi @@ -675,7 +683,7 @@ function generate_pairs(_return, unfiltered_pairs, notice("Run as root to generate package manager cache") } - # Get ordered list of everything to consider + # Get ordered list of everything to consider. Duplicates will be filtered out later. for (i = 1; i in cfg_pmm_priority; i++) { partial_considerations[++partial_consideration_count] = cfg_pmm_priority[i] } @@ -707,9 +715,11 @@ function generate_pairs(_return, unfiltered_pairs, considerations[++consideration_count] = pair "" i } } - for (i in package_manager_canary_executables) { - if (!(i in system_package_managers)) { - considerations[++consideration_count] = pair "" i + if (!cfg_ignore_non_system_package_managers) { + for (i in package_manager_canary_executables) { + if (!(i in system_package_managers)) { + considerations[++consideration_count] = pair "" i + } } } } else { @@ -717,7 +727,8 @@ function generate_pairs(_return, unfiltered_pairs, } } - # Build final (unfiltered) pair list. Remove disallowed and repeated items. + # Build final (unfiltered) pair list. Remove repeated items and items + # which do not exist on disk. for (c = 1; c in considerations; c++) { pair = considerations[c] split(pair, a, ":") @@ -767,6 +778,11 @@ function prep_shell_environment(stratum, package_manager, items, _local, output, f, i, a, count) { output = "export stratum=\""shell_escape(stratum)"\";" output = output " export package_manager=\""shell_escape(package_manager)"\";" + if (am_root && unprivileged_user) { + output = output " export unprivileged_user=\"sudo -u " unprivileged_user "\";" + } else { + output = output " export unprivileged_user=\"\";" + } output = output " export flags=\"" count = 0 for (f in global_flags) { diff --git a/src/slash-bedrock/share/pmm/package_managers/pacman b/src/slash-bedrock/share/pmm/package_managers/pacman index 59bea04c..9ec00307 100644 --- a/src/slash-bedrock/share/pmm/package_managers/pacman +++ b/src/slash-bedrock/share/pmm/package_managers/pacman @@ -43,7 +43,7 @@ user_interfaces["pacman", "mark-packages-implicit"] = "pmm -D/--database --asd user_interfaces["pacman", "show-package-information"] = "pmm -S/--sync -i/--info " user_interfaces["pacman", "clear-cache"] = "pmm -S/--sync -c/--clean" user_interfaces["pacman", "remove-orphans"] = "" # no user facing command -user_interfaces["pacman", "update-package-database"] = "" # no separate file database concept, uses combine +user_interfaces["pacman", "update-package-database"] = "pmm -S/--sync -y/--refresh" user_interfaces["pacman", "update-file-database"] = "pmm -F/--files -y/--refresh" user_interfaces["pacman", "upgrade-packages-limited"] = "" # no partial upgrade concept user_interfaces["pacman", "upgrade-packages-full"] = "pmm -S/--sync -u/--sysupgrade" @@ -83,7 +83,7 @@ user_interfaces["pacman", "upgrade-packages-full,install-packages"] user_interfaces["pacman", "update-package-database,upgrade-packages-partial,install-packages"] = "" user_interfaces["pacman", "update-package-database,upgrade-packages-full,install-packages"] = "" user_interfaces["pacman", "update-package-database,update-file-database,upgrade-packages-partial,install-packages"] = "" -user_interfaces["pacman", "update-package-database,update-file-database,upgrade-packages-full,install-packages"] = "pmm -S/--sync -y/--refresh -u/--sysupgrade " +user_interfaces["pacman", "update-package-database,update-file-database,upgrade-packages-full,install-packages"] = "" implementations["pacman", "clear-cache,remove-orphans"] = "" implementations["pacman", "mark-packages-implicit,remove-orphans"] = "" @@ -100,8 +100,8 @@ implementations["pacman", "upgrade-packages-limited,install-packages"] implementations["pacman", "upgrade-packages-full,install-packages"] = "strat -r ${stratum} pacman ${flags} -Su --asexplicit ${items}" implementations["pacman", "update-package-database,upgrade-packages-partial,install-packages"] = "strat -r ${stratum} pacman ${flags} -Syu --asexplicit ${items}" implementations["pacman", "update-package-database,upgrade-packages-full,install-packages"] = "strat -r ${stratum} pacman ${flags} -Syu --asexplicit ${items}" -implementations["pacman", "update-package-database,update-file-database,upgrade-packages-partial,install-packages"] = "strat -r ${stratum} pacman ${flags} -Syu --asexplicit ${items}" -implementations["pacman", "update-package-database,update-file-database,upgrade-packages-full,install-packages"] = "strat -r ${stratum} pacman ${flags} -Syu --asexplicit ${items}" +implementations["pacman", "update-package-database,update-file-database,upgrade-packages-partial,install-packages"] = "" +implementations["pacman", "update-package-database,update-file-database,upgrade-packages-full,install-packages"] = "" # # Operations which have a standardized output format. @@ -121,7 +121,7 @@ implementations["pacman", "list-installed-explicit"] = "strat -r ${stratum} implementations["pacman", "list-installed-implicit"] = "strat -r ${stratum} pacman -Qd | cut -d' ' -f1" implementations["pacman", "list-installed-packages"] = "strat -r ${stratum} pacman -Q | cut -d' ' -f1" implementations["pacman", "list-available-packages"] = "strat -r ${stratum} pacman -Sl | cut -d' ' -f2" -implementations["pacman", "search-for-package-by-name"] = "strat -r ${stratum} pacman -Sl | cut -d' ' -f2 | grep ${items}" +implementations["pacman", "search-for-package-by-name"] = "strat -r ${stratum} pacman -Sl ${items} | cut -d' ' -f2 | grep ${items}" implementations["pacman", "search-for-package-by-all"] = "strat -r ${stratum} pacman -Ss ${items} | awk -F'[ /]' '/^[^ ]/{print$2}'" implementations["pacman", "which-package-owns-file"] = "strat -r ${stratum} pacman -Qo ${items} | awk '{print$(NF-1)}'" implementations["pacman", "which-packages-provide-file"] = "strat -r ${stratum} pacman -F ${items} |\ diff --git a/src/slash-bedrock/share/pmm/package_managers/yay b/src/slash-bedrock/share/pmm/package_managers/yay new file mode 100644 index 00000000..bb87e94b --- /dev/null +++ b/src/slash-bedrock/share/pmm/package_managers/yay @@ -0,0 +1,168 @@ +#!/bedrock/libexec/busybox awk -f +# +# Package Manager Manager yay support script +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# version 2 as published by the Free Software Foundation. +# +# Copyright (c) 2020 Daniel Thau + +# +# `yay -S --asexplicit` is used because `yay -S` retains +# explicit/implicit tracking on reinstalls. Without `--asexplicit`, attempts +# to force a package to be explicitly installed by installing it would fail if +# it is already installed as a dependency. +# +# yay refuses to run as root. ${unprivileged_user} wrapping is required for +# all calls. +# +# pmm assumes package managers have independent installed package lists. To +# avoid apparent ownership conflicts between yay and pacman, have yay report it +# does not have any packages installed. Most workflows should be unimpaired by +# this; one may `pmm -S` and `pmm -R` AUR files without issue. The notable +# exception here is the world file, which will become confused. +# + +package_manager_canary_executables["yay"] = "yay" + +# +# General, operation independent flags. +# +# Unlike operations, flags should not have implementations[]. +# +user_interfaces["yay", "assume-no"] = "" +user_interfaces["yay", "assume-yes"] = "--noconfirm" +user_interfaces["yay", "confirm"] = "" +user_interfaces["yay", "quiet"] = "" +user_interfaces["yay", "verbose"] = "-v/--verbose" + +# +# Operations which directly forward the underlying command output. +# +user_interfaces["yay", "install-packages"] = "pmm -S/--sync " +user_interfaces["yay", "reinstall-packages"] = "" # not differentiated from install +user_interfaces["yay", "remove-packages-limited"] = "pmm -R/--remove " +user_interfaces["yay", "remove-packages-full"] = "pmm -R/--remove -n/--nosave " +user_interfaces["yay", "verify-packages"] = "pmm -Q/--query -k/--check " +user_interfaces["yay", "verify-all-packages"] = "pmm -Q/--query -k/--check" +user_interfaces["yay", "mark-packages-explicit"] = "pmm -D/--database --asexplicit " +user_interfaces["yay", "mark-packages-implicit"] = "pmm -D/--database --asdeps " +user_interfaces["yay", "show-package-information"] = "pmm -S/--sync -i/--info " +user_interfaces["yay", "clear-cache"] = "pmm -S/--sync -c/--clean" +user_interfaces["yay", "remove-orphans"] = "" # no user facing command +user_interfaces["yay", "update-package-database"] = "pmm -S/--sync -y/--refresh" +user_interfaces["yay", "update-file-database"] = "pmm -F/--files -y/--refresh" +user_interfaces["yay", "upgrade-packages-limited"] = "" # no partial upgrade concept +user_interfaces["yay", "upgrade-packages-full"] = "pmm -S/--sync -u/--sysupgrade" + +implementations["yay", "install-packages"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -S --asexplicit ${items}" +implementations["yay", "reinstall-packages"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -S ${items}" +implementations["yay", "remove-packages-limited"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -R ${items}" +implementations["yay", "remove-packages-full"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Rn ${items}" +implementations["yay", "verify-packages"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Qk ${items}" +implementations["yay", "verify-all-packages"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Qk" +implementations["yay", "mark-packages-explicit"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -D --asexplicit ${items}" +implementations["yay", "mark-packages-implicit"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -D --asdeps ${items}" +implementations["yay", "show-package-information"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Si ${items}" +implementations["yay", "clear-cache"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Sc ${items}" +implementations["yay", "remove-orphans"] = "! ${unprivileged_user} strat -r ${stratum} yay -Qdtq >/dev/null || ${unprivileged_user} strat -r ${stratum} yay -Qdtq | ${unprivileged_user} strat -r ${stratum} yay ${flags} -Rs -" +implementations["yay", "update-package-database"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Sy" +implementations["yay", "update-file-database"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Fy" +implementations["yay", "upgrade-packages-limited"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Su" +implementations["yay", "upgrade-packages-full"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Su" + +# +# Combine operations. +# +user_interfaces["yay", "clear-cache,remove-orphans"] = "" +user_interfaces["yay", "mark-packages-implicit,remove-orphans"] = "" +user_interfaces["yay", "remove-packages-limited,remove-orphans"] = "pmm -R/--remove -s/--recursive " +user_interfaces["yay", "remove-packages-full,remove-orphans"] = "pmm -R/--remove -s/--recursive -n/--nosave " +user_interfaces["yay", "update-package-database,update-file-database"] = "pmm -S/--sync -y/--refresh" +user_interfaces["yay", "update-package-database,upgrade-packages-partial"] = "" +user_interfaces["yay", "update-package-database,upgrade-packages-full"] = "" +user_interfaces["yay", "update-package-database,update-file-database,upgrade-packages-partial"] = "" +user_interfaces["yay", "update-package-database,update-file-database,upgrade-packages-full"] = "pmm -S/--sync -y/--refresh -u/--sysupgrade" +user_interfaces["yay", "update-package-database,install-packages"] = "" +user_interfaces["yay", "update-package-database,update-file-database,install-packages"] = "pmm -S/--sync -y/--refresh " +user_interfaces["yay", "upgrade-packages-limited,install-packages"] = "" +user_interfaces["yay", "upgrade-packages-full,install-packages"] = "pmm -S/--sync -u/--sysupgrade " +user_interfaces["yay", "update-package-database,upgrade-packages-partial,install-packages"] = "" +user_interfaces["yay", "update-package-database,upgrade-packages-full,install-packages"] = "" +user_interfaces["yay", "update-package-database,update-file-database,upgrade-packages-partial,install-packages"] = "" +user_interfaces["yay", "update-package-database,update-file-database,upgrade-packages-full,install-packages"] = "" + +implementations["yay", "clear-cache,remove-orphans"] = "" +implementations["yay", "mark-packages-implicit,remove-orphans"] = "" +implementations["yay", "remove-packages-limited,remove-orphans"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Rs ${items}" +implementations["yay", "remove-packages-full,remove-orphans"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Rs ${items}" +implementations["yay", "update-package-database,update-file-database"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Sy" +implementations["yay", "update-package-database,upgrade-packages-partial"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Syu" +implementations["yay", "update-package-database,upgrade-packages-full"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Syu" +implementations["yay", "update-package-database,update-file-database,upgrade-packages-partial"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Syu" +implementations["yay", "update-package-database,update-file-database,upgrade-packages-full"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Syu" +implementations["yay", "update-package-database,install-packages"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Sy --asexplicit ${items}" +implementations["yay", "update-package-database,update-file-database,install-packages"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Sy --asexplicit ${items}" +implementations["yay", "upgrade-packages-limited,install-packages"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Su --asexplicit ${items}" +implementations["yay", "upgrade-packages-full,install-packages"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Su --asexplicit ${items}" +implementations["yay", "update-package-database,upgrade-packages-partial,install-packages"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Syu --asexplicit ${items}" +implementations["yay", "update-package-database,upgrade-packages-full,install-packages"] = "${unprivileged_user} strat -r ${stratum} yay ${flags} -Syu --asexplicit ${items}" +implementations["yay", "update-package-database,update-file-database,upgrade-packages-partial,install-packages"] = "" +implementations["yay", "update-package-database,update-file-database,upgrade-packages-full,install-packages"] = "" + +# +# Operations which have a standardized output format. +# +user_interfaces["yay", "list-installed-package-files"] = "pmm -Q/--query -l/--list " +user_interfaces["yay", "list-installed-explicit"] = "pmm -Q/--query -e/--explicit" +user_interfaces["yay", "list-installed-implicit"] = "pmm -Q/--query -d/--deps" +user_interfaces["yay", "list-installed-packages"] = "pmm -Q/--query" +user_interfaces["yay", "list-available-packages"] = "pmm -S/--sync -l/--list" +user_interfaces["yay", "search-for-package-by-name"] = "" +user_interfaces["yay", "search-for-package-by-all"] = "pmm -S/--sync -s/--search " +user_interfaces["yay", "which-package-owns-file"] = "pmm -Q/--query -o/--owns " +user_interfaces["yay", "which-packages-provide-file"] = "pmm -F/--files " + +implementations["yay", "list-installed-package-files"] = "${unprivileged_user} strat -r ${stratum} yay -Ql ${items} | cut -d' ' -f2-" +implementations["yay", "list-installed-explicit"] = "" +implementations["yay", "list-installed-implicit"] = "" +implementations["yay", "list-installed-packages"] = "" +implementations["yay", "list-available-packages"] = "strat -r ${stratum} yay -Sl | cut -d' ' -f2" +implementations["yay", "search-for-package-by-name"] = "strat -r ${stratum} yay -Sl ${items} | cut -d' ' -f2 | grep ${items}" +implementations["yay", "search-for-package-by-all"] = "strat -r ${stratum} yay -Ss ${items} | awk -F'[ /]' '/^[^ ]/{print$2}'" +implementations["yay", "which-package-owns-file"] = "strat -r ${stratum} yay -Qo ${items} | awk '{print$(NF-1)}'" +implementations["yay", "which-packages-provide-file"] = "strat -r ${stratum} yay -F ${items} |\ + awk '/^[^ ]/ {\ + split($(NF-1), a, \"/\");\ + print a[2]\"\t/\"$1\ + }'" + +# +# Internal pmm operations. +# +implementations["yay", "is-package-installed"] = "false" +implementations["yay", "is-package-available"] = "${unprivileged_user} strat -r ${stratum} yay -Si ${items} >/dev/null 2>&1" +implementations["yay", "is-file-db-available"] = "true" +implementations["yay", "print-file-db-install-instructions"] = "" +implementations["yay", "print-package-version"] = "${unprivileged_user} strat -r ${stratum} yay -Si ${items} |\ + awk '\ + $1 == \"Version\" {\ + sub(/[0-9]*:/, \"\", $3);\ + sub(/^[^0-9]/, \"\", $3);\ + sub(/[^0-9.].*/, \"\", $3);\ + sub(/[.]$/, \"\", $3);\ + print $3\ + }'" +implementations["yay", "cache-package-db"] = "${unprivileged_user} strat -r ${stratum} yay -Sl --aur |\ + awk '$3 == \"unknown-version\" {\ + print $2\"\t0\"\ + next\ + }\ + {\ + sub(/[0-9]*:/, \"\", $3);\ + sub(/^[^0-9]*/, \"\", $3);\ + sub(/[^0-9.].*/, \"\", $3);\ + sub(/[.]$/, \"\", $3);\ + print $2\"\t\"$3\ + }'"