#!/bin/sh # This program is free software: you can redistribute it and/or modify it under # the terms of the GNU Affero General Public License as published by the Free # Software Foundation, either version 3 of the License, or (at your option) any # later version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more # details. readonly PKGSRC_ROOT="$HOME/.local/src/pkgsrc" # TODO: Make configurable readonly PKGSRC_DURATIONS="$XDG_DATA_HOME/pkgsrc/durations" main() { PKGSRC_INIT="$(time_unix)" # Handle opts while getopts ":h" opt do case "$opt" in h) usage && exit 0 ;; *) printf "Invalid option passed: %s\n" "$OPTARG" >&2 ;; esac done shift $(( OPTIND - 1 )) if [ $# -lt 1 ] then usage exit 1 fi PKGSRC_ACTION="action_$1" ; shift if ! command -V "$PKGSRC_ACTION" 2>/dev/null | grep -qwi function then usage exit 1 fi $PKGSRC_ACTION "$@" } action_add() { mkdir -p -- "$PKGSRC_DURATIONS" for package in "$@" do cd -- "$PKGSRC_ROOT" # cd wont fail here if pkg_resolve had no output if ! cd -- "$(pkg_resolve "$package")" then printf "No package found for %s\n" "$package" continue fi bmake install \ && bmake clean-depends \ && bmake clean \ || continue printf "%d\n" "$(( $(time_unix) - PKGSRC_INIT ))" \ >> "$PKGSRC_DURATIONS/$package" done printf "Installation took %s\n" "$(time_duration "$PKGSRC_INIT" "$(time_unix)")" } action_del() { for package in "$@" do cd -- "$PKGSRC_ROOT" if ! cd -- "$(pkg_resolve "$package")" then printf "No package found for %s\n" "$package" continue fi bmake deinstall done } action_grep() { cd -- "$PKGSRC_ROOT" find . -maxdepth 2 -type d \ | cut -c 3- \ | grep "$@" } action_init() { export CVS_RSH="ssh" if [ ! -d "$PKGSRC_ROOT" ] then mkdir -p -- "${PKGSRC_ROOT%/*}" cd -- "${PKGSRC_ROOT%/*}" cvs -d anoncvs@anoncvs.NetBSD.org:/cvsroot checkout -P pkgsrc || die 1 fi if [ -d "$HOME/.pkgsrc" ] then printf "pkgsrc seems to have been initialized already at $HOME/.pkgsrc\n" exit 1 fi cd -- "$PKGSRC_ROOT/bootstrap" rm -fr -- work ./bootstrap --unprivileged --prefix="$HOME/.pkgsrc" # TODO: Make configurable printf "Bootstrapped in %s\n" "$(time_duration "$PKGSRC_INIT" "$(time_unix)")" } action_opts() { cd -- "$(pkg_resolve "$1")" || die "No package found for $1" bmake show-options } action_time() { for package in "$@" do if [ ! -f "$PKGSRC_DURATIONS/$package" ] then printf "%s: No timings\n" "$package" continue fi package_min="$(sort "$PKGSRC_DURATIONS/$package" | head -n 1)" package_max="$(sort "$PKGSRC_DURATIONS/$package" | tail -n 1)" package_avg="$(awk '{ sum += $1 } END { printf("%.0f", (sum / NR)) }' "$PKGSRC_DURATIONS/$package")" printf "%s: %s / %s / %s \n" \ "$package" \ "$(time_duration "$package_min")" \ "$(time_duration "$package_avg")" \ "$(time_duration "$package_max")" done } action_update() { cd -- "$PKGSRC_ROOT" cvs up printf "Updated in %s\n" "$(time_duration "$PKGSRC_INIT" "$(time_unix)")" } usage() { cat < [target] Interact with pkgsrc. Options: -h Show this help text and exit. Actions: add Install one or more TARGETs. del Uninstall one or more TARGETs. grep Search for TARGET. init Initialize the pkgsrc repository, and run the bootstrap script. opts Show the options of TARGET. time Show min, avg, max installation times for TARGETs. update Update the pkgsrc repository. EOF } # # Helper utilities # die() { printf "%s\n" "$*" >&2 exit 1 } pkg_resolve() { readlink -f "$PKGSRC_ROOT"/*/"$1" || readlink -f "$PKGSRC_ROOT/$1" # What if both fail? } time_unix() { awk 'BEGIN{srand();print srand()}' } time_duration() { if [ ! -z "$2" ] then elapsed="$(( $2 - $1 ))" else elapsed="$1" fi printf "%dh %02dm %02ds" \ "$(( elapsed / 60 / 60 ))" \ "$(( elapsed / 60 % 60))" \ "$(( elapsed % 60 ))" } main "$@"