forked from EvergreenCrypto/docker-finance
docker-finance | modern accounting for the power-user
Dedicated to Michael Morgan: a beautiful, beautiful soul.
---
Internal signing keys:
Aaron Fiore (sole author)
- 518A22F85BEFD32BCC99C48603F90C4F35E0213E
- 31ECA5C347A0CC0815EDE730A3EACCFCDA7E685E
- C8187C585CB07A4DA81CC0F37318B50EBE9C0DA8
Internal repositories (rebased from):
Staging:
$ git log -n1 --pretty=format:"%H"
c8e0cd66f6c89fa7b3c62f72fb524a4cc454b7b6
$ git rev-list --max-parents=0 HEAD
ac3863b8c234755855f1aea3a07a853122decdf2
Private:
$ git log -n1 --pretty=format:"%H"
69bb3591eaa2990a9637832bb484690e00c4f926
$ git rev-list --max-parents=0 HEAD
a5c1cc9fb593c4cf09bc0adfef6cb6d2964511ae
This commit is contained in:
88
client/src/docker/lib/internal/dev-tools/lib_doxygen.bash
Normal file
88
client/src/docker/lib/internal/dev-tools/lib_doxygen.bash
Normal file
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# docker-finance | modern accounting for the power-user
|
||||
#
|
||||
# Copyright (C) 2021-2024 Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# "Libraries"
|
||||
#
|
||||
|
||||
source "$(dirname "$(realpath -s $0)")/src/docker/lib/internal/lib_docker.bash" || exit 1
|
||||
source "$(dirname "$(realpath -s $0)")/../container/src/finance/lib/internal/lib_utils.bash" || exit 1
|
||||
|
||||
#
|
||||
# Implementation
|
||||
#
|
||||
|
||||
function lib_doxygen::__parse_args()
|
||||
{
|
||||
[ -z "$global_usage" ] && lib_utils::die_fatal
|
||||
[ -z "$global_arg_delim_2" ] && lib_utils::die_fatal
|
||||
[ -z "$global_arg_delim_3" ] && lib_utils::die_fatal
|
||||
|
||||
# TODO: pass `doxygen` arguments to gen
|
||||
local -r _usage="
|
||||
\e[32mDescription:\e[0m
|
||||
|
||||
Manage Doxygen documentation
|
||||
|
||||
\e[32mUsage:\e[0m
|
||||
|
||||
$ $global_usage <gen|rm>
|
||||
|
||||
\e[32mExamples:\e[0m
|
||||
|
||||
\e[37;2m# Generate Doxygen\e[0m
|
||||
$ $global_usage gen
|
||||
|
||||
\e[37;2m# Remove previously generated Doxygen\e[0m
|
||||
$ $global_usage rm
|
||||
"
|
||||
|
||||
[[ $# -eq 0 || $# -gt 1 ]] && lib_utils::die_usage "$_usage"
|
||||
|
||||
for _arg in "$@"; do
|
||||
[[ ! "$_arg" =~ ^gen$|^rm$ ]] \
|
||||
&& lib_utils::die_usage "$_usage"
|
||||
done
|
||||
|
||||
declare -gr global_arg_cmd="$1"
|
||||
}
|
||||
|
||||
function lib_doxygen::__doxygen()
|
||||
{
|
||||
[ -z "$DOCKER_FINANCE_CLIENT_REPO" ] && lib_utils::die_fatal
|
||||
local -r _dir="${DOCKER_FINANCE_CLIENT_REPO}/client/Doxygen"
|
||||
|
||||
case "$global_arg_cmd" in
|
||||
gen)
|
||||
lib_docker::__run "doxygen ${_dir}/Doxyfile \
|
||||
&& echo -e \"\nNow, open your browser to:\n\n file://${_dir}/html/index.html\n\""
|
||||
;;
|
||||
rm)
|
||||
lib_docker::__run "rm --verbose -fr ${_dir}/html"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
function lib_doxygen::doxygen()
|
||||
{
|
||||
lib_doxygen::__parse_args "$@"
|
||||
lib_doxygen::__doxygen
|
||||
}
|
||||
|
||||
# vim: sw=2 sts=2 si ai et
|
||||
256
client/src/docker/lib/internal/dev-tools/lib_license.bash
Normal file
256
client/src/docker/lib/internal/dev-tools/lib_license.bash
Normal file
@@ -0,0 +1,256 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# docker-finance | modern accounting for the power-user
|
||||
#
|
||||
# Copyright (C) 2021-2024 Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# "Libraries"
|
||||
#
|
||||
|
||||
source "$(dirname "$(realpath -s $0)")/../container/src/finance/lib/internal/lib_utils.bash" || exit 1
|
||||
|
||||
#
|
||||
# Implementation
|
||||
#
|
||||
|
||||
function lib_license::__parse_args()
|
||||
{
|
||||
[ -z "$global_usage" ] && lib_utils::die_fatal
|
||||
[ -z "$global_arg_delim_2" ] && lib_utils::die_fatal
|
||||
[ -z "$global_arg_delim_3" ] && lib_utils::die_fatal
|
||||
|
||||
local -r _usage="
|
||||
\e[32mDescription:\e[0m
|
||||
|
||||
Add license text to a given file
|
||||
|
||||
\e[32mUsage:\e[0m
|
||||
|
||||
$ $global_usage file${global_arg_delim_2}<file>
|
||||
|
||||
\e[32mArguments:\e[0m
|
||||
|
||||
File path:
|
||||
|
||||
file${global_arg_delim_2}<path to file>
|
||||
|
||||
\e[32mExamples:\e[0m
|
||||
|
||||
\e[37;2m# Add license to given file\e[0m
|
||||
$ $global_usage file${global_arg_delim_2}/path/to/file.ext
|
||||
"
|
||||
|
||||
#
|
||||
# Ensure supported arguments
|
||||
#
|
||||
|
||||
[ $# -eq 0 ] && lib_utils::die_usage "$_usage"
|
||||
|
||||
for _arg in "$@"; do
|
||||
[[ ! "$_arg" =~ ^file[s]?${global_arg_delim_2} ]] \
|
||||
&& lib_utils::die_usage "$_usage"
|
||||
done
|
||||
|
||||
#
|
||||
# Parse arguments before testing
|
||||
#
|
||||
|
||||
# Parse key for value
|
||||
for _arg in "$@"; do
|
||||
local _key="${_arg%${global_arg_delim_2}*}"
|
||||
local _len="$((${#_key} + 1))"
|
||||
|
||||
if [[ "$_key" =~ ^file[s]?$ ]]; then
|
||||
local _arg_file="${_arg:${_len}}"
|
||||
[ -z "$_arg_file" ] && lib_utils::die_usage "$_usage"
|
||||
fi
|
||||
done
|
||||
|
||||
#
|
||||
# Test argument values, set globals
|
||||
#
|
||||
|
||||
IFS="$global_arg_delim_3"
|
||||
|
||||
# Arg: file
|
||||
if [ ! -z "$_arg_file" ]; then
|
||||
readonly global_arg_file="$_arg_file" # TODO: make array when multiple files implemented
|
||||
fi
|
||||
}
|
||||
|
||||
function lib_license::__get_file_type()
|
||||
{
|
||||
local -r _file="$(basename $1)"
|
||||
local -r _file_type="${_file##*.}"
|
||||
|
||||
if [ -z "$_file_type" ]; then
|
||||
lib_utils::die_fatal "File type not detected for '${_file}'"
|
||||
elif [[ "$_file_type" == "in" ]]; then
|
||||
# Dockerfile may have OS/platform in filename
|
||||
if [[ "$_file" =~ Dockerfile ]]; then
|
||||
readonly global_file_type="docker"
|
||||
else
|
||||
# Get real extension of .in file
|
||||
# TODO: optimize: remove cut, use bash
|
||||
global_file_type="$(echo $_file | cut -d'.' -f2)"
|
||||
readonly global_file_type
|
||||
fi
|
||||
else
|
||||
readonly global_file_type="$_file_type"
|
||||
fi
|
||||
|
||||
case "$global_file_type" in
|
||||
bash | yaml | yml | docker | rules | clang-format)
|
||||
readonly global_comment_type="#"
|
||||
;;
|
||||
cc | hh | C | php) # .C = ROOT macro file
|
||||
readonly global_comment_type="//"
|
||||
;;
|
||||
csv)
|
||||
readonly global_comment_type="//!"
|
||||
;;
|
||||
md)
|
||||
# NOTE: impl MUST complete this comment (see below)
|
||||
readonly global_comment_type="[//]: # ("
|
||||
;;
|
||||
*)
|
||||
lib_utils::die_fatal "Unsupported file type '${global_file_type}' for '${_file}'"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
function lib_license::__license()
|
||||
{
|
||||
local _deps=("gawk")
|
||||
lib_utils::deps_check "${_deps[@]}"
|
||||
|
||||
[ ! -f "$global_arg_file" ] \
|
||||
&& lib_utils::die_fatal "File not found '${global_arg_file}'"
|
||||
|
||||
lib_license::__get_file_type "$global_arg_file"
|
||||
|
||||
# TODO: add year= and author= arg options
|
||||
local -r _text="docker-finance | modern accounting for the power-user
|
||||
|
||||
Copyright (C) <year> <author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>."
|
||||
|
||||
# NOTE: docker-finance `.in` files will have docker-finance version on 1st line
|
||||
case "$global_file_type" in
|
||||
cc | hh | C | yaml | yml | docker | rules | clang-format)
|
||||
# Has no expectations of input
|
||||
local _sed_args=("-e" "s\^\\$global_comment_type \g" "-e" "s: *$::g")
|
||||
local _awk_args=('BEGIN{print text"\n"}{print}')
|
||||
;;
|
||||
bash | php | csv)
|
||||
local _sed_args=("-e" "s\^\\$global_comment_type \g" "-e" "s: *$::g")
|
||||
local _awk_args=(
|
||||
'{
|
||||
# Expects first 3 input lines as:
|
||||
#
|
||||
# 1 file tag (bash shebang, php opening tag, docker-finance version info, etc.)
|
||||
# 2
|
||||
# 3 code or text
|
||||
|
||||
# Save first line if needed
|
||||
if (NR==1 && NF) {first = $0}
|
||||
|
||||
# First line then license text
|
||||
if (NR<2)
|
||||
{
|
||||
if (global_file_type == "csv")
|
||||
{
|
||||
print text
|
||||
print first
|
||||
}
|
||||
else
|
||||
{
|
||||
print first
|
||||
print "\n"text"\n"
|
||||
}
|
||||
}
|
||||
|
||||
# Remaining file
|
||||
if (NR>2) {print}
|
||||
}')
|
||||
;;
|
||||
md)
|
||||
# - Create empty first line
|
||||
# - Replace pre-existing (' and ')' with '[' and ']'
|
||||
# - Add ')' to EOL
|
||||
local _sed_args=("-e" "s:(:[:g" "-e" "s:):]:g" "-e" "s\^\\${global_comment_type}\g" "-e" "s: *$:):g")
|
||||
local _awk_args=(
|
||||
'{
|
||||
# Save first line if needed
|
||||
if (NR==1 && NF) {first = $0}
|
||||
|
||||
# Uncomment if text itself does not have newline at beginning
|
||||
#if (NR==1 && NF) {print ""}
|
||||
|
||||
# License text then first line
|
||||
if (NR<2) {print "\n"text"\n"; print first"\n"}
|
||||
|
||||
# Remaining file
|
||||
if (NR>2) {print}
|
||||
}')
|
||||
;;
|
||||
*)
|
||||
lib_utils::die_fatal "Unsupported file type '${global_file_type}' for '${global_arg_file}'"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Setup temp
|
||||
local -r _tmp_dir="$(mktemp -d -p /tmp docker-finance_XXX)"
|
||||
local -r _tmp_file="$(mktemp -p $_tmp_dir license_XXX)"
|
||||
|
||||
# Add text
|
||||
lib_utils::print_normal "Writing to '${global_arg_file}' as type '${global_file_type}'"
|
||||
|
||||
# Execute
|
||||
gawk \
|
||||
-v global_file_type="$global_file_type" \
|
||||
-v text="$(echo -e $_text | sed "${_sed_args[@]}")" \
|
||||
"${_awk_args[@]}" "$global_arg_file" >"$_tmp_file" \
|
||||
&& mv -f "$_tmp_file" "$global_arg_file"
|
||||
|
||||
# Cleanup
|
||||
[ -d "$_tmp_dir" ] && rmdir "$_tmp_dir"
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
lib_utils::die_fatal "Did not exist successfully"
|
||||
fi
|
||||
}
|
||||
|
||||
function lib_license::license()
|
||||
{
|
||||
lib_license::__parse_args "$@"
|
||||
lib_license::__license && lib_utils::print_info "License written successfully!"
|
||||
}
|
||||
|
||||
# vim: sw=2 sts=2 si ai et
|
||||
266
client/src/docker/lib/internal/dev-tools/lib_linter.bash
Normal file
266
client/src/docker/lib/internal/dev-tools/lib_linter.bash
Normal file
@@ -0,0 +1,266 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# docker-finance | modern accounting for the power-user
|
||||
#
|
||||
# Copyright (C) 2021-2024 Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# "Libraries"
|
||||
#
|
||||
|
||||
source "$(dirname "$(realpath -s $0)")/src/docker/lib/internal/lib_docker.bash" || exit 1
|
||||
source "$(dirname "$(realpath -s $0)")/../container/src/finance/lib/internal/lib_utils.bash" || exit 1
|
||||
|
||||
#
|
||||
# Implementation
|
||||
#
|
||||
|
||||
function lib_linter::__parse_args()
|
||||
{
|
||||
[ -z "$global_usage" ] && lib_utils::die_fatal
|
||||
[ -z "$global_arg_delim_2" ] && lib_utils::die_fatal
|
||||
[ -z "$global_arg_delim_3" ] && lib_utils::die_fatal
|
||||
|
||||
local -r _usage="
|
||||
\e[32mDescription:\e[0m
|
||||
|
||||
Lint docker-finance source files
|
||||
|
||||
\e[32mUsage:\e[0m
|
||||
|
||||
$ $global_usage type${global_arg_delim_2}<type> [file${global_arg_delim_2}<file>]
|
||||
|
||||
\e[32mArguments:\e[0m
|
||||
|
||||
File type:
|
||||
|
||||
type${global_arg_delim_2}<bash|php|c++>
|
||||
|
||||
File path:
|
||||
|
||||
file${global_arg_delim_2}<path to file>
|
||||
|
||||
\e[32mNotes:\e[0m
|
||||
|
||||
Cannot use multiple types with file argument present
|
||||
|
||||
\e[32mExamples:\e[0m
|
||||
|
||||
\e[37;2m# Lint only PHP files\e[0m
|
||||
$ $global_usage type${global_arg_delim_2}php
|
||||
|
||||
\e[37;2m# Lint *all* development files\e[0m
|
||||
$ $global_usage type${global_arg_delim_2}bash${global_arg_delim_3}php${global_arg_delim_3}c++
|
||||
|
||||
\e[37;2m# Lint given C++ files\e[0m
|
||||
$ $global_usage type${global_arg_delim_2}c++ file${global_arg_delim_2}path/file_1.hh${global_arg_delim_3}path/file_2.hh
|
||||
"
|
||||
|
||||
#
|
||||
# Ensure supported arguments
|
||||
#
|
||||
|
||||
[ $# -eq 0 ] && lib_utils::die_usage "$_usage"
|
||||
|
||||
for _arg in "$@"; do
|
||||
[[ ! "$_arg" =~ ^type[s]?${global_arg_delim_2} ]] \
|
||||
&& [[ ! "$_arg" =~ ^file[s]?${global_arg_delim_2} ]] \
|
||||
&& lib_utils::die_usage "$_usage"
|
||||
done
|
||||
|
||||
#
|
||||
# Parse arguments before testing
|
||||
#
|
||||
|
||||
# Parse key for value
|
||||
for _arg in "$@"; do
|
||||
local _key="${_arg%${global_arg_delim_2}*}"
|
||||
local _len="$((${#_key} + 1))"
|
||||
|
||||
if [[ "$_key" =~ ^type[s]?$ ]]; then
|
||||
local _arg_type="${_arg:${_len}}"
|
||||
[ -z "$_arg_type" ] && lib_utils::die_usage "$_usage"
|
||||
fi
|
||||
|
||||
if [[ "$_key" =~ ^file[s]?$ ]]; then
|
||||
local _arg_file="${_arg:${_len}}"
|
||||
[ -z "$_arg_file" ] && lib_utils::die_usage "$_usage"
|
||||
fi
|
||||
done
|
||||
|
||||
#
|
||||
# Test argument values, set globals
|
||||
#
|
||||
|
||||
IFS="$global_arg_delim_3"
|
||||
|
||||
# Arg: type
|
||||
if [ ! -z "$_arg_type" ]; then
|
||||
read -ra _read <<<"$_arg_type"
|
||||
|
||||
for _type in "${_read[@]}"; do
|
||||
if [[ ! "$_type" =~ ^bash$|^shell$|^c\+\+$|^cpp$|^php$ ]]; then
|
||||
lib_utils::die_usage "$_usage"
|
||||
fi
|
||||
done
|
||||
|
||||
declare -gr global_arg_type=("${_read[@]}")
|
||||
fi
|
||||
|
||||
# Arg: file
|
||||
if [ ! -z "$_arg_file" ]; then
|
||||
read -ra _read <<<"$_arg_file"
|
||||
|
||||
if [ "${#global_arg_type[@]}" -gt 1 ]; then
|
||||
# Multiple types not supported if file is given
|
||||
lib_utils::die_usage "$_usage"
|
||||
fi
|
||||
|
||||
declare -gr global_arg_file=("${_read[@]}")
|
||||
fi
|
||||
}
|
||||
|
||||
function lib_linter::__lint_bash()
|
||||
{
|
||||
local -r _path=("$@")
|
||||
local -r _exts=("bash" "bash.in")
|
||||
|
||||
local -r _shfmt="shfmt -ln bash -i 2 -ci -bn -fn -w"
|
||||
local -r _shellcheck="shellcheck --color=always --norc --enable=all --shell=bash --severity=warning"
|
||||
|
||||
if [ -z "${_path[*]}" ]; then
|
||||
# Do all
|
||||
for _ext in "${_exts[@]}"; do
|
||||
lib_docker::__docker_compose exec -it docker-finance /bin/bash -i -c \
|
||||
"find ${DOCKER_FINANCE_CLIENT_REPO}/ -type f -name \*.${_ext} \
|
||||
| while read _file
|
||||
do echo Linting \'\${_file}\'
|
||||
$_shfmt \$_file \$_file && $_shellcheck \${_file}
|
||||
done"
|
||||
done
|
||||
else
|
||||
# Do only given file(s)
|
||||
for _p in "${_path[@]}"; do
|
||||
local _file
|
||||
_file="$(dirs +1)/${_p}"
|
||||
lib_utils::print_normal "Linting '${_file}'"
|
||||
lib_docker::__docker_compose exec -it docker-finance /bin/bash -i -c \
|
||||
"$_shfmt $_file $_file && $_shellcheck $_file"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
function lib_linter::__lint_cpp()
|
||||
{
|
||||
local -r _path=("$@")
|
||||
local -r _exts=("hh" "C")
|
||||
|
||||
local -r _clang_format="clang-format -i"
|
||||
local -r _cpplint="cpplint --root=${DOCKER_FINANCE_CLIENT_REPO} --filter=-whitespace/braces,-whitespace/newline,-whitespace/line_length,-build/c++11 --headers=hh --extensions=hh,C"
|
||||
local -r _cppcheck="cppcheck --enable=warning,style,performance,portability --inline-suppr --std=c++17"
|
||||
|
||||
if [ -z "${_path[*]}" ]; then
|
||||
# Do all
|
||||
for _ext in "${_exts[@]}"; do
|
||||
lib_docker::__docker_compose exec -it docker-finance /bin/bash -i -c \
|
||||
"find ${DOCKER_FINANCE_CLIENT_REPO}/ -type f -name \*.${_ext} \
|
||||
| while read _file
|
||||
do echo Linting \'\${_file}\'
|
||||
$_clang_format \$_file && $_cpplint \$_file && $_cppcheck \$_file
|
||||
done"
|
||||
done
|
||||
else
|
||||
# Do only given file(s)
|
||||
for _p in "${_path[@]}"; do
|
||||
local _file
|
||||
_file="$(dirs +1)/${_p}"
|
||||
lib_utils::print_normal "Linting '${_file}'"
|
||||
lib_docker::__docker_compose exec -it docker-finance /bin/bash -i -c \
|
||||
"$_clang_format $_file && $_cpplint $_file && $_cppcheck $_file"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
function lib_linter::__lint_php()
|
||||
{
|
||||
local -r _path=("$@")
|
||||
local -r _ext="php"
|
||||
|
||||
local -r _php_cs_fixer="time php-cs-fixer fix --rules=@PSR12 --verbose"
|
||||
local -r _phpstan="time phpstan analyse --debug --autoload-file /usr/local/lib/php/vendor/autoload.php --level 6" # TODO: incrementally increase to 9
|
||||
|
||||
if [ -z "${_path[*]}" ]; then
|
||||
# Do all
|
||||
lib_docker::__docker_compose exec -it docker-finance /bin/bash -i -c \
|
||||
"$_php_cs_fixer $DOCKER_FINANCE_CLIENT_REPO \
|
||||
&& $_phpstan $DOCKER_FINANCE_CLIENT_REPO"
|
||||
else
|
||||
# Do only given file(s)
|
||||
for _p in "${_path[@]}"; do
|
||||
local _file
|
||||
_file="$(dirs +1)/${_p}"
|
||||
lib_utils::print_normal "Linting '${_file}'"
|
||||
lib_docker::__docker_compose exec -it docker-finance /bin/bash -i -c \
|
||||
"$_php_cs_fixer $_file && $_phpstan $_file"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
function lib_linter::__linter()
|
||||
{
|
||||
[ -z "$DOCKER_FINANCE_CLIENT_REPO" ] && lib_utils::die_fatal
|
||||
|
||||
[[ ! "$PWD" =~ ^$DOCKER_FINANCE_CLIENT_REPO && ! -z "${global_arg_file[*]}" ]] \
|
||||
&& lib_utils::die_fatal "Sorry, you must work (and lint) from within parent directory '${DOCKER_FINANCE_CLIENT_REPO}'"
|
||||
|
||||
lib_utils::print_debug "Bringing up network and container"
|
||||
|
||||
[ -z "$global_network" ] && lib_utils::die_fatal
|
||||
local -r _no_funny_business="--internal=true"
|
||||
docker network create "$_no_funny_business" "$global_network" 2>/dev/null
|
||||
lib_docker::__docker_compose up -d docker-finance || lib_utils::die_fatal
|
||||
|
||||
# Transparent bind-mount: although it's the container repo, its path is identical to client repo
|
||||
pushd "$DOCKER_FINANCE_CLIENT_REPO" 1>/dev/null || lib_utils::die_fatal
|
||||
|
||||
for _type in "${global_arg_type[@]}"; do
|
||||
case "$_type" in
|
||||
bash | shell)
|
||||
lib_linter::__lint_bash "${global_arg_file[@]}"
|
||||
;;
|
||||
c++ | cpp)
|
||||
lib_linter::__lint_cpp "${global_arg_file[@]}"
|
||||
;;
|
||||
php)
|
||||
lib_linter::__lint_php "${global_arg_file[@]}"
|
||||
;;
|
||||
esac
|
||||
lib_utils::print_custom "\n"
|
||||
done
|
||||
|
||||
popd 1>/dev/null || lib_utils::die_fatal
|
||||
|
||||
lib_docker::__docker_compose down
|
||||
docker network rm "$global_network" 1>/dev/null
|
||||
}
|
||||
|
||||
function lib_linter::linter()
|
||||
{
|
||||
lib_linter::__parse_args "$@"
|
||||
lib_linter::__linter && lib_utils::print_info "Linting completed successfully!"
|
||||
}
|
||||
|
||||
# vim: sw=2 sts=2 si ai et
|
||||
323
client/src/docker/lib/internal/lib_docker.bash
Normal file
323
client/src/docker/lib/internal/lib_docker.bash
Normal file
@@ -0,0 +1,323 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# docker-finance | modern accounting for the power-user
|
||||
#
|
||||
# Copyright (C) 2021-2024 Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# "Libraries"
|
||||
#
|
||||
|
||||
# Utilities (a container library (but container is never exposed to client code))
|
||||
source "$(dirname "$(realpath -s $0)")/../container/src/finance/lib/internal/lib_utils.bash" || exit 1
|
||||
|
||||
#
|
||||
# Implementation
|
||||
#
|
||||
|
||||
# Dependencies
|
||||
deps=("docker" "sed")
|
||||
lib_utils::deps_check "${deps[@]}"
|
||||
|
||||
if ! docker compose version 1>/dev/null; then
|
||||
lib_utils::die_fatal "Docker compose plugin not installed"
|
||||
fi
|
||||
|
||||
if [ -z "$EDITOR" ]; then
|
||||
editors=("vim" "vi" "emacs" "nano")
|
||||
for editor in "${editors[@]}"; do
|
||||
hash "$editor" &>/dev/null && export EDITOR="$editor" && break
|
||||
done
|
||||
if [ $? -ne 0 ]; then
|
||||
lib_utils::die_fatal "Shell EDITOR is not set, export EDITOR in your shell"
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# `docker compose`
|
||||
#
|
||||
|
||||
function lib_docker::__docker_compose()
|
||||
{
|
||||
[ -z "$global_env_file" ] && lib_utils::die_fatal
|
||||
[ -z "$global_dockerfile_path" ] && lib_utils::die_fatal
|
||||
|
||||
[ ! -f "$global_env_file" ] \
|
||||
&& lib_utils::die_fatal "$global_env_file not found! Run the gen command!"
|
||||
|
||||
pushd "$global_dockerfile_path" 1>/dev/null \
|
||||
|| return $? \
|
||||
&& docker compose -f docker-compose.yml --env-file "$global_env_file" "$@"
|
||||
popd 1>/dev/null || return $?
|
||||
}
|
||||
|
||||
function lib_docker::__build()
|
||||
{
|
||||
time lib_docker::__docker_compose build --pull docker-finance "$@"
|
||||
}
|
||||
|
||||
function lib_docker::__up()
|
||||
{
|
||||
# NOTE: for openvpn support, input this into /etc/docker/daemon.json and restart docker:
|
||||
# {
|
||||
# "default-address-pools" : [
|
||||
# {
|
||||
# "base" : "172.31.0.0/16",
|
||||
# "size" : 24
|
||||
# }
|
||||
# ]
|
||||
# }
|
||||
lib_utils::print_debug "Bringing up network and container"
|
||||
docker network create "$global_network" 2>/dev/null
|
||||
lib_docker::__docker_compose up -d docker-finance "$@" \
|
||||
&& docker exec -it "$global_container" /bin/bash
|
||||
}
|
||||
|
||||
function lib_docker::__down()
|
||||
{
|
||||
[ -z "$global_network" ] && lib_utils::die_fatal
|
||||
|
||||
lib_utils::print_debug "Bringing down container and network"
|
||||
lib_docker::__docker_compose down "$@" \
|
||||
&& docker network rm "$global_network" 1>/dev/null
|
||||
}
|
||||
|
||||
function lib_docker::__start()
|
||||
{
|
||||
lib_utils::print_debug "Starting container"
|
||||
lib_docker::__docker_compose start "$@"
|
||||
}
|
||||
|
||||
function lib_docker::__stop()
|
||||
{
|
||||
lib_utils::print_debug "Stopping container"
|
||||
lib_docker::__docker_compose stop "$@"
|
||||
}
|
||||
|
||||
function lib_docker::__backup()
|
||||
{
|
||||
# NOTE: does not export to tar, simply tags
|
||||
local -r _backup="${global_image}:backup_$(date +%s)"
|
||||
if docker tag "${global_image}:${global_tag}" "$_backup"; then
|
||||
lib_utils::print_info "Created backup: ${global_image}:${global_tag} -> $_backup"
|
||||
else
|
||||
lib_utils::die_fatal "Could not create backup -> $_backup"
|
||||
fi
|
||||
}
|
||||
|
||||
function lib_docker::__rm()
|
||||
{
|
||||
[ -z "$global_image" ] && lib_utils::die_fatal
|
||||
[ -z "$global_tag" ] && lib_utils::die_fatal
|
||||
|
||||
lib_utils::print_debug "Removing image"
|
||||
docker image rm "${global_image}:${global_tag}" "$@"
|
||||
}
|
||||
|
||||
function lib_docker::__run()
|
||||
{
|
||||
[ -z "$global_network" ] && lib_utils::die_fatal
|
||||
|
||||
lib_utils::print_debug "Creating network"
|
||||
docker network create "$global_network" &>/dev/null
|
||||
|
||||
# NOTE: runs bash as interactive so .bashrc doesn't `return` (sources/aliases are needed)
|
||||
lib_utils::print_debug "Spawning container with command '$*'"
|
||||
lib_docker::__docker_compose run -it --rm --entrypoint='/bin/bash -i -c' docker-finance "$@"
|
||||
local -r _return=$?
|
||||
|
||||
lib_utils::print_debug "Removing network"
|
||||
docker network rm "$global_network" &>/dev/null # Don't force, if in use
|
||||
|
||||
return $_return
|
||||
}
|
||||
|
||||
function lib_docker::__shell()
|
||||
{
|
||||
[ -z "$global_usage" ] && lib_utils::die_fatal
|
||||
[ -z "$global_arg_delim_2" ] && lib_utils::die_fatal
|
||||
[ -z "$global_arg_delim_3" ] && lib_utils::die_fatal
|
||||
[ -z "$global_user" ] && lib_utils::die_fatal
|
||||
|
||||
local -r _arg="$1"
|
||||
local -r _usage="
|
||||
\e[32mDescription:\e[0m
|
||||
|
||||
Open a shell as given container user
|
||||
|
||||
\e[32mUsage:\e[0m
|
||||
|
||||
$ $global_usage user${global_arg_delim_2}<user>
|
||||
|
||||
\e[32mArguments:\e[0m
|
||||
|
||||
Container user:
|
||||
|
||||
user${global_arg_delim_2}<${global_user}|root|...>
|
||||
|
||||
\e[32mExamples:\e[0m
|
||||
|
||||
\e[37;2m# Open shell as current user (no arg)\e[0m
|
||||
$ $global_usage
|
||||
|
||||
\e[37;2m# Open shell as current user (with arg)\e[0m
|
||||
$ $global_usage user${global_arg_delim_2}${global_user}
|
||||
|
||||
\e[37;2m# Open root shell\e[0m
|
||||
$ $global_usage user${global_arg_delim_2}root
|
||||
"
|
||||
|
||||
if [ $# -gt 1 ]; then
|
||||
lib_utils::die_usage "$_usage"
|
||||
fi
|
||||
|
||||
# Get/Set user
|
||||
if [ ! -z "$_arg" ]; then
|
||||
if [[ ! "$_arg" =~ ^user[s]?${global_arg_delim_2} ]]; then
|
||||
lib_utils::die_usage "$_usage"
|
||||
fi
|
||||
|
||||
# Parse key for value
|
||||
local _key="${_arg%${global_arg_delim_2}*}"
|
||||
local _len="$((${#_key} + 1))"
|
||||
if [[ "$_key" =~ ^user[s]?$ ]]; then
|
||||
local _arg_user="${_arg:${_len}}"
|
||||
if [ -z "$_arg_user" ]; then
|
||||
lib_utils::die_usage "$_usage"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Use default user
|
||||
local _arg_user="${global_user}"
|
||||
fi
|
||||
|
||||
if [ -z "$_arg_user" ]; then
|
||||
lib_utils::die_usage "$_usage"
|
||||
fi
|
||||
|
||||
[ -z "$global_container" ] && lib_utils::die_fatal
|
||||
|
||||
lib_utils::print_debug "Spawning shell in container '${global_container}'"
|
||||
docker exec -it --user "$_arg_user" --workdir / "$global_container" /bin/bash
|
||||
}
|
||||
|
||||
function lib_docker::__edit()
|
||||
{
|
||||
[ -z "$global_usage" ] && lib_utils::die_fatal
|
||||
[ -z "$global_arg_delim_2" ] && lib_utils::die_fatal
|
||||
[ -z "$global_arg_delim_3" ] && lib_utils::die_fatal
|
||||
|
||||
local -r _usage="
|
||||
\e[32mDescription:\e[0m
|
||||
|
||||
Edit client configuration files
|
||||
|
||||
\e[32mUsage:\e[0m
|
||||
|
||||
$ $global_usage type${global_arg_delim_2}<type>
|
||||
|
||||
\e[32mArguments:\e[0m
|
||||
|
||||
Configuration type:
|
||||
|
||||
type${global_arg_delim_2}<env|{shell|superscript}>
|
||||
|
||||
\e[32mExamples:\e[0m
|
||||
|
||||
\e[37;2m# Edit client/container environment variables\e[0m
|
||||
$ $global_usage type${global_arg_delim_2}env
|
||||
|
||||
\e[37;2m# Edit client/container shell (superscript) \e[0m
|
||||
$ $global_usage type${global_arg_delim_2}shell
|
||||
|
||||
\e[37;2m# Edit client/container shell (w/ alternate wording) and environment variables\e[0m
|
||||
$ $global_usage type${global_arg_delim_2}superscript${global_arg_delim_3}env
|
||||
"
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
lib_utils::die_usage "$_usage"
|
||||
fi
|
||||
|
||||
# Get/Set type
|
||||
local -r _arg="$1"
|
||||
|
||||
if [ ! -z "$_arg" ]; then
|
||||
if [[ ! "$_arg" =~ ^type[s]?${global_arg_delim_2} ]]; then
|
||||
lib_utils::die_usage "$_usage"
|
||||
fi
|
||||
|
||||
# Parse key for value
|
||||
local _key="${_arg%${global_arg_delim_2}*}"
|
||||
local _len="$((${#_key} + 1))"
|
||||
if [[ "$_key" =~ ^type[s]?$ ]]; then
|
||||
local _arg_type="${_arg:${_len}}"
|
||||
if [ -z "$_arg_type" ]; then
|
||||
lib_utils::die_usage "$_usage"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
IFS="$global_arg_delim_3"
|
||||
|
||||
# Arg: type
|
||||
if [ ! -z "$_arg_type" ]; then
|
||||
read -ra _read <<<"$_arg_type"
|
||||
|
||||
for _type in "${_read[@]}"; do
|
||||
if [[ ! "$_type" =~ ^env$|^shell$|^superscript$ ]]; then
|
||||
lib_utils::die_usage "$_usage"
|
||||
fi
|
||||
done
|
||||
|
||||
readonly _edit_arg_type=("${_read[@]}")
|
||||
fi
|
||||
|
||||
[ -z "$EDITOR" ] \
|
||||
&& lib_utils::die_fatal "Export EDITOR to your preferred editor"
|
||||
|
||||
[ -z "$global_env_file" ] && lib_utils::die_fatal
|
||||
[ ! -f "$global_env_file" ] \
|
||||
&& lib_utils::die_fatal "Environment file now found"
|
||||
|
||||
[ -z "$global_shell_file" ] && lib_utils::die_fatal
|
||||
[ ! -f "$global_shell_file" ] \
|
||||
&& lib_utils::die_fatal "Shell (superscript) file now found"
|
||||
|
||||
# Run all files through one editor instance
|
||||
local _paths=()
|
||||
|
||||
for _type in "${_edit_arg_type[@]}"; do
|
||||
case "$_type" in
|
||||
env)
|
||||
_paths+=("$global_env_file")
|
||||
;;
|
||||
shell | superscript)
|
||||
[ -z "$global_platform" ] && lib_utils::die_fatal
|
||||
|
||||
[[ "$global_platform" == "dev-tools" ]] \
|
||||
&& lib_utils::die_fatal "Invalid platform, use finance image"
|
||||
|
||||
_paths+=("$global_shell_file")
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Execute
|
||||
lib_utils::print_debug "Editing '${_paths[*]}'"
|
||||
$EDITOR "${_paths[@]}"
|
||||
}
|
||||
|
||||
# vim: sw=2 sts=2 si ai et
|
||||
712
client/src/docker/lib/internal/lib_gen.bash
Normal file
712
client/src/docker/lib/internal/lib_gen.bash
Normal file
@@ -0,0 +1,712 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# docker-finance | modern accounting for the power-user
|
||||
#
|
||||
# Copyright (C) 2021-2024 Aaron Fiore (Founder, Evergreen Crypto LLC)
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#
|
||||
# "Libraries"
|
||||
#
|
||||
|
||||
source "$(dirname "$(realpath -s $0)")/../container/src/finance/lib/internal/lib_utils.bash" || exit 1
|
||||
|
||||
#
|
||||
# Implementation
|
||||
#
|
||||
|
||||
if [ $UID -lt 1000 ]; then
|
||||
lib_utils::die_fatal "Do not run as root or system user!"
|
||||
fi
|
||||
|
||||
# IMPORTANT: keep umask for security
|
||||
umask o-rwx
|
||||
|
||||
if ! docker compose version 1>/dev/null; then
|
||||
lib_utils::die_fatal "Docker compose plugin not installed"
|
||||
fi
|
||||
|
||||
if [ -z "$EDITOR" ]; then
|
||||
editors=("vim" "vi" "emacs" "nano")
|
||||
for editor in "${editors[@]}"; do
|
||||
hash "$editor" &>/dev/null && export EDITOR="$editor" && break
|
||||
done
|
||||
if [ $? -ne 0 ]; then
|
||||
lib_utils::die_fatal "Shell EDITOR is not set, export EDITOR in your shell"
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# "Constructor" for environment generation
|
||||
#
|
||||
# Sets client-side environment with defaults or use existing environment
|
||||
#
|
||||
|
||||
function lib_gen::gen()
|
||||
{
|
||||
lib_utils::print_debug "Constructing environment"
|
||||
|
||||
# Repository-provided (not user-defined) default environment
|
||||
global_repo_conf_dir="$(dirname "$(realpath -s $0)")/docker-finance.d"
|
||||
declare -gr global_repo_conf_dir
|
||||
|
||||
declare -gr global_repo_env_file="${global_repo_conf_dir}/client/env/gen.bash"
|
||||
[ ! -f "$global_repo_env_file" ] \
|
||||
&& lib_utils::die_fatal "Missing environment defaults! ($global_repo_env_file)"
|
||||
|
||||
#
|
||||
# If empty environment, bootstrap with defaults
|
||||
#
|
||||
|
||||
if [ -z "$DOCKER_FINANCE_CLIENT_CONF" ]; then
|
||||
# shellcheck source=/dev/null
|
||||
source "$global_repo_env_file"
|
||||
fi
|
||||
|
||||
[ -z "$DOCKER_FINANCE_CLIENT_CONF" ] \
|
||||
&& lib_utils::die_fatal "Defaults not generated! (${global_repo_env_file})"
|
||||
|
||||
[ -z "$DOCKER_FINANCE_USER" ] && lib_utils::die_fatal
|
||||
global_env_filename="${DOCKER_FINANCE_USER}@$(uname -n)"
|
||||
declare -gr global_env_filename
|
||||
|
||||
lib_gen::__set_client_globals
|
||||
|
||||
#
|
||||
# Reset environment with user-provided (user-defined) existing file (if available)
|
||||
#
|
||||
|
||||
[ -z "$global_platform" ] && lib_utils::die_fatal
|
||||
[ -z "$global_tag" ] && lib_utils::die_fatal
|
||||
|
||||
local -r _env_dir="${DOCKER_FINANCE_CLIENT_CONF}/client/env/$(uname -s)-$(uname -m)/${global_platform}/${global_tag}"
|
||||
local -r _env_file="${_env_dir}/${global_env_filename}"
|
||||
|
||||
if [ -f "$_env_file" ]; then
|
||||
if [ -s "$_env_file" ]; then
|
||||
# Re-bootstrap with (new) environment
|
||||
lib_utils::print_debug "Environment found! Using '${_env_file}'"
|
||||
lib_gen::__read_env "$_env_file"
|
||||
lib_gen::__set_client_globals
|
||||
else
|
||||
lib_utils::print_warning \
|
||||
"Client environment '${_env_file}' is empty! Writing defaults"
|
||||
lib_gen::__write_env "$_env_file"
|
||||
fi
|
||||
else
|
||||
[ -z "$global_basename" ] && lib_utils::die_fatal
|
||||
|
||||
if [[ -z "$global_command" || "$global_command" != "gen" ]]; then
|
||||
lib_utils::die_fatal \
|
||||
"Client environment not found! Run gen command'"
|
||||
fi
|
||||
|
||||
lib_utils::print_info \
|
||||
"Client environment not found, writing defaults to '${_env_file}'"
|
||||
lib_gen::__write_env "$_env_file"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Set client globals from environment
|
||||
#
|
||||
|
||||
function lib_gen::__set_client_globals()
|
||||
{
|
||||
lib_utils::print_debug "Setting client globals"
|
||||
|
||||
# Appending all client-side conf paths
|
||||
local _client_path_tag
|
||||
_client_path_tag="$(uname -s)-$(uname -m)/${global_platform}/${global_tag}"
|
||||
|
||||
# Client-side environment file (if available)
|
||||
local _client_env_dir="${DOCKER_FINANCE_CLIENT_CONF}/client/env/${_client_path_tag}"
|
||||
|
||||
[ ! -d "$_client_env_dir" ] && mkdir -p "$_client_env_dir"
|
||||
global_env_file="${_client_env_dir}/${global_env_filename}"
|
||||
lib_utils::print_debug "global_env_file=${global_env_file}"
|
||||
|
||||
# NOTE:
|
||||
#
|
||||
# Client env tag format is avoided because:
|
||||
#
|
||||
# - We copy over static bash_aliases in Dockerfile,
|
||||
# and superscript must be referenced by that static path
|
||||
#
|
||||
# - The needed dynamicness appears to not be satisfied via docker-compose
|
||||
|
||||
local _client_shell_dir="${DOCKER_FINANCE_CLIENT_CONF}/container/shell"
|
||||
[ ! -d "$_client_shell_dir" ] && mkdir -p "$_client_shell_dir"
|
||||
global_shell_file="${_client_shell_dir}/superscript.bash"
|
||||
lib_utils::print_debug "global_shell_file=${global_shell_file}"
|
||||
|
||||
# Client view of client portion of repository
|
||||
[ -z "$DOCKER_FINANCE_CLIENT_REPO" ] && lib_utils::die_fatal
|
||||
global_repo_client="${DOCKER_FINANCE_CLIENT_REPO}/client"
|
||||
[ ! -d "$global_repo_client" ] && lib_utils::die_fatal "Repository '${global_repo_client}' not found!"
|
||||
lib_utils::print_debug "global_repo_client=${global_repo_client}"
|
||||
|
||||
# Backup-file extension
|
||||
# TODO: make configurable
|
||||
global_suffix="$(date +%Y-%m-%d_%H:%M:%S)"
|
||||
lib_utils::print_debug "global_suffix=${global_suffix}"
|
||||
}
|
||||
|
||||
#
|
||||
# Get/Set client-side environment with given file
|
||||
#
|
||||
|
||||
function lib_gen::__read_env()
|
||||
{
|
||||
lib_utils::print_debug "Get/Set environment"
|
||||
|
||||
# Unset
|
||||
unset "$(printenv | grep -Eo "^DOCKER_FINANCE[^=]+")"
|
||||
|
||||
# Set, if a script that generates env
|
||||
if [[ "$(head -n1 $1)" =~ (bin|env|sh|bash) ]]; then
|
||||
# shellcheck source=/dev/null
|
||||
source "$global_repo_env_file"
|
||||
return $?
|
||||
fi
|
||||
|
||||
# Set, if env file format (docker / bash)
|
||||
while read _line; do
|
||||
export "${_line?}" # SC2163
|
||||
lib_utils::print_debug "$_line"
|
||||
done <"$1"
|
||||
}
|
||||
|
||||
#
|
||||
# Write client-side environment to given file
|
||||
#
|
||||
|
||||
function lib_gen::__write_env()
|
||||
{
|
||||
lib_utils::print_debug "Writing environment"
|
||||
|
||||
printenv | grep "DOCKER_FINANCE" | sort >"$1"
|
||||
}
|
||||
|
||||
#
|
||||
# Generate new configurations
|
||||
#
|
||||
|
||||
function lib_gen::generate()
|
||||
{
|
||||
lib_utils::print_custom "\n"
|
||||
lib_utils::print_info "Generating client/container environment"
|
||||
|
||||
# WARNING: client generation MUST be done before container generation
|
||||
lib_gen::__gen_client
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
if [ "$global_platform" != "dev-tools" ]; then
|
||||
lib_gen::__gen_container
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
lib_utils::print_info "Congratulations, environment sucessfully generated!"
|
||||
lib_utils::print_custom "\n"
|
||||
else
|
||||
lib_utils::die_fatal "Environment not fully generated! Try again"
|
||||
fi
|
||||
}
|
||||
|
||||
function lib_gen::__gen_client()
|
||||
{
|
||||
lib_utils::print_debug "Generating client"
|
||||
|
||||
# Backup existing client-side environment file
|
||||
if [ -f "$global_env_file" ]; then
|
||||
lib_utils::print_custom " \e[32m│\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m├─\e[34;1m Client-side environment found, backup then generate new one? [Y/n] \e[0m"
|
||||
|
||||
read -p "" _read
|
||||
local _confirm="${_read:-y}"
|
||||
|
||||
if [[ "$_confirm" == [yY] ]]; then
|
||||
cp -a "$global_env_file" "${global_env_file}_${global_suffix}" \
|
||||
|| lib_utils::die_fatal
|
||||
|
||||
# Get/Set with repository defaults
|
||||
lib_gen::__read_env "$global_repo_env_file"
|
||||
lib_gen::__write_env "$global_env_file"
|
||||
fi
|
||||
fi
|
||||
|
||||
lib_utils::print_custom " \e[32m│ └─\e[34m Edit (new) environment now? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
local _confirm="${_read:-y}"
|
||||
[[ "$_confirm" == [yY] ]] && $EDITOR "$global_env_file"
|
||||
|
||||
# Get/Set new (edited) environment variables
|
||||
lib_gen::__read_env "$global_env_file"
|
||||
lib_gen::__set_client_globals
|
||||
}
|
||||
|
||||
function lib_gen::__gen_container()
|
||||
{
|
||||
lib_utils::print_debug "Generating container"
|
||||
|
||||
#
|
||||
# Check to proceed
|
||||
#
|
||||
|
||||
lib_utils::print_custom " \e[32m│\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m├─\e[34;1m Generate (or update) container profile configs and/or accounts? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
local _confirm="${_read:-y}"
|
||||
if [[ "$_confirm" != [yY] ]]; then
|
||||
lib_utils::print_custom " \e[32m│\e[0m\n"
|
||||
lib_utils::print_normal ""
|
||||
return 0
|
||||
fi
|
||||
|
||||
[ -z "$DOCKER_FINANCE_CLIENT_FLOW" ] && lib_utils::die_fatal
|
||||
if [ -d "$DOCKER_FINANCE_CLIENT_FLOW" ]; then
|
||||
lib_utils::print_custom " \e[32m│ ├─\e[34m hledger-flow path exists, continue with backup and generation? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
if [[ "$_confirm" != [yY] ]]; then
|
||||
lib_utils::print_custom " \e[32m│\e[0m\n"
|
||||
lib_utils::print_normal ""
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Development setup
|
||||
#
|
||||
|
||||
lib_utils::print_custom " \e[32m│ │\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│ ├─\e[34;1m Will this profile be used for development and/or demonstration? [N/y] \e[0m"
|
||||
read -p "" _read
|
||||
local _is_testing="${_read:-false}"
|
||||
if [[ "$_read" == [yY] ]]; then
|
||||
_is_testing=true
|
||||
fi
|
||||
lib_utils::print_debug "_is_testing=${_is_testing}"
|
||||
|
||||
#
|
||||
# Construct full path to subprofile
|
||||
#
|
||||
|
||||
lib_utils::print_custom " \e[32m│ │ │\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│ │ ├─\e[34m Enter profile name (e.g., family in 'family/alice'): \e[0m"
|
||||
read -p "" _read
|
||||
local -r _profile="${_read:-default}"
|
||||
lib_utils::print_custom " \e[32m│ │ │ └─\e[34m Using profile:\e[0m ${_profile}\n"
|
||||
|
||||
lib_utils::print_custom " \e[32m│ │ │\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│ │ └─\e[34m Enter subprofile name (e.g., alice in 'family/alice'): \e[0m"
|
||||
read -p "" _read
|
||||
local -r _subprofile="${_read:-${global_user}}"
|
||||
lib_utils::print_custom " \e[32m│ │ └─\e[34m Using subprofile:\e[0m ${_subprofile}\n"
|
||||
|
||||
#
|
||||
# Execute
|
||||
#
|
||||
|
||||
lib_utils::print_custom " \e[32m│ │\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│ ├─\e[34;1m Generate (or update) joint client/container shell script (superscript)? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
if [[ "$_confirm" == [yY] ]]; then
|
||||
local _gen_path="\${DOCKER_FINANCE_CONTAINER_FLOW}/profiles/${_profile}/${_subprofile}" # \$ for container view
|
||||
local _gen_conf_path="${_gen_path}/docker-finance.d"
|
||||
lib_utils::print_debug "_gen_path=${_gen_path}"
|
||||
lib_utils::print_debug "_gen_conf_path=${_gen_conf_path}"
|
||||
|
||||
lib_gen::__gen_shell "$_gen_path" "$_gen_conf_path"
|
||||
fi
|
||||
|
||||
lib_utils::print_custom " \e[32m│ │\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│ ├─\e[34;1m Generate (or update) container hledger-flow configs and/or accounts? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
if [[ "$_confirm" == [yY] ]]; then
|
||||
local _gen_path="${DOCKER_FINANCE_CLIENT_FLOW}/profiles/${_profile}/${_subprofile}" # client's view
|
||||
local _gen_conf_path="${_gen_path}/docker-finance.d"
|
||||
lib_utils::print_debug "_gen_path=${_gen_path}"
|
||||
lib_utils::print_debug "_gen_conf_path=${_gen_conf_path}"
|
||||
|
||||
lib_gen::__gen_flow "$_gen_path" "$_gen_conf_path"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Generate client-side container superscript
|
||||
#
|
||||
|
||||
function lib_gen::__gen_shell()
|
||||
{
|
||||
local -r _gen_path="$1"
|
||||
local -r _gen_conf_path="$2"
|
||||
|
||||
# Subprofile source added to superscript
|
||||
local -r _source="source \"${_gen_conf_path}/shell/subprofile.bash\""
|
||||
|
||||
local _file="$global_shell_file"
|
||||
if [ -f "$_file" ]; then
|
||||
# Backup
|
||||
lib_utils::print_custom " \e[32m│ │ └─\e[34m Shell superscript found, backup before continuing? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
local _confirm="${_read:-y}"
|
||||
if [[ "$_confirm" == [yY] ]]; then
|
||||
# Backup
|
||||
local -r _backup=("cp" "-a" "$_file" "${_file}_${global_suffix}")
|
||||
lib_utils::print_debug "${_backup[@]}"
|
||||
"${_backup[@]}" || lib_utils::die_fatal
|
||||
fi
|
||||
|
||||
lib_utils::print_custom " \e[32m│ │ └─\e[34m Overwrite existing file? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
local _confirm="${_read:-y}"
|
||||
if [[ "$_confirm" == [yY] ]]; then
|
||||
# Overwrite existing file
|
||||
lib_gen::__gen_shell_write
|
||||
else
|
||||
# Append subprofile source to existing file
|
||||
lib_utils::print_custom " \e[32m│ │ └─\e[34m Append to existing file? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
local _confirm="${_read:-y}"
|
||||
if [[ "$_confirm" == [yY] ]]; then
|
||||
grep "$_source" "$_file" >&/dev/null || sed -i "$(wc -l <$_file)i\\$_source\\" "$_file"
|
||||
fi
|
||||
fi
|
||||
|
||||
local _print_custom=" \e[32m│ │ └─\e[34m Edit (new) superscript now? [Y/n] \e[0m"
|
||||
else
|
||||
# Create new file
|
||||
lib_gen::__gen_shell_write
|
||||
local _print_custom=" \e[32m│ │ └─\e[34m Edit (new) superscript now? [Y/n] \e[0m"
|
||||
fi
|
||||
|
||||
lib_utils::print_custom "$_print_custom"
|
||||
read -p "" _read
|
||||
local _confirm="${_read:-y}"
|
||||
[[ "$_confirm" == [yY] ]] && $EDITOR "$_file"
|
||||
}
|
||||
|
||||
function lib_gen::__gen_shell_write()
|
||||
{
|
||||
[ -z "$global_repo_conf_dir" ] && lib_utils::die_fatal
|
||||
[ -z "$DOCKER_FINANCE_VERSION" ] && lib_utils::die_fatal
|
||||
|
||||
lib_utils::print_debug "global_repo_conf_dir=${global_repo_conf_dir}"
|
||||
lib_utils::print_debug "DOCKER_FINANCE_VERSION=${DOCKER_FINANCE_VERSION}"
|
||||
|
||||
sed \
|
||||
-e "s:@DOCKER_FINANCE_SUBPROFILE_SOURCE@:${_source}:g" \
|
||||
-e "s:@DOCKER_FINANCE_VERSION@:${DOCKER_FINANCE_VERSION}:g" \
|
||||
"${global_repo_conf_dir}/container/shell/superscript.bash.in" >"$_file"
|
||||
}
|
||||
|
||||
#
|
||||
# Generate hledger-flow
|
||||
#
|
||||
|
||||
function lib_gen::__gen_flow()
|
||||
{
|
||||
local -r _gen_path="$1"
|
||||
local -r _gen_conf_path="$2"
|
||||
|
||||
lib_utils::print_custom " \e[32m│ │ │\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│ │ ├─\e[34;1m Generate (or update) subprofile's shell script? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
[[ "$_confirm" == [yY] ]] && lib_gen::__gen_flow_shell
|
||||
|
||||
lib_utils::print_custom " \e[32m│ │ │\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│ │ ├─\e[34;1m Generate (or update) subprofile's fetch configuration? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
[[ "$_confirm" == [yY] ]] && lib_gen::__gen_flow_fetch
|
||||
|
||||
lib_utils::print_custom " \e[32m│ │ │\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│ │ ├─\e[34;1m Generate (or update) subprofile's financial metadata? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
[[ "$_confirm" == [yY] ]] && lib_gen::__gen_flow_meta
|
||||
|
||||
lib_utils::print_custom " \e[32m│ │ │\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│ │ ├─\e[34;1m Generate (or update) subprofile's hledger-flow accounts? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
[[ "$_confirm" == [yY] ]] && lib_gen::__gen_flow_accounts
|
||||
|
||||
lib_utils::print_custom " \e[32m│\e[0m\n"
|
||||
|
||||
# Placeholder connector between hledger-flow code and end-user's hledger-flow profiles
|
||||
# NOTE: entrypoint will (MUST) update this on every container run (yes, looks different than entrypoint)
|
||||
lib_utils::print_custom " \e[32m├─\e[34;1m Connecting flow sources \e[0m\n"
|
||||
|
||||
[ -z "$DOCKER_FINANCE_CONTAINER_REPO" ] && lib_utils::die_fatal
|
||||
ln -f -s "${DOCKER_FINANCE_CONTAINER_REPO}/src/hledger-flow" "${DOCKER_FINANCE_CLIENT_FLOW}/src"
|
||||
|
||||
lib_utils::print_custom " \e[32m│\e[0m\n"
|
||||
}
|
||||
|
||||
#
|
||||
# Generate subprofile script
|
||||
#
|
||||
|
||||
function lib_gen::__gen_flow_shell()
|
||||
{
|
||||
local _dir="${_gen_conf_path}/shell"
|
||||
[ ! -d "$_dir" ] && mkdir -p "$_dir"
|
||||
|
||||
local _file="${_dir}/subprofile.bash"
|
||||
if [ -f "$_file" ]; then
|
||||
lib_utils::print_custom " \e[32m│ │ │ └─\e[34m Subprofile script found, backup then generate new one? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
|
||||
if [[ "$_confirm" == [yY] ]]; then
|
||||
cp -a "$_file" "${_file}_${global_suffix}" || lib_utils::die_fatal
|
||||
|
||||
lib_gen::__gen_flow_shell_write
|
||||
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit (new) subprofile script now? [Y/n] \e[0m"
|
||||
fi
|
||||
else
|
||||
lib_gen::__gen_flow_shell_write
|
||||
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit (new) subprofile script now? [Y/n] \e[0m"
|
||||
fi
|
||||
|
||||
lib_utils::print_custom "$_print_custom"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
[[ "$_confirm" == [yY] ]] && $EDITOR "$_file"
|
||||
}
|
||||
|
||||
function lib_gen::__gen_flow_shell_write()
|
||||
{
|
||||
[ -z "$DOCKER_FINANCE_CONTAINER_CMD" ] && lib_utils::die_fatal
|
||||
sed \
|
||||
-e "s:@DOCKER_FINANCE_CONTAINER_CMD@:${DOCKER_FINANCE_CONTAINER_CMD}:g" \
|
||||
-e "s:@DOCKER_FINANCE_CONTAINER_REPO@:${DOCKER_FINANCE_CONTAINER_REPO}:g" \
|
||||
-e "s:@DOCKER_FINANCE_VERSION@:${DOCKER_FINANCE_VERSION}:g" \
|
||||
-e "s:@DOCKER_FINANCE_PROFILE@:${_profile}:g" \
|
||||
-e "s:@DOCKER_FINANCE_SUBPROFILE@:${_subprofile}:g" \
|
||||
"${global_repo_conf_dir}/container/shell/subprofile.bash.in" >"$_file"
|
||||
}
|
||||
|
||||
#
|
||||
# Generate client-side container fetch
|
||||
#
|
||||
|
||||
function lib_gen::__gen_flow_fetch()
|
||||
{
|
||||
local _dir="${_gen_conf_path}/fetch"
|
||||
[ ! -d "$_dir" ] && mkdir -p "$_dir"
|
||||
|
||||
local _file="${_dir}/fetch.yaml"
|
||||
if [ -f "$_file" ]; then
|
||||
|
||||
lib_utils::print_custom " \e[32m│ │ │ └─\e[34m Subprofile's fetch configuration found, backup then generate new one? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
|
||||
if [[ "$_confirm" == [yY] ]]; then
|
||||
cp -a "$_file" "${_file}_${global_suffix}" || lib_utils::die_fatal
|
||||
|
||||
lib_gen::__gen_flow_fetch_write
|
||||
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit (new) subprofile's fetch configuration now? [Y/n] \e[0m"
|
||||
fi
|
||||
else
|
||||
lib_gen::__gen_flow_fetch_write
|
||||
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit (new) subprofile's fetch configuration now? [Y/n] \e[0m"
|
||||
fi
|
||||
|
||||
lib_utils::print_custom "$_print_custom"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
[[ "$_confirm" == [yY] ]] && $EDITOR "$_file"
|
||||
}
|
||||
|
||||
function lib_gen::__gen_flow_fetch_write()
|
||||
{
|
||||
[ -z "$DOCKER_FINANCE_VERSION" ] && lib_utils::die_fatal
|
||||
|
||||
[ -z "$_profile" ] && lib_utils::die_fatal
|
||||
[ -z "$_subprofile" ] && lib_utils::die_fatal
|
||||
|
||||
[ -z "$global_repo_conf_dir" ] && lib_utils::die_fatal
|
||||
[ -z "$_file" ] && lib_utils::die_fatal
|
||||
|
||||
sed \
|
||||
-e "s:@DOCKER_FINANCE_VERSION@:${DOCKER_FINANCE_VERSION}:g" \
|
||||
-e "s:@DOCKER_FINANCE_PROFILE@:${_profile}:g" \
|
||||
-e "s:@DOCKER_FINANCE_SUBPROFILE@:${_subprofile}:g" \
|
||||
"${global_repo_conf_dir}/container/fetch/fetch.yaml.in" >"$_file"
|
||||
}
|
||||
|
||||
#
|
||||
# Generate financial metadata
|
||||
#
|
||||
|
||||
function lib_gen::__gen_flow_meta()
|
||||
{
|
||||
local _dir="${_gen_conf_path}/meta"
|
||||
[ ! -d "$_dir" ] && mkdir -p "$_dir"
|
||||
|
||||
local _file="${_dir}/meta.csv"
|
||||
if [ -f "$_file" ]; then
|
||||
|
||||
lib_utils::print_custom " \e[32m│ │ │ └─\e[34m Subprofile's financial metadata found, backup then generate new one? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
|
||||
if [[ "$_confirm" == [yY] ]]; then
|
||||
cp -a "$_file" "${_file}_${global_suffix}" || lib_utils::die_fatal
|
||||
|
||||
lib_gen::__gen_flow_meta_write
|
||||
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit (new) subprofile's financial metadata now? [Y/n] \e[0m"
|
||||
fi
|
||||
else
|
||||
lib_gen::__gen_flow_meta_write
|
||||
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit (new) subprofile's financial metadata now? [Y/n] \e[0m"
|
||||
fi
|
||||
|
||||
lib_utils::print_custom "$_print_custom"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
[[ "$_confirm" == [yY] ]] && $EDITOR "$_file"
|
||||
}
|
||||
|
||||
function lib_gen::__gen_flow_meta_write()
|
||||
{
|
||||
# Deletes default comments or else ROOT meta sample won't work out-of-the-box
|
||||
sed \
|
||||
-e "/\/\/\\!/d" \
|
||||
-e "s:@DOCKER_FINANCE_VERSION@:${DOCKER_FINANCE_VERSION}:g" \
|
||||
"${global_repo_conf_dir}/container/meta/meta.csv.in" >"$_file"
|
||||
}
|
||||
|
||||
#
|
||||
# Generate accounts
|
||||
#
|
||||
|
||||
function lib_gen::__gen_flow_accounts()
|
||||
{
|
||||
lib_utils::print_debug "Generating accounts"
|
||||
|
||||
local _subprofile_path="${_gen_path}/import/${_subprofile}"
|
||||
lib_utils::print_debug "_subprofile_path=${_subprofile_path}"
|
||||
|
||||
if [ -d "$_subprofile_path" ]; then
|
||||
lib_utils::print_custom " \e[32m│ │ │ ├─\e[34m Subprofile import path exists! Continue with account generation (files will be backed up)? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
[[ "$_confirm" == [yY] ]] || return 0
|
||||
else
|
||||
mkdir -p "$_subprofile_path"
|
||||
fi
|
||||
|
||||
# docker-finance templates
|
||||
local _templates_paths
|
||||
mapfile -t _templates_paths < <(find ${DOCKER_FINANCE_CLIENT_REPO}/container/src/hledger-flow/accounts -name template | sort)
|
||||
declare -r _templates_paths
|
||||
lib_utils::print_debug "_templates_paths=${_templates_paths[*]}"
|
||||
|
||||
lib_utils::print_custom " \e[32m│ │ │ │\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│ │ │ ├─\e[34;1m Generate individual subprofile accounts instead of generating them all at once? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
|
||||
# Cycle through all available docker-finance templates and populate subprofile
|
||||
if [[ $_confirm == [yY] ]]; then
|
||||
for _template_path in "${_templates_paths[@]}"; do
|
||||
lib_utils::print_debug "_template_path=${_template_path}"
|
||||
lib_utils::print_custom " \e[32m│ │ │ │ │\e[0m\n"
|
||||
lib_utils::print_custom " \e[32m│ │ │ │ ├─\e[34m\e[1m Generate $(echo $_template_path | rev | cut -d/ -f2 | rev) ? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
[[ "$_confirm" == [yY] ]] \
|
||||
&& lib_gen::__gen_flow_accounts_populate "$_subprofile_path" "$_template_path" "$_is_testing"
|
||||
done
|
||||
else
|
||||
for _template_path in "${_templates_paths[@]}"; do
|
||||
lib_utils::print_debug "$_subprofile_path $_template_path $_is_testing"
|
||||
lib_gen::__gen_flow_accounts_populate "$_subprofile_path" "$_template_path" "$_is_testing"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
function lib_gen::__gen_flow_accounts_populate()
|
||||
{
|
||||
[ -z "$1" ] && lib_utils::die_fatal
|
||||
[ -z "$2" ] && lib_utils::die_fatal
|
||||
[ -z "$3" ] && lib_utils::die_fatal
|
||||
local _subprofile_path="$1"
|
||||
local _template_path="$2"
|
||||
local _is_testing="$3"
|
||||
|
||||
# Continue if hledger-flow account exists
|
||||
local _continue
|
||||
_continue=true
|
||||
|
||||
local _account_path
|
||||
_account_path="${_subprofile_path}/$(echo $_template_path | rev | cut -d/ -f2 | rev)"
|
||||
lib_utils::print_debug "_account_path=${_account_path}"
|
||||
|
||||
# TODO: doesn't check for blockchain explorer shared rules/bash
|
||||
if [ -d "$_account_path" ]; then
|
||||
lib_utils::print_custom " \e[32m│ │ │ │ │ └─\e[34m Account exists! Continue with backup and generation? [Y/n] \e[0m"
|
||||
read -p "" _read
|
||||
_confirm="${_read:-y}"
|
||||
[[ "$_confirm" == [yY] ]] || _continue=false
|
||||
fi
|
||||
|
||||
# Populate with template
|
||||
if [[ $_continue == true ]]; then
|
||||
|
||||
# Populates account and blockchain explorer's shared rules/preprocess
|
||||
# (at top-level, along with all the account's shared rules/preprocess)
|
||||
lib_utils::print_debug "Copying '${_template_path}/*' to '${_subprofile_path}/'"
|
||||
cp -a -R --backup --suffix="_${global_suffix}" \
|
||||
"${_template_path}"/* "$_subprofile_path/" || lib_utils::die_fatal
|
||||
|
||||
# If not blockchain explorers (since those exist as subaccounts)
|
||||
if [[ ! "$_template_path" =~ "blockchain-explorers" ]]; then
|
||||
|
||||
# Add year to 1-in
|
||||
while read _in_path; do
|
||||
local _year_path
|
||||
_year_path="${_in_path}/$(date +%Y)"
|
||||
lib_utils::print_debug "Making year path '${_year_path}'"
|
||||
mkdir -p "$_year_path"
|
||||
|
||||
# Appropriate test data if testing
|
||||
local _mockup="${_in_path}/mockup"
|
||||
lib_utils::print_debug "Getting mockup '${_mockup}'"
|
||||
|
||||
if [[ $_is_testing == true ]]; then
|
||||
lib_utils::print_debug "Copying mockup to '${_in_path}'"
|
||||
cp -a -R --backup --suffix="_${global_suffix}" "${_mockup}"/* "${_in_path}/" || lib_utils::die_fatal
|
||||
fi
|
||||
|
||||
# Always remove original test data
|
||||
rm -fr "$_mockup"
|
||||
|
||||
done < <(find "$_account_path" -name 1-in)
|
||||
fi
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
# vim: sw=2 sts=2 si ai et
|
||||
Reference in New Issue
Block a user