Compare commits

..

15 Commits

Author SHA1 Message Date
91780024f0 v3.7.5
=====================================================================

--- New Features -------------------------

- adding variables of the format `^SCWRYPTS_GROUP_LOADERS__[a-z_]\+=`
  will let those files be explicitly sourced during run (this should
  allow custom group usage in CI)
2023-11-13 12:27:15 -07:00
3ca4fe0c65 v3.7.4
=====================================================================

--- Bug Fixes ----------------------------

- fixed typo in Vundle.vim clone
2023-11-11 15:27:34 -07:00
e6dfff255c v3.7.3
=====================================================================

--- Changes ------------------------------

- Helm template generation looks for default values in file://
  dependencies in addition to the standard values locations

- vundle installer now *actually installs Vundle.vim* if it is missing
2023-11-11 15:13:30 -07:00
15942bb08d v3.7.2
=====================================================================

--- Bug Fixes ----------------------------

- Various github-actions fixes
2023-11-10 17:41:01 -07:00
6f42c9cb16 v3.7.0
=====================================================================

--- New Features -------------------------

- Github Actions integration from 3.7.0 and up!

```yaml
  # try it out in gh actions
  - uses: wrynegade/scwrypts@main
    with:
      version: v3.7.0
      scwrypt: --name hello-world --group scwrypts --type py
      args: --message "hello from github actions ci <3"
```

--- New Scripts --------------------------

zsh/helm )
  smart helm template functions (simply pass a filename)
   - get-template
   - update-dependencies

--- Changes ------------------------------

- CHECK_ENVIRONMENT now uses proper argument parsing

- scwrypts/plugins loaded by setting in config or environment:
   SCWRYPTS_PLUGIN_ENABLED__plugin=1

- SCWRYPTS__GET_PATH_TO_RELATIVE_ARGUMENT was missed in the v2->v3
  refactor and has now been reincluded as SCWRYPTS__GET_REALPATH
2023-11-10 16:32:05 -07:00
570fc6a435 v3.6.6
=====================================================================

--- Changes ------------------------------

- Allow CI more leniency in preparing aws environment
2023-10-23 12:47:53 -06:00
768350e6ab v3.6.5
=====================================================================

--- Bug fixes ----------------------------

- Some exit error cases were not handled properly by the default eval
  string due to early exit failing within the primary subshell of the
  scwrypt; moving the runstring one subshell deeper allows the capture
  of exit cases
2023-10-19 20:04:25 -06:00
531aa52146 v3.6.4
=====================================================================

--- Changes ------------------------------

- Introduced lazy environment variable checking on ECR_LOGIN
2023-10-19 14:44:01 -06:00
f8ccce9285 v3.6.3
=====================================================================

--- Bug fixes ----------------------------

- Silenced a startup error
2023-10-05 14:40:45 -06:00
6fc17bcfe5 v3.6.2
=====================================================================

--- Bug fixes ----------------------------

- fixed some bugs with kubectl plugin preloading and argument processing
2023-10-05 14:36:40 -06:00
2034325ac9 v3.6.1
=====================================================================

--- Changes ------------------------------

- Adjusted USAGE (from zsh/lib/utils/io.zsh) to allow dynamic variable
  insertion in help dialogues by setting USAGE__<help-group> and using
  the syntax listed

- Various quality-of-life changes and and fixes to experimental kubectl
  plugin

--- Bug fixes ----------------------------

- sourcing 'scwrypts.plugin.zsh' no longer sets __SCWRYPT=1 in your
  current environment
2023-08-30 17:26:13 -06:00
ab567f6950 v3.6.0
=====================================================================

--- New Features -------------------------

- Introducing an optional plugin for `kubectl` facilitation! Check out
  'plugins/kubectl/README.md' for more details.

--- Changes ------------------------------

- The function which lists all available scwrypts now ignores
  directories with a top-level base called "plugins." If this is a name
  conflict, you will need to define your own
  `SCWRYPTS__LIST_AVAILABLE_SCWRYPTS__<group>` function!

  (ref the changes in 'zsh/lib/scwrypts/run.module.zsh')
2023-08-28 20:31:04 -06:00
e199e9bf91 v3.5.0
=====================================================================

--- Changes ------------------------------

- AWS (the cli wrapper) now checks for it's required variables *on run*.
  This accomodates scwrypts which may need to run in multiple regions,
  but make the downstream scwrypt responsible for adding AWS_REGION to
  the REQUIRED_ENV list!

- Got rid of all kinds of hackiness surrounding postgres password evals
  between both the postgres library and the rds library

--- Bug Fixes ----------------------------

- scwrypts --update now pulls tags for proper versioning
2023-08-24 17:11:34 -06:00
4c161aba49 v3.4.0
=====================================================================

--- Changes ------------------------------

- Allow the group variable `REQUIRED_ENVIRONMENT_REGEX` to enforce that
  only some environments can run within the group
2023-08-22 14:20:03 -06:00
3ea2e0cd8f v3.3.3
=====================================================================

--- Bug Fixes ----------------------------

- load static config files in all scwrypts contexts; not just groups
2023-08-18 12:40:14 -06:00
51 changed files with 1476 additions and 172 deletions

16
.github/workflows/update-semver.yaml vendored Normal file
View File

@ -0,0 +1,16 @@
---
name: Update Semver
on: # yamllint disable-line rule:truthy
push:
branches-ignore:
- '**'
tags:
- 'v*.*.*'
jobs:
update-semver:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: rickstaa/action-update-semver@v1

68
action.yaml Normal file
View File

@ -0,0 +1,68 @@
--- # allow running scwrypts in Github Actions
name: scwrypts
author: yage
description: check required dependencies and run a scwrypt
inputs:
scwrypt:
description: "args / identifiers for scwrypts CLI (e.g. '--name <scwrypt-name> --group <group-name> --type <type-name>')"
required: true
args:
description: "arguments to pass to the scwrypt-to-be-run"
required: false
version:
description: "scwrypts version; defaults to latest (minimum v3.7.0)"
required: false
scwrypts-env:
description: "override value for SCWRYPTS_ENV"
required: false
default: "ci.github-actions"
runs:
using: composite
steps:
- uses: actions/checkout@v4
with:
repository: wrynegade/scwrypts
path: ./wrynegade/scwrypts
ref: ${{ inputs.version }}
- name: check dependencies
shell: bash
env:
CI: true
SCWRYPTS_PLUGIN_ENABLED__ci: 1
run: |
[ $CI_SCWRYPTS_READY ] && [[ $CI_SCWRYPTS_READY -eq 1 ]] && echo 'setup completed previously' && exit 0
echo "updating package dependencies"
{
sudo apt-get update
sudo apt-get install --yes zsh fzf ripgrep
for D in $($GITHUB_WORKSPACE/wrynegade/scwrypts/scwrypts -n --name check-all-dependencies --group ci --type zsh)
do
echo "--- installing $D ---"
( sudo apt-get install --yes $D; exit 0; )
done
} > $HOME/.scwrypts.apt-get.log 2>&1
echo "updating virtual dependencies"
$GITHUB_WORKSPACE/wrynegade/scwrypts/scwrypts -n \
--name scwrypts/virtualenv/update-all \
--group scwrypts \
--type zsh \
> $HOME/.scwrypts.virtualenv.log 2>&1
echo "CI_SCWRYPTS_READY=1" >> $GITHUB_ENV
exit 0
- name: run scwrypt
shell: bash
env:
CI: true
SCWRYPTS_ENV: ${{ inputs.scwrypts-env }}
run: $GITHUB_WORKSPACE/wrynegade/scwrypts/scwrypts ${{inputs.scwrypt}} -- ${{inputs.args}} || exit 1

View File

@ -0,0 +1 @@
#!/bin/zsh

10
plugins/ci/README.md Normal file
View File

@ -0,0 +1,10 @@
# Kubernetes `kubectl` Helper Plugin
Leverages a local `redis` application to quickly and easily set an alias `k` for `kubectl --context <some-context> --namespace <some-namespace>`.
Much like scwrypts environments, `k` aliases are *only* shared amongst session with the same `SCWRYPTS_ENV` to prevent accidental cross-contamination.
## Getting Started
Enable the plugin in `~/.config/scwrypts/config.zsh` by adding `SCWRYPTS_PLUGIN_ENABLED__KUBECTL=1`.
Use `k` as your new `kubectl` and checkout `k --help` and `k meta --help`.

View File

@ -0,0 +1,40 @@
#!/bin/zsh
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
#####################################################################
MAIN() {
cd "$SCWRYPTS_ROOT__scwrypts/"
DEPENDENCIES+=()
for group in ${SCWRYPTS_GROUPS[@]}
do
[[ $group =~ ^ci$ ]] && continue
GROUP_HOME="$(eval 'echo $SCWRYPTS_ROOT__'$group)"
[ $GROUP_HOME ] && [ -d "$GROUP_HOME" ] || continue
STATUS "checking dependencies for $group"
DEPENDENCIES+=($(
for file in $(
{
cd "$GROUP_HOME"
rg -l '^DEPENDENCIES\+=\($'
rg -l '^DEPENDENCIES\+=\([^)]\+\)'
} | grep -v '\.md$' | grep -v 'check-all-dependencies$')
do
sed -z 's/.*DEPENDENCIES+=(\([^)]*\)).*/\1\n/; s/#.*\n//g; s/\s\+/\n/g' "$GROUP_HOME/$file"
done
))
done
DEPENDENCIES=(zsh $(echo $DEPENDENCIES | sed 's/ /\n/g' | sort -u | grep '^[-_a-zA-Z]\+$'))
STATUS "discovered dependencies: ($DEPENDENCIES)"
echo $DEPENDENCIES | sed 's/ /\n/g'
CHECK_ENVIRONMENT && SUCCESS "all dependencies satisfied"
}
#####################################################################
MAIN $@

View File

@ -0,0 +1,5 @@
SCWRYPTS_GROUPS+=(ci)
export SCWRYPTS_TYPE__ci=zsh
export SCWRYPTS_ROOT__ci="$SCWRYPTS_ROOT__scwrypts/plugins/ci"
export SCWRYPTS_COLOR__ci='\033[0m'

View File

@ -0,0 +1,2 @@
#!/bin/zsh
export SCWRYPTS_KUBECTL_REDIS=

View File

@ -0,0 +1 @@
SCWRYPTS_KUBECTL_REDIS | (currently only 'managed') 'managed' or 'custom' redis configuration

View File

@ -0,0 +1,4 @@
export SCWRYPTS_KUBECTL_REDIS_HOST__managed=127.0.0.1
export SCWRYPTS_KUBECTL_REDIS_PORT__managed=26379
export SCWRYPTS_KUBECTL_REDIS_AUTH__managed=
export SCWRYPTS_KUBECTL_REDIS_KEY_PREFIX__managed=

10
plugins/kubectl/README.md Normal file
View File

@ -0,0 +1,10 @@
# Kubernetes `kubectl` Helper Plugin
Leverages a local `redis` application to quickly and easily set an alias `k` for `kubectl --context <some-context> --namespace <some-namespace>`.
Much like scwrypts environments, `k` aliases are *only* shared amongst session with the same `SCWRYPTS_ENV` to prevent accidental cross-contamination.
## Getting Started
Enable the plugin in `~/.config/scwrypts/config.zsh` by adding `SCWRYPTS_PLUGIN_ENABLED__KUBECTL=1`.
Use `k` as your new `kubectl` and checkout `k --help` and `k meta --help`.

View File

@ -0,0 +1,31 @@
#####################################################################
command -v compdef >/dev/null 2>&1 || return 0
#####################################################################
_k() {
local C=$(k meta get context)
local NS=$(k meta get namespace)
local KUBEWORDS=(kubectl)
[ $C ] && KUBEWORDS+=(--context $C)
[ $NS ] && KUBEWORDS+=(--namespace $NS)
words="$KUBEWORDS ${words[@]:1}"
_kubectl
}
compdef _k k
#####################################################################
_h() {
local C=$(k meta get context)
local NS=$(k meta get namespace)
local KUBEWORDS=(kubectl)
[ $C ] && KUBEWORDS+=(--context $C)
[ $NS ] && KUBEWORDS+=(--namespace $NS)
words="$KUBEWORDS ${words[@]:1}"
_helm
}
compdef _h h

View File

@ -0,0 +1,195 @@
[[ $SCWRYPTS_KUBECTL_DRIVER_READY -eq 1 ]] && return 0
unalias k h >/dev/null 2>&1
k() { _SCWRYPTS_KUBECTL_DRIVER kubectl $@; }
h() { _SCWRYPTS_KUBECTL_DRIVER helm $@; }
_SCWRYPTS_KUBECTL_DRIVER() {
[ ! $SCWRYPTS_ENV ] && {
ERROR "must set SCWRYPTS_ENV in order to use '$(echo $CLI | head -c1)'"
return 1
}
which REDIS >/dev/null 2>&1 \
|| eval "$(scwrypts -n --name meta/get-static-redis-definition --type zsh --group kubectl)"
local CLI="$1"; shift 1
local SCWRYPTS_GROUP CUSTOM_COMMANDS=(meta)
for SCWRYPTS_GROUP in ${SCWRYPTS_GROUPS[@]}
do
CUSTOM_COMMANDS+=($(eval echo '$SCWRYPTS_KUBECTL_CUSTOM_COMMANDS__'$SCWRYPTS_GROUP))
done
##########################################
local USAGE="
usage: - [...args...] [...options...] -- [...$CLI options...]
args: -
options: -
--subsession [0-9] use indicated subsession (use for script clarity instead of positional arg)
-h, --help display this help dialogue
-v, --verbose output debugging information
description: -
"
local USAGE__usage=$(echo $CLI | head -c1)
local USAGE__args="$(
{
echo "\\033[0;32m[0-9]\\033[0m^if the first argument is a number 0-9, uses or creates a subsession (default 0)"
echo " ^ "
for C in ${CUSTOM_COMMANDS[@]}
do
echo "\\033[0;32m$C\\033[0m^$(SCWRYPTS_KUBECTL_CUSTOM_COMMAND_DESCRIPTION__$C 2>/dev/null)"
done
} | column -ts '^'
)"
local USAGE__options="
-n, --namespace set the namespace
-k, --context set the context
"
local USAGE__description="
Provides 'k' (kubectl) and 'h' (helm) shorthands to the respective
utility. These functions leverage redis and scwrypts environments to
allow quick selection of contexts and namespaces usable across all
active shell instances.
The scwrypts group 'kubectl' has simple selection executables for
kubecontext and namespace, but also provides the library to enable
enriched, use-case-sensitive setup of kubernetes context.
All actions are scoped to the current SCWRYPTS_ENV
currently : \\033[0;33m$SCWRYPTS_ENV\\033[0m
"
##########################################
local USER_ARGS=()
local CUSTOM_COMMAND=0
local VERBOSE=0
local HELP=0
local ERRORS=0
local COMMAND_SWITCH_CASE="@($(echo $CUSTOM_COMMANDS | sed 's/ /|/g'))"
[ ! $SUBSESSION ] && local SUBSESSION=0
[[ $1 =~ ^[0-9]$ ]] && SUBSESSION=$1 && shift 1
while [[ $# -gt 0 ]]
do
case $1 in
meta )
CUSTOM_COMMAND=$1
SCWRYPTS_KUBECTL_CUSTOM_COMMAND_PARSE__$1 ${@:2}
break
;;
-v | --verbose ) VERBOSE=1 ;;
-h | --help ) HELP=1 ;;
--subsession ) SUBSESSION=$2; shift 1 ;;
-n | --namespace )
echo "TODO: set namespace ('$2')" >&2
USER_ARGS+=(--namespace $2); shift 1
;;
-k | --context | --kube-context )
echo "TODO: set context ('$2')" >&2
[[ $CLI =~ ^helm$ ]] && USER_ARGS+=(--kube-context $2)
[[ $CLI =~ ^kubectl$ ]] && USER_ARGS+=(--context $2)
shift 1
;;
-- ) shift 1; break ;;
* )
[ ! $CUSTOM_COMMAND ] && {
for C in ${CUSTOM_COMMANDS[@]}
do
[[ $1 =~ ^$C$ ]] && {
SCWRYPTS_KUBECTL_CUSTOM_COMMAND_PARSE__$1 ${@:2}
break
}
done
}
USER_ARGS+=($1)
;;
esac
shift 1
done
while [[ $# -gt 0 ]]; do USER_ARGS+=($1); shift 1; done
CHECK_ERRORS --no-fail || return 1
[[ $HELP -eq 1 ]] && { USAGE; return 0; }
#####################################################################
local STRICT=$(_SCWRYPTS_KUBECTL_SETTINGS get strict || echo 1)
case $CUSTOM_COMMAND in
0 )
local CLI_ARGS=()
local CONTEXT=$(k meta get context)
local NAMESPACE=$(k meta get namespace)
[ $CONTEXT ] && [[ $CLI =~ ^helm$ ]] && CLI_ARGS+=(--kube-context $CONTEXT)
[ $CONTEXT ] && [[ $CLI =~ ^kubectl$ ]] && CLI_ARGS+=(--context $CONTEXT)
[[ $STRICT -eq 1 ]] && {
[ $CONTEXT ] || ERROR "missing kubectl 'context'"
[ $NAMESPACE ] || ERROR "missing kubectl 'namespace'"
CHECK_ERRORS --no-fail --no-usage || {
ERROR "with 'strict' settings enabled, context and namespace must be set!"
REMINDER "
these values can be set directly with
$(echo $CLI | head -c1) meta set (namespace|context)
"
return 2
}
}
[ $NAMESPACE ] && CLI_ARGS+=(--namespace $NAMESPACE)
[[ $VERBOSE -eq 1 ]] && {
INFO "
context '$CONTEXT'
namespace '$NAMESPACE'
environment '$SCWRYPTS_ENV'
subsession '$SUBSESSION'
"
STATUS "running $CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}"
} || {
[[ $(_SCWRYPTS_KUBECTL_SETTINGS get context) =~ ^show$ ]] && {
INFO "$SCWRYPTS_ENV.$SUBSESSION : $CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}"
}
}
$CLI ${CLI_ARGS[@]} ${USER_ARGS[@]}
;;
* ) SCWRYPTS_KUBECTL_CUSTOM_COMMAND__$CUSTOM_COMMAND ${USER_ARGS[@]} ;;
esac
}
_SCWRYPTS_KUBECTL_SETTINGS() {
# (get setting-name) or (set setting-name setting-value)
REDIS h$1 ${SCWRYPTS_ENV}:kubectl:settings ${@:2} | grep .
}
#####################################################################
source ${0:a:h}/kubectl.completion.zsh
source ${0:a:h}/meta.zsh

View File

@ -0,0 +1,140 @@
SCWRYPTS_KUBECTL_CUSTOM_COMMAND_PARSE__meta() {
USAGE__usage+=" meta"
USAGE__args="
- get output value of meta variable
- set interactively configure value of meta variable
- clear clear current subsession variables
(settings args)
- show output context for every command
- hide (default) hide output context for every command
- strict (default) require context *and* namespace to be set
- loose do not require context and namespace to be set
"
USAGE__options=''
USAGE__description=$(SCWRYPTS_KUBECTL_CUSTOM_COMMAND_DESCRIPTION__meta)
META_SUBARGS="
- namespace
- context
"
while [[ $# -gt 0 ]]
do
case $1 in
-h | --help ) HELP=1 ;;
set )
USAGE__usage+=" set"
USAGE__args="set (namespace|context)"
USAGE__description="interactively set a namespace or context for '$SCWRYPTS_ENV'"
case $2 in
namespace | context ) USER_ARGS+=($1 $2) ;;
-h | --help ) HELP=1 ;;
* ) ERROR "cannot set '$2'" ;;
esac
shift 1
;;
get )
USAGE__usage+=" get"
USAGE__args="get (namespace|context|all)"
USAGE__description="output the current namespace or context for '$SCWRYPTS_ENV'"
case $2 in
namespace | context | all ) USER_ARGS+=($1 $2) ;;
-h | --help ) HELP=1 ;;
* ) ERROR "cannot get '$2'" ;;
esac
shift 1
;;
copy )
USAGE__usage+=" copy"
USAGE__args+="copy [0-9]"
USAGE__description="copy current subsession ($SUBSESSION) to target subsession id"
case $2 in
[0-9] ) USER_ARGS+=($1 $2) ;;
-h | --help ) HELP=1 ;;
* ) ERROR "target session must be a number [0-9]" ;;
esac
shift 1
;;
clear | show | hide | strict | loose ) USER_ARGS+=($1) ;;
* ) ERROR "no meta command '$1'"
esac
shift 1
done
}
SCWRYPTS_KUBECTL_CUSTOM_COMMAND__meta() {
case $1 in
get )
[[ $2 =~ ^all$ ]] && {
local CONTEXT=$(REDIS get --prefix current:context | grep . || echo "\\033[1;31mnone set\\033[0m")
local NAMESPACE=$(REDIS get --prefix current:namespace | grep . || echo "\\033[1;31mnone set\\033[0m")
echo "
environment : $SCWRYPTS_ENV
context : $CONTEXT
namespace : $NAMESPACE
CLI settings
command context : $(_SCWRYPTS_KUBECTL_SETTINGS get context)
strict mode : $([[ $STRICT -eq 1 ]] && echo "on" || echo "\\033[1;31moff\\033[0m")
" | sed 's/^ \+//' >&2
return 0
}
REDIS get --prefix current:$2
;;
set )
scwrypts -n --name set-$2 --type zsh --group kubectl -- --subsession $SUBSESSION >/dev/null \
&& SUCCESS "$2 set"
;;
copy )
: \
&& STATUS "copying $1 to $2" \
&& scwrypts -n --name set-context --type zsh --group kubectl -- --subsession $2 $(k meta get context | grep . || echo 'reset') \
&& scwrypts -n --name set-namespace --type zsh --group kubectl -- --subsession $2 $(k meta get namespace | grep . || echo 'reset') \
&& SUCCESS "subsession $1 copied to $2" \
;
;;
clear )
scwrypts -n --name set-context --type zsh --group kubectl -- --subsession $SUBSESSION reset >/dev/null \
&& SUCCESS "subsession $SUBSESSION reset to default"
;;
show )
_SCWRYPTS_KUBECTL_SETTINGS set context show >/dev/null \
&& SUCCESS "now showing full command context"
;;
hide )
_SCWRYPTS_KUBECTL_SETTINGS set context hide >/dev/null \
&& SUCCESS "now hiding command context"
;;
loose )
_SCWRYPTS_KUBECTL_SETTINGS set strict 0 >/dev/null \
&& WARNING "now running in 'loose' mode"
;;
strict )
_SCWRYPTS_KUBECTL_SETTINGS set strict 1 >/dev/null \
&& SUCCESS "now running in 'strict' mode"
;;
esac
}
SCWRYPTS_KUBECTL_CUSTOM_COMMAND_DESCRIPTION__meta() {
[ $CLI ] || CLI='kubectl'
echo "operations for $CLI session variables and other CLI settings"
}

16
plugins/kubectl/get-context Executable file
View File

@ -0,0 +1,16 @@
#!/bin/zsh
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
use kubectl --group kubectl
CHECK_ENVIRONMENT
#####################################################################
MAIN() {
KUBECTL__GET_CONTEXT
}
#####################################################################
MAIN $@

16
plugins/kubectl/get-namespace Executable file
View File

@ -0,0 +1,16 @@
#!/bin/zsh
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
use kubectl --group kubectl
CHECK_ENVIRONMENT
#####################################################################
MAIN() {
KUBECTL__GET_NAMESPACE
}
#####################################################################
MAIN $@

View File

@ -0,0 +1,11 @@
SCWRYPTS_GROUPS+=(kubectl)
export SCWRYPTS_TYPE__kubectl=zsh
export SCWRYPTS_ROOT__kubectl="$SCWRYPTS_ROOT__scwrypts/plugins/kubectl"
export SCWRYPTS_COLOR__kubectl='\033[0;31m'
SCWRYPTS_STATIC_CONFIG__kubectl+=(
"$SCWRYPTS_ROOT__kubectl/.config/static/redis.zsh"
)
source "$SCWRYPTS_ROOT__kubectl/driver/kubectl.driver.zsh"

View File

@ -0,0 +1,89 @@
#####################################################################
DEPENDENCIES+=(
kubectl
)
REQUIRED_ENV+=()
use redis --group kubectl
#####################################################################
KUBECTL() {
local NAMESPACE=$(REDIS get --prefix "current:namespace")
local CONTEXT=$(KUBECTL__GET_CONTEXT)
local KUBECTL_ARGS=()
[ $NAMESPACE ] && KUBECTL_ARGS+=(--namespace $NAMESPACE)
[ $CONTEXT ] && KUBECTL_ARGS+=(--context $CONTEXT)
kubectl ${KUBECTL_ARGS[@]} $@
}
#####################################################################
KUBECTL__GET_CONTEXT() { REDIS get --prefix "current:context"; }
KUBECTL__SET_CONTEXT() {
local CONTEXT=$1
[ ! $CONTEXT ] && return 1
[[ $CONTEXT =~ reset ]] && {
: \
&& REDIS del --prefix "current:context" \
&& KUBECTL__SET_NAMESPACE reset \
;
return $?
}
: \
&& REDIS set --prefix "current:context" "$CONTEXT" \
&& KUBECTL__SET_NAMESPACE reset \
;
}
KUBECTL__SELECT_CONTEXT() {
KUBECTL__LIST_CONTEXTS | FZF 'select a context'
}
KUBECTL__LIST_CONTEXTS() {
echo reset
local ALL_CONTEXTS=$(KUBECTL config get-contexts -o name | sort)
echo $ALL_CONTEXTS | grep -v '^arn:aws:eks'
[[ $AWS_ACCOUNT ]] && {
echo $ALL_CONTEXTS | grep "^arn:aws:eks:.*:$AWS_ACCOUNT"
true
} || {
echo $ALL_CONTEXTS | grep '^arn:aws:eks'
}
}
#####################################################################
KUBECTL__GET_NAMESPACE() { REDIS get --prefix "current:namespace"; }
KUBECTL__SET_NAMESPACE() {
local NAMESPACE=$1
[ ! $NAMESPACE ] && return 1
[[ $NAMESPACE =~ reset ]] && {
REDIS del --prefix "current:namespace"
return $?
}
REDIS set --prefix "current:namespace" "$NAMESPACE"
}
KUBECTL__SELECT_NAMESPACE() {
KUBECTL__LIST_NAMESPACES | FZF 'select a namespace'
}
KUBECTL__LIST_NAMESPACES() {
echo reset
echo default
KUBECTL get namespaces -o name | sed 's/^namespace\///' | sort
}

View File

@ -0,0 +1,97 @@
#####################################################################
DEPENDENCIES+=(
redis-cli
docker
)
# TODO; allow custom redis configuration
export SCWRYPTS_KUBECTL_REDIS=managed
REQUIRED_ENV+=(
SCWRYPTS_KUBECTL_REDIS
)
#####################################################################
REDIS() {
[ ! $USAGE ] && local USAGE="
usage: [...options...]
options:
--subsession [0-9] use a particular subsession
-p, --prefix apply dynamic prefix to the next command line argument
--get-prefix output key prefix for current session+subsession
--get-static-definition output the static ZSH function definition for REDIS
additional arguments and options are passed through to 'redis-cli'
"
local REDIS_ARGS=() USER_ARGS=()
[ $SUBSESSION ] || local SUBSESSION=0
local REDIS_PREFIX=$(eval echo '$SCWRYPTS_KUBECTL_REDIS_KEY_PREFIX__'$SCWRYPTS_KUBECTL_REDIS)
[ $REDIS_PREFIX ] && REDIS_PREFIX+=':'
while [[ $# -gt 0 ]]
do
case $1 in
-p | --prefix ) USER_ARGS+=("${REDIS_PREFIX}${SCWRYPTS_ENV}:${SUBSESSION}:$2"); shift 1 ;;
--subsession ) SUBSESSION=$2; shift 1 ;;
--get-prefix ) echo $REDIS_PREFIX; return 0 ;;
--get-static-definition ) ECHO_STATIC_DEFINITION=1 ;;
* ) USER_ARGS+=($1) ;;
esac
shift 1
done
local REDIS_HOST=$(eval echo '$SCWRYPTS_KUBECTL_REDIS_HOST__'$SCWRYPTS_KUBECTL_REDIS)
local REDIS_PORT=$(eval echo '$SCWRYPTS_KUBECTL_REDIS_PORT__'$SCWRYPTS_KUBECTL_REDIS)
local REDIS_AUTH=$(eval echo '$SCWRYPTS_KUBECTL_REDIS_AUTH__'$SCWRYPTS_KUBECTL_REDIS)
[ $REDIS_HOST ] && REDIS_ARGS+=(-h $REDIS_HOST)
[ $REDIS_PORT ] && REDIS_ARGS+=(-p $REDIS_PORT)
[ $REDIS_AUTH ] && REDIS_ARGS+=(-a $REDIS_AUTH)
REDIS_ARGS+=(--raw)
[[ $ECHO_STATIC_DEFINITION -eq 1 ]] && {
echo "REDIS() {\
local USER_ARGS=(); \
[ ! \$SUBSESSION ] && local SUBSESSION=0 ;\
while [[ \$# -gt 0 ]]; \
do \
case \$1 in
-p | --prefix ) USER_ARGS+=(\"${REDIS_PREFIX}\${SCWRYPTS_ENV}:\${SUBSESSION}:\$2\"); shift 1 ;; \
* ) USER_ARGS+=(\$1) ;; \
esac; \
shift 1; \
done; \
redis-cli ${REDIS_ARGS[@]} \${USER_ARGS[@]}; \
}" | sed 's/\s\+/ /g'
return 0
}
redis-cli ${REDIS_ARGS[@]} ${USER_ARGS[@]}
}
REDIS ping | grep -qi pong || {
RPID=$(docker ps -a | grep scwrypts-kubectl-redis | awk '{print $1;}')
[ $RPID ] && STATUS 'refreshing redis instance' && docker rm -f $RPID
unset RPID
docker run \
--detach \
--name scwrypts-kubectl-redis \
--publish $SCWRYPTS_KUBECTL_REDIS_PORT__managed:6379 \
redis >/dev/null 2>&1
STATUS 'awaiting redis connection'
until REDIS ping 2>/dev/null | grep -qi pong; do sleep 0.5; done
}

View File

@ -0,0 +1,11 @@
#!/bin/zsh
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
use redis --group kubectl
CHECK_ENVIRONMENT
#####################################################################
echo $(REDIS --get-static-definition)

46
plugins/kubectl/set-context Executable file
View File

@ -0,0 +1,46 @@
#!/bin/zsh
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
use kubectl --group kubectl
CHECK_ENVIRONMENT
#####################################################################
MAIN() {
local USAGE="
usage: [context] [...options...]
args:
context (optional) the full name of the kubeconfig context to set
options:
--subsession REDIS subsession (default 0)
"
local CONTEXT
local SUBSESSION=0
while [[ $# -gt 0 ]]
do
case $1 in
--subsession ) SUBSESSION=$2; shift 1 ;;
* )
[ $CONTEXT ] && ERROR "unexpected argument '$2'"
CONTEXT=$1
;;
esac
shift 1
done
[ $CONTEXT ] || CONTEXT=$(KUBECTL__SELECT_CONTEXT)
[ $CONTEXT ] || ERROR 'must provide or select a valid kube context'
CHECK_ERRORS
KUBECTL__SET_CONTEXT $CONTEXT
}
#####################################################################
MAIN $@

46
plugins/kubectl/set-namespace Executable file
View File

@ -0,0 +1,46 @@
#!/bin/zsh
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
use kubectl --group kubectl
CHECK_ENVIRONMENT
#####################################################################
MAIN() {
local USAGE="
usage: [namespace] [...options...]
args:
namespace (optional) the full name of the namespace context to set
options:
--subsession REDIS subsession (default 0)
"
local NAMESPACE
local SUBSESSION=0
while [[ $# -gt 0 ]]
do
case $1 in
--subsession ) SUBSESSION=$2; shift 1 ;;
* )
[ $NAMESPACE ] && ERROR "unexpected argument '$2'"
NAMESPACE=$1
;;
esac
shift 1
done
[ $NAMESPACE ] || NAMESPACE=$(KUBECTL__SELECT_NAMESPACE)
[ $NAMESPACE ] || ERROR 'must provide or select a valid namespace'
CHECK_ERRORS
KUBECTL__SET_NAMESPACE $NAMESPACE
}
#####################################################################
MAIN $@

23
run
View File

@ -85,6 +85,7 @@ __RUN() {
--update ) --update )
cd "$SCWRYPTS__ROOT__scwrypts" cd "$SCWRYPTS__ROOT__scwrypts"
git fetch --quiet origin main git fetch --quiet origin main
git fetch --quiet origin main --tags
local SYNC_STATUS=$? local SYNC_STATUS=$?
git diff --exit-code origin/main -- . >&2 git diff --exit-code origin/main -- . >&2
@ -208,22 +209,34 @@ __RUN() {
########################################## ##########################################
local ENV_REQUIRED=$(__CHECK_ENV_REQUIRED && echo 1 || echo 0) local ENV_REQUIRED=$(__CHECK_ENV_REQUIRED && echo 1 || echo 0)
local REQUIRED_ENVIRONMENT_REGEX=$(eval echo '$SCWRYPTS_REQUIRED_ENVIRONMENT_REGEX__'$SCWRYPT_GROUP)
[ $REQUIRED_ENVIRONMENT_REGEX ] && {
[[ $ENV_NAME =~ $REQUIRED_ENVIRONMENT_REGEX ]] \
|| FAIL 5 "group '$SCWRYPT_GROUP' requires current environment to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)"
}
[[ $ENV_REQUIRED -eq 1 ]] && { [[ $ENV_REQUIRED -eq 1 ]] && {
[ ! $ENV_NAME ] && ENV_NAME=$(SCWRYPTS__SELECT_ENV) [ ! $ENV_NAME ] && ENV_NAME=$(SCWRYPTS__SELECT_ENV)
for GROUP in ${SCWRYPTS_GROUPS[@]} for GROUP in ${SCWRYPTS_GROUPS[@]}
do do
local ENV_FILE=$(SCWRYPTS__GET_ENV_FILE "$ENV_NAME" "$GROUP") local ENV_FILE=$(SCWRYPTS__GET_ENV_FILE "$ENV_NAME" "$GROUP")
source "$ENV_FILE" || FAIL 5 "missing or invalid environment '$GROUP/$ENV_NAME'" source "$ENV_FILE" || FAIL 5 "missing or invalid environment '$GROUP/$ENV_NAME'"
for f in $(eval 'echo $SCWRYPTS_STATIC_CONFIG__'$GROUP)
do
source "$f" || FAIL 5 "invalid static config '$f'"
done
done done
export ENV_NAME export ENV_NAME
} }
for f in $(eval 'echo $SCWRYPTS_STATIC_CONFIG__'$SCWRYPT_GROUP) [ $REQUIRED_ENVIRONMENT_REGEX ] && {
do [[ $ENV_NAME =~ $REQUIRED_ENVIRONMENT_REGEX ]] \
source "$f" || FAIL 5 "invalid static config '$f'" || FAIL 5 "group '$SCWRYPT_GROUP' requires current environment to match '$REQUIRED_ENVIRONMENT_REGEX' (currently $ENV_NAME)"
done }
########################################## ##########################################
@ -263,7 +276,7 @@ __RUN() {
{ {
[ $HEADER ] && echo $HEADER [ $HEADER ] && echo $HEADER
echo '\033[1;33m--- BEGIN OUTPUT -------------------------\033[0m' echo '\033[1;33m--- BEGIN OUTPUT -------------------------\033[0m'
eval "$RUN_STRING $(printf "%q " "$@")" (eval "$RUN_STRING $(printf "%q " "$@")")
EXIT_CODE=$? EXIT_CODE=$?
echo '\033[1;33m--- END OUTPUT ---------------------------\033[0m' echo '\033[1;33m--- END OUTPUT ---------------------------\033[0m'

View File

@ -12,13 +12,7 @@ CREATE_BACKUP() {
local DB_HOST DB_PORT DB_NAME DB_USER DB_PASS local DB_HOST DB_PORT DB_NAME DB_USER DB_PASS
RDS__GET_DATABASE_CREDENTIALS $@ || return 1 RDS__GET_DATABASE_CREDENTIALS $@ || return 1
PG_DUMP \ PG_DUMP
--host $DB_HOST \
--port $DB_PORT \
--name $DB_NAME \
--user $DB_USER \
--pass $DB_PASS \
;
} }
##################################################################### #####################################################################

View File

@ -12,13 +12,7 @@ RDS_INTERACTIVE_LOGIN() {
local DB_HOST DB_PORT DB_NAME DB_USER DB_PASS local DB_HOST DB_PORT DB_NAME DB_USER DB_PASS
RDS__GET_DATABASE_CREDENTIALS $@ || return 1 RDS__GET_DATABASE_CREDENTIALS $@ || return 1
POSTGRES__LOGIN_INTERACTIVE \ POSTGRES__LOGIN_INTERACTIVE
--host $DB_HOST \
--port $DB_PORT \
--name $DB_NAME \
--user $DB_USER \
--pass $DB_PASS \
;
} }

View File

@ -12,13 +12,7 @@ LOAD_BACKUP() {
local DB_HOST DB_PORT DB_NAME DB_USER DB_PASS local DB_HOST DB_PORT DB_NAME DB_USER DB_PASS
RDS__GET_DATABASE_CREDENTIALS $@ || return 1 RDS__GET_DATABASE_CREDENTIALS $@ || return 1
PG_RESTORE \ PG_RESTORE
--host $DB_HOST \
--port $DB_PORT \
--name $DB_NAME \
--user $DB_USER \
--pass $DB_PASS \
;
} }

17
zsh/helm/get-template Executable file
View File

@ -0,0 +1,17 @@
#!/bin/zsh
DEPENDENCIES+=()
REQUIRED_ENV+=()
use helm
use scwrypts
CHECK_ENVIRONMENT
#####################################################################
MAIN() {
unset USAGE
HELM__TEMPLATE__GET $@
}
#####################################################################
MAIN $@

17
zsh/helm/update-dependencies Executable file
View File

@ -0,0 +1,17 @@
#!/bin/zsh
DEPENDENCIES+=()
REQUIRED_ENV+=()
use helm
use scwrypts
CHECK_ENVIRONMENT
#####################################################################
MAIN() {
unset USAGE
HELM__DEPENDENCY__UPDATE $@
}
#####################################################################
MAIN $@

View File

@ -4,18 +4,20 @@ DEPENDENCIES+=(
aws aws
) )
REQUIRED_ENV+=( REQUIRED_ENV+=()
AWS_ACCOUNT
AWS_PROFILE
AWS_REGION
)
##################################################################### #####################################################################
AWS() { AWS() {
aws \ local ARGS=()
--profile $AWS_PROFILE \
--region $AWS_REGION \ ARGS+=(--output json)
--output json \
$@ [ ! $CI ] && {
REQUIRED_ENV=(AWS_REGION AWS_ACCOUNT AWS_PROFILE) CHECK_ENVIRONMENT || return 1
ARGS+=(--profile $AWS_PROFILE)
ARGS+=(--region $AWS_REGION)
}
aws ${ARGS[@]} $@
} }

View File

