Overengineering cookiecutters

3 mincookiecuttertemplategitwhiptailrefreshtuioverengineering

I’ve overengineered my cookiecutter template selection thing.

I can remember some obscure git flag, but I cannot remember the cookiecutter templates I have. So I wanted some small menu that showed me the way. In the past I’ve done things with dialog and the new kids play with whiptail. So I went with what the cool kids use. In addition I added git config support, so I can set some default per projects so I don’t need to remember typing. Ha, laziness is a virtue friends.

In addition, I got really sick and tired of cookiecutter keep asking me to re-download my template directory repo. So I switched it to the template directory itself to silence it and added a refresh toggle to the script. All done via zparseopts. Which is still sort of a black box, but I’m getting results, so.. I’m good with me not fully understanding it.

The logic of the script is simple, have a cookiecutter template repo, clone it if the directory is missing.

Check if we want refresh the shit show, if yes, git does its thing. And yes, these are git commands in my world, git fetch --all and a clever little branch reset script that works with git-update-refs and git reset --hard. You want to have a look at my bum toolkit for that.

We exec cookiecutter with the directory path as a handy helper, for DRY-reasons. And if we have arguments (and we’re not even on Reddit) we use that, but only if the template directory exists.

And we check if can get a preconfigured template via git and if we don’t have all that: Find the templates and list them with whiptail and open cookiecutter with the selected template.

And all this because I got fed up with l $HOME/.cookiecuttersopndev-cookiecutter. 47 lines of zsh to reduce 42 characters of typing. Well, less with tab-completion. But we are not arguing facts today.

zsh
#!/usr/bin/env zsh

zmodload zsh/zutil
zparseopts -D -E -F - refresh=ff -refresh=ff no-git=ng -no-git=ng || exit 1

ff=${#ff}
ng=${#ng}

CK_DIR="$HOME/.cookiecutters/opndev-cookiecutter"

[[ ! -d "$CK_DIR" ]] && git clone \
  git@gitlab.com:opndev/opndev-cookiecutter.git $CK_DIR

if [[ $ff -eq 1 ]]
then
  git -C $CK_DIR fat
  git -C $CK_DIR reset-branch master origin/master
fi

do_ck() {
  exec cookiecutter $CK_DIR --directory $*
}

[[ -n "$1" && -d "$CK_DIR/$1" ]] && do_ck $*

if [[ -z "$1" && $ng -eq 0 ]]
then
  default_template=$(git config get bum.cookiecutter)
  [[ $? -eq 0 ]] && do_ck $default_template
fi

declare -a templates;
templates=($(find $CK_DIR -mindepth 1 -maxdepth 1 -type d \! \( -name LICENSES -or -name .git \) -printf '%P\0'| sort -z))

menu_args=()
for opt in $templates; do
  menu_args+=("$opt" "")
done

CHOICE=$(whiptail --title "Cookiecutter template selector" \
                  --menu "Choose a cookiecutter template:" 15 60 7 \
                  "${(@)menu_args}" \
                  3>&1 1>&2 2>&3)

[[ $? -ne 0 ]] && echo "Aborted!" >&2 && exit 1
do_ck $CHOICE