lots of new stuff, good working version
authorIan Kelling <ian@iankelling.org>
Mon, 15 Aug 2016 01:39:46 +0000 (18:39 -0700)
committerIan Kelling <ian@iankelling.org>
Mon, 15 Aug 2016 01:39:46 +0000 (18:39 -0700)
README
src/identify-distros
src/package-manager-abstractions

diff --git a/README b/README
index 73756458728d112cca545c61857fc4820fabdc11..d0017ce0c6ac9a407689bd5c44601081cf3038e4 100644 (file)
--- a/README
+++ b/README
@@ -1,5 +1,6 @@
-Bash functions to identify and abstract differences between distros. Currentlly,
-debian based & fedora.
-Feedback, contributions, etc very welcome via gitorious or email to the
-maintainer Ian Kelling <ian@iankelling.org>.
-https://gitorious.org/distro-functions
+Identify distros & abstract package managers
+
+Currently: debian based, fedora and arch. Debian has the best support.
+
+Please email me if you have a patches, bugs, feedback, or republish this
+somewhere else: Ian Kelling <ian@iankelling.org>.
index 0d7a8fe1a9a1eff9b93a178efbe4839871c40c41..f75cb0f36b3b936c3a9970a9c36300bf0d48ba43 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-distro_name() {
+distro-name() {
     if [[ -f /etc/fedora-release ]]; then
         echo fedora
+    elif [[ -e /etc/os-release ]]; then
+        sed -rn 's/^ID=(.*)/\1/p' /etc/os-release
     else
-        grep "^ID=.*" /etc/os-release | sed 's/^ID=//'
+        echo "unknown distro"
+        return 1
     fi
 }
+
+distro-name-ver() {
+    echo `distro-name``debian-archive`
+}
+
+debian-archive() {
+    isdeb || return 0
+    local archive
+    local policy="${1:-$(apt-cache policy)}"
+    # a = archive
+    # n = codename
+    # o = origin
+    # c = component (licensing component)
+    # l = label (Debian{,-Security,-Updates})
+    { for archive in stable testing unstable; do
+          # print priority + archive name. priority is in
+          # the previous line after finding the archive.
+          read -rd '' expression <<EOF ||:
+/o=Debian,a=$archive,.*l=Debian,c=main/{x;s/^ *([-0-9]+).*/\1 $archive/p;q};h
+EOF
+          echo "$policy" | sed -rn "$expression"
+      done
+    } | sort -rn | head -n1 | grep -oE "\w+$"
+}
+
+
+isdebian-testing() {
+    [[ $(debian-archive) == testing ]]
+}
+# I only do testing or stable.
+isdebian-stable() {
+    [[ $(debian-archive) == stable ]]
+}
+
+debian-codename() {
+    isdeb || return 0
+    local policy="$(apt-cache policy)"
+    archive=$(debian-archive "$policy")
+    echo "$policy" | sed -rn "s/^.*a=$archive,n=([a-z]+).*/\1/p;T;q"
+}
 isfedora() {
-    local d=$(distro_name)
-    [[ $d == fedora ]] || return 1
+    [[ $(distro-name) == fedora ]]
 }
 isdebian() {
-    local d=$(distro_name)
-    [[ $d == debian ]] || return 1
+    [[ $(distro-name) == debian ]]
 }
-isdeb() {
-    local d=$(distro_name)
-    [[ $d == debian || $d == ubuntu ]] || return 1
+isarch() {
+    [[ $(distro-name) == arch ]]
 }
+# is debian/apt based
+isdeb() { command -v apt-get &>/dev/null; }
 isubuntu() {
-    local d=$(distro_name)
-    [[ $d == ubuntu ]] || return 1
+    [[ $(distro-name) == ubuntu ]]
 }
index a92d80d71080df13e11c64b82865f692f231fdd3..53ae02942561c631e4d17fcf30e1339acd69caeb 100644 (file)
 # limitations under the License.
 
 # basic yum/apt package manager abstraction, plus a few minor conveniences
-if type -p yum > /dev/null; then
+if command -v yum &> /dev/null; then
     # package manager
     p() {
-        local x
-        [[ $EUID == 0 ]] && x=sudo
-        $x yum "$@"
+        local s; [[ $EUID != 0 ]] && s=sudo
+        $s yum "$@"
     }
     # package install
     pi() {
-        local x
-        [[ $EUID == 0 ]] && x=sudo
-        $x yum -y install "$@"
+        local s; [[ $EUID != 0 ]] && s=sudo
+        $s yum -y install "$@"
     }
     # package find
     pf() {
-        local x
-        [[ $EUID == 0 ]] && x=sudo
-        $x yum search "$@"
+        local s; [[ $EUID != 0 ]] && s=sudo
+        $s yum search "$@"
     }
     # package remove/uninstall
     pu() {
-        local x
-        [[ $EUID == 0 ]] && x=sudo
-        $x yum autoremove "$@"
+        local s; [[ $EUID != 0 ]] && s=sudo
+        $s yum autoremove "$@"
     }
     pup() { # upgrade
-        local x
-        [[ $EUID == 0 ]] && x=sudo
-        $x yum -y distro-sync full
+        local s; [[ $EUID != 0 ]] && s=sudo
+        $s yum -y distro-sync full "$@"
     }
     # package list info
     pl() {
         yum info "$@"
     }
+    pfile() {
+        yum whatprovides \*/$1
+    }
     
-else
+elif command -v apt-get &>/dev/null; then
     p() {
-        local x
-        [[ $EUID == 0 ]] && x=sudo
-        $x aptitude "$@"
+        local s; [[ $EUID != 0 ]] && s=sudo
+        $s apt-get "$@"
     }
-    pi() {
-        local x
-        [[ $EUID == 0 ]] && x=sudo
-        # update package list if its more than an hour old
-        if (( $(( $(date +%s) - $(stat -c %Y /var/lib/apt/periodic/update-success-stamp) )) > 60*60 )); then
-            $x aptitude update
+    pupdate() {
+        local s f; [[ $EUID != 0 ]] && s=sudo
+        # update package list if its more than an 2 hours old
+        f=/var/cache/apt/pkgcache.bin
+        if [[ ! -r $f ]] \
+               || (( $(( $(date +%s) - $(stat -c %Y $f ) )) > 60*60*2 )); then
+            $s apt-get update
         fi
-        $x aptitude -y install "$@"
+    }
+    pi() {
+        pupdate
+        local s; [[ $EUID != 0 ]] && s=sudo
+        $s apt-get -y install "$@"
+    }
+    pi-nostart() {
+        local s; [[ $EUID != 0 ]] && s=sudo
+        local f=/usr/sbin/policy-rc.d
+        $s dd of=$f <<EOF
+#!/bin/sh
+exit 101
+EOF
+        $s chmod +x $f
+        pi "$@"
+        $s rm $f
     }
     pf() {
-        # scratch a very annoying itch.
-        # package description width as wide as the screen, and package name field small
-        # aptitude manual can't figure out how wide emacs terminal is,
-        # of course it doesn't consult the $COLUMNS variable...
-        # and in a normal terminal, it makes the package name field ridiculously big
+        # scratch a very annoying itch.  package description width as
+        # wide as the screen, and package name field small aptitude
+        # manual can't figure out how wide emacs terminal is, of course
+        # it doesn't consult the $COLUMNS variable...  and in a normal
+        # terminal, it makes the package name field ridiculously big
         # also, remove that useless dash before the description
-        local x
-        [[ $EUID == 0 ]] && x=sudo
-        $x aptitude -F "%c%a%M %p %$((COLUMNS - 30))d" -w $COLUMNS search "$@"
+        local s; [[ $EUID != 0 ]] && s=sudo
+        $s aptitude -F "%c%a%M %p %$((COLUMNS - 30))d" -w $COLUMNS search "$@"
     }
     pu() {
-        local x
-        [[ $EUID == 0 ]] && x=sudo
-        $x aptitude -y purge "$@"
+        local s; [[ $EUID != 0 ]] && s=sudo
+        $s apt-get -y purge "$@"
+        $s apt-get -y autoremove
     }
     pup() { # upgrade
-        local x
-        [[ $EUID == 0 ]] && x=sudo
-        $x aptitude -y full-upgrade "$@"
+        pupdate
+        local s; [[ $EUID != 0 ]] && s=sudo
+        $s apt-get -y dist-upgrade "$@"
+        $s apt-get -y autoremove
     }
     # package info
     pl() {
         aptitude show "$@"
     }
-    
+    pfile() {
+        if [[ $file == /* ]] && ucfq -w $file | grep -v ::: &>/dev/null; then
+            ucfq $file
+        elif [[ $file == */* ]]; then
+            apt-file find -x "$1"\$
+        else
+            apt-file find -x /"$1"\$
+        fi
+    }
+    pkgfiles() {
+        if dpkg -s "$1" &>/dev/null; then
+            dpkg-query -L $1
+        else
+            apt-file -x list "^$1$"
+        fi
+    }
+
+elif command -v pacman &>/dev/null; then
+    p() {
+        pacaur "$@"
+    }
+    pi() {
+        pacaur -S --noconfirm --needed --noedit "$@"
+    }
+    pf() {
+        pacaur -Ss "$@"
+    }
+    pu() {
+        pacaur -Rs --noconfirm "$@"
+        if p=$(pacaur -Qdtq); then
+            pacaur -Rs $p
+        fi
+    }
+    aurex() {
+        p="$1"
+        aur='https://aur.archlinux.org'
+        curl -s $aur/$(curl -s "$aur/rpc.php?type=info&arg=$p" \
+                           | jq -r .results.URLPath) | tar xz
+        cd "$p"
+
+    }
+    pmirror() {
+        local s; [[ $EUID != 0 ]] && s=sudo
+        local x=$(mktemp)
+        curl -s "https://www.archlinux.org/mirrorlist/\
+?country=US&protocol=https&ip_version=4&ip_version=6&use_mirror_status=on" \
+            | sed -r 's/^[ #]*(Server *=)/\1/' > $x
+        if (( $(stat -c %s $x ) > 10 )); then
+            $s cp $x /etc/pacman.d/mirrorlist
+            rm $x
+        fi
+    }
+    pup() { # upgrade
+        local s; [[ $EUID != 0 ]] && s=sudo
+        # file_time + 24 hours > current_time
+        if ! (( $(stat -c%Y /etc/pacman.d/mirrorlist) + 60*60*24 > $(date +%s) ))
+        then
+            pmirror
+        fi
+        pacaur -Syu --noconfirm "$@"
+    }
+    # package info
+    pl() {
+        pacaur -Si "$@"
+    }
+    pfile() {
+        pkgfile "$1"
+    }
+    pkgfiles() {
+        if pacaur -Qs "^$1$" &>/dev/null; then
+            pacman -Ql $1
+        else
+            pkgfile -l $1
+        fi
+    }
 fi