Skip to content

Instantly share code, notes, and snippets.

@janderudder
Last active October 9, 2021 10:50
Show Gist options
  • Save janderudder/7e0a2bf7070e065bdd3b082b87e48e41 to your computer and use it in GitHub Desktop.
Save janderudder/7e0a2bf7070e065bdd3b082b87e48e41 to your computer and use it in GitHub Desktop.
vsc new version
#!/bin/bash
#########################################################
## ##
## Create dev project and launch Visual Studio Code ##
## ##
#########################################################
### Please customize here ###
declare -r TemplateRoot="/home/$USER/dev/cpp/_template/"
declare -r ProjectNamePlaceholder='__PROJECT_NAME__'
### Cool, it's done. ###
declare -Ar Templates=( \
[c++2a-premake]='cpp-premake | cppm : C++2a project with Premake5 support' \
)
declare -r BaseName="$(basename -s'.sh' "$0")"
ListTemplate()
{
declare -ar TplDescriptions=("${Templates[@]}")
declare -ri TplCount=${#TplDescriptions[@]}-1
for I in $(seq 0 $TplCount); do
echo "${TplDescriptions[$I]}"
done
}
Help()
{
cat <<-HERE_DOCUMENT
Setup a project based on a folder template + launch Visual Studio Code.
USAGE
1: ${BaseName} --new TEMPLATE-NAME TARGET-DIR
2: ${BaseName} [TARGET-DIR]
1: copy relevant files according to TEMPLATE-NAME in TARGET-DIR,
then launch vscode there.
2: launch vscode in TARGET-DIR, or in current directory if not specified.
AVAILABLE TEMPLATES
HERE_DOCUMENT
ListTemplate
cat <<-HERE_DOCUMENT
EXAMPLES
Create ./MyProject folder configured as a c++2a project with Premake:
\$ ${BaseName} --new cppm MyProject
HERE_DOCUMENT
}
## is help called?
## -------------------------------------------------------------------
for Arg in "$@"; do
case "$Arg" in
'--help'|'-h')
Help
exit
;;
'--list'|'-l')
echo -en "Available templates\n\n$(ListTemplate)\n\n"
exit
;;
esac
done
## utilities
## -------------------------------------------------------------------
FatalError() {
echo "$1"
[[ $2 ]] && exit $2 || exit 1
}
Sanitize()
{
while [[ $# -gt 1 ]]; do printf '%q ' "$1"; shift; done
[[ $# -gt 0 ]] && printf '%q' "$1"
}
Unescape()
{
while [[ $# -gt 1 ]]; do eval "printf '%s '" "$@"; shift; done
[[ $# -gt 0 ]] && eval "printf '%s'" "$@"
}
## check code is installed
## -------------------------------------------------------------------
type code &> /dev/null
if [[ $? -ne 0 ]]
then
FatalError "Sorry, the 'code' program does not seem to be installed." -1
fi
## arguments parsing
## -------------------------------------------------------------------
declare TemplateName=''
declare ProjectName=''
declare TargetPath=''
declare BuildFileRelPath='build/premake5.lua'
ParseTemplateName()
{
case "$1" in
'cpp-premake'|'cppm'|'c++2a-premake'|'c++-premake'|'c++premake')
TemplateName="c++2a-premake"
;;
*)
FatalError "unknown template name"
;;
esac
}
ParseTargetProject()
{
TargetPath="$(Sanitize "$(realpath "$1")")"
ProjectName="$(Unescape "$(basename "$TargetPath")")"
}
while [[ $# -ne 0 ]]
do
case "$1" in
'--new'|'-n')
shift
[[ $# -lt 1 ]] && FatalError "no template name provided"
ParseTemplateName "$1"
;;
*)
if [[ $1 =~ ^- ]]
then
ArgWithoutHyphen="$(sed 's/^-\{1,2\}//g'<<<${1})"
FatalError "argument not understood (\"${ArgWithoutHyphen}\")"
else
ParseTargetProject "$1"
fi
;;
esac
shift
done
## (if asked) create a project based on folder template
## -------------------------------------------------------------------
if [[ ! -z $TemplateName ]]
then
## check we don't write in an existing directory or over a file
## -----------------------------------------------------------
if [[ -d $TargetPath ]]; then
[[ ! -z "$(ls -A "$TargetPath")" ]] && \
FatalError "target directory already exists and is not empty"
elif [[ -f $TargetPath ]]; then
FatalError "target path exists as a file"
fi
## utilites
## -----------------------------------------------------------
CopyTemplate()
{
declare -r TemplateName="$1"
declare -r TargetPath="$2"
declare -r TemplatePath="$TemplateRoot/$TemplateName"
cp -r "$TemplatePath" "$TargetPath"
[[ $? -ne 0 ]] && FatalError "couldn't create the target directory"
}
ReplaceProjectName()
{
declare -r ProjectName="$1"
declare -r FileTarget="$2/$BuildFileRelPath"
sed -i "s/$ProjectNamePlaceholder/$ProjectName/g" "$FileTarget"
[[ $? -ne 0 ]] && FatalError "couldn't put project name in build file"
}
## do stuff
## -----------------------------------------------------------
CopyTemplate "$TemplateName" "$TargetPath"
ReplaceProjectName "$ProjectName" "$TargetPath"
# If we're not creating a new project and have not provided a target path
## -------------------------------------------------------------------
elif [[ -z $TargetPath ]]
then
ParseTargetProject '.'
fi
## launch vscode
## -------------------------------------------------------------------
echo "Opening vscode in '${ProjectName}/'"
eval code "$TargetPath"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment