bash script to create new projects from project skeletons
#!/usr/bin/env bash
# List available skeletons
list()
{
local SKELETON N=0
for SKELETON in ${SKELETONS}/*
do
[ -d "$SKELETON" ] || continue
printf "%2d %s\n" $(( ++N )) "${SKELETON##*/}"
done
}
# Create a new project from a skeleton
#
# @param 1 - skeleton name or number
# @param 2 - name of new project
new()
{
(( $# < 2 )) && return 1
local SKELETON=$1
if (( SKELETON > 0 ))
then
local N=$SKELETON
for SKELETON in ${SKELETONS}/*
do
[ -d "$SKELETON" ] || continue
(( --N )) || break
done
SKELETON=${SKELETON##*/}
fi
if [ -r "$2" ]
then
echo "error: $2 already exists" >&2
return $?
fi
cp -ri "$SKELETONS/$SKELETON" "$2" || return $?
# preserve working directory when sourced
(
cd "$2" || return $?
local INIT=${0##*/}.sh
if [ -f "$INIT" ]
then
bash "$INIT" || return $?
rm -f "$INIT"
fi
)
}
# Create an init script for a new skeleton
init()
{
cat << EOF > "${0##*/}.sh"
#!/usr/bin/env bash
# Run this script to initialize the template or use skel to do it for you:
# https://gist.github.com/markusfisch/5e73a372241231a3a7c8
# Refactor in file contents and file/directory names
#
# @param 1 - case-sensitive pattern to replace
# @param 2 - replacement string
# @param 3 - working directory (optional)
refactor()
{
local PATTERN=\$1
local REPLACEMENT=\$2
local DIR=\${3:-.}
(( \$# < 2 )) && return 1
# rename directories before files
local TYPE
for TYPE in d f
do
find "\$DIR" -type "\$TYPE" -name "*\$PATTERN*" | while read -r
do
mv "\$REPLY" "\${REPLY//\$PATTERN/\$REPLACEMENT}"
done
done
local BASH_SOURCE_FILE=\${0##*/}
local TMP="\$0-\$\$"
grep -rl "\$PATTERN" "\$DIR"/* | while read -r
do
[ "\${REPLY##*/}" == "\$BASH_SOURCE_FILE" ] && continue
[ "\$REPLY" == "\$0" ] && continue
sed -e "s/\$PATTERN/\$REPLACEMENT/g" < "\$REPLY" > "\$TMP" &&
cat "\$TMP" > "\$REPLY"
rm -f "\$TMP"
done
}
#refactor 'AppName' "\${PWD##*/}"
EOF
}
# Print help
help()
{
cat << EOF
___
´ \` ___
( ) ( ) ´ \`
\`.(").´ ( ) ( )
|===| \`.(").´
\`---´ |===|
o \`---´
_--.--o--.--_ o
()\.-- o --./() _--.--o--.--_
| .-- o --. | ()\.-- o --./()
| .-- o --. | | .-- o --. |
usage: ${0##*/} COMMAND [ARGUMENT...]
COMMAND may be one of:
EOF
local DESC=
while read -r
do
case $REPLY in
''|refactor*)
DESC=
;;
\#\ *)
[ "$DESC" ] && continue
DESC=${REPLY#*#}
;;
*\(\))
[ "$DESC" ] || continue
echo "${REPLY%(*} -$DESC"
DESC=
;;
esac
done < "$0"
}
readonly SKELETONS=${SKELETONS:-$HOME/src/${0##*/}}
if [ "${BASH_SOURCE[0]}" == "$0" ]
then
"${@:-list}"
fi
Create new projects from project skeletons.
This script is for you if you create nontrivial projects that can be derived from a common base.
$ skel new android Happy
This creates a new "Happy" project from the skeleton "android".
By default, skeletons live in ~/src/skel. If you want another location:
export SKELETONS=/path/to/skeletons
To refactor a skeleton after creation, put a file named skel.sh into the root of your skeleton directory. This file is run immediately after the new project has been set up.
You may generate a blank skel.sh by running
$ skel init
This template contains a refactor function to refactor in files as well as in file and directory names.
For example, if your skeleton contains the literal "AppName" and you want to replace it, say with the directory name of the new project, you may put
refactor 'AppName' "${PWD##*/}"
into skel.sh in the skeleton root directory.
For more info use:
$ skel help