@ -4,16 +4,15 @@ DEPENDENCIES+=(
docker docker
) )
REQUIRED_ENV+=( REQUIRED_ENV+=()
AWS_ACCOUNT
AWS_REGION
)
use cloud/aws/cli use cloud/aws/cli
##################################################################### #####################################################################
ECR_LOGIN() { ECR_LOGIN() {
REQUIRED_ENV=(AWS_REGION AWS_ACCOUNT) CHECK_ENVIRONMENT || return 1
STATUS "performing AWS ECR docker login" STATUS "performing AWS ECR docker login"
AWS ecr get-login-password \ AWS ecr get-login-password \
| docker login \ | docker login \

View File

@ -86,14 +86,9 @@ RDS__GET_DATABASE_CREDENTIALS() {
user-input ) _RDS_AUTH__userinput ;; user-input ) _RDS_AUTH__userinput ;;
esac esac
STATUS [[ $PRINT_PASSWORD -eq 1 ]] && INFO "password : $DB_PASS"
STATUS "host : $DB_HOST"
STATUS "type : $DB_TYPE" return 0
STATUS "port : $DB_PORT"
STATUS "database : $DB_NAME"
STATUS "username : $DB_USER"
[[ $PRINT_PASSWORD -eq 1 ]] && STATUS "password : $DB_PASS"
STATUS
} }
_RDS_AUTH__iam() { _RDS_AUTH__iam() {
@ -108,10 +103,10 @@ _RDS_AUTH__iam() {
_RDS_AUTH__secretsmanager() { _RDS_AUTH__secretsmanager() {
local CREDENTIALS=$(_RDS__GET_SECRETSMANAGER_CREDENTIALS) local CREDENTIALS=$(_RDS__GET_SECRETSMANAGER_CREDENTIALS)
echo $CREDENTIALS | jq -e '.pass' >/dev/null 2>&1 \ echo $CREDENTIALS | jq -e '.pass' >/dev/null 2>&1 \
&& DB_PASS="'$(echo $CREDENTIALS | jq -r '.pass' | sed "s/'/'\"'\"'/g")'" && DB_PASS="$(echo $CREDENTIALS | jq -r '.pass')"
echo $CREDENTIALS | jq -e '.password' >/dev/null 2>&1 \ echo $CREDENTIALS | jq -e '.password' >/dev/null 2>&1 \
&& DB_PASS="'$(echo $CREDENTIALS | jq -r '.password' | sed "s/'/'\"'\"'/g")'" && DB_PASS="$(echo $CREDENTIALS | jq -r '.password')"
echo $CREDENTIALS | jq -e '.user' >/dev/null 2>&1 \ echo $CREDENTIALS | jq -e '.user' >/dev/null 2>&1 \
&& DB_USER=$(echo $CREDENTIALS | jq -r '.user') && DB_USER=$(echo $CREDENTIALS | jq -r '.user')

Binary file not shown.

View File

@ -39,4 +39,21 @@ source "$SCWRYPTS_ROOT/zsh/lib/config.group.zsh" \
|| FAIL 69 'failed to set up scwrypts group; aborting' || FAIL 69 'failed to set up scwrypts group; aborting'
##################################################################### #####################################################################
__SCWRYPT=1 # arbitrary; indicates currently inside a scwrypt
for plugin in $(ls $SCWRYPTS_ROOT__scwrypts/plugins)
do
[[ $(eval 'echo $SCWRYPTS_PLUGIN_ENABLED__'$plugin) -eq 1 ]] && {
source "$SCWRYPTS_ROOT/plugins/$plugin/$plugin.scwrypts.zsh"
}
done
#####################################################################
for GROUP_LOADER in $(env | sed -n 's/^SCWRYPTS_GROUP_LOADER__[a-z_]\+=//p')
do
[ -f "$GROUP_LOADER" ] && source "$GROUP_LOADER"
done
#####################################################################
[ $NO_EXPORT_CONFIG ] || __SCWRYPT=1 # arbitrary; indicates currently inside a scwrypt
true

View File

@ -4,7 +4,6 @@ DEPENDENCIES+=(
pg_dump pg_dump
pg_restore pg_restore
psql psql
pgcli
) )
REQUIRED_ENV+=() REQUIRED_ENV+=()
@ -12,22 +11,22 @@ REQUIRED_ENV+=()
##################################################################### #####################################################################
PSQL() { PSQL() {
[[ ${#ARGS[@]} -eq 0 ]] && POSTGRES__SET_LOGIN_ARGS $@ POSTGRES__SET_LOGIN_ARGS $@
eval PGPASSWORD=$(printf '%q ' "$DB_PASS") psql ${PSQL_ARGS[@]}
eval PGPASSWORD=$_PASS psql ${_ARGS[@]}
} }
##################################################################### #####################################################################
PG_DUMP() { PG_DUMP() {
local _HOST _NAME _PORT _USER _FILE local DATA_DIR
local DATA_DIR _PASS _ARGS=()
POSTGRES__SET_LOGIN_ARGS --verbose $@ POSTGRES__SET_LOGIN_ARGS --verbose $@
local OUTPUT_FILE="$DATA_DIR/backup.$(date '+%Y-%m-%d.%H-%M')" local OUTPUT_FILE="$DATA_DIR/backup.$(date '+%Y-%m-%d.%H-%M')"
STATUS " STATUS "
making backup of : $_USER@$_HOST:$_PORT/$_NAME making backup of : $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME
(compressed) : '$OUTPUT_FILE.dump' (compressed) : '$OUTPUT_FILE.dump'
(safe-raw) : '$OUTPUT_FILE.sql' (safe-raw) : '$OUTPUT_FILE.sql'
@ -36,23 +35,33 @@ PG_DUMP() {
: \ : \
&& STATUS "creating compressed backup..." \ && STATUS "creating compressed backup..." \
&& eval PGPASSWORD=$_PASS pg_dump ${_ARGS[@]} --format custom --file "$OUTPUT_FILE.dump" \ && eval PGPASSWORD=$(printf '%q ' "$DB_PASS") psql ${PSQL_ARGS[@]} \
--format custom \
--file "$OUTPUT_FILE.dump" \
--verbose \
&& SUCCESS "completed compressed backup" \ && SUCCESS "completed compressed backup" \
&& STATUS "creating raw backup..." \ && STATUS "creating raw backup..." \
&& eval PGPASSWORD=$_PASS pg_dump ${_ARGS[@]} > "$OUTPUT_FILE.raw.sql" \ && pg_restore -f "$OUTPUT_FILE.raw.sql" "$OUTPUT_FILE.dump" \
&& SUCCESS "completed raw backup" \ && SUCCESS "completed raw backup" \
&& STATUS "creating single-transaction raw backup..." \ && STATUS "creating single-transaction raw backup..." \
&& { echo "BEGIN;"; cat "$OUTPUT_FILE.raw.sql"; echo "END;" } > "$OUTPUT_FILE.sql" \ && { echo "BEGIN;\n"; cat "$OUTPUT_FILE.raw.sql"; echo "\nEND;" } > "$OUTPUT_FILE.sql" \
&& SUCCESS "completed single-transaction raw backup" \ && SUCCESS "completed single-transaction raw backup" \
|| { ERROR "error creating backup for '$_HOST/$_NAME' (see above)"; return 1; } || { ERROR "error creating backup for '$DB_HOST/$DB_NAME' (see above)"; return 1; }
SUCCESS "
completed backup : $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME
(compressed) : '$OUTPUT_FILE.dump'
(safe-raw) : '$OUTPUT_FILE.sql'
(raw) : '$OUTPUT_FILE.raw.sql'
"
} }
##################################################################### #####################################################################
PG_RESTORE() { PG_RESTORE() {
local _HOST _NAME _PORT _USER local _ARGS=()
local _PASS _ARGS=() local FILE
local _FILE
POSTGRES__SET_LOGIN_ARGS $@ POSTGRES__SET_LOGIN_ARGS $@
local INPUT_FILE=$(find "$DATA_DIR"/backup.* -type f | FZF 'select database file to restore') local INPUT_FILE=$(find "$DATA_DIR"/backup.* -type f | FZF 'select database file to restore')
@ -72,7 +81,7 @@ PG_RESTORE() {
[[ $INPUT_FILE =~ \\.dump$ ]] && RAW=0 [[ $INPUT_FILE =~ \\.dump$ ]] && RAW=0
STATUS " STATUS "
loading backup for : $_USER@$_HOST:$_PORT/$_NAME loading backup for : $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME
file : '$INPUT_FILE' file : '$INPUT_FILE'
" "
@ -92,7 +101,7 @@ PG_RESTORE() {
} }
[[ $RAW -eq 0 ]] && { [[ $RAW -eq 0 ]] && {
PGPASSWORD="$_PASS" pg_restore ${_ARGS[@]} \ eval PGPASSWORD=$(printf '%q ' "$DB_PASS") pg_restore ${PSQL_ARGS[@]} \
--verbose \ --verbose \
--format custom \ --format custom \
--single-transaction \ --single-transaction \
@ -101,8 +110,8 @@ PG_RESTORE() {
} }
[[ $EXIT_CODE -eq 0 ]] \ [[ $EXIT_CODE -eq 0 ]] \
&& SUCCESS "finished restoring backup for '$_HOST/$_NAME'" \ && SUCCESS "finished restoring backup for '$DB_HOST/$DB_NAME'" \
|| ERROR "error restoring backup for '$_HOST/$_NAME' (see above)" \ || ERROR "error restoring backup for '$DB_HOST/$DB_NAME' (see above)" \
; ;
return $EXIT_CODE return $EXIT_CODE
@ -111,48 +120,70 @@ PG_RESTORE() {
##################################################################### #####################################################################
POSTGRES__LOGIN_INTERACTIVE() { POSTGRES__LOGIN_INTERACTIVE() {
local _PASS _ARGS=() DEPENDENCIES=(pgcli) CHECK_ENVIRONMENT --optional \
&& COMMAND=pgcli || COMMAND=psql
[[ $COMMAND =~ psql ]] && WARNING "using 'psql' instead"
POSTGRES__SET_LOGIN_ARGS $@ POSTGRES__SET_LOGIN_ARGS $@
STATUS "performing login : $_USER@$_HOST:$_PORT/$_NAME" STATUS "
STATUS "working directory : $DATA_DIR" performing login : $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME
working directory : $DATA_DIR
"
eval PGPASSWORD=$_PASS pgcli ${_ARGS[@]} eval PGPASSWORD=$(printf '%q ' "$DB_PASS") $COMMAND ${PSQL_ARGS[@]}
} }
##################################################################### #####################################################################
POSTGRES__SET_LOGIN_ARGS() { POSTGRES__SET_LOGIN_ARGS() {
# allow for manual override with PSQL_ARGS
[[ ${#PSQL_ARGS[@]} -gt 0 ]] && return 0
local DATA_DIR_PREFIX
while [[ $# -gt 0 ]] while [[ $# -gt 0 ]]
do do
case $1 in case $1 in
--host ) _ARGS+=(-h $2); _HOST="$2"; shift 1 ;; -h | --host ) DB_HOST="$2"; shift 1 ;;
--name ) _ARGS+=(-d $2); _NAME="$2"; shift 1 ;; -p | --port ) DB_PORT="$2"; shift 1 ;;
--port ) _ARGS+=(-p $2); _PORT="$2"; shift 1 ;; -d | --name ) DB_NAME="$2"; shift 1 ;;
--user ) _ARGS+=(-U $2); _USER="$2"; shift 1 ;; -U | --user ) DB_USER="$2"; shift 1 ;;
-P | --pass ) DB_PASS="$2"; shift 1 ;;
--pass ) _PASS="$2"; shift 1 ;; --file ) PSQL_FILE="$2"; shift 1 ;;
--file ) _FILE="$2"; shift 1 ;; --data-dir-prefix ) DATA_DIR_PREFIX="$2"; shift 1 ;;
* ) _ARGS+=($1) ;; * ) PSQL_ARGS+=($1) ;;
esac esac
shift 1 shift 1
done done
[ $_FILE ] && [ ! -f "$_FILE" ] && { [ $PSQL_FILE ] && [ ! -f "$PSQL_FILE" ] \
ERROR "no such file '$_FILE'" && ERROR "no such file available:\n'$PSQL_FILE'"
exit 1
}
[ $_HOST ] && [ $_NAME ] \ CHECK_ERRORS
&& DATA_DIR="$SCWRYPTS_DATA_PATH/db/$_HOST/$_NAME" \
##########################################
[ $DATA_DIR_PREFIX ] && {
DATA_DIR="$SCWRYPTS_DATA_PATH/$DATA_DIR_PREFIX"
} || {
[ $DB_HOST ] && [ $DB_NAME ] \
&& DATA_DIR="$SCWRYPTS_DATA_PATH/db/$DB_HOST/$DB_NAME" \
|| DATA_DIR="$EXECUTION_DIR/temp-db" \ || DATA_DIR="$EXECUTION_DIR/temp-db" \
; ;
}
[ ! -d "$DATA_DIR" ] && mkdir -p "$DATA_DIR" mkdir -p "$DATA_DIR"
cd "$DATA_DIR" cd "$DATA_DIR"
return 0 [ $DB_HOST ] || DB_HOST=127.0.0.1
} [ $DB_PORT ] || DB_PORT=5432
[ $DB_NAME ] || DB_NAME=postgres
[ $DB_USER ] || DB_USER=postgres
PSQL_ARGS+=(-h $DB_HOST -p $DB_PORT -d $DB_NAME -U $DB_USER)
}

View File

