Skip to content

Instantly share code, notes, and snippets.

@nazfox
Created March 23, 2023 12:06
Show Gist options
  • Save nazfox/3e8d5b1803826a4ec79e3a5c9bd7393c to your computer and use it in GitHub Desktop.
Save nazfox/3e8d5b1803826a4ec79e3a5c9bd7393c to your computer and use it in GitHub Desktop.
供養
#!/usr/bin/env bash
readonly DOPPEL_VER="0.0.1"
readonly DOPPEL_ROOT="${DOPPEL_ROOT:-"${HOME}/.doppel"}"
# These messages were generated by ChatGPT
readonly DOPPEL_SUCCES_MESSAGES=(
"Your project has been generated, time to fire up the coffee machine and get coding!"
"Project generation complete. Time to caffeinate and conquer some code!"
"Project generated. Time to put on some tunes and dive into some coding wizardry."
"Congratulations, your project has been generated! May your code be as bug-free as the Matrix."
"Project generated. May the source be with you!"
"Your project is generated and ready to hack."
"Project generation successful! Time to hack the planet."
"The project has been created. Your coding journey continues."
"Your project is now generated and ready for infinite coding adventures!"
"Your project has been successfully created, time to put on your coding cape and save the day!"
)
function doppel_version() {
echo "${DOPPEL_VER}"
}
function doppel_help() {
echo "Usage: doppel [OPTIONS] TEMPLATE_DIRECTORY"
echo ""
echo " Generate a new project from the specified TEMPLATE_DIRECTORY."
echo ""
echo "Options:"
echo " -n, --name NAME Specify the project name."
echo " -o, --output OUTPUT_DIR Specify the output directory."
echo " -f, --force Overwrite existing files without prompting."
echo " -v, --version Show the version information."
echo " -h, --help Show this message and exit."
echo ""
echo "Example:"
echo " doppel /path/to/template"
echo " doppel /path/to/template -n my_project -o /path/to/output"
}
function clean_line() {
echo "$1" | \
sed -e 's/#.*//' \
-e 's/^[[:space:]]*//' \
-e 's/[[:space:]]*$//' \
-e 's/[[:space:]]*=[[:space:]]*/=/'
}
function split_values() {
local fpat="([^,]+)|([[:space:]]*\"[^\"]+\"[[:space:]]*)|([[:space:]]*'[^']+'[[:space:]]*)"
echo "$1" | awk -vFPAT="${fpat}" '{ for(i=1;i<=NF;i++) { print $i } }'
}
function sanitize_value() {
local v=""
v="$(echo "$1" | \
sed -e 's/^[[:space:]]*//' \
-e 's/[[:space:]]*$//' \
-e "s/^[\"']//" \
-e "s/[\"']\$//" \
-e "s/'/'\"'\"''/g")"
echo "'$v'"
}
function extract_key() {
local key="$1"
key="$(echo "${key}" | cut -d'=' -f1)"
echo "${key}"
}
function extract_values() {
local values="$1"
values="$(echo "${values}" | cut -d'=' -f2)"
values="$(split_values "${values}")"
while IFS= read -r v; do
echo "$(sanitize_value "$v")"
done <<< "${values}"
}
function print_vars() {
local key="$1"
local values="$2"
local num_values="$(echo "${values}" | wc -l)"
local v=""
local cnt=0
echo -n "${key}="
if [[ "${num_values}" -gt 1 ]]; then
echo -n "("
while IFS= read -r v; do
cnt="$((cnt + 1))"
echo -n "$v"
if [[ "${cnt}" -ne "${num_values}" ]]; then
echo -n " "
fi
done <<< "${values}"
echo ")"
else
echo "${values}"
fi
}
function load_conf() {
local template_directory="$1"
local conf_file="${template_directory}/doppel.conf"
local lineno=0
local line=""
local cleaned_line=""
local key=""
local values=""
if [[ ! -f "${conf_file}" ]]; then
echo "ERROR: doppel.conf not found in the specified template directory"
exit 1
fi
while read -r line; do
lineno="$((lineno + 1))"
cleaned_line="$(clean_line "${line}")"
if [[ -z "${cleaned_line}" ]]; then
continue
fi
if [[ ! "${cleaned_line}" =~ "=" ]]; then
echo "WARN: Invalid syntax at line ${lineno}: ${line}"
continue
fi
key="$(extract_key "${cleaned_line}")"
values="$(extract_values "${cleaned_line}")"
print_vars "${key}" "${values}"
done < "${conf_file}"
}
function variable_prompt() {
echo 'hi'
}
function expansion_templates() {
echo 'hi'
}
function show_success_message() {
local array_len="${#DOPPEL_SUCCES_MESSAGES[@]}"
local index="$((RANDOM % array_len))"
echo "${DOPPEL_SUCCES_MESSAGES[$index]}"
}
function generate_project() {
local template_directory="$1"
local project_name="$2"
local output_directory="$3"
local overwrite="$4"
if [[ ! -d "${template_directory}" ]]; then
echo "ERROR: specified template directory does not exist"
exit 1
fi
if [[ -d "${output_directory}" ]] && [[ ! ${overwrite} ]]; then
echo "ERROR: Project directory already exists. Use --force option to overwrite."
exit 1
fi
# doppel.confの構文解析
# コメント行を削除
# 展開すべき変数を解析
# 不正な行があれば、行番号と一緒にエラーメッセージを表示
# 最終的に完成したファイルを一時ファイルに出力
# 変数の確認プロンプトを表示(デフォルト値はdoppel.confの内容)
# テンプレートのコピーと変数の展開
# ディレクトリ名、ファイル名を展開
# ファイルの中身を展開
# 完了メッセージを表示
load_conf "${template_directory}"
variable_prompt
expansion_templates
show_success_message
}
function doppel_main() {
local template_directory=""
local project_name=""
local output_directory=""
local force="false"
local show_version=false
local show_help=false
while [[ $# -gt 0 ]]; do
case "$1" in
-n|--name)
if [[ $# -lt 2 ]]; then
echo "ERROR: argument missing for $1 option."
exit 1
fi
project_name="$2"
shift; shift;
;;
-o|--output)
if [[ $# -lt 2 ]]; then
echo "ERROR: argument missing for $1 option."
exit 1
fi
output_directory="$2"
shift; shift;
;;
-f|--force) overwrite="true"; shift ;;
-v|--version) show_version=true; shift ;;
-h|--help) show_help=true; shift ;;
-*|--*)
echo "ERROR: invalid option -- '$1'"
echo "Try `doppel --help` for more information"
exit 1
;;
*)
break
;;
esac
done
if [[ $# -eq 0 ]]; then
echo "ERROR: Missing TEMPLATE_DIRECTORY argument"
echo "Try `doppel --help` for more information"
exit 1
fi
if [[ $# -gt 1 ]]; then
echo "ERROR: Unexpected argument '$2'"
echo "Try `doppel --help` for more information"
exit 1
fi
template_directory="$1"
if ${show_version} && ${show_help}; then
doppel_version
doppel_help
elif ${show_version}; then
doppel_version
elif ${show_help}; then
doppel_help
else
generate_project "${template_directory}" "${project_name}" "${output_directory}" "${overwrite}"
fi
}
doppel_main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment