#!/bin/sh
# {{{ Copyright

# ph - list installed packages

# Copyright 2013 Dave Woodfall <dave@dawoodfall.net>
# All rights reserved.
#
# Redistribution and use of this script, with or without modification, is
# permitted provided that the following conditions are met:
#
# 1. Redistributions of this script must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
# EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# Shellcheck note: --exclude=SC2016,SC1117,SC2012
# }}}
# {{{ Version
version() {
		printf "%s\n" "$SCRIPT $VERSION - $DESC.
(C) 2013- Dave Woodfall <dave@dawoodfall.net>. All rights reserved."
}
# }}}
# {{{ Usage
usage() {
	version
	printf "%s\n" "
Usage: $SCRIPT [options] N

Where N is number of most recently installed packages to list.
If N is omitted all packages will be listed.
If N is negative the first N packages will be listed.

Options are:
-d		Omit dates and times.
-v		Omit versions.
-t <TAG>	List only packages with TAG.
-s		List only SBo packages (equivalent to -t _SBo).
-i		Use long-iso format for dates.
-h		Usage.
--help		Usage with examples.

NOTE:

The list order depends on the modified times of the files in /var/log/packages.
If these files have been touched since the packages were installed then the
results will be wrong."
}
# }}}
# {{{ Long Usage
long_usage() {
	usage
printf "
Example usage:

Simply print the last 10 packages that were installed:

ph 10

List the first 10 packages installed:

ph -10

Print out the last 5 SBo (slackbuilds.org) packages installed:

ph -s 5

Get a count of all SBo packages installed:

ph -s | wc -l

List all of alienBOB's packages (not including compat32) with install dates and
versions:

ph -t alien

List all compat32 packages omitting dates and versions:

ph -d -v -t compat32

Uninstall the last 5 SBo packages installed:

removepkg \`ph -v -d -s 5\`

Uninstall ALL SBo packages:

removepkg \`ph -v -d -s\`

ph supports the ROOT variable. To list the last SBo package installed in the
root partition mounted at /mnt/slack:

ROOT=/mnt/slack ph -s 1

removepkg also supports ROOT, but obviously it is saner to export it in the
environment than to type it twice for the removepkg and ph commands.

To uninstall ALL SBo packages installed in a mounted partition:

export ROOT=/mnt/slack
removepkg \`ph -v -d -s\`

NOTES:

Test without removepkg first (a dry run) to see exactly which packages will be
uninstalled in case the modification times are off.

Remember to unset ROOT before resuming normal operations on the host system.
"
	exit
}
# }}}
# {{{ Errors
error() {
	if [ "$1" = "cd" ]; then
		printf "%s\n" "Error: Could not change directory to $PKGDIR."
	elif [ "$1" = "tag" ]; then
		printf "%s\n" "Error: -t used but no tag specified."
	fi
	exit 1
}
# }}}
# {{{ Do the list
dolist() {
	ls -t1"$L" --time-style="$TIMESTYLE" -- *"$TAG" 2>/dev/null | \
		rev | cut -d- -f"$CUT"- | rev | \
		$hdtl -n "$num" | \
		awk "$AWK"
}
# }}}
# {{{ Init
init() {
	PKGDIR="$ROOT/var/log/packages"
	cd "$PKGDIR" 2>/dev/null || error "cd"
	# Don't want this if it's set:
	unset LS_OPTIONS
	SCRIPT=$(basename "$0")
	VERSION="1.0.1"
	DESC="A Slackware Package History"
	CUT=3
	L="l"
	TIMESTYLE='+%a %b %d %Y %R'
	AWK='{printf ("%-40s %-20s %s\n", $11, $6" "$7" "$8" "$9, $10)}'

	while [ -n "$1" ]
	do
		if [ "$1" = "-d" ]; then
			AWK='{print $0}'
			unset L
		elif [ "$1" = "-v" ]; then
			CUT=4
		elif [ "$1" = "-s" ]; then
			TAG="_SBo"
		elif [ "$1" = "-t" ]; then
			TAG="$2"
			if [ -z "$TAG" ]; then
				error "tag"
			elif [ $(expr "x$TAG" : "x[a-zA-Z_]*$") -eq 0 ]; then
				error "tag"
			else
				shift
			fi
		elif [ "$1" = "-i" ]; then
			TIMESTYLE="long-iso"
			AWK='{printf ("%-40s %-15s %s\n", $8, $6, $7)}'
		elif [ "$1" = "-h" ]; then
			usage
			exit
		elif [ "$1" = "--help" ]; then
			long_usage
		else
			num=$1
		fi
		shift
	done

	numpackages=$(ls | wc -w)
	[ -z "$num" ]||[ "$num" -eq 0 ] && num="$numpackages"
	[ -n "$num" ]&&[ "$num" -lt 0 ] && hdtl="tail" || hdtl="head"
}
# }}}
# {{{ Start
init "$@"
dolist "$@"
# }}}
# vim: colorcolumn=79
