forked from EvergreenCrypto/docker-finance
1151 lines
38 KiB
Bash
1151 lines
38 KiB
Bash
#!/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/>.
|
|
|
|
[ -z "$DOCKER_FINANCE_CLIENT_REPO" ] && exit 1
|
|
|
|
#
|
|
# "Libraries"
|
|
#
|
|
|
|
# Runtime environment handler
|
|
source "${DOCKER_FINANCE_CLIENT_REPO}/client/src/docker/lib/internal/lib_env.bash" || exit 1
|
|
|
|
# Utilities (a container library (but container is never exposed to client code))
|
|
source "${DOCKER_FINANCE_CLIENT_REPO}/container/src/finance/lib/internal/lib_utils.bash" || exit 1
|
|
|
|
#
|
|
# Implementation
|
|
#
|
|
|
|
function lib_gen::__parse_args()
|
|
{
|
|
[ -z "$global_usage" ] && lib_utils::die_fatal
|
|
[ -z "$global_arg_delim_1" ] && lib_utils::die_fatal
|
|
[ -z "$global_arg_delim_2" ] && lib_utils::die_fatal
|
|
[ -z "$global_arg_delim_3" ] && lib_utils::die_fatal
|
|
|
|
# All available hledger-flow accounts
|
|
local _accounts
|
|
mapfile -t _accounts < <(find ${DOCKER_FINANCE_CLIENT_REPO}/container/src/hledger-flow/accounts -name template | sort | rev | cut -d/ -f2 | rev)
|
|
declare -r _accounts
|
|
|
|
local -r _usage="
|
|
\e[32mDescription:\e[0m
|
|
|
|
Generate environment and configurations
|
|
|
|
\e[32mUsage:\e[0m
|
|
|
|
$ $global_usage <<[all${global_arg_delim_2}<type1[{${global_arg_delim_2}type2${global_arg_delim_3}...}]>] [type${global_arg_delim_3}<type1[${global_arg_delim_3}type2...]>]> [<[profile${global_arg_delim_2}<profile>]> [config${global_arg_delim_2}<config1[${global_arg_delim_3}config2...]>] [account${global_arg_delim_2}<account1[${global_arg_delim_3}account2...]>]] [confirm${global_arg_delim_2}<{on|yes|true} | {off|no|false}>] [dev${global_arg_delim_2}<{on|yes|true} | {off|no|false}>]
|
|
|
|
\e[32mArguments:\e[0m
|
|
|
|
All categories and data:
|
|
|
|
all${global_arg_delim_2}<all | type>
|
|
|
|
Note: 'type' is currently the same as 'all'
|
|
|
|
Category type:
|
|
|
|
type${global_arg_delim_2}<env | build | flow | superscript>
|
|
|
|
Flow (only):
|
|
|
|
Full profile (w/ subprofile):
|
|
|
|
profile${global_arg_delim_2}<parent${global_arg_delim_1}child>
|
|
|
|
Configuration type:
|
|
|
|
config${global_arg_delim_2}<fetch | hledger | meta | subscript>
|
|
|
|
Accounts:
|
|
|
|
account${global_arg_delim_2}<$(echo "${_accounts[@]}" | sed 's: : | :g')>
|
|
|
|
Enable developer profile w/ mockups:
|
|
|
|
dev${global_arg_delim_2}<{on|yes|true} | {off|no|false}> # (default disabled)
|
|
|
|
Enable confirmations:
|
|
|
|
confirm${global_arg_delim_2}<{on|yes|true} | {off|no|false}> # (default enabled)
|
|
|
|
|
|
\e[32mExamples:\e[0m
|
|
|
|
\e[37;2m#\e[0m
|
|
\e[37;2m# All (client, container)\e[0m
|
|
\e[37;2m#\e[0m
|
|
|
|
\e[37;2m# Generate all client and container data\e[0m
|
|
$ $global_usage all${global_arg_delim_2}all
|
|
|
|
\e[37;2m# Generate all client and container data, skipping confirmations (using a default profile/subprofile name)\e[0m
|
|
$ $global_usage all${global_arg_delim_2}all confirm${global_arg_delim_2}no
|
|
|
|
\e[37;2m# Generate all client and container data for profile called 'parent/child', skipping confirmations\e[0m
|
|
$ $global_usage all${global_arg_delim_2}all profile${global_arg_delim_2}parent${global_arg_delim_1}child confirm${global_arg_delim_2}off
|
|
|
|
\e[37;2m#\e[0m
|
|
\e[37;2m# Client (joint container)\e[0m
|
|
\e[37;2m#\e[0m
|
|
|
|
\e[37;2m# Generate only the Docker environment\e[0m
|
|
$ $global_usage type${global_arg_delim_2}env
|
|
|
|
\e[37;2m# Generate custom Dockerfile and joint client/container superscript\e[0m
|
|
$ $global_usage type${global_arg_delim_2}build${global_arg_delim_3}superscript
|
|
|
|
\e[37;2m# Generate all client related data\e[0m
|
|
$ $global_usage type${global_arg_delim_2}env${global_arg_delim_3}build${global_arg_delim_3}superscript
|
|
|
|
\e[37;2m#\e[0m
|
|
\e[37;2m# Flow: Profile -> Configs / Accounts\e[0m
|
|
\e[37;2m#\e[0m
|
|
|
|
\e[37;2m# Generate all client related and all flow related for profile/subprofile called 'parent/child'\e[0m
|
|
$ $global_usage type${global_arg_delim_2}env${global_arg_delim_3}build${global_arg_delim_3}superscript${global_arg_delim_3}flow profile${global_arg_delim_2}parent${global_arg_delim_1}child
|
|
|
|
\e[37;2m# Same command as above but without confirmations and with developer mockups\e[0m
|
|
$ $global_usage type${global_arg_delim_2}env${global_arg_delim_3}build${global_arg_delim_3}superscript${global_arg_delim_3}flow profile${global_arg_delim_2}parent${global_arg_delim_1}child confirm${global_arg_delim_2}false dev${global_arg_delim_2}true
|
|
|
|
\e[37;2m# Generate only the given configurations for 'parent/child'\e[0m
|
|
$ $global_usage type${global_arg_delim_2}flow profile${global_arg_delim_2}parent${global_arg_delim_1}child config${global_arg_delim_2}fetch${global_arg_delim_3}hledger${global_arg_delim_3}meta${global_arg_delim_3}subscript
|
|
|
|
\e[37;2m# Generate only the given accounts for 'parent/child'\e[0m
|
|
$ $global_usage type${global_arg_delim_2}flow profile${global_arg_delim_2}parent${global_arg_delim_1}child account${global_arg_delim_2}capital-one${global_arg_delim_3}chase${global_arg_delim_3}coinbase
|
|
|
|
\e[37;2m# Generate the given configs and accounts for given 'parent/child'\e[0m
|
|
$ $global_usage type${global_arg_delim_2}flow profile${global_arg_delim_2}parent${global_arg_delim_1}child config${global_arg_delim_2}meta${global_arg_delim_3}subscript account${global_arg_delim_2}ethereum-based${global_arg_delim_3}metamask
|
|
|
|
\e[32mNotes:\e[0m
|
|
|
|
- The 'profile' argument is limited to 'type' flow
|
|
- The 'config' and 'account' arguments require 'profile'
|
|
"
|
|
|
|
#
|
|
# Ensure supported arguments
|
|
#
|
|
|
|
[ $# -eq 0 ] && lib_utils::die_usage "$_usage"
|
|
|
|
for _arg in "$@"; do
|
|
[[ ! "$_arg" =~ ^all${global_arg_delim_2} ]] \
|
|
&& [[ ! "$_arg" =~ ^type${global_arg_delim_2} ]] \
|
|
&& [[ ! "$_arg" =~ ^profile${global_arg_delim_2} ]] \
|
|
&& [[ ! "$_arg" =~ ^config[s]?${global_arg_delim_2} ]] \
|
|
&& [[ ! "$_arg" =~ ^account[s]?${global_arg_delim_2} ]] \
|
|
&& [[ ! "$_arg" =~ ^confirm${global_arg_delim_2} ]] \
|
|
&& [[ ! "$_arg" =~ ^dev${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" =~ ^all$ ]]; then
|
|
local _arg_all="${_arg:${_len}}"
|
|
[ -z "$_arg_all" ] && lib_utils::die_usage "$_usage"
|
|
fi
|
|
|
|
if [[ "$_key" =~ ^type$ ]]; then
|
|
local _arg_type="${_arg:${_len}}"
|
|
[ -z "$_arg_type" ] && lib_utils::die_usage "$_usage"
|
|
fi
|
|
|
|
if [[ "$_key" =~ ^profile$ ]]; then
|
|
local _arg_profile="${_arg:${_len}}"
|
|
[ -z "$_arg_profile" ] && lib_utils::die_usage "$_usage"
|
|
fi
|
|
|
|
if [[ "$_key" =~ ^config[s]?$ ]]; then
|
|
local _arg_config="${_arg:${_len}}"
|
|
[ -z "$_arg_config" ] && lib_utils::die_usage "$_usage"
|
|
fi
|
|
|
|
if [[ "$_key" =~ ^account[s]?$ ]]; then
|
|
local _arg_account="${_arg:${_len}}"
|
|
[ -z "$_arg_account" ] && lib_utils::die_usage "$_usage"
|
|
fi
|
|
|
|
if [[ "$_key" =~ ^confirm$ ]]; then
|
|
local _arg_confirm="${_arg:${_len}}"
|
|
[ -z "$_arg_confirm" ] && lib_utils::die_usage "$_usage"
|
|
fi
|
|
|
|
if [[ "$_key" =~ ^dev$ ]]; then
|
|
local _arg_dev="${_arg:${_len}}"
|
|
[ -z "$_arg_dev" ] && lib_utils::die_usage "$_usage"
|
|
fi
|
|
|
|
done
|
|
|
|
#
|
|
# Test for valid ordering/functionality of argument values
|
|
#
|
|
|
|
[[ -z "$_arg_all" && -z "$_arg_type" ]] && lib_utils::die_usage "$_usage"
|
|
|
|
# Arg: all
|
|
if [ ! -z "$_arg_all" ]; then
|
|
# If all= then no need for type= or config= or account=
|
|
if [[ ! -z "$_arg_type" || ! -z "$_arg_config" || ! -z "$_arg_account" ]]; then
|
|
lib_utils::die_usage "$_usage"
|
|
fi
|
|
fi
|
|
|
|
# Arg: type
|
|
# Note: check not needed
|
|
|
|
# Arg: profile
|
|
if [ ! -z "$_arg_profile" ]; then
|
|
# Requires type to be set
|
|
if [[ ! "${_arg_all[*]}" =~ all|type && -z "$_arg_type" ]]; then
|
|
lib_utils::die_usage "$_usage"
|
|
fi
|
|
fi
|
|
|
|
# Arg: config
|
|
if [ ! -z "$_arg_config" ]; then
|
|
# Requires profile to be set
|
|
if [ -z "$_arg_profile" ]; then
|
|
lib_utils::die_usage "$_usage"
|
|
fi
|
|
fi
|
|
|
|
# Arg: account
|
|
if [ ! -z "$_arg_account" ]; then
|
|
# Requires profile to be set
|
|
if [ -z "$_arg_profile" ]; then
|
|
lib_utils::die_usage "$_usage"
|
|
fi
|
|
fi
|
|
|
|
# Arg: confirm
|
|
# Note: optional argument, check not needed
|
|
|
|
# Arg: dev
|
|
# Note: optional argument, check not needed
|
|
|
|
#
|
|
# Test argument values, set globals
|
|
#
|
|
|
|
IFS="$global_arg_delim_3"
|
|
|
|
# Arg: all
|
|
if [ ! -z "$_arg_all" ]; then
|
|
read -ra _read <<<"$_arg_all"
|
|
for _arg in "${_read[@]}"; do
|
|
# Supported values
|
|
[[ ! "$_arg" =~ ^all$|^type[s]?$ ]] \
|
|
&& lib_utils::die_usage "$_usage"
|
|
|
|
# If all=all then no need for all={type}
|
|
[[ "$_arg" == "all" && "${#_read[@]}" -gt 1 ]] \
|
|
&& lib_utils::die_usage "$_usage"
|
|
done
|
|
# TODO: currently, 'all' will be equivalent 'type'
|
|
declare -gr global_arg_all=("${_read[@]}")
|
|
fi
|
|
|
|
# Arg: type
|
|
if [ ! -z "$_arg_type" ]; then
|
|
read -ra _read <<<"$_arg_type"
|
|
for _arg in "${_read[@]}"; do
|
|
if [[ ! "$_arg" =~ ^env$|^build$|^flow$|^superscript$ ]]; then
|
|
lib_utils::die_usage "$_usage"
|
|
fi
|
|
done
|
|
declare -gr global_arg_type=("${_read[@]}")
|
|
fi
|
|
|
|
# Arg: profile
|
|
if [ ! -z "$_arg_profile" ]; then
|
|
# Requires flow type
|
|
if [[ ! "${global_arg_all[*]}" =~ all|type && ! "${global_arg_type[*]}" =~ flow ]]; then
|
|
lib_utils::die_usage "$_usage"
|
|
fi
|
|
if [[ ! "$_arg_profile" =~ $global_arg_delim_1 ]]; then
|
|
lib_utils::die_usage "$_usage"
|
|
fi
|
|
declare -gr global_arg_profile="${_arg_profile%${global_arg_delim_1}*}"
|
|
declare -gr global_arg_subprofile="${_arg_profile##*${global_arg_delim_1}}"
|
|
fi
|
|
|
|
# Arg: config
|
|
if [ ! -z "$_arg_config" ]; then
|
|
# Requires profile type
|
|
if [ -z "$global_arg_profile" ]; then
|
|
lib_utils::die_usage "$_usage"
|
|
fi
|
|
read -ra _read <<<"$_arg_config"
|
|
for _arg in "${_read[@]}"; do
|
|
if [[ ! "$_arg" =~ ^fetch$|^hledger$|^meta$|^subscript$ ]]; then
|
|
lib_utils::die_usage "$_usage"
|
|
fi
|
|
done
|
|
declare -gr global_arg_config=("${_read[@]}")
|
|
fi
|
|
|
|
# Arg: account
|
|
if [ ! -z "$_arg_account" ]; then
|
|
# Requires profile type
|
|
if [ -z "$global_arg_profile" ]; then
|
|
lib_utils::die_usage "$_usage"
|
|
fi
|
|
read -ra _read <<<"$_arg_account"
|
|
# Test if given account is supported
|
|
for _arg in "${_read[@]}"; do
|
|
_found=false
|
|
for _account in "${_accounts[@]}"; do
|
|
[[ "$_arg" == "$_account" ]] && _found=true
|
|
done
|
|
[ $_found == true ] && continue || lib_utils::die_usage "$_usage"
|
|
done
|
|
declare -gr global_arg_account=("${_read[@]}")
|
|
fi
|
|
|
|
# Arg: confirm
|
|
if [ ! -z "$_arg_confirm" ]; then
|
|
if [[ ! "$_arg_confirm" =~ (^on$|^yes$|^true$)|(^off$|^no$|^false$) ]]; then
|
|
lib_utils::die_usage "$_usage"
|
|
fi
|
|
if [[ "$_arg_confirm" =~ ^off$|^no$|^false$ ]]; then
|
|
declare -gr global_arg_confirm=""
|
|
else
|
|
declare -gr global_arg_confirm="true"
|
|
fi
|
|
else
|
|
declare -gr global_arg_confirm="true"
|
|
fi
|
|
|
|
# Arg: dev
|
|
if [ ! -z "$_arg_dev" ]; then
|
|
if [[ ! "$_arg_dev" =~ (^on$|^yes$|^true$)|(^off$|^no$|^false$) ]]; then
|
|
lib_utils::die_usage "$_usage"
|
|
fi
|
|
if [[ "$_arg_dev" =~ ^on$|^yes$|^true$ ]]; then
|
|
declare -gr global_arg_dev="true"
|
|
else
|
|
declare -gr global_arg_dev=""
|
|
fi
|
|
else
|
|
declare -gr global_arg_dev=""
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Generate new configurations or layout
|
|
#
|
|
|
|
function lib_gen::gen()
|
|
{
|
|
lib_gen::__parse_args "$@"
|
|
|
|
lib_utils::print_custom "\n"
|
|
lib_utils::print_info "Generating client/container environment"
|
|
|
|
lib_gen::__gen_client
|
|
|
|
if [ $? -eq 0 ]; then
|
|
[ -z "$global_platform" ] && lib_utils::die_fatal
|
|
if [ "$global_platform" != "dev-tools" ]; then
|
|
lib_gen::__gen_container
|
|
fi
|
|
fi
|
|
|
|
if [ $? -eq 0 ]; then
|
|
lib_utils::print_custom "\n"
|
|
lib_utils::print_info "Congratulations, environment sucessfully generated!"
|
|
lib_utils::print_custom "\n"
|
|
else
|
|
lib_utils::print_custom "\n"
|
|
lib_utils::die_fatal "Environment not fully generated! Try again"
|
|
lib_utils::print_custom "\n"
|
|
fi
|
|
}
|
|
|
|
function lib_gen::__gen_client()
|
|
{
|
|
[ -z "$global_suffix" ] && lib_utils::die_fatal
|
|
|
|
lib_utils::print_debug "Generating client"
|
|
|
|
#
|
|
# Client-side environment file
|
|
#
|
|
|
|
if [[ -z "${global_arg_type[*]}" || "${global_arg_type[*]}" =~ env ]]; then
|
|
|
|
[ -z "$global_env_file" ] && lib_utils::die_fatal
|
|
[ -z "$global_repo_env_file" ] && lib_utils::die_fatal
|
|
|
|
# Backup existing 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 environment file found, backup then generate new one? [Y/n] \e[0m"
|
|
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
local _confirm="${_read:-y}"
|
|
|
|
if [[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]]; then
|
|
cp -a "$global_env_file" "${global_env_file}_${global_suffix}" \
|
|
|| lib_utils::die_fatal
|
|
|
|
# Get/Set with repository defaults
|
|
lib_utils::print_debug "Reading $global_repo_env_file"
|
|
lib_env::__read "$global_repo_env_file"
|
|
|
|
lib_utils::print_debug "Writing $global_env_file"
|
|
lib_env::__write "$global_env_file"
|
|
fi
|
|
fi
|
|
|
|
lib_utils::print_custom " \e[32m│ └─\e[34m Edit file now? [Y/n] \e[0m"
|
|
lib_gen::__gen_edit "$global_env_file"
|
|
|
|
# Get/Set new (edited) environment variables
|
|
lib_env::__read "$global_env_file"
|
|
lib_env::__set_client_globals
|
|
|
|
fi
|
|
|
|
#
|
|
# Custom (optional) Dockerfile
|
|
#
|
|
|
|
if [[ -z "${global_arg_type[*]}" || "${global_arg_type[*]}" =~ build ]]; then
|
|
|
|
[ -z "$global_custom_dockerfile" ] && lib_utils::die_fatal
|
|
[ -z "$global_repo_custom_dockerfile" ] && lib_utils::die_fatal
|
|
|
|
# Backup existing custom Dockerfile
|
|
if [ -f "$global_custom_dockerfile" ]; then
|
|
lib_utils::print_custom " \e[32m│\e[0m\n"
|
|
lib_utils::print_custom " \e[32m├─\e[34;1m Custom (optional) Dockerfile found, backup then generate new one? [Y/n] \e[0m"
|
|
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
local _confirm="${_read:-y}"
|
|
if [[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]]; then
|
|
cp -a "$global_custom_dockerfile" "${global_custom_dockerfile}_${global_suffix}" || lib_utils::die_fatal
|
|
cp -fa "$global_repo_custom_dockerfile" "$global_custom_dockerfile" || lib_utils::die_fatal
|
|
fi
|
|
else
|
|
lib_utils::print_custom " \e[32m│\e[0m\n"
|
|
lib_utils::print_custom " \e[32m├─\e[34;1m Generating new custom (optional) Dockerfile\e[0m\n"
|
|
|
|
lib_utils::print_debug "$global_repo_custom_dockerfile"
|
|
lib_utils::print_debug "$global_custom_dockerfile"
|
|
|
|
cp -a "$global_repo_custom_dockerfile" "$global_custom_dockerfile"
|
|
fi
|
|
|
|
lib_utils::print_custom " \e[32m│ └─\e[34m Edit file now? [Y/n] \e[0m"
|
|
lib_gen::__gen_edit "$global_custom_dockerfile"
|
|
fi
|
|
}
|
|
|
|
function lib_gen::__gen_container()
|
|
{
|
|
lib_utils::print_debug "Generating container"
|
|
|
|
#
|
|
# Generate joint client/container superscript
|
|
#
|
|
|
|
if [[ -z "${global_arg_type[*]}" || "${global_arg_type[*]}" =~ superscript ]]; then
|
|
|
|
lib_utils::print_custom " \e[32m│\e[0m\n"
|
|
lib_utils::print_custom " \e[32m├─\e[34;1m Generate joint client/container superscript? [Y/n] \e[0m"
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
_confirm="${_read:-y}"
|
|
if [[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]]; then
|
|
lib_gen::__gen_superscript
|
|
fi
|
|
|
|
fi
|
|
|
|
#
|
|
# Generate plugins (custom)
|
|
#
|
|
|
|
[ -z "$DOCKER_FINANCE_CLIENT_PLUGINS" ] && lib_utils::die_fatal
|
|
if [ ! -d "$DOCKER_FINANCE_CLIENT_PLUGINS" ]; then
|
|
mkdir -p "$DOCKER_FINANCE_CLIENT_PLUGINS" || lib_utils::die_fatal
|
|
fi
|
|
|
|
lib_gen::__gen_plugins
|
|
|
|
#
|
|
# Generate flow
|
|
#
|
|
|
|
if [[ "${global_arg_all[*]}" =~ all|type || "${global_arg_type[*]}" =~ flow ]]; then
|
|
|
|
lib_utils::print_custom " \e[32m│\e[0m\n"
|
|
lib_utils::print_custom " \e[32m├─\e[34;1m Generate container finance flow (layout and profiles)? [Y/n] \e[0m"
|
|
# Prompt if type not given
|
|
if [[ ! "${global_arg_all[*]}" =~ all|type || -z "${global_arg_type[*]}" ]]; then
|
|
if [ -z "$global_arg_confirm" ]; then
|
|
lib_utils::print_custom "\n"
|
|
else
|
|
read -p "" _read
|
|
local _confirm="${_read:-y}"
|
|
if [[ "$_confirm" != [yY] ]]; then
|
|
lib_utils::print_custom " \e[32m│\e[0m\n"
|
|
return 0
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
[ -z "$DOCKER_FINANCE_CLIENT_FLOW" ] && lib_utils::die_fatal
|
|
if [ ! -d "$DOCKER_FINANCE_CLIENT_FLOW" ]; then
|
|
mkdir -p "$DOCKER_FINANCE_CLIENT_FLOW" || lib_utils::die_fatal
|
|
fi
|
|
|
|
lib_gen::__gen_times
|
|
lib_gen::__gen_profile
|
|
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Generate joint client/container superscript
|
|
#
|
|
|
|
function lib_gen::__gen_superscript()
|
|
{
|
|
[ -z "$global_superscript" ] && lib_utils::die_fatal
|
|
|
|
if [ -f "$global_superscript" ]; then
|
|
lib_utils::print_custom " \e[32m│ └─\e[34m Backup existing file and generate a new one? [N/y] \e[0m"
|
|
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
local _confirm="${_read:-n}"
|
|
|
|
if [[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]]; then
|
|
# Backup
|
|
local -r _backup=("cp" "-a" "$global_superscript" "${global_superscript}_${global_suffix}")
|
|
lib_utils::print_debug "${_backup[@]}"
|
|
"${_backup[@]}" || lib_utils::die_fatal
|
|
# Write
|
|
lib_gen::__gen_superscript_write
|
|
fi
|
|
local _print_custom=" \e[32m│ └─\e[34m Edit file now? [Y/n] \e[0m"
|
|
else
|
|
# Generate new default file
|
|
lib_gen::__gen_superscript_write
|
|
local _print_custom=" \e[32m│ │ └─\e[34m Edit file now? [Y/n] \e[0m"
|
|
fi
|
|
|
|
lib_utils::print_custom "$_print_custom"
|
|
lib_gen::__gen_edit "$global_superscript"
|
|
}
|
|
|
|
function lib_gen::__gen_superscript_write()
|
|
{
|
|
[ -z "$global_repo_conf_dir" ] && lib_utils::die_fatal
|
|
lib_utils::print_debug "global_repo_conf_dir=${global_repo_conf_dir}"
|
|
|
|
[ -z "$global_client_version" ] && lib_utils::die_fatal
|
|
lib_utils::print_debug "global_client_version=${global_client_version}"
|
|
|
|
[ -z "$global_superscript" ] && lib_utils::die_fatal
|
|
lib_utils::print_debug "global_superscript=${global_superscript}"
|
|
|
|
sed \
|
|
-e "s:@DOCKER_FINANCE_VERSION@:${global_client_version}:g" \
|
|
"${global_repo_conf_dir}/container/shell/superscript.bash.in" >"$global_superscript"
|
|
}
|
|
|
|
#
|
|
# Generate plugins (custom):
|
|
#
|
|
# - Provides:
|
|
# - A layout to drop-in custom plugins
|
|
# * Underlying impl expects this layout
|
|
#
|
|
|
|
function lib_gen::__gen_plugins()
|
|
{
|
|
[ -z "$DOCKER_FINANCE_CLIENT_PLUGINS" ] && lib_utils::die_fatal
|
|
|
|
lib_utils::print_debug "Generating custom plugins layout"
|
|
|
|
local -r _client="${DOCKER_FINANCE_CLIENT_PLUGINS}/client"
|
|
if [ ! -d "${_client}/docker" ]; then
|
|
mkdir -p "${_client}/docker" || lib_utils::die_fatal
|
|
fi
|
|
|
|
local -r _container="${DOCKER_FINANCE_CLIENT_PLUGINS}/container"
|
|
if [ ! -d "${_container}/finance" ]; then
|
|
mkdir -p "${_container}/finance" || lib_utils::die_fatal
|
|
fi
|
|
if [ ! -d "${_container}/root" ]; then
|
|
mkdir -p "${_container}/root" || lib_utils::die_fatal
|
|
fi
|
|
}
|
|
|
|
#
|
|
# Generate flow: times
|
|
#
|
|
# - Provides a place for:
|
|
# * timew database
|
|
# * Anything time-related (among all profiles)
|
|
#
|
|
|
|
function lib_gen::__gen_times()
|
|
{
|
|
lib_utils::print_debug "Generating times"
|
|
|
|
local -r _times="${DOCKER_FINANCE_CLIENT_FLOW}/times"
|
|
if [ ! -d "$_times" ]; then
|
|
mkdir -p "$_times" || lib_utils::die_fatal
|
|
fi
|
|
|
|
# NOTE: timew database will be created upon first call
|
|
}
|
|
|
|
#
|
|
# Generate flow: profile/subprofile
|
|
#
|
|
|
|
function lib_gen::__gen_profile()
|
|
{
|
|
lib_utils::print_debug "Generating profiles"
|
|
|
|
local -r _profiles="${DOCKER_FINANCE_CLIENT_FLOW}/profiles"
|
|
if [ ! -d "$_profiles" ]; then
|
|
mkdir -p "$_profiles" || lib_utils::die_fatal
|
|
fi
|
|
|
|
#
|
|
# Profile: construct full path to subprofile
|
|
#
|
|
|
|
[ -z "$global_user" ] && lib_utils::die_fatal
|
|
|
|
# Profile
|
|
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"
|
|
if [ ! -z "$global_arg_profile" ]; then
|
|
lib_utils::print_custom "\n"
|
|
_read="$global_arg_profile"
|
|
else
|
|
if [ -z "$global_arg_confirm" ]; then
|
|
lib_utils::print_custom "\n"
|
|
_read=""
|
|
else
|
|
read -p "" _read
|
|
fi
|
|
fi
|
|
local -r _profile="${_read:-default}"
|
|
lib_utils::print_custom " \e[32m│ │ │ └─\e[34m Using profile:\e[0m ${_profile}\n"
|
|
|
|
# Subprofile
|
|
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"
|
|
if [ ! -z "$global_arg_subprofile" ]; then
|
|
lib_utils::print_custom "\n"
|
|
_read="$global_arg_subprofile"
|
|
else
|
|
if [ -z "$global_arg_confirm" ]; then
|
|
lib_utils::print_custom "\n"
|
|
_read=""
|
|
else
|
|
read -p "" _read
|
|
fi
|
|
fi
|
|
local -r _subprofile="${_read:-${global_user}}"
|
|
lib_utils::print_custom " \e[32m│ │ │ └─\e[34m Using subprofile:\e[0m ${_subprofile}\n"
|
|
|
|
# Check if full profile exists
|
|
if [ -d "${_profiles}/${_profile}/${_subprofile}" ]; then
|
|
lib_utils::print_custom " \e[32m│ │ │ └─\e[34m Subprofile exists! Continue with backup and generation? [Y/n] \e[0m"
|
|
|
|
if [ -z "$global_arg_confirm" ]; then
|
|
lib_utils::print_custom "\n"
|
|
_read=""
|
|
else
|
|
read -p "" _read
|
|
fi
|
|
_confirm="${_read:-y}"
|
|
if [[ "$_confirm" != [yY] ]]; then
|
|
lib_utils::print_custom " \e[32m│\e[0m\n"
|
|
lib_utils::print_normal ""
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
#
|
|
# Profile: generate profile-specific
|
|
#
|
|
|
|
local -r _gen_path="${_profiles}/${_profile}/${_subprofile}"
|
|
lib_utils::print_debug "_gen_path=${_gen_path}"
|
|
|
|
local -r _gen_conf_path="${_gen_path}/docker-finance.d"
|
|
lib_utils::print_debug "_gen_conf_path=${_gen_conf_path}"
|
|
|
|
lib_gen::__gen_subprofile_flow
|
|
}
|
|
|
|
#
|
|
# Subprofile: generate flow
|
|
#
|
|
|
|
function lib_gen::__gen_subprofile_flow()
|
|
{
|
|
[[ -z "$_gen_path" || -z "$_gen_conf_path" ]] && lib_utils::die_fatal
|
|
|
|
if lib_gen::__gen_subprofile_flow_args_config "subscript"; then
|
|
lib_utils::print_custom " \e[32m│ │ │\e[0m\n"
|
|
lib_utils::print_custom " \e[32m│ │ ├─\e[34;1m Generate subprofile's subscript file? [Y/n] \e[0m"
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
_confirm="${_read:-y}"
|
|
if [[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]]; then
|
|
# Subprofile's shell script
|
|
lib_gen::__gen_subprofile_flow_subscript
|
|
# Append subprofile source to superscript
|
|
lib_gen::__gen_subprofile_flow_superscript
|
|
fi
|
|
fi
|
|
|
|
if lib_gen::__gen_subprofile_flow_args_config "fetch"; then
|
|
# Prompt for default generation
|
|
lib_utils::print_custom " \e[32m│ │ │\e[0m\n"
|
|
lib_utils::print_custom " \e[32m│ │ ├─\e[34;1m Generate subprofile's fetch configuration file? [Y/n] \e[0m"
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
_confirm="${_read:-y}"
|
|
[[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]] && lib_gen::__gen_subprofile_flow_fetch
|
|
fi
|
|
|
|
if lib_gen::__gen_subprofile_flow_args_config "meta"; then
|
|
lib_utils::print_custom " \e[32m│ │ │\e[0m\n"
|
|
lib_utils::print_custom " \e[32m│ │ ├─\e[34;1m Generate subprofile's financial metadata file? [Y/n] \e[0m"
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
_confirm="${_read:-y}"
|
|
[[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]] && lib_gen::__gen_subprofile_flow_meta
|
|
fi
|
|
|
|
if lib_gen::__gen_subprofile_flow_args_config "hledger"; then
|
|
lib_utils::print_custom " \e[32m│ │ │\e[0m\n"
|
|
lib_utils::print_custom " \e[32m│ │ ├─\e[34;1m Generate subprofile's hledger configuration file? [Y/n] \e[0m"
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
_confirm="${_read:-y}"
|
|
[[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]] && lib_gen::__gen_subprofile_flow_hledger
|
|
fi
|
|
|
|
if lib_gen::__gen_subprofile_flow_args_account; then
|
|
lib_utils::print_custom " \e[32m│ │ │\e[0m\n"
|
|
lib_utils::print_custom " \e[32m│ │ ├─\e[34;1m Generate subprofile's hledger-flow accounts? [Y/n] \e[0m"
|
|
if [ ! -z "${global_arg_account[*]}" ]; then
|
|
lib_utils::print_custom "\n"
|
|
lib_gen::__gen_subprofile_flow_accounts
|
|
else
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
_confirm="${_read:-y}"
|
|
[[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]] && lib_gen::__gen_subprofile_flow_accounts
|
|
fi
|
|
fi
|
|
|
|
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"
|
|
}
|
|
|
|
function lib_gen::__gen_subprofile_flow_args_config()
|
|
{
|
|
[ -z "$1" ] && lib_utils::die_fatal
|
|
if [[ -z "${global_arg_type[*]}" || ("${global_arg_type[*]}" =~ flow && -z "$global_arg_profile") || ("${global_arg_type[*]}" =~ flow && ! -z "$global_arg_profile" && -z "${global_arg_account[*]}" && -z "${global_arg_config[*]}") || "${global_arg_config[*]}" =~ $1 ]]; then
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
function lib_gen::__gen_subprofile_flow_args_account()
|
|
{
|
|
if [[ -z "${global_arg_type[*]}" || ("${global_arg_type[*]}" =~ flow && -z "$global_arg_profile") || ("${global_arg_type[*]}" =~ flow && ! -z "$global_arg_profile" && -z "${global_arg_account[*]}" && -z "${global_arg_config[*]}") || ("${global_arg_type[*]}" =~ flow && ! -z "$global_arg_profile" && ! -z "${global_arg_account[*]}") ]]; then
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
#
|
|
# Subprofile: flow: generate subprofile subscript
|
|
#
|
|
|
|
function lib_gen::__gen_subprofile_flow_subscript()
|
|
{
|
|
[[ -z "$_gen_path" || -z "$_gen_conf_path" ]] && lib_utils::die_fatal
|
|
|
|
local _dir="${_gen_conf_path}/shell"
|
|
[ ! -d "$_dir" ] && mkdir -p "$_dir"
|
|
|
|
local _file="${_dir}/subscript.bash"
|
|
if [ -f "$_file" ]; then
|
|
lib_utils::print_custom " \e[32m│ │ │ └─\e[34m File found, backup then generate new one? [Y/n] \e[0m"
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
_confirm="${_read:-y}"
|
|
|
|
if [[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]]; then
|
|
cp -a "$_file" "${_file}_${global_suffix}" || lib_utils::die_fatal
|
|
|
|
lib_gen::__gen_subprofile_flow_subscript_write
|
|
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit file now? [Y/n] \e[0m"
|
|
fi
|
|
else
|
|
lib_gen::__gen_subprofile_flow_subscript_write
|
|
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit file now? [Y/n] \e[0m"
|
|
fi
|
|
|
|
lib_utils::print_custom "$_print_custom"
|
|
lib_gen::__gen_edit "$_file"
|
|
}
|
|
|
|
function lib_gen::__gen_subprofile_flow_subscript_write()
|
|
{
|
|
[[ -z "$DOCKER_FINANCE_CONTAINER_REPO" || -z "$DOCKER_FINANCE_CONTAINER_CMD" ]] && lib_utils::die_fatal
|
|
|
|
[[ -z "$_profile" || -z "$_subprofile" || -z "$_file" ]] && lib_utils::die_fatal
|
|
|
|
[ -z "$global_client_version" ] && lib_utils::die_fatal
|
|
[ -z "$global_repo_conf_dir" ] && 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@:${global_client_version}:g" \
|
|
-e "s:@DOCKER_FINANCE_PROFILE@:${_profile}:g" \
|
|
-e "s:@DOCKER_FINANCE_SUBPROFILE@:${_subprofile}:g" \
|
|
"${global_repo_conf_dir}/container/shell/subscript.bash.in" >"$_file"
|
|
}
|
|
|
|
#
|
|
# Subprofile: flow: append subscript to superscript
|
|
#
|
|
|
|
function lib_gen::__gen_subprofile_flow_superscript()
|
|
{
|
|
[[ -z "$_profile" || -z "$_subprofile" ]] && lib_utils::die_fatal
|
|
|
|
[ -z "$global_superscript" ] && lib_utils::die_fatal
|
|
[ ! -f "$global_superscript" ] && lib_utils::die_fatal "Superscript does not exist!"
|
|
|
|
# Append subprofile source to superscript
|
|
local -r _source="source \"\${DOCKER_FINANCE_CONTAINER_FLOW}/profiles/${_profile}/${_subprofile}/docker-finance.d/shell/subscript.bash\""
|
|
lib_utils::print_custom " \e[32m│ │ │ └─\e[34m Appending subprofile to superscript\e[0m\n"
|
|
|
|
# If source subprofile does not exist, append
|
|
grep "$_source" "$global_superscript" >&/dev/null \
|
|
|| sed -i "$(wc -l <$global_superscript)i\\$_source\\" "$global_superscript"
|
|
|
|
lib_utils::print_custom " \e[32m│ │ │ └─\e[34m Edit superscript now? [Y/n] \e[0m"
|
|
lib_gen::__gen_edit "$global_superscript"
|
|
}
|
|
|
|
#
|
|
# Subprofile: flow: generate fetch config
|
|
#
|
|
|
|
function lib_gen::__gen_subprofile_flow_fetch()
|
|
{
|
|
[[ -z "$_gen_path" || -z "$_gen_conf_path" ]] && lib_utils::die_fatal
|
|
|
|
local -r _dir="${_gen_conf_path}/fetch"
|
|
[ ! -d "$_dir" ] && mkdir -p "$_dir"
|
|
|
|
local -r _file="${_dir}/fetch.yaml"
|
|
if [ -f "$_file" ]; then
|
|
lib_utils::print_custom " \e[32m│ │ │ └─\e[34m File found, backup then generate new one? [Y/n] \e[0m"
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
_confirm="${_read:-y}"
|
|
|
|
if [[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]]; then
|
|
cp -a "$_file" "${_file}_${global_suffix}" || lib_utils::die_fatal
|
|
|
|
lib_gen::__gen_subprofile_flow_fetch_write
|
|
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit file now? [Y/n] \e[0m"
|
|
fi
|
|
else
|
|
lib_gen::__gen_subprofile_flow_fetch_write
|
|
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit file now? [Y/n] \e[0m"
|
|
fi
|
|
|
|
lib_utils::print_custom "$_print_custom"
|
|
lib_gen::__gen_edit "$_file"
|
|
}
|
|
|
|
function lib_gen::__gen_subprofile_flow_fetch_write()
|
|
{
|
|
[[ -z "$_profile" || -z "$_subprofile" || -z "$_file" ]] && lib_utils::die_fatal
|
|
|
|
[ -z "$global_client_version" ] && lib_utils::die_fatal
|
|
[ -z "$global_repo_conf_dir" ] && lib_utils::die_fatal
|
|
|
|
sed \
|
|
-e "s:@DOCKER_FINANCE_VERSION@:${global_client_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"
|
|
}
|
|
|
|
#
|
|
# Subprofile: flow: generate financial metadata
|
|
#
|
|
|
|
function lib_gen::__gen_subprofile_flow_meta()
|
|
{
|
|
[[ -z "$_gen_path" || -z "$_gen_conf_path" ]] && lib_utils::die_fatal
|
|
|
|
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 File found, backup then generate new one? [Y/n] \e[0m"
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
_confirm="${_read:-y}"
|
|
|
|
if [[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]]; then
|
|
cp -a "$_file" "${_file}_${global_suffix}" || lib_utils::die_fatal
|
|
|
|
lib_gen::__gen_subprofile_flow_meta_write
|
|
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit file now? [Y/n] \e[0m"
|
|
fi
|
|
else
|
|
lib_gen::__gen_subprofile_flow_meta_write
|
|
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit file now? [Y/n] \e[0m"
|
|
fi
|
|
|
|
lib_utils::print_custom "$_print_custom"
|
|
lib_gen::__gen_edit "$_file"
|
|
}
|
|
|
|
function lib_gen::__gen_subprofile_flow_meta_write()
|
|
{
|
|
[ -z "$_file" ] && lib_utils::die_fatal
|
|
|
|
[ -z "$global_client_version" ] && lib_utils::die_fatal
|
|
[ -z "$global_repo_conf_dir" ] && lib_utils::die_fatal
|
|
|
|
# Deletes default comments or else ROOT meta sample won't work out-of-the-box
|
|
sed \
|
|
-e "/\/\/\\!/d" \
|
|
-e "s:@DOCKER_FINANCE_VERSION@:${global_client_version}:g" \
|
|
"${global_repo_conf_dir}/container/meta/meta.csv.in" >"$_file"
|
|
}
|
|
|
|
#
|
|
# Subprofile: flow: generate hledger configuration file
|
|
#
|
|
|
|
function lib_gen::__gen_subprofile_flow_hledger()
|
|
{
|
|
[[ -z "$_gen_path" || -z "$_gen_conf_path" ]] && lib_utils::die_fatal
|
|
|
|
local _dir="${_gen_conf_path}/hledger"
|
|
[ ! -d "$_dir" ] && mkdir -p "$_dir"
|
|
|
|
local _file="${_dir}/hledger.conf"
|
|
if [ -f "$_file" ]; then
|
|
lib_utils::print_custom " \e[32m│ │ │ └─\e[34m File found, backup then generate new one? [Y/n] \e[0m"
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
_confirm="${_read:-y}"
|
|
|
|
if [[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]]; then
|
|
cp -a "$_file" "${_file}_${global_suffix}" || lib_utils::die_fatal
|
|
|
|
lib_gen::__gen_subprofile_flow_hledger_write
|
|
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit file now? [Y/n] \e[0m"
|
|
fi
|
|
else
|
|
lib_gen::__gen_subprofile_flow_hledger_write
|
|
local _print_custom=" \e[32m│ │ │ └─\e[34m Edit file now? [Y/n] \e[0m"
|
|
fi
|
|
|
|
lib_utils::print_custom "$_print_custom"
|
|
lib_gen::__gen_edit "$_file"
|
|
}
|
|
|
|
function lib_gen::__gen_subprofile_flow_hledger_write()
|
|
{
|
|
[ -z "$_file" ] && lib_utils::die_fatal
|
|
|
|
[ -z "$global_client_version" ] && lib_utils::die_fatal
|
|
lib_utils::print_debug "global_client_version=${global_client_version}"
|
|
|
|
[ -z "$global_repo_conf_dir" ] && lib_utils::die_fatal
|
|
lib_utils::print_debug "global_repo_conf_dir=${global_repo_conf_dir}"
|
|
|
|
sed \
|
|
-e "s:@DOCKER_FINANCE_VERSION@:${global_client_version}:g" \
|
|
"${global_repo_conf_dir}/container/hledger/hledger.conf.in" >"$_file"
|
|
}
|
|
|
|
#
|
|
# Subprofile: flow: generate accounts
|
|
#
|
|
|
|
function lib_gen::__gen_subprofile_flow_accounts()
|
|
{
|
|
[[ -z "$_gen_path" || -z "$_gen_conf_path" || -z "$_subprofile" ]] && lib_utils::die_fatal
|
|
|
|
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"
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
_confirm="${_read:-y}"
|
|
[[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]] || return 0
|
|
else
|
|
mkdir -p "$_subprofile_path"
|
|
fi
|
|
|
|
# All available hledger-flow account paths
|
|
local _templates_paths
|
|
mapfile -t _templates_paths < <(find "${DOCKER_FINANCE_CLIENT_REPO}"/container/src/hledger-flow/accounts -name template | sort)
|
|
declare -r _templates_paths
|
|
|
|
# All available hledger-flow account names
|
|
local _accounts
|
|
if [ -z "${global_arg_account[*]}" ]; then
|
|
for _template in "${_templates_paths[@]}"; do
|
|
_accounts+=("$(echo "$_template" | rev | cut -d/ -f2 | rev)")
|
|
done
|
|
else
|
|
declare -r _accounts=("${global_arg_account[@]}")
|
|
fi
|
|
|
|
# Cycle through all available docker-finance templates and populate subprofile
|
|
for _account in "${_accounts[@]}"; do
|
|
for _template_path in "${_templates_paths[@]}"; do
|
|
if [[ "$_template_path" =~ \/$_account\/ ]]; then
|
|
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 $_account ? [Y/n] \e[0m"
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
_confirm="${_read:-y}"
|
|
[[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]] \
|
|
&& lib_gen::__gen_subprofile_flow_accounts_populate "$_subprofile_path" "$_template_path"
|
|
fi
|
|
done
|
|
done
|
|
}
|
|
|
|
function lib_gen::__gen_subprofile_flow_accounts_populate()
|
|
{
|
|
[[ -z "$1" || -z "$2" ]] && lib_utils::die_fatal
|
|
local _subprofile_path="$1"
|
|
local _template_path="$2"
|
|
|
|
# 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"
|
|
[ -z "$global_arg_confirm" ] && lib_utils::print_custom "\n" || read -p "" _read
|
|
_confirm="${_read:-y}"
|
|
[[ "$_confirm" == [yY] || -z "$global_arg_confirm" ]] || _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 [ ! -z "$global_arg_dev" ]; 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
|
|
}
|
|
|
|
function lib_gen::__gen_edit()
|
|
{
|
|
local _file="$1"
|
|
[[ -z "$_file" || ! -f "$_file" ]] && lib_utils::die_fatal
|
|
|
|
if [ -z "$global_arg_confirm" ]; then
|
|
lib_utils::print_custom "\n"
|
|
_read="n"
|
|
else
|
|
read -p "" _read
|
|
fi
|
|
local _confirm="${_read:-y}"
|
|
|
|
[ -z "$EDITOR" ] && lib_utils::die_fatal
|
|
[[ "$_confirm" == [yY] ]] && $EDITOR "$_file" || return 0
|
|
}
|
|
|
|
# vim: sw=2 sts=2 si ai et
|