#!/bin/bash ScriptFile=$(readlink -f "${BASH_SOURCE[0]}") ScriptDir=$(dirname "${ScriptFile}") IgnoreVsCodeSettings=1 UseGit=0 Verbose=0 Update=0 CMakeModules="" CMakeModulesForced="" Operations=() function Log() { printf "$@\n" } function Verbose() { if [[ $Verbose -eq 1 ]]; then Log "$@" fi } function Error() { >&2 printf "$@\n" } function Panic() { Error "$@" exit 1 } function PrintHelp() { printf "This is a tool to create a new project group or projects inside an exsisting group. Parameters: -g|--group <group-directory> Create a new project group at the given directory. -i|--interface <name> <group-directory> Create a new interface library project with the given name at the given directory. -l|--library <name> <group-directory> Create a new library project with the given name at the given directory. -e|--executable <name> <group-directory> Create a new executable project with the given name at the given directory. -m|--modules <remote> -M|--force-modules <remote> Add the CMake Modules from the given remote repository as submodule of the new project. --git Initialize a new git repository when creating a new project or group. -u|--update Update an exsisting project. -s|--vscode Add default settings for visual studio code -v|--verbose Print extra debug output. -?|-h|--help Print this help. " } function Copy() { srcDir="$1" dstDir="$2" file="$3" oldName="$4" newName="$5" tmpSrc="$srcDir$file" tmpDst="$dstDir$file" if [[ -n "$oldName$newName" ]]; then tmpDst=${tmpDst//$oldName/$newName} fi tmpDir=$(dirname $tmpDst) Verbose " Copy .$file to $tmpDst" mkdir -p "$tmpDir" \ || Panic "Unable to create directory: $tmpDir!" cp "$tmpSrc" "$tmpDst" \ || Panic "Unable to copy file: $tmpSrc > $tmpDst!" if [[ -n "$oldName$newName" ]]; then oldUpper=$(echo $oldName | awk -F: '{ print toupper($1) }') newUpper=$(echo $newName | awk -F: '{ print toupper($1) }') sed -i -e "s/$oldName/$newName/g" "$tmpDst" \ || Panic "Unable to replace names!" sed -i -e "s/$oldUpper/$newUpper/g" "$tmpDst" \ || Panic "Unable to replace names!" fi } function CreateGroup() { dir="$1" Log "\nCreate Project Group: $dir" # Create directory Log " Create directory: $dir" mkdir -p "$dir" \ || Panic "Unable to create project group directory: $dir!" # Create git repository Log " Create git repository" git -C $dir init \ || Panic "Git init failed!" # Add cmake modules Log " Add git submodule for CMake modules" if [[ -n "$CMakeModules" ]]; then git -C $dir submodule add $CMakeModulesForced "$CMakeModules" "cmake/modules" \ || Panic "Git submodule add failed!" git -C $dir/cmake/modules fetch --all \ || Panic "Git submodule fetch failed!" git -C $dir/cmake/modules reset --hard origin/master \ || Panic "Git submodule reset failed!" fi # Copy files Log " Copy files" srcDir="$ScriptDir" for file in $(find $srcDir -type f); do # Ignore unrelated files if [[ $file == $ScriptFile ]] \ || [[ $file == $srcDir/build/* ]] \ || [[ $file == $srcDir/.git/* ]] \ || [[ $file == $srcDir/.gitmodules ]] \ || [[ $file == $srcDir/projects/* ]] \ || [[ $file == $srcDir/cmake/* ]] then relFile=.${file/$srcDir/} Verbose " Ignore $relFile" # Ignore .vscode settings elif [[ IgnoreVsCodeSettings -eq 1 ]] \ && [[ $file == $srcDir/.vscode/* ]] then relFile=.${file/$srcDir/} Verbose " Ignore $relFile" # Copy related files else Copy "$srcDir" "$dir" "${file/$srcDir/}" fi done } function CreateProject() { name="$1" groupdir="$2" src="$3" dir="$groupdir/projects/$name" Log "\nCreate Project $1 in director $2" # Create directory Log " Create directory: $dir" mkdir -p "$dir" \ || Panic "Unable to create directory: $dir!" # Create/Update git repository if [[ $Update -eq 1 ]]; then if [[ -e "$dir/cmake/modules/.git" ]]; then Log " Update git submodule for CMake modules" git -C "$dir/cmake/modules" fetch origin \ || Panic "Unable to fetch cmake module!" git -C "$dir/cmake/modules" checkout master \ || Panic "Unable to checkout cmake module!" git -C "$dir/cmake/modules" reset --hard origin/master \ || Panic "Unable to reset cmake module!" fi elif [[ $UseGit -eq 1 ]]; then Log " Create git repository" git -C $dir init \ || Panic "Git init failed!" # Add cmake modules if [[ -n "$CMakeModules" ]]; then Log " Add git submodule for CMake modules" git -C $dir submodule add $CMakeModulesForced "$CMakeModules" "cmake/modules" \ || Panic "Git submodule add failed!" git -C $dir/cmake/modules fetch --all \ || Panic "Git submodule fetch failed!" git -C $dir/cmake/modules reset --hard origin/master \ || Panic "Git submodule reset failed!" fi fi # Copy files Log " Copy files" Copy "$ScriptDir/cmake" "$groupdir/cmake" "/Find$src.cmake" "$src" "$name" srcDir="$ScriptDir/projects/$src" for file in $(find $srcDir -type f); do targetFile="${file/$srcDir/}" targetFile="${dir}${targetFile}" targetFile="${targetFile//$src/$name}" # exclude build directory and cmake modules if [[ $file == $srcDir/build/* ]] \ || [[ $file == $srcDir/cmake/modules/* ]] then relFile=.${file/$srcDir/} Verbose " Ignore $relFile" # Ignore .vscode settings elif [[ IgnoreVsCodeSettings -eq 1 ]] \ && [[ $file == $srcDir/.vscode/* ]] then relFile=.${file/$srcDir/} Verbose " Ignore $relFile" # ignore git files elif [[ $UseGit -eq 0 ]] \ && [[ $file == $srcDir/.git* ]] then relFile=.${file/$srcDir/} Verbose " Ignore $relFile" # update elif [[ $Update -eq 1 ]] \ && [[ ! -f ${targetFile} ]] then relFile=.${file/$srcDir/} Verbose " Ignore $relFile" # copy else Copy "$srcDir" "$dir" "${file/$srcDir/}" "$src" "$name" fi done } # Parse arguments while [ $# -gt 0 ]; do case $1 in "-g" | "--group" ) if [ $# -lt 2 ]; then Panic "Parameter $1 expects exactly one parameter!" fi tmp=$(readlink -m "$2") Operations+=("grp:$tmp") shift ;; "-i" | "--interface" ) if [ $# -lt 3 ]; then Panic "Parameter $1 expects exactly two parameter!" fi tmp=$(readlink -m "$3") Operations+=("intf:$2:$tmp") shift shift ;; "-l" | "--library" ) if [ $# -lt 3 ]; then Panic "Parameter $1 expects exactly two parameter!" fi tmp=$(readlink -m "$3") Operations+=("lib:$2:$tmp") shift shift ;; "-e" | "--executable" ) if [ $# -lt 3 ]; then Panic "Parameter $1 expects exactly two parameter!" fi tmp=$(readlink -m "$3") Operations+=("exe:$2:$tmp") shift shift ;; "-m" | "--modules" ) if [ $# -lt 2 ]; then Panic "Parameter $1 expects exactly one parameter!" fi CMakeModules="$2" shift ;; "-M" | "--force-modules" ) if [ $# -lt 2 ]; then Panic "Parameter $1 expects exactly one parameter!" fi CMakeModules="$2" CMakeModulesForced="--force" shift ;; "-u" | "--update") Update=1 ;; "-s" | "--vscode") IgnoreVsCodeSettings=0 ;; "--git" ) UseGit=1 ;; "-v" | "--verbose" ) Verbose=1 ;; "-h" | "-?" | "--help" ) PrintHelp exit 0 ;; * ) Panic "Invalid or unknown parameter: $1" ;; esac shift done # Execute operations for data in "${Operations[@]}"; do op=$(echo $data | awk -F: '{ print $1 }') case $op in grp) dir=$(echo $data | awk -F: '{ print $2 }') CreateGroup "$dir" ;; intf) name=$(echo $data | awk -F: '{ print $2 }') dir=$(echo $data | awk -F: '{ print $3 }') CreateProject "$name" "$dir" "libinterface" ;; lib) name=$(echo $data | awk -F: '{ print $2 }') dir=$(echo $data | awk -F: '{ print $3 }') CreateProject "$name" "$dir" "libhelloworld" ;; exe) name=$(echo $data | awk -F: '{ print $2 }') dir=$(echo $data | awk -F: '{ print $3 }') CreateProject "$name" "$dir" "helloworld" ;; *) Panic "Invalid or unknown operation: $op" ;; esac done