@ -0,0 +1,42 @@
#####################################################################
DEPENDENCIES+=(helm kubeval)
REQUIRED_ENV+=()
use helm/validate
#####################################################################
HELM__DEPENDENCY__UPDATE() {
[ ! $USAGE ] && local USAGE="
usage: [...options...]
options
-t, --template-filename path to a template/*.yaml file of a helm chart
Auto-detect chart and build dependencies for any file within a helm chart.
"
local TEMPLATE_FILENAME CHART_ROOT VALUES_FILES=()
local COLORIZE=0 RAW=0 DEBUG=0
while [[ $# -gt 0 ]]
do
case $1 in
-t | --template-filename ) TEMPLATE_FILENAME="$(SCWRYPTS__GET_REALPATH "$2")"; shift 1 ;;
* ) ERROR "unexpected argument '$1'" ;;
esac
shift 1
done
HELM__VALIDATE
CHECK_ERRORS || return 1
##########################################
STATUS "updating helm dependencies for '$CHART_ROOT'" \
&& cd $CHART_ROOT \
&& helm dependency update \
&& SUCCESS "helm chart dependencies updated" \
|| { ERROR "unable to update helm chart dependencies (see above)"; return 1; }
}

View File

@ -0,0 +1,9 @@
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
use helm/dependency
use helm/template
#####################################################################

View File

@ -0,0 +1,104 @@
#####################################################################
DEPENDENCIES+=(helm kubeval)
REQUIRED_ENV+=()
use helm/validate
#####################################################################
HELM__TEMPLATE__GET() {
[ ! $USAGE ] && local USAGE="
usage: [...options...] (--) [...helm args...]
options
-t, --template-filename path to a template/*.yaml file of a helm chart
--colorize use 'bat' to colorize output
--raw remove scwrypts-added fluff and only output helm template details
Smart helm-template generator which auto-detects the chart
and sample values for testing and developing helm charts.
"
local HELM_ARGS=()
local TEMPLATE_FILENAME TEMPLATE_NAME CHART_ROOT CHART_NAME VALUES_FILES=()
local COLORIZE=0 RAW=0 DEBUG=0
while [[ $# -gt 0 ]]
do
case $1 in
-t | --template-filename ) TEMPLATE_FILENAME="$(SCWRYPTS__GET_REALPATH "$2")"; shift 1 ;;
--colorize )
DEPENDENCIES=(bat) CHECK_ENVIRONMENT || return 1
COLORIZE=1
;;
--raw ) RAW=1 ;;
-- ) shift 1; break ;;
* ) HELM_ARGS+=($1) ;;
esac
shift 1
done
while [[ $# -gt 0 ]]; do HELM_ARGS+=($1); shift 1; done
HELM__VALIDATE
CHECK_ERRORS || return 1
##########################################
local EXIT_CODE=0
local TEMPLATE_OUTPUT DEBUG_OUTPUT
[ $USE_CHART_ROOT ] && [[ $USE_CHART_ROOT -eq 1 ]] && {
CAPTURE TEMPLATE_OUTPUT DEBUG_OUTPUT helm template "$CHART_ROOT" ${HELM_ARGS[@]} --debug
true
} || {
CAPTURE TEMPLATE_OUTPUT DEBUG_OUTPUT helm template "$CHART_ROOT" ${HELM_ARGS[@]} --debug --show-only "$(echo $TEMPLATE_FILENAME | sed "s|^$CHART_ROOT/||")"
}
[ ! $TEMPLATE_OUTPUT ] && EXIT_CODE=1
[[ $RAW -eq 1 ]] && {
[ $USE_CHART_ROOT ] && [[ $USE_CHART_ROOT -eq 1 ]] || HELM_ARGS+=(--show-only $(echo $TEMPLATE_FILENAME | sed "s|^$CHART_ROOT/||"))
[[ $COLORIZE -eq 1 ]] \
&& helm template "$CHART_ROOT" ${HELM_ARGS[@]} 2>&1 | bat --language yaml --color always \
|| helm template "$CHART_ROOT" ${HELM_ARGS[@]} | grep -v '^# Source:.*$' \
;
return $EXIT_CODE
}
[ $TEMPLATE_OUTPUT ] && {
KUBEVAL_RAW=$(echo $TEMPLATE_OUTPUT | kubeval --schema-location https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master)
true
} || {
TEMPLATE_OUTPUT="---\nerror: chart or '$(basename $(dirname $TEMPLATE_FILENAME))/$(basename $TEMPLATE_FILENAME)' invalid"
KUBEVAL_RAW="no template output; kubeval skipped"
[ $USE_CHART_ROOT ] && [[ $USE_CHART_ROOT -eq 1 ]] || {
DEBUG_OUTPUT="$(helm template "$CHART_ROOT" ${HELM_ARGS[@]} --debug 2>&1 >/dev/null)"
}
}
TEMPLATE_OUTPUT="$TEMPLATE_OUTPUT
---
debug: |
$(echo $DEBUG_OUTPUT | sed 's/^/ /g')
kubeval: |
$(echo $KUBEVAL_RAW | sed 's/^/ /g')
lint: |
$(helm lint $CHART_ROOT ${HELM_ARGS[@]} 2>&1 | sed 's/^/ /g')
"
[[ $COLORIZE -eq 1 ]] && {
echo $TEMPLATE_OUTPUT | bat --language yaml --color always
} || {
echo $TEMPLATE_OUTPUT
}
return $EXIT_CODE
}

View File

@ -0,0 +1,88 @@
#####################################################################
DEPENDENCIES+=(yq)
REQUIRED_ENV+=()
#####################################################################
HELM__VALIDATE() {
[ ! $USAGE ] && USAGE="
usage:
environment
TEMPLATE_FILENAME target template filename
Smart helm-detection / validator which determines the helm
chart root and other details given a particular filename.
"
[ $TEMPLATE_FILENAME ] && [ -f "$TEMPLATE_FILENAME" ] || {
ERROR 'must provide a template filename'
return 1
}
_HELM__GET_CHART_ROOT
[ $CHART_ROOT ] && [ -d "$CHART_ROOT" ] || {
ERROR 'unable to determine helm root; is this a helm template file?'
return 1
}
CHART_NAME=$(yq -r .name "$CHART_ROOT/Chart.yaml")
[[ $TEMPLATE_FILENAME =~ values*.yaml$ ]] && {
HELM_ARGS+=(--values $TEMPLATE_FILENAME)
USE_CHART_ROOT=1
}
[[ $(dirname $TEMPLATE_FILENAME) =~ ^$CHART_ROOT$ ]] \
&& USE_CHART_ROOT=1
_HELM__GET_DEFAULT_VALUES_ARGS
return 0
}
_HELM__GET_CHART_ROOT() {
local SEARCH_DIR=$(dirname "$TEMPLATE_FILENAME")
while [ ! $CHART_ROOT ] && [[ ! $SEARCH_DIR =~ ^/$ ]]
do
[ -f "$SEARCH_DIR/Chart.yaml" ] && CHART_ROOT="$SEARCH_DIR" && return 0
SEARCH_DIR="$(dirname "$SEARCH_DIR")"
done
return 1
}
_HELM__GET_DEFAULT_VALUES_ARGS() {
for LOCAL_REPOSITORY in $(\
cat "$CHART_ROOT/Chart.yaml" \
| yq -r '.dependencies[] | .repository' \
| grep '^file://' \
| sed 's|file://||' \
)
do
[[ $LOCAL_REPOSITORY =~ ^[/~] ]] \
&& LOCAL_REPOSITORY_ROOT="$LOCAL_REPOSITORY" \
|| LOCAL_REPOSITORY_ROOT="$CHART_ROOT/$LOCAL_REPOSITORY" \
;
for F in \
"$LOCAL_REPOSITORY_ROOT/values.yaml" \
"$LOCAL_REPOSITORY_ROOT/values.test.yaml" \
"$LOCAL_REPOSITORY_ROOT/tests/default.yaml" \
;
do
[ -f "$F" ] && HELM_ARGS+=(--values "$F")
done
done
for F in \
"$CHART_ROOT/values.yaml" \
"$CHART_ROOT/values.test.yaml" \
"$CHART_ROOT/tests/default.yaml" \
;
do
[ -f "$F" ] && HELM_ARGS+=(--values "$F")
done
}

View File

@ -10,7 +10,7 @@ REQUIRED_ENV+=()
##################################################################### #####################################################################
LATEX__GET_MAIN_FILENAME() { LATEX__GET_MAIN_FILENAME() {
local FILENAME=$(SCWRYPTS__GET_PATH_TO_RELATIVE_ARGUMENT "$1") local FILENAME=$(SCWRYPTS__GET_REALPATH "$1")
local DIRNAME="$FILENAME" local DIRNAME="$FILENAME"
for _ in {1..3} for _ in {1..3}

View File

@ -64,7 +64,11 @@ SCWRYPTS__GET_ENV_NAMES() {
ERROR 'environment initialization error' ERROR 'environment initialization error'
return 1 return 1
} }
[ $REQUIRED_ENVIRONMENT_REGEX ] && {
ls "$SCWRYPTS_ENV_PATH/scwrypts" | grep "$REQUIRED_ENVIRONMENT_REGEX" | sort -r
} || {
ls "$SCWRYPTS_ENV_PATH/scwrypts" | sort -r ls "$SCWRYPTS_ENV_PATH/scwrypts" | sort -r
}
} }
SCWRYPTS__INIT_ENVIRONMENTS() { SCWRYPTS__INIT_ENVIRONMENTS() {

View File

@ -54,6 +54,7 @@ SCWRYPTS__LIST_AVAILABLE_SCWRYPTS__scwrypts() {
| grep -v '\.git' \ | grep -v '\.git' \
| grep -v 'node_modules' \ | grep -v 'node_modules' \
| sed "s/^\\.\\///; s/\\.[^.]*$//; s/^/$GROUP_TYPE/" \ | sed "s/^\\.\\///; s/\\.[^.]*$//; s/^/$GROUP_TYPE/" \
| grep -v '^plugins/' \
; ;
} }

View File

@ -0,0 +1,15 @@
#####################################################################
DEPENDENCIES+=()
REQUIRED_ENV+=()
#####################################################################
SCWRYPTS__GET_REALPATH() {
[[ ! $1 =~ ^[/~] ]] \
&& echo $(readlink -f "$EXECUTION_DIR/$1") \
|| echo "$1" \
;
return 0
}

View File

@ -1,9 +1,6 @@
##################################################################### #####################################################################
DEPENDENCIES+=( DEPENDENCIES+=()
virtualenv
nodeenv
)
REQUIRED_ENV+=() REQUIRED_ENV+=()
use utils use utils
@ -15,14 +12,14 @@ AVAILABLE_VIRTUALENVS=(py zx)
REFRESH_VIRTUALENV() { REFRESH_VIRTUALENV() {
local GROUP="$1" local GROUP="$1"
local TYPE="$2" local TYPE="$2"
[ ! $TYPE ] && { local VIRTUALENV_PATH="$(_VIRTUALENV__GET_PATH)"
ERROR 'no virtualenv type specified'
return 1 [ ! $TYPE ] && { ERROR 'no virtualenv type specified'; return 1; }
}
STATUS "refreshing $GROUP/$TYPE virtual environment" STATUS "refreshing $GROUP/$TYPE virtualenv"
DELETE_VIRTUALENV $GROUP $TYPE \ DELETE_VIRTUALENV $GROUP $TYPE \
&& UPDATE_VIRTUALENV $GROUP $TYPE \ && UPDATE_VIRTUALENV $GROUP $TYPE \
&& SUCCESS 'successfully refreshed virtual environment' \ && SUCCESS 'successfully refreshed virtualenv' \
|| { ERROR 'something went wrong during refresh (see above)'; return 1; } \ || { ERROR 'something went wrong during refresh (see above)'; return 1; } \
; ;
} }
@ -30,64 +27,50 @@ REFRESH_VIRTUALENV() {
UPDATE_VIRTUALENV() { UPDATE_VIRTUALENV() {
local GROUP="$1" local GROUP="$1"
local TYPE="$2" local TYPE="$2"
[ ! $TYPE ] && { local VIRTUALENV_PATH="$(_VIRTUALENV__GET_PATH)"
ERROR 'no virtualenv type specified'
return 1
}
local VIRTUALENV_PATH=$(GET_VIRTUALENV_PATH $GROUP $TYPE) [ ! $TYPE ] && { ERROR 'no virtualenv type specified'; return 1; }
[ ! -d $VIRTUALENV_PATH ] && { : \
which CREATE_VIRTUALENV__${GROUP}__${TYPE} >/dev/null 2>&1 \ && which CREATE_VIRTUALENV__${GROUP}__${TYPE} >/dev/null 2>&1 \
&& CREATE_VIRTUALENV__${GROUP}__${TYPE} $VIRTUALENV_PATH \ && which ACTIVATE_VIRTUALENV__${GROUP}__${TYPE} >/dev/null 2>&1 \
|| return 0 && which UPDATE_VIRTUALENV__${GROUP}__${TYPE} >/dev/null 2>&1 \
} && which DEACTIVATE_VIRTUALENV__${GROUP}__${TYPE} >/dev/null 2>&1 \
|| { STATUS "no virtualenv available for $GROUP/$TYPE; skipping"; return 0; }
STATUS "updating $TYPE virtual environment" STATUS "updating $GROUP/$TYPE virtualenv" \
&& CREATE_VIRTUALENV__${GROUP}__${TYPE} \
source $VIRTUALENV_PATH/bin/activate || { && ACTIVATE_VIRTUALENV__${GROUP}__${TYPE} \
ERROR 'failed to activate virtualenv; did create fail?' && UPDATE_VIRTUALENV__${GROUP}__${TYPE} \
return 1 && DEACTIVATE_VIRTUALENV__${GROUP}__${TYPE} \
} && SUCCESS "$GROUP/$TYPE virtualenv up-to-date" \
|| { ERROR "failed to update $GROUP/$TYPE virtualenv (see errors above)"; return 2; }
cd $SCWRYPTS_ROOT
local UPDATE_CODE=0
case $TYPE in
py ) cd py; pip install --no-cache-dir -r requirements.txt; UPDATE_CODE=$? ;;
zx ) cd zx; npm install ;;
esac
UPDATE_CODE=$?
[[ $UPDATE_CODE -eq 0 ]] \
&& SUCCESS "$TYPE virtual environment up-to-date" \
|| ERROR "failed to update $TYPE virtual environment (see errors above)" \
;
deactivate_node >/dev/null 2>&1
deactivate >/dev/null 2>&1
return $UPDATE_CODE
} }
DELETE_VIRTUALENV() { DELETE_VIRTUALENV() {
[ $CI ] && return 0
local GROUP="$1" local GROUP="$1"
local TYPE="$2" local TYPE="$2"
local VIRTUALENV_PATH="$(GET_VIRTUALENV_PATH $GROUP $TYPE)" local VIRTUALENV_PATH="$(_VIRTUALENV__GET_PATH)"
STATUS "dropping $TYPE virtual environment artifacts" [ ! $TYPE ] && { ERROR 'no virtualenv type specified'; return 1; }
STATUS "dropping $GROUP/$TYPE virtualenv artifacts"
[ ! -d $VIRTUALENV_PATH ] && { [ ! -d $VIRTUALENV_PATH ] && {
SUCCESS "no $TYPE environment detected" SUCCESS "no $GROUP/$TYPE environment detected"
return 0 return 0
} }
rm -rf $VIRTUALENV_PATH \ rm -rf $VIRTUALENV_PATH \
&& SUCCESS "succesfully cleaned up $TYPE virtual environment" \ && SUCCESS "succesfully cleaned up $GROUP/$TYPE virtualenv" \
|| { ERROR "unabled to remove '$VIRTUALENV_PATH'"; return 1; } || { ERROR "unabled to remove '$VIRTUALENV_PATH'"; return 1; }
} }
GET_VIRTUALENV_PATH() { #####################################################################
local GROUP="$1"
local TYPE="$2"
_VIRTUALENV__GET_PATH() {
local ENV_PATH="$(eval echo '$SCWRYPTS_VIRTUALENV_PATH__'$GROUP 2>/dev/null)" local ENV_PATH="$(eval echo '$SCWRYPTS_VIRTUALENV_PATH__'$GROUP 2>/dev/null)"
[ ! $ENV_PATH ] && ENV_PATH="$SCWRYPTS_VIRTUALENV_PATH__scwrypts" [ ! $ENV_PATH ] && ENV_PATH="$SCWRYPTS_VIRTUALENV_PATH__scwrypts"
@ -97,9 +80,14 @@ GET_VIRTUALENV_PATH() {
##################################################################### #####################################################################
CREATE_VIRTUALENV__scwrypts__py() { CREATE_VIRTUALENV__scwrypts__py() {
[ $CI ] && return 0
[ -d $VIRTUALENV_PATH ] && return 0
DEPENDENCIES=(virtualenv) CHECK_ENVIRONMENT || return 1
local VIRTUALENV_PATH="$1" local VIRTUALENV_PATH="$1"
STATUS 'creating python virtual environment' STATUS 'creating python virtualenv'
local PY PYTHON local PY PYTHON
for PY in $(echo $SCWRYPTS_PREFERRED_PYTHON_VERSIONS__scwrypts) for PY in $(echo $SCWRYPTS_PREFERRED_PYTHON_VERSIONS__scwrypts)
do do
@ -122,7 +110,37 @@ CREATE_VIRTUALENV__scwrypts__py() {
} }
} }
ACTIVATE_VIRTUALENV__scwrypts__py() {
[ $CI ] && return 0
source $VIRTUALENV_PATH/bin/activate || {
ERROR "failed to activate virtualenv $GROUP/$TYPE; did create fail?"
return 1
}
}
UPDATE_VIRTUALENV__scwrypts__py() {
local PIP_INSTALL_ARGS=()
PIP_INSTALL_ARGS+=(--no-cache-dir)
PIP_INSTALL_ARGS+=(-r requirements.txt)
cd "$SCWRYPTS_ROOT/py"
pip install ${PIP_INSTALL_ARGS[@]}
}
DEACTIVATE_VIRTUALENV__scwrypts__py() {
deactivate >/dev/null 2>&1
return 0
}
##########################################
CREATE_VIRTUALENV__scwrypts__zx() { CREATE_VIRTUALENV__scwrypts__zx() {
[ $CI ] && return 0
[ -d $VIRTUALENV_PATH ] && return 0
DEPENDENCIES=(nodeenv) CHECK_ENVIRONMENT || return 1
local VIRTUALENV_PATH="$1" local VIRTUALENV_PATH="$1"
STATUS 'setting up nodeenv' STATUS 'setting up nodeenv'
@ -133,3 +151,23 @@ CREATE_VIRTUALENV__scwrypts__zx() {
return 2 return 2
} }
} }
ACTIVATE_VIRTUALENV__scwrypts__zx() {
[ $CI ] && return 0
source $VIRTUALENV_PATH/bin/activate || {
ERROR "failed to activate virtualenv $GROUP/$TYPE; did create fail?"
return 1
}
}
UPDATE_VIRTUALENV__scwrypts__zx() {
local NPM_INSTALL_ARGS=()
cd "$SCWRYPTS_ROOT/zx"
npm install ${NPM_INSTALL_ARGS[@]}
}
DEACTIVATE_VIRTUALENV__scwrypts__zx() {
deactivate_node >/dev/null 2>&1
return 0
}

View File

@ -20,7 +20,7 @@ VUNDLE__PLUGIN_LIST=$(ls $VUNDLE__PLUGIN_DIR | grep -v 'Vundle.vim' | grep -v 'b
source $VUNDLE__BUILD_DEFINITIONS source $VUNDLE__BUILD_DEFINITIONS
for PLUGIN in $(echo $VUNDLE__PLUGIN_LIST) for PLUGIN in $(echo $VUNDLE__PLUGIN_LIST)
do do
typeset -f VUNDLE__BUILD__$PLUGIN >/dev/null 2>/dev/null || { which VUNDLE__BUILD__$PLUGIN >/dev/null 2>/dev/null || {
echo -e "\nVUNDLE__BUILD__$PLUGIN() {\n # ... build steps from $HOME/.vim/$PLUGIN \n}" \ echo -e "\nVUNDLE__BUILD__$PLUGIN() {\n # ... build steps from $HOME/.vim/$PLUGIN \n}" \
>> $VUNDLE__BUILD_DEFINITIONS >> $VUNDLE__BUILD_DEFINITIONS
VUNDLE__BUILD__$PLUGIN() {} VUNDLE__BUILD__$PLUGIN() {}

View File

@ -1,5 +1,6 @@
__CHECK_DEPENDENCIES() { __CHECK_DEPENDENCIES() {
local DEP ERROR=0 local DEP ERROR=0
[ ! $E ] && E=ERROR
DEPENDENCIES=($(echo $DEPENDENCIES | sed 's/ \+/\n/g' | sort -u)) DEPENDENCIES=($(echo $DEPENDENCIES | sed 's/ \+/\n/g' | sort -u))
@ -13,7 +14,7 @@ __CHECK_DEPENDENCY() {
local DEPENDENCY="$1" local DEPENDENCY="$1"
[ ! $DEPENDENCY ] && return 1 [ ! $DEPENDENCY ] && return 1
command -v $DEPENDENCY >/dev/null 2>&1 || { command -v $DEPENDENCY >/dev/null 2>&1 || {
ERROR "'$1' required but not available on PATH $(__CREDITS $1)" $E "application '$1' "$([[ $OPTIONAL -eq 1 ]] && echo preferred || echo required)" but not available on PATH $(__CREDITS $1)"
return 1 return 1
} }
} }

View File

@ -32,7 +32,7 @@ __CHECK_ENV_VAR() {
[ $DEFAULT_VALUE ] && $NAME="$DEFAULT_VALUE" [ $DEFAULT_VALUE ] && $NAME="$DEFAULT_VALUE"
return 0 return 0
} || { } || {
ERROR "'$NAME' required" ERROR "variable '$NAME' required"
return 1 return 1
} }
} }

View File

@ -55,37 +55,81 @@ ABORT() { FAIL 69 'user abort'; }
CHECK_ERRORS() { CHECK_ERRORS() {
local FAIL_OUT=1 local FAIL_OUT=1
local DISPLAY_USAGE=1
while [[ $# -gt 0 ]] while [[ $# -gt 0 ]]
do do
case $1 in case $1 in
-n | --no-fail ) FAIL_OUT=0 ;; --no-fail ) FAIL_OUT=0 ;;
--no-usage ) DISPLAY_USAGE=0 ;;
esac esac
shift 1 shift 1
done done
[ ! $ERRORS ] && ERRORS=0 [ ! $ERRORS ] && ERRORS=0
[[ $ERRORS -ne 0 ]] && USAGE [[ $ERRORS -eq 0 ]] && return 0
[[ $ERRORS -eq 0 ]] || {
[[ $FAIL_OUT -eq 1 ]] \ [[ $DISPLAY_USAGE -eq 1 ]] && USAGE
&& exit $ERRORS \
|| return $ERRORS [[ $FAIL_OUT -eq 1 ]] && exit $ERRORS
}
return $ERRORS
} }
USAGE() { USAGE() { # formatter for USAGE variable
[ ! $USAGE ] && return 0 [ ! $USAGE ] && return 0
USAGE=$(echo $USAGE | sed "s/^\t\+//; s/\s\+$//") local USAGE_LINE=$(echo $USAGE | grep -i '^[ ]*usage *:' | sed 's/^[ ]*//')
local USAGE_LINE=$(\ [ $USAGE__usage ] && echo $USAGE_LINE | grep -q 'usage: -' \
echo $USAGE \ && USAGE_LINE=$(echo $USAGE_LINE | sed "s/usage: -/usage: $USAGE__usage/")
| grep -i '^ *usage *:' \
[ $__SCWRYPT ] \
&& USAGE_LINE=$(
echo $USAGE_LINE \
| sed "s;^[^:]*:;& scwrypts $SCWRYPT_NAME --;" \ | sed "s;^[^:]*:;& scwrypts $SCWRYPT_NAME --;" \
| sed 's/ \{2,\}/ /g; s/scwrypts -- scwrypts/scwrypts/' \ | sed 's/ \{2,\}/ /g; s/scwrypts -- scwrypts/scwrypts/' \
) )
local THE_REST=$(echo $USAGE | grep -vi '^ *usage *:' | sed 'N;/^\n$/D;P;D;')
{ echo; printf "$__DARK_BLUE $USAGE_LINE$__COLOR_RESET\n"; echo $THE_REST; echo } >&2 local THE_REST=$(echo $USAGE | grep -vi '^[ ]*usage *:' )
local DYNAMIC_USAGE_ELEMENT
#
# create dynamic usage elements (like 'args') by defining USAGE__<element>
# then using the syntax "<element>: -" in your USAGE variable
#
# e.g.
#
# USAGE__args="
# subcommand arg 1 arg 1 description
# subcommand arg 2 some other description
# "
#
# USAGE="
# usage: some-command [...args...]
#
# args: -
# -h, --help some arguments are applicable everywhere
# "
#
for DYNAMIC_USAGE_ELEMENT in $(echo $THE_REST | sed -n 's/^\([^:]*\): -$/\1/p')
do
DYNAMIC_USAGE_ELEMENT_TEXT=$(eval echo '$USAGE__'$DYNAMIC_USAGE_ELEMENT)
[[ ! $DYNAMIC_USAGE_ELEMENT =~ ^description$ ]] \
&& DYNAMIC_USAGE_ELEMENT_TEXT=$(echo $DYNAMIC_USAGE_ELEMENT_TEXT | sed 's/[^ ]/ &/')
THE_REST=$(echo $THE_REST | perl -pe "s/$DYNAMIC_USAGE_ELEMENT: -/$DYNAMIC_USAGE_ELEMENT:\n$DYNAMIC_USAGE_ELEMENT_TEXT\n\n/")
done
# allow for dynamic 'description: -' but delete the 'description:' header line
THE_REST=$(echo $THE_REST | sed '/^[ ]*description:$/d')
echo "$__DARK_BLUE$USAGE_LINE$__COLOR_RESET\n\n$THE_REST" \
| sed "s/^\t\+//; s/\s\+$//; s/^\\s*$//;" \
| sed '/./,$!d; :a; /^\n*$/{$d;N;ba;};' \
| perl -p0e 's/\n{2,}/\n\n/g' \
| perl -p0e 's/:\n{2,}/:\n/g' \
>&2
} }
INPUT() { INPUT() {
@ -99,7 +143,7 @@ Yn() {
PROMPT "$@ [Yn]" PROMPT "$@ [Yn]"
[ $CI ] && { echo y; return 0; } [ $CI ] && { echo y; return 0; }
local Yn; READ -k Yn; echo local Yn; READ -k Yn; echo >&2
[[ $Yn =~ [nN] ]] && return 1 || return 0 [[ $Yn =~ [nN] ]] && return 1 || return 0
} }
@ -107,10 +151,22 @@ yN() {
PROMPT "$@ [yN]" PROMPT "$@ [yN]"
[ $CI ] && { echo y; return 0; } [ $CI ] && { echo y; return 0; }
local yN; READ -k yN; echo local yN; READ -k yN; echo >&2
[[ $yN =~ [yY] ]] && return 0 || return 1 [[ $yN =~ [yY] ]] && return 0 || return 1
} }
CAPTURE() {
[ ! $USAGE ] && USAGE="
usage: stdout-varname stderr-varname [...cmd and args...]
captures stdout and stderr on separate variables for a command
"
{
IFS=$'\n' read -r -d '' $2;
IFS=$'\n' read -r -d '' $1;
} < <((printf '\0%s\0' "$(${@:3})" 1>&2) 2>&1)
}
##################################################################### #####################################################################
GETSUDO() { GETSUDO() {

View File

@ -18,6 +18,18 @@ source ${0:a:h}/environment.zsh
##################################################################### #####################################################################
CHECK_ENVIRONMENT() { CHECK_ENVIRONMENT() {
local OPTIONAL=0
while [[ $# -gt 0 ]]
do
case $1 in
--optional ) OPTIONAL=1 ;;
esac
shift 1
done
[[ $OPTIONAL -eq 1 ]] && E=WARNING || E=ERROR
local ENVIRONMENT_STATUS=0 local ENVIRONMENT_STATUS=0
__CHECK_DEPENDENCIES $DEPENDENCIES __CHECK_DEPENDENCIES $DEPENDENCIES
@ -55,9 +67,9 @@ CHECK_ENVIRONMENT() {
########################################## ##########################################
[[ ENVIRONMENT_STATUS -eq 0 ]] || { [[ ENVIRONMENT_STATUS -ne 0 ]] && [[ $OPTIONAL -eq 0 ]] && {
ERROR_MESSAGE=$(echo $ERROR_MESSAGE | sed '1d; s/^/ /') ERROR_MESSAGE=$(echo $ERROR_MESSAGE | sed '1d; s/^/ /')
ERROR "environment errors found (see above)\n$ERROR_MESSAGE" $E "environment errors found (see above)\n$ERROR_MESSAGE"
} }
[[ $MISSING_ENVIRONMENT_VARIABLES -ne 0 ]] && { [[ $MISSING_ENVIRONMENT_VARIABLES -ne 0 ]] && {
@ -67,10 +79,11 @@ CHECK_ENVIRONMENT() {
" "
} }
[[ $ENVIRONMENT_STATUS -eq 0 ]] || { [[ $ENVIRONMENT_STATUS -ne 0 ]] && [[ $NO_EXIT -ne 1 ]] && [[ $OPTIONAL -eq 0 ]] && {
[[ $NO_EXIT -eq 1 ]] && return $ENVIRONMENT_STATUS
exit $ENVIRONMENT_STATUS exit $ENVIRONMENT_STATUS
} }
return $ENVIRONMENT_STATUS
} }
CHECK_ENVIRONMENT CHECK_ENVIRONMENT

View File

@ -8,7 +8,7 @@ CHECK_ENVIRONMENT
##################################################################### #####################################################################
CLEAN_LATEX_LOGFILES() { CLEAN_LATEX_LOGFILES() {
local DIRECTORY=$(SCWRYPTS__GET_PATH_TO_RELATIVE_ARGUMENT ".") local DIRECTORY=$(SCWRYPTS__GET_REALPATH ".")
[ $1 ] && DIRECTORY="$(dirname "$(LATEX__GET_MAIN_FILENAME "$1")")" [ $1 ] && DIRECTORY="$(dirname "$(LATEX__GET_MAIN_FILENAME "$1")")"
[ $DIRECTORY ] && [ -d $DIRECTORY ] \ [ $DIRECTORY ] && [ -d $DIRECTORY ] \
|| FAIL 1 'unable to parse valid directory' || FAIL 1 'unable to parse valid directory'

View File

@ -22,4 +22,4 @@ done
[[ $FAILED_COUNT -eq 0 ]] \ [[ $FAILED_COUNT -eq 0 ]] \
&& SUCCESS 'all environments up-to-date' \ && SUCCESS 'all environments up-to-date' \
|| FAIL $FAILED_COUNT 'failed to update one or more environments' || FAIL $FAILED_COUNT "failed to update $FAILED_COUNT more environment(s)"

View File

@ -8,6 +8,11 @@ CHECK_ENVIRONMENT
##################################################################### #####################################################################
PLUGIN_INSTALL() { PLUGIN_INSTALL() {
[ -d "$HOME/.vim/bundle/Vundle.vim" ] || {
mkdir -p "$HOME/.vim/bundle/"
git clone https://github.com/VundleVim/Vundle.vim.git "$HOME/.vim/bundle/Vundle.vim"
}
VUNDLE__PLUGIN_INSTALL || return 1 VUNDLE__PLUGIN_INSTALL || return 1
VUNDLE__REBUILD_PLUGINS || return 2 VUNDLE__REBUILD_PLUGINS || return 2
} }