i've been working in this script to manage ports in FreeBSD, called Portman
it's still pretty experimental and serves mostly as aliases for make targets, but here it is:
lemme know what you guys think, i need ideas for improvements
it's still pretty experimental and serves mostly as aliases for make targets, but here it is:
Bash:
#!/usr/bin/env zsh
# extra pull options in case you've
# cloned the tree differently
#PULL_OPTS=(--rebase)
# we need word splitting here
setopt shwordsplit
msg() {
tput bold
if [[ $1 = "ERROR" ]]; then
tput setaf 1
elif [[ $1 = "WARNING" ]]; then
tput setaf 3
else
tput setaf 7
fi
printf "$1"
tput setaf 7
printf ": "
tput sgr0
printf "${*:2}"
}
error() {
msg "ERROR" "${*:2}\n"
exit $1
}
exist_check() {
# check if we even have an argument
[[ -z $1 ]] && error 1 "a port must be specified!"
# then, check if the thing actually
# exists
[[ -d /usr/ports/$1 ]] || error 1 "$1 doesn't exist!"
}
# default pager options:
# shift 5 characters,
# quit if the file fits in a single screen,
# interpret ANSI escape codes,
# and 4-character long tabs
export LESS="-5 -F -R -x4"
# check if we're root so we can
# actually operate
perm_check() {
[[ $(id -u) = 0 ]] || error 2 "you are not root!"
}
cd /usr/ports
case $1 in
"update" | "u")
perm_check
git pull ${PULL_OPTS[@]}
;;
"install" | "i")
perm_check
for ARG in ${@:2}; do
case $ARG in
"-d")
# check if the user doesn't wanna run
# make config first;
# because of `&&', add a dummy
# program here to run
WANTS_CONFIG=(true)
;;
"-k")
# also check if they wanna keep the
# work files;
# ditto
WANTS_CLEAN=(true)
;;
"-r")
# also check if they actually wanna
# reinstall the port
WANTS_REINSTALL=(make deinstall)
;;
*)
# if those haven't been set, set them
# to their defaults
[[ ! $WANTS_REINSTALL ]] && WANTS_REINSTALL=(true)
[[ ! $WANTS_CONFIG ]] && WANTS_CONFIG=(make config)
[[ ! $WANTS_CLEAN ]] && WANTS_CLEAN=(make clean)
exist_check ${ARG}
cd ${ARG}
# run setup
${WANTS_CONFIG[@]}
# build it
make &&
# if performing an update on it,
# deinstall it first
${WANTS_REINSTALL[@]}
# finally, install it
make install &&
# and maybe clean its directory
${WANTS_CLEAN[@]}
# and go to previous directory as
# we iterate thru them
cd -
;;
esac
done
;;
"clean" | "c")
perm_check
for PKG in ${@:2}; do
exist_check ${PKG}
cd ${PKG}
make clean
done
;;
"cleandist" | "C")
perm_check
if [[ -d "distfiles/" ]]; then
rm -rf distfiles/
else
echo "It's already clean!"
fi
;;
"remove" | "r")
perm_check
# ditto #1
for PKG in ${@:2}; do
cd ${PKG}
make deinstall
# ditto #2
cd -
done
;;
"find" | "f")
[[ -z $2 ]] && error 1 "a search term must be supplied!"
make search name=$2
;;
"desc" | "d")
exist_check $2
less $2/pkg-descr
;;
"getcfg" | "g")
exist_check $2
make -C $2 showconfig
;;
"peek" | "p")
exist_check $2
less $2/Makefile
;;
"switch" | "s")
perm_check
git switch $2
;;
"version" | "v")
tput bold
echo -n "Portman v1.0.0a"
tput sgr0
echo ","
echo "written by ruby R53 in October 2025"
;;
"help" | "h" | *)
msg "Usage" "$0 <action>"
msg "\nActions (and their short forms)" \
"\n(u)pdate - update ports tree by issuing \`git clone'" \
"\n(i)nstall [-d] [-k] <port> - install port, more than one may be listed." \
"\n You may also install it without running" \
"\n \`make config' as well ([d]efaults), " \
"\n and/or [k]eeping its work files" \
"\n(c)lean <port> - clean <port>'s work files" \
"\n(C)leandist - get rid of all distfiles in /usr/ports" \
"\n(r)emove <port> - uninstall package, more than one may be" \
"\n listed too" \
"\n(f)ind <query> - find ports that match <query>" \
"\n(d)esc <port> - get <port>'s description" \
"\n(g)etcfg <port> - get <port>'s configuration options" \
"\n(p)eek <port> - peek at <port>'s Makefile" \
"\n(s)witch <branch> - switch ports tree to <branch>" \
"\n(v)ersion - get running Portman version\n"
[[ $1 != "help" ]] && [[ $1 != "h" ]] && exit 1
;;
esac