From 137e4ed9d74891349de1b0da1e0cf2653ea92c5e Mon Sep 17 00:00:00 2001 From: Max Mahn Date: Wed, 20 May 2026 09:23:50 -0400 Subject: initial commit --- src/args.sh | 79 ++++++++++++++++++++++++++++++++++++++++++ src/main.sh | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/util.sh | 15 ++++++++ 3 files changed, 205 insertions(+) create mode 100644 src/args.sh create mode 100644 src/main.sh create mode 100644 src/util.sh (limited to 'src') diff --git a/src/args.sh b/src/args.sh new file mode 100644 index 0000000..25a11db --- /dev/null +++ b/src/args.sh @@ -0,0 +1,79 @@ + +SHORT_OPTS="" +LONG_OPTS="" +for option in $(seq 0 5 $((${#OPTIONS[@]}-1)) ) +do + SHORT_OPTS+="${OPTIONS[(${option} + 1)]}${OPTIONS[(${option} + 3)]:+:}" + LONG_OPTS+="${OPTIONS[(${option} + 2)]}${OPTIONS[(${option} + 3)]:+:}," +done + +GETOPT_CMD="getopt -n $(basename $0) -o ${SHORT_OPTS} -l ${LONG_OPTS} -- $@" + + +USAGES=( + "mktree [options] " + "mktree -f [options] " +) + + +PrintHelp() { + leader="Usage: " + for usage in "${USAGES[@]}" + do + echo "${leader}${usage}" + leader=" or " + done + echo "Options:" + for option in $(seq 0 5 $((${#OPTIONS[@]}-1)) ) + do + short="${OPTIONS[(${option} + 1)]}" + long="${OPTIONS[(${option} + 2)]}" + arg="${OPTIONS[(${option} + 3)]}" + desc="${OPTIONS[(${option} + 4)]}" + + printf " -%-6s --%-16s %-48s\n" \ + "${short} ${arg}" "${long}${arg:+=${arg}}" "${desc}" + done +} + + +ParseOpts() { + while [ $# -gt 0 ] + do + case $1 in + "--") # end of options + shift + if [ -z "${FMT_PATH}" ] + then + FMT_PATH=$(GetTemplate $(Unquote $1)) + [ 0 -ne $? ] && Error "Couldn't find template $1!" && exit 1 + shift + fi + PROJECT_NAME=$(Unquote $1) + shift + [ -z "${PROJECT_NAME}" ] && Error "Project name not specified!\n" && exit 1 + MakeProject ${FMT_PATH} ${PROJECT_NAME} $@ + exit $? + ;; + -*) # options + for i in $( seq 0 5 $((${#OPTIONS[@]}-1)) ) + do + callback="${OPTIONS[${i}]}" + short="${OPTIONS[(${i} + 1)]}" + long="${OPTIONS[(${i} + 2)]}" + arg="${OPTIONS[(${i} + 3)]}" + desc="${OPTIONS[(${i} + 4)]}" + case $1 in + "-${short}" | "--${long}") + eval "${callback}" "${arg:+$2}" || exit $? + [ -n "${arg}" ] && shift # extra shift if the option takes an arg + break + ;; + esac + done + ;; + esac + shift + done +} + diff --git a/src/main.sh b/src/main.sh new file mode 100644 index 0000000..1b38eab --- /dev/null +++ b/src/main.sh @@ -0,0 +1,111 @@ +#!/bin/sh + +########################################## +## { mktree } ## +## Copyright(C) 2026 Maxwell Mahn ## +## see LICENSE file for license details ## +## - -- - -- - -- - -- - -- - -- - -- - ## +## just a shell script for automating ## +## the creation of repetative directory ## +## structures. (like everytime you want ## +## to start a new project; now you can ## +## eliminate the setup time; surely ## +## you'll finish the project this time) ## +########################################## + + +# default program configuration +SETUP_SCRIPT=".setup.sh" + +cfg_dir="${MKTREE_CONFIGDIR:-${HOME}/.config/mktree}" + +USER_TEMPLATES="$cfg_dir/skel" +SYSTEM_TEMPLATES="/etc/mktree/skel" + +##include src/util.sh + + +GetTemplate() { + [ -z "$1" ] && return 1 + + for prefix in "${CUSTOM_TEMPLATES}" "${USER_TEMPLATES}" "${SYSTEM_TEMPLATES}" + do + [ -z "${prefix}" ] && continue + temp_path="${prefix}/$1" + Debug 2 "Checking template path '${temp_path}'..." + [ -d "${temp_path}" ] && echo "${temp_path}" && return 0 + done + return 1 +} + + +MakeProject() { # format_path, project_name + [ -z "$1" ] && Error "Project format not defined!" && return 1 + [ -z "$2" ] && Error "Project name not defined!" && return 1 + + [ -d "$2" ] && Error "Can't make project in $2. Directory already exists." && return 1 + + # copy skeleton + Debug 1 "Copying template skeleton..." + cp -r "$1" "./$2" && cd "./$2" + + # run hooks + Debug 1 "Running setup hooks..." + shift 2 + setup="./${SETUP_SCRIPT}" + [ -f "${setup}" ] && sh "${setup}" $@ + + if [ $? -eq 0 ] + then + Debug 2 "Removing setup script..." + rm -f "${setup}" + else + Error "Failed to run setup hooks!" + fi + + Debug 1 "Done." + return 0 +} + + +ListTemplates() { + [ -d ${USER_TEMPLATES} ] && echo "User Templates:" && \ + for template in ${USER_TEMPLATES}/* + do + echo " $(basename ${template})" + done + [ -d ${SYSTEM_TEMPLATES} ] && echo "System Templates:" && \ + for template in ${SYSTEM_TEMPLATES}/* + do + echo " $(basename ${template})" + done + exit 0 +} + + +SetSystemDir() { + [ -d "$1" ] && SYSTEM_TEMPLATES="$1" return 0 || return 1; +} + +SetUserDir() { + [ -d "$1" ] && USER_TEMPLATES="$1" return 0 || return 1; +} + +SetFormatPath() { + [ -d "$1" ] && FMT_PATH="$1" return 0 || return 1; +} + +SetVerbose() { + VERBOSITY+=1 +} + + +##insert awk -v OUTPUT=shell -f args.awk res/args + +##include src/args.sh + + +# parsing options +options=$(${GETOPT_CMD}) && ParseOpts ${options} \ + || Error "Run '$(basename $0) -h' for usage information." && exit 1 + diff --git a/src/util.sh b/src/util.sh new file mode 100644 index 0000000..f190a82 --- /dev/null +++ b/src/util.sh @@ -0,0 +1,15 @@ + +Error() { + echo "$@" 1>&2 +} + +Unquote() { + out=${1#\'} + echo "${out%\'}" +} + +VERBOSITY=0 +Debug() { + [ $1 -le $VERBOSITY ] && shift && echo "$@" >&2 +} + -- cgit v1.2.3