Useful scripts

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:
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
lemme know what you guys think, i need ideas for improvements
 
Back
Top