#!/usr/bin/env sh
#
# stowpkg package manager
#
# Copyright (C) 2017 Silvio Rhatto - rhatto at riseup.net
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published
# by the Free Software Foundation, either version 3 of the License,
# or 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
# Parameters
PROGRAM="$0"
VERSION="0.0.1"
DIRNAME="$(cd `dirname $PROGRAM` && pwd)"
BASENAME="`basename $PROGRAM`"
ACTION="$1"
CWD="`pwd`"
__stowpkg_cd () {
if [ -z "$1" ]; then
cd $CWD > /dev/null 2>&1
else
if [ -d "$1" ]; then
cd $1 > /dev/null 2>&1
fi
fi
}
__stowpkg_initialize () {
# Check for stow
if ! which stow > /dev/null 2>&1; then
echo "$BASENAME: please install stow first"
exit 1
fi
# Sudo config
if [ "`whoami`" != 'root' ]; then
SUDO="sudo"
fi
# Source config file
if [ -e "$HOME/.config/stowpkg" ]; then
. "$HOME/.config/stowpkg"
fi
# Ports
if [ -z "$PORTS" ]; then
PORTS="$DIRNAME/ports"
fi
# Set base
if [ -z "$BASE" ]; then
BASE="$DIRNAME/tree/`uname -m`"
fi
# Sources
if [ -z "$SOURCES" ]; then
SOURCES="$BASE/src"
fi
# Binaries
if [ -z "$BINARIES" ]; then
BINARIES="$BASE/stow"
fi
# Ensure folders exists
mkdir -p $BASE $PORTS $SOURCES $BINARIES
# Export
export BASE="$BASE"
export PORTS="$PORTS"
export SOURCES="$SOURCES"
export BINARIES="$BINARIES"
}
stowpkg_usage () {
echo "$BASENAME $VERSION - a package manager"
echo ""
echo "usage: $BASENAME [options]"
echo ""
echo "available actions:"
echo ""
grep "^stowpkg_" $PROGRAM | cut -d ' ' -f 1 | sed -e 's/stowpkg_//' | sort | xargs -L 6 | column -t -c 6 | sed -e 's/^/\t/'
echo ""
exit 1
}
stowpkg_search () {
local package="$1"
if [ ! -z "$package" ]; then
stowpkg_search | grep "$package$"
else
( __stowpkg_cd $PORTS && find -name 'desc' | sed -e 's|^\./||' -e 's|/desc||' )
fi
}
stowpkg_install () {
local package="$1"
if [ -z "$package" ]; then
stowpkg_usage
fi
# Find package on ports
local location="$PORTS/`$PROGRAM search $package`"
if [ "$location" = "${PORTS}/" ]; then
echo "$BASENAME: package not found: $package"
exit 1
fi
if [ "`basename $location`" != "$package" ]; then
echo "$BASENAME: package not found: $package"
exit 1
fi
local installed="`stowpkg_list $package-`"
if [ ! -z "$installed" ]; then
echo "$BASENAME: package $package already installed"
echo "to reinstall, use '$BASENAME reinstall $package'"
exit 1
fi
# Source environment
if [ -e "$location/env" ]; then
. $location/env
fi
# Set default version
if [ -z "$version" ]; then
version="latest"
fi
if [ "$source_format" = "git" ]; then
source_version="git"
else
source_version="$version"
fi
# Resolve default dependencies
if [ ! -z "$dependencies_stowpkg" ]; then
for dependency in $dependencies_stowpkg; do
$PROGRAM install $dependency
done
fi
# Resolve debian dependencies
if [ -e "/etc/debian_version" ]; then
if [ ! -z "$dependencies_debian" ]; then
$SUDO apt install $dependencies_debian
fi
fi
# Go to sources folder
__stowpkg_cd $SOURCES
# Download sources if needed
if [ ! -d "${package}-${source_version}" ]; then
if [ "$source_format" = "git" ]; then
git clone $url ${package}-${source_version}
fi
fi
# Check source
if [ ! -d "${package}-${source_version}" ]; then
echo "$BASENAME: source not found for package $package"
exit 1
fi
# Go to source folder
__stowpkg_cd ${package}-${source_version}
if [ "$source_format" = "git" ]; then
git fetch --all
git checkout $version
fi
# Build
stowpkg_build $package $version
}
stowpkg_reinstall () {
local package="$1"
if [ -z "$package" ]; then
echo "usage: $BASENAME reinstall "
exit 1
fi
stowpkg_remove $package && stowpkg_install $package
}
stowpkg_build () {
local package="$1"
local version="$2"
# Check
if [ -z "$version" ]; then
echo "$BASENAME: please specify package name and version"
exit 1
fi
# Set PREFIX
if [ -z "$PREFIX" ]; then
PREFIX="$BINARIES/${package}-${version}"
fi
# Build
if [ -e "$location/rules" ]; then
. $location/rules
else
# Try default rules
if [ -e "Makefile" ]; then
make clean
fi
if [ -e "configure" ]; then
./configure --prefix=$PREFIX
fi
if [ -e "Makefile" ]; then
make PREFIX=$PREFIX
make PREFIX=$PREFIX install
fi
fi
__stowpkg_cd $BINARIES
if [ -d "${package}-${version}" ]; then
stow ${package}-${version} || exit 1
else
echo "$BASENAME: error building $package"
exit 1
fi
__stowpkg_cd
}
stowpkg_list () {
local pattern="$1"
if [ ! -z "$pattern" ]; then
local name="-name \'$pattern*\'"
fi
find $BASE -type l | grep -v "^src/" | grep -v "^stow/" | while read file; do
dest="`stat $file | head -n 1 | cut -d '>' -f 2 | sed -e 's/ //'`"
if echo $dest | grep -q "^stow/" || echo $dest | grep -q "/stow/"; then
echo $dest | sed -e 's|.*stow/\(.*\)/.*|\1|'
fi
done | sort | uniq
}
stowpkg_binaries () {
ls -1 $BINARIES
}
stowpkg_sources () {
ls -1 $SOURCES
}
stowpkg_ls () {
( cd $BASE && ls $* )
}
stowpkg_location () {
echo $BASE
}
stowpkg_switch () {
local package="$1"
local version="$2"
if [ -z "$version" ]; then
echo "usage: $BASENAME switch "
exit 1
fi
if [ ! -d "$BINARIES/${package}-${version}" ]; then
echo "$BASENAME: binaries not found for ${package}-${version}"
exit 1
fi
local installed="`stowpkg_list $package | sed -e "s/$package-//"`"
if [ "$version" = "$installed" ]; then
echo "$BASENAME: package $version already installed"
exit
fi
__stowpkg_cd $BINARIES
echo "Removing currently installed ${package}-${installed}..."
stow --delete ${package}-${installed}
echo "Switching to ${package}-${version}..."
stow ${package}-${version}
__stowpkg_cd
}
stowpkg_remove () {
local package="$1"
if [ -z "$package" ]; then
echo "usage: $BASENAME remove "
exit 1
fi
local installed="`stowpkg_list $package-`"
if [ -z "$installed" ]; then
echo "$BASENAME: package $package not installed"
exit 1
fi
__stowpkg_cd $BINARIES
echo "Removing currently installed ${installed}..."
stow --delete $installed
__stowpkg_cd
}
stowpkg_purge () {
local package="$1"
if [ -z "$package" ]; then
echo "usage: $BASENAME purge "
exit 1
fi
local installed="`stowpkg_list $package-`"
if [ ! -z "$installed" ]; then
stowpkg_remove $package
fi
echo "Removing all sources and binaries that matches $package..."
rm -rf $BINARIES/$package-*
rm -rf $SOURCES/$package-*
}
stowpkg_upgrade () {
local package="$1"
if [ -z "$package" ]; then
echo "usage: $BASENAME upgrade "
exit 1
fi
local location="$PORTS/`$PROGRAM search $package`"
if [ "$location" = "${PORTS}/" ]; then
echo "$BASENAME: package not found: $package"
exit 1
fi
local installed="`stowpkg_list $package-`"
if [ -z "$installed" ]; then
echo "$BASENAME: package $package not installed"
exit 1
fi
if [ -e "$location/env" ]; then
. $location/env
fi
local current="`stowpkg_list $package | sed -e "s/$package-//"`"
if [ "$version" = "$current" ]; then
echo "$BASENAME: current package $version already installed"
exit
fi
stowpkg_remove $package && stowpkg_install $package
}
stowpkg_update () {
__stowpkg_cd $DIRNAME && git pull
__stowpkg_cd
}
# Dispatch
if grep -q "^stowpkg_$ACTION () {$" $PROGRAM; then
__stowpkg_initialize
shift
stowpkg_$ACTION $*
else
stowpkg_usage
fi