Updates to the Zsh pkgtools.
authorSteve Youngs <steve@steveyoungs.com>
Thu, 18 Feb 2021 09:26:37 +0000 (19:26 +1000)
committerSteve Youngs <steve@steveyoungs.com>
Thu, 18 Feb 2021 09:26:37 +0000 (19:26 +1000)
Mostly this is to do with having groups span multiple lines in
/etc/group.  Toward that end, parsing /etc/group is not done anymore.
To get at the 'install' group members we use groupmems(8) (via sudo).

The output of Lpkg() was cleaned up.  Yup, I just discovered
column(1). :-)

Two new functions:
  dpkg() -- Print a package's short description
  Dpkg() -- Print a package's long description.

The old dpkg() to show a package's dependencies has been renamed to pkgdeps()

* etc/pkgusr/zsh/_zsh-pkgtools (_pkgtools_users): Use groupmems
instead of parsing /etc/group.

* etc/pkgusr/zsh/zsh-pkgtools: Whitespace reformat.  Tabs are 8
chars wide, but in shell-scripts I like 4 char indents.
(pkgdeps): New, renamed from 'dpkg'.
(dpkg): Now prints a package's short description.
(Dpkg): New, print a package's long description.
(pkglst): New.  Saves package list to a var, $PKGLST
(fpkg): Use $PKGLST. Add `-E' grep option.
(lpkg): Parse $PKGLST instead of /etc/group.
(Lpkg): Parse $PKGLST instead of /etc/group, use column(1) for
cleaner output.
(pkg_install): Call pkglst() to update $PKGLST
(pkgwant): Use $PKGLST instead of calling lpkg()

Signed-off-by: Steve Youngs <steve@steveyoungs.com>
etc/pkgusr/zsh/_zsh-pkgtools
etc/pkgusr/zsh/zsh-pkgtools

index 769106e..95e0b4c 100644 (file)
@@ -1,8 +1,9 @@
-#compdef cpkg dpkg fpkg gpkg ipkg ppkg upkg vpkg wpkg pkgrepo pkgsu pkgwant vtar xtar
+#compdef cpkg dpkg Dpkg gpkg ipkg ppkg upkg vpkg wpkg pkgdeps pkgrepo pkgsu pkgwant vtar xtar
+
 
 _pkgtools_users()
 {
-    compadd "$@" - $(awk -F: '/^install/ {print $4;}' /etc/group|tr -s , ' ')
+    compadd "$@" - $(sudo groupmems -lg install)
 }
 
 _zsh-pkgtools()
@@ -14,7 +15,7 @@ _zsh-pkgtools()
             (cpkg) _command_names -e ;;
        (?pkg|pkg*) _arguments -C -s ':Package User:_pkgtools_users' ;;
          ([xv]tar) _wanted file expl 'Tarball' _files -g \
-             '*.{t{gz,bz{,2},lz,xz},tar.{Z,gz,bz2,lzma,xz}}(-.)' ;;
+           '*.{t{gz,bz{,2},lz,xz},tar.{Z,gz,bz2,lz{,ma},xz,zst{,d}}}(-.)' ;;
     esac
 }
 
index 4c0d8a5..a33dbfa 100644 (file)
@@ -1,25 +1,29 @@
 # -*- Shell-script -*-
-# Copyright (C) 2007 - 2013 Steve Youngs <steve@steveyoungs.com>
+# Copyright (C) 2007 - 2021 Steve Youngs <steve@steveyoungs.com>
 #
 #  A collection of Zsh functions that I use day to day for maintaining
 #  and administering my machines.  These come in very handy if you set up
 #  one of your users as a "package manager".  There is a corresponding
 #  _zsh-pkgtools file that provides completion for most of what is here.
+
+## Help
 H-pkg ()
 {
         cat<<EOF
 
         fpkg [REGEXP] -- finds pkg names matching REGEXP.                      
         ppkg [NAME]   -- print pkg NAME pkg info.  
-        cpkg [CMD]    -- find what package provides CMD.     
+        cpkg [CMD]    -- find what package provides CMD. (regex OK)
         lpkg          -- list installed packages.
         Lpkg          -- list installed packages with dates last updated.
+        dpkg [PKG]    -- print PKG short description.
+       Dpkg [PKG]    -- print PKG long description.
+        gpkg [PKG]    -- print PKG general notes.
+        ipkg [PKG]    -- print PKG install notes.
         upkg [PKG]    -- date/time the last time PKG was updated.
         vpkg [PKG]    -- print the version of PKG.
-        ipkg [PKG]    -- print install notes of PKG.
-        gpkg [PKG]    -- print general notes of PKG.
         wpkg [PKG]    -- print PKG website URL.
-        dpkg [PKG]    -- print PKG dependencies.
+       pkgdeps [PKG] -- print PKG dependencies.
        pkgwant [PKG] -- print a list of packages that depend on PKG
         pkgrepo [PKG] <t> -- print the source repo location of PKG
                              with optional 2nd arg non-nil, also print
@@ -39,188 +43,238 @@ H-pkg ()
 EOF
 }
 
+## Keep a list of all packages.
+#  This needs sudo setup to allow the "package manager" to run commands
+#  with no password.  I gave the wheel group such access.
+pkglst () { PKGLST=($(sudo groupmems -lg install)) }
+
+## Find packages matching a regexp
 fpkg () 
 {
-        if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
-                echo Invalid or missing argument >&2
-                echo "Usage: $0 [REGEXP]" >&2
-                return 1
-        else
-                sed -n '/^install:/,$p' /etc/group|cut -d: -f1| \
-                  grep -i --colour ${argv[1]}
-        fi
+    if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [REGEXP]" >&2
+       return 1
+    else
+       print ${PKGLST[*]}|tr ' ' '\n'|grep -iE --colour ${argv[1]}
+    fi
 }
 
+## Print a package's .project
 ppkg () 
 {
-        if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
-                echo Invalid or missing argument >&2
-                echo "Usage: $0 [NAME]" >&2
-                return 1
-        else
-                pinky -l $argv[1]|less
-        fi
+    if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [NAME]" >&2
+       return 1
+    else
+       pinky -l $argv[1]|less
+    fi
 }
 
+## Find package names for commands matching regexp
 cpkg ()
 {
-        if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
-                echo Invalid or missing argument >&2
-                echo "Usage: $0 [CMD]" >&2
-                return 1
-        else
-                find $path -type f -regex "^.*/$argv[1].*$" \
-                  -printf "%f -- (%u:%g)\n"|grep --colour '(.*)'
-        fi
+    if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [CMD]" >&2
+       return 1
+    else
+       find $path -type f -regex "^.*/$argv[1].*$" \
+           -printf "%f -- (%u:%g)\n"|grep --colour '(.*)'
+    fi
 }
 
+## List all packages
 lpkg () 
 {
-        sed -n '/^install/p' /etc/group|cut -d: -f4|tr ',' '\n'|less
+    print ${PKGLST[*]}|tr ' ' '\n'|less
 }
 
+## Show date/time a package was last updated
 upkg()
 {
-        if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
-                echo Invalid or missing argument >&2
-                echo "Usage: $0 [PKG]" >&2
-                return 1
-        else
-                grep --colour 'Last_Updated:.*' ~$argv[1]/.project
-        fi
+    if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [PKG]" >&2
+       return 1
+    else
+       grep --colour 'Last_Updated: ' ~$argv[1]/.project
+    fi
 }
 
+## List all packages with last-updated date/time
 Lpkg ()
 {
-        for pkg in $(sed -n '/^install/p' /etc/group|cut -d: -f4|tr ',' '\n'); do
-                printf "${pkg}\t\t\t$(upkg ${pkg}|cut -d' ' -f3-)\n"
-        done|less
+    for ((i=1; i<=${#PKGLST}; i++)); do
+       print "${PKGLST[${i}]}#$(upkg ${PKGLST[${i}]}|cut -d' ' -f3-)"
+    done|column -t -s\#|less
 }
 
+## Display a package's version
 vpkg()
 {
-        if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
-                echo Invalid or missing argument >&2
-                echo "Usage: $0 [PKG]" >&2
-                return 1
-        else
-                grep --colour 'Version: ' ~$argv[1]/.project
-        fi
+    if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [PKG]" >&2
+       return 1
+    else
+       grep --colour 'Version: ' ~$argv[1]/.project
+    fi
 }
 
+## Display a package's install notes
 ipkg()
 {
-        if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
-                echo Invalid or missing argument >&2
-                echo "Usage: $0 [PKG]" >&2
-                return 1
-        else
-                local top=$(grep -n "Install Notes" ~$argv[1]/.project|cut -d: -f1)
-                local bot=$(grep -n "General Notes" ~$argv[1]/.project|cut -d: -f1)
-                sed -n ${top},${bot}p  ~$argv[1]/.project|less
-        fi
-}
-               
+    if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [PKG]" >&2
+       return 1
+    else
+       local top=$(grep -n "Install Notes" ~$argv[1]/.project|cut -d: -f1)
+       local bot=$(grep -n "General Notes" ~$argv[1]/.project|cut -d: -f1)
+       sed -n ${top},${bot}p  ~$argv[1]/.project|less
+    fi
+}
+
+## Display a package's general notes
 gpkg()
 {
-        if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
-                echo Invalid or missing argument >&2
-                echo "Usage: $0 [PKG]" >&2
-                return 1
-        else
-                local top=$(grep -n "General Notes" ~$argv[1]/.project|cut -d: -f1)
-                local bot=$(grep -n "CONTENTS" ~$argv[1]/.project|cut -d: -f1)
-                sed -n ${top},${bot}p ~$argv[1]/.project|less
-        fi
+    if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [PKG]" >&2
+       return 1
+    else
+       local top=$(grep -n "General Notes" ~$argv[1]/.project|cut -d: -f1)
+       local bot=$(grep -n "CONTENTS" ~$argv[1]/.project|cut -d: -f1)
+       sed -n ${top},${bot}p ~$argv[1]/.project|less
+    fi
 }
 
+## Display a package's short description
 dpkg()
 {
-        if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
-                echo Invalid or missing argument >&2
-                echo "Usage: $0 [PKG]" >&2
-                return 1
-        else
-               grep --colour 'Deps: ' ~$argv[1]/.project
-       fi
+    if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [PKG]" >&2
+       return 1
+    else
+       grep --colour 'Description: ' ~$argv[1]/.project
+    fi
+}
+
+## Display a package's long description
+Dpkg()
+{
+    if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [PKG]" >&2
+       return 1
+    else
+       local top=$(grep -n "Description:" ~$argv[1]/.project|cut -d: -f1)
+       local bot=$(grep -n "Repo_Type:" ~$argv[1]/.project|cut -d: -f1)
+       sed -n ${top},${bot}p ~$argv[1]/.project|less
+    fi
 }
 
+## Display a package's website
 wpkg()
 {
-        if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
-                echo Invalid or missing argument >&2
-                echo "Usage: $0 [PKG]" >&2
-                return 1
-        else
-                grep --colour 'Web_Site: ' ~$argv[1]/.project
-        fi
+    if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [PKG]" >&2
+       return 1
+    else
+       grep --colour 'Web_Site: ' ~$argv[1]/.project
+    fi
+}
+
+## Display a package's dependencies
+pkgdeps()
+{
+    if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [PKG]" >&2
+       return 1
+    else
+       grep --colour 'Deps: ' ~$argv[1]/.project
+    fi
 }
 
+## Display a package's repo URL
 pkgrepo()
 {
-        if [[ $ARGC -lt 1 || $ARGC -gt 2 ]]; then
-                echo Invalid or missing argument >&2
-                echo "Usage: $0 [PKG] <t>" >&2
-                return 1
-        else
-                grep --colour 'Repo_Location: ' ~$argv[1]/.project
-                [[ -n "$argv[2]" ]] && grep --colour 'Repo_Type: ' ~$argv[1]/.project
-        fi
+    if [[ $ARGC -lt 1 || $ARGC -gt 2 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [PKG] <t>" >&2
+       return 1
+    else
+       grep --colour 'Repo_Location: ' ~$argv[1]/.project
+       [[ -n "$argv[2]" ]] && grep --colour 'Repo_Type: ' ~$argv[1]/.project
+    fi
 }
 
+## Display all packages that depend on package
 pkgwant()
 {
-       if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
-               echo Invalid or mission argument >&2
-               echo "Usage: $0 [PKG]" >&2
-               return 1
-       fi
+    if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
+       echo Invalid or mission argument >&2
+       echo "Usage: $0 [PKG]" >&2
+       return 1
+    fi
 
-       for p in $(lpkg); do
-               dpkg ${p} | grep -wq $argv[1] && print ${p}
-       done
+    for p in ${PKGLST[@]}; do
+       pkgdeps ${p} | grep -wq $argv[1] && print ${p}
+    done
 }
 
+## Convenience: create tarballs
 ctar()
 {
-        if [[ $ARGC -ne 2 ]]; then
-               echo Invalid or missing argument >&2
-               echo "Usage: $0 [FILE] [DIRECTORY]" >&2
-               return 1
-        fi
+    if [[ $ARGC -ne 2 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [FILE] [DIRECTORY]" >&2
+       return 1
+    fi
 
-        local opts
-        opts=(--create --owner=0 --group=0 --auto-compress --file)
+    local opts
+    opts=(--create --owner=0 --group=0 --auto-compress --file)
 
-        tar ${opts} $1 $2
+    tar ${opts} $1 $2
 }
 
+## Change to package user
 pkgsu()
 {
-        if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
-                echo Invalid or missing argument >&2
-                echo "Usage: $0 [PKGUSR]" >&2
-                return 1
-        else
-                ssh -l root localhost -t DISPLAY=${DISPLAY} su - $argv[1]
-        fi
+    if [[ $ARGC -lt 1 || $ARGC -gt 1 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [PKGUSR]" >&2
+       return 1
+    else
+       ssh -l root localhost -t DISPLAY=${DISPLAY} su - $argv[1]
+    fi
 }
 
+## Install new package
 pkg_install()
 {
-        if [[ $ARGC -lt 3 || $ARGC -gt 3 ]]; then
-                echo Invalid or missing argument >&2
-                echo "Usage: $0 [DESCRIPTION] [USER] [GROUP]" >&2
-                return 1
-        else
-                ssh -l root localhost -t install_package \
-                  ${argv[1]} $argv[2] $argv[3]
-        fi
+    if [[ $ARGC -lt 3 || $ARGC -gt 3 ]]; then
+       echo Invalid or missing argument >&2
+       echo "Usage: $0 [DESCRIPTION] [USER] [GROUP]" >&2
+       return 1
+    else
+       ssh -l root localhost -t install_package \
+           ${argv[1]} $argv[2] $argv[3]
+    fi &&
+    pkglst
 }
 
+## Couple handy aliases
 alias pkg_ldconfig='ssh -l root localhost ldconfig'
 alias vtar=less
 alias xtar='tar xf'
 
+## On-Load actions
+pkglst
 ### End