Created
March 23, 2023 12:06
-
-
Save nazfox/3e8d5b1803826a4ec79e3a5c9bd7393c to your computer and use it in GitHub Desktop.
供養
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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