Compare commits

..

14 Commits

Author SHA1 Message Date
187a467092 v2.7.0
=====================================================================

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

- `__override` variables now allow values to be force-overwritten
2023-01-11 17:09:59 -07:00
a1256bb0af v2.6.3
=====================================================================

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

- s3/media-sync/push now pushes (instead of pull -- oops!)
- fixed a typo in the launch-or-show help
- environment actions no longer overwrite overwrite symlinks
2022-09-30 20:23:37 -06:00
73e26a2ecb v2.6.2
=====================================================================

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

- VARIABLE__select actually sets the variable value after selection
2022-09-01 07:40:06 -06:00
20b7cc32eb v2.6.1
=====================================================================

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

- i3/create-local-font-override uses the correct variables for the
  correct settings now
2022-08-24 12:01:24 -06:00
22dd6f8112 v2.6.0
=====================================================================

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

- i3 window manager scrypts (see --help for more info)
   - zsh/i3/create-local-font-override
   - zsh/i3/launch-or-show

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

Now support `__select` syntax in environment files!
(see zsh/scwrypts/README.md for more detail)

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

- moved some rogue configuration files under the scwrypts config
   - ~/.vim/bundle/build.zsh >> ~/.config/scwrypts/vundle.zsh
   - ~/.config/scwrypts/config.dotfile.zsh >> ~/.config/scwrypts/dotfiles.zsh

- __FZF, __FZF_TAIL, and __FZF_HEAD now create prompt+response logs

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

- zsh/config/symlinks
   - don't fail when trying to symlink a directory
   - no longer fails when trying to replace a broken symlink

- scwrypts now detects environments which are symlinked

- USAGE syntax now correctly shows the position of the '--' argument
  delimiter

support __select in env files; ignore __lower_case suffix in env files; put blank line before comments in env files

added i3 scripts
2022-08-22 21:47:46 -06:00
710d42e248 v2.5.3
=====================================================================

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

- __READ and __EDIT no longer fail on CI, just skip
2022-08-18 19:48:10 -06:00
244c188deb v2.5.2
=====================================================================

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

- added __GET_RANDOM_COLOR for funsies
2022-08-16 23:29:10 -06:00
5c882597da v2.5.1
=====================================================================

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

- git/package/install didn't create build dir if it did not exist
2022-08-16 18:48:56 -06:00
4047aad29e fixed credits bug with dashes 2022-08-16 18:44:25 -06:00
6333a2f6b8 v2.5.0
=====================================================================

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

zsh )
  vundle-vim helpers
   - vim/vundle/edit-build-actions
   - vim/vundle/install
   - vim/vundle/rebuild

  quick install-from-source scripts
   - git/package/install
   - git/package/build    (install --only-build)
   - git/package/download (install --only-pull)
   - git/package/update   (install --update)

  config sym-linker (for source-controlled .configs)
   - config/update    (symlinks + terminfo)
   - config/symlinks  (set all symlinks from settings)
   - config/settings  (edit settings which aren't scwrypts env variables)
   - config/terminfo  (load all terminfo from settings)

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

- helper comments are now inserted in all env files
- removed underscore prefix for standard AWS environment variables
- added "opening" and "finished editing" comments to __EDIT util
- added __USAGE to format $USAGE variable to std:err
- added __ERROR_CHECK to exit if any __ERROR(s) were called
2022-08-16 18:26:55 -06:00
a740a66870 v2.4.0
=====================================================================

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

zsh )
  memo program; quickly take notes!
   - memo/open
   - memo/remove
2022-08-10 00:46:07 -06:00
96992e9344 v2.3.0
=====================================================================

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

zsh )
  latex + latex template engine
   - latex/build-pdf
   - latex/cleanup
   - latex/create-new
   - latex/get-pdf
   - latex/open-pdf

  beta SQL script -- got tired of floating this; works, but only OK
   - db/run-sql/postgres

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

- Added 'math', 'basic', and 'times-new-roman' templates to latex
- Added 'readlink' to list of required coreutils
- Added __INPUT to read into a variable with prompt (zsh/utils/io)
- Added $EXECUTION_DIR to interact with the user's working directory

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

- subscwrypts no longer force stdout/stderr to tty
2022-08-09 21:51:31 -06:00
e8bb889789 v2.2.0
=====================================================================

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

zsh )
  amazon EKS
   - aws/eks/login

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

- moved global .config to global/config.zsh
- moved various global configurations to global/

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

- REDIS_AUTH no longer required to attempt connection
- global configurations now propagate to non-zsh scripts
2022-08-09 13:18:41 -06:00
89e899d49d v2.1.0
=====================================================================

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

zsh )
  database backup/restore
   - db/postgres/pg_dump
   - db/postgres/pg_restore
   - aws/rds/create-backup
   - aws/rds/load-backup

  redis-cached curl commands
   - redis/curl

  youtube download
   - youtube/download
   - youtube/get-audio-clip

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

- 'scwrypts' executable now reloads upon execution to prevent staleness
- added various options to improve api/cli; see 'scwrypts --help' for more

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

- fixed an issue with .config settings' visibility to non-zsh scripts
- fixed an issue with command arguments globbing too early
2022-08-02 00:24:29 -06:00
86 changed files with 2175 additions and 423 deletions

View File

@ -1,10 +1,14 @@
#!/bin/zsh
export AWS_ACCOUNT=
export AWS_PROFILE=
export AWS_REGION=
export AWS__EFS__LOCAL_MOUNT_POINT=
export AWS__S3__MEDIA_BUCKET=
export AWS__S3__MEDIA_TARGETS=
export I3__BORDER_PIXEL_SIZE=
export I3__DMENU_FONT_SIZE=
export I3__GLOBAL_FONT_SIZE=
export I3__MODEL_CONFIG=
export REDIS_AUTH=
export REDIS_HOST=
export REDIS_PORT=
export _AWS_ACCOUNT=
export _AWS_PROFILE=
export _AWS_REGION=

View File

@ -0,0 +1,17 @@
AWS_ACCOUNT | standard AWS environment variables used by awscli and other tools
AWS_PROFILE |
AWS_REGION |
AWS__EFS__LOCAL_MOUNT_POINT | fully-qualified path to mount the EFS drive
AWS__S3__MEDIA_BUCKET | s3 bucket name and filesystem targets for media backups
AWS__S3__MEDIA_TARGETS |
I3__BORDER_PIXEL_SIZE | custom i3 configuration settings
I3__DMENU_FONT_SIZE |
I3__GLOBAL_FONT_SIZE |
I3__MODEL_CONFIG |
REDIS_AUTH | redis connection credentials
REDIS_HOST |
REDIS_PORT |

View File

@ -45,7 +45,6 @@ After determining which script to run, if no environment has been specified, Scw
Set environment variable `CI=true` (and use the no install method) to run in an automated pipeline.
There are a few notable changes to this runtime:
- **The Scwrypts sandbox environment will not load.** All variables will be read from context.
- The underscore-prefixed `_AWS_(PROFILE|REGION|ACCOUNT)` variables will be read from the standard `AWS_` variables
- User yes/no prompts will **always be YES**
- Other user input will default to an empty string
- Logs will not be captured

42
global/common.zsh Normal file
View File

@ -0,0 +1,42 @@
#####################################################################
[ ! $SCWRYPTS_ROOT ] && SCWRYPTS_ROOT="$(dirname ${0:a:h})"
source "${0:a:h}/config.zsh"
#####################################################################
__SCWRYPT=1 # arbitrary; indicates scwrypts exists
__PREFERRED_PYTHON_VERSIONS=(3.10 3.9)
__NODE_VERSION=18.0.0
__ENV_TEMPLATE=$SCWRYPTS_ROOT/.env.template
#####################################################################
__GET_PATH_TO_RELATIVE_ARGUMENT() {
[[ $1 =~ ^[.] ]] \
&& echo $(readlink -f "$EXECUTION_DIR/$1") \
|| echo "$1" \
;
true
}
#####################################################################
__RUN_SCWRYPT() {
((SUBSCWRYPT+=1))
{ printf ' '; printf '--%.0s' {1..$SUBSCWRYPT}; printf " ($SUBSCWRYPT) "; } >&2
echo " BEGIN SUBSCWRYPT : $@" >&2
SUBSCWRYPT=$SUBSCWRYPT SCWRYPTS_ENV=$ENV_NAME \
"$SCWRYPTS_ROOT/scwrypts" $@
EXIT_CODE=$?
{ printf ' '; printf '--%.0s' {1..$SUBSCWRYPT}; printf " ($SUBSCWRYPT) "; } >&2
echo " END SUBSCWRYPT : $1" >&2
((SUBSCWRYPT-=1))
return $EXIT_CODE
}

Binary file not shown.

View File

@ -8,7 +8,7 @@ class RedisClient(StrictRedis):
super().__init__(
host = getenv('REDIS_HOST'),
port = getenv('REDIS_PORT'),
password = getenv('REDIS_AUTH'),
password = getenv('REDIS_AUTH', required=False),
decode_responses = True,
)

269
run Executable file
View File

@ -0,0 +1,269 @@
#!/bin/zsh
export EXECUTION_DIR=$(pwd)
SCWRYPTS_ROOT="${0:a:h}"
source "$SCWRYPTS_ROOT/zsh/common.zsh" || exit 42
#####################################################################
__RUN() {
local USAGE='
usage: scwrypts [OPTIONS ...] SCRIPT -- [SCRIPT OPTIONS ...]
OPTIONS
-e, --env <env-name> set environment; overwrites SCWRYPTS_ENV
-n, --no-log skip logging (useful when calling scwrypts as an api)
-l, --list print out command list and exit
-h, --help display this message and exit
'
cd "$SCWRYPTS_ROOT"
local ENV_NAME="$SCWRYPTS_ENV"
local SEARCH_PATTERNS=()
local ERROR=0
while [[ $# -gt 0 ]]
do
case $1 in
-h | --help )
__USAGE
return 0
;;
-n | --no-log )
[ ! $SUBSCWRYPT ] && SUBSCWRYPT=0
shift 1
;;
-e | --env )
[ $ENV_NAME ] && __WARNING 'overwriting session environment'
ENV_NAME="$2"
__STATUS "using CLI environment '$ENV_NAME'"
shift 2
;;
-l | --list )
__OUTPUT_COMMAND_LIST
return 0
;;
-- )
shift 1
break # pass arguments after '--' to the scwrypt
;;
-* )
__ERROR "unrecognized argument '$1'"
shift 1
;;
* )
SEARCH_PATTERNS+=$1
shift 1
;;
esac
done
__ERROR_CHECK
##########################################
local SCRIPT=$(__SELECT_SCRIPT $SEARCH_PATTERNS)
[ ! $SCRIPT ] && exit 2
export SCWRYPT_NAME=$SCRIPT
local ENV_REQUIRED=$(__CHECK_ENV_REQUIRED && echo 1 || echo 0)
[[ $ENV_REQUIRED -eq 1 ]] && {
[ ! $ENV_NAME ] && ENV_NAME=$(__SELECT_ENV)
local ENV_FILE=$(__GET_ENV_FILE $ENV_NAME)
[ -f "$ENV_FILE" ] && source "$ENV_FILE" \
|| __FAIL 5 "missing or invalid environment '$ENV_NAME'"
export ENV_NAME
}
[ ! $SUBSCWRYPT ] \
&& [[ $ENV_NAME =~ prod ]] \
&& { __VALIDATE_UPSTREAM_TIMELINE || __ABORT; }
local RUN_STRING=$(__GET_RUN_STRING $SCRIPT $ENV_NAME)
[ ! $RUN_STRING ] && exit 3
##########################################
local LOGFILE=$(__GET_LOGFILE $SCRIPT)
local HEADER=$(
[ $SUBSCWRYPT ] && return 0
echo '====================================================================='
echo "script : $SCRIPT"
echo "run at : $(date)"
echo "config : $ENV_NAME"
[ ! $LOGFILE ] && echo '\033[1;33m------------------------------------------\033[0m'
)
[ ! $LOGFILE ] && {
[ $HEADER ] && echo $HEADER
[ $SUBSCWRYPT ] && {
eval $RUN_STRING $@
exit $?
} || {
eval $RUN_STRING $@ </dev/tty >/dev/tty 2>&1
exit $?
}
}
{
[ $HEADER ] && echo $HEADER
echo '\033[1;33m--- BEGIN OUTPUT -------------------------\033[0m'
eval $RUN_STRING $@
EXIT_CODE=$?
echo '\033[1;33m--- END OUTPUT ---------------------------\033[0m'
[[ $EXIT_CODE -eq 0 ]] && EXIT_COLOR='32m' || EXIT_COLOR='31m'
echo "terminated with\\033[1;$EXIT_COLOR code $EXIT_CODE\\033[0m"
} 2>&1 | tee --append "$LOGFILE"
exit $(\
sed -n 's/^terminated with.*code \([0-9]*\).*$/\1/p' $LOGFILE \
| tail -n1
)
}
#####################################################################
__OUTPUT_COMMAND_LIST() {
local LAST_TYPE LAST_SUBSET
for SCRIPT in $(__GET_AVAILABLE_SCRIPTS)
do
TYPE=$(echo $SCRIPT | sed 's/\/.*//')
SUBSET=$(echo $SCRIPT | sed 's/.*\/\(.*\)\/[^\/]*$/\1/')
[[ ! $LAST_TYPE =~ $TYPE ]] && {
echo >&2
echo "\\033[1;32m$TYPE scwrypts\\033[0m" >&2
LAST_SUBSET=''
}
[ $LAST_SUBSET ] && [[ ! $LAST_SUBSET =~ $SUBSET ]] && {
echo >&2
}
printf ' - ' >&2
echo $SCRIPT
LAST_TYPE=$TYPE
LAST_SUBSET=$SUBSET
done
}
#####################################################################
__SELECT_SCRIPT() {
local SCRIPT
local SCRIPTS=$(__GET_AVAILABLE_SCRIPTS)
local SEARCH=($@)
[[ ${#SEARCH[@]} -eq 0 ]] && {
SCRIPT=$(echo $SCRIPTS | __FZF 'select a script')
}
[[ ${#SEARCH[@]} -eq 1 ]] && [ -f ./$SEARCH ] && {
SCRIPT=$SEARCH
}
[ ! $SCRIPT ] && [[ ${#SEARCH[@]} -gt 0 ]] && {
SCRIPT=$SCRIPTS
for PATTERN in $SEARCH
do
SCRIPT=$(echo $SCRIPT | grep $PATTERN)
done
[ ! $SCRIPT ] && __FAIL 2 "no script found by name '$@'"
[[ $(echo $SCRIPT | wc -l) -gt 1 ]] && {
__STATUS "more than one script matched '$@'"
SCRIPT=$(echo $SCRIPT | __FZF 'select a script')
}
}
echo $SCRIPT
}
__GET_RUN_STRING() {
local SCRIPT="$1"
local ENV_NAME="$2"
local TYPE=$(echo $SCRIPT | sed 's/\/.*$//')
local RUN_STRING
local _VIRTUALENV="$SCWRYPTS_VIRTUALENV_PATH/$TYPE/bin/activate"
[ -f $_VIRTUALENV ] && source $_VIRTUALENV
case $TYPE in
py ) __CHECK_DEPENDENCY python || return 1
RUN_STRING="python -m $(echo $SCRIPT | sed 's/\//./g; s/\.py$//; s/\.\.//')"
CURRENT_PYTHON_VERSION=$(python --version | sed 's/^[^0-9]*\(3\.[^.]*\).*$/\1/')
echo $__PREFERRED_PYTHON_VERSIONS | grep -q $CURRENT_PYTHON_VERSION || {
__WARNING "only tested on the following python versions: $(printf ', %s.x' ${__PREFERRED_PYTHON_VERSIONS[@]} | sed 's/^, //')"
__WARNING 'compatibility may vary'
}
;;
zsh ) __CHECK_DEPENDENCY zsh || return 1
RUN_STRING="noglob ./$SCRIPT"
;;
zx ) __CHECK_DEPENDENCY zx || return 1
RUN_STRING="FORCE_COLOR=3 ./$SCRIPT.mjs"
;;
* ) __ERROR "unsupported script type '$SCRIPT_TYPE'"
return 2
;;
esac
RUN_STRING="SCWRYPTS_ENV='$ENV_NAME' $RUN_STRING"
[ -f $_VIRTUALENV ] && RUN_STRING="source '$_VIRTUALENV'; $RUN_STRING"
echo $RUN_STRING
}
__CHECK_ENV_REQUIRED() {
[ $CI ] && return 1
echo $SCRIPT | grep -q 'zsh/scwrypts/logs' && return 1
return 0
}
__VALIDATE_UPSTREAM_TIMELINE() {
__STATUS "on '$ENV_NAME'; checking diff against origin/main"
git fetch --quiet origin main
local SYNC_STATUS=$?
git diff --exit-code origin/main -- . >&2
local DIFF_STATUS=$?
[[ $SYNC_STATUS -eq 0 ]] && [[ $DIFF_STATUS -eq 0 ]] && {
__SUCCESS 'up-to-date with origin/main'
} || {
__WARNING
[[ $SYNC_STATUS -ne 0 ]] && __WARNING 'unable to synchronize with origin/main'
[[ $DIFF_STATUS -ne 0 ]] && __WARNING 'your branch differs from origin/main (diff listed above)'
__WARNING
__yN 'continue?' || return 1
}
}
__GET_LOGFILE() {
local SCRIPT="$1"
[ $SUBSCWRYPT ] \
|| [[ $SCRIPT =~ scwrypts/logs ]] \
|| [[ $SCRIPT =~ interactive ]] \
&& return 0
echo "$SCWRYPTS_LOG_PATH/$(echo $SCRIPT | sed 's/^\.\///; s/\//\%/g').log"
}
#####################################################################
__RUN $@

208
scwrypts
View File

@ -1,208 +1,2 @@
#!/bin/zsh
SCWRYPTS_ROOT="${0:a:h}"
source "$SCWRYPTS_ROOT/zsh/common.zsh" || exit 42
#####################################################################
__RUN() {
cd "$SCWRYPTS_ROOT"
local ENV_NAME="$SCWRYPTS_ENV"
local SEARCH_PATTERNS=()
while [[ $# -gt 0 ]]
do
case $1 in
-e | --env )
[ $ENV_NAME ] && __WARNING 'overwriting session environment'
ENV_NAME="$2"
__STATUS "using CLI environment '$ENV_NAME'"
shift 2
;;
-- )
shift 1
break # pass arguments after '--' to the scwrypt
;;
* )
SEARCH_PATTERNS+=$1
shift 1
;;
esac
done
##########################################
local SCRIPT=$(__SELECT_SCRIPT $SEARCH_PATTERNS)
[ ! $SCRIPT ] && exit 2
local ENV_REQUIRED=$(__CHECK_ENV_REQUIRED && echo 1 || echo 0)
[[ $ENV_REQUIRED -eq 1 ]] && {
[ ! $ENV_NAME ] && ENV_NAME=$(__SELECT_ENV)
local ENV_FILE=$(__GET_ENV_FILE $ENV_NAME)
[ -f "$ENV_FILE" ] && source "$ENV_FILE" \
|| __FAIL 5 "missing or invalid environment '$ENV_NAME'"
export ENV_NAME
}
[ ! $SUBSCWRYPT ] \
&& [[ $ENV_NAME =~ prod ]] \
&& { __VALIDATE_UPSTREAM_TIMELINE || __ABORT; }
local RUN_STRING=$(__GET_RUN_STRING $SCRIPT $ENV_NAME)
[ ! $RUN_STRING ] && exit 3
##########################################
local LOGFILE=$(__GET_LOGFILE $SCRIPT)
local HEADER=$(
[ $SUBSCWRYPT ] && return 0
echo '====================================================================='
echo "script : $SCRIPT"
echo "run at : $(date)"
echo "config : $ENV_NAME"
[ ! $LOGFILE ] && echo '\033[1;33m------------------------------------------\033[0m'
)
[ ! $LOGFILE ] && {
[ $HEADER ] && echo $HEADER
eval $RUN_STRING $@ </dev/tty >/dev/tty 2>&1
exit $?
}
{
[ $HEADER ] && echo $HEADER
echo '\033[1;33m--- BEGIN OUTPUT -------------------------\033[0m'
eval $RUN_STRING $@
EXIT_CODE=$?
echo '\033[1;33m--- END OUTPUT ---------------------------\033[0m'
[[ $EXIT_CODE -eq 0 ]] && EXIT_COLOR='32m' || EXIT_COLOR='31m'
echo "terminated with\\033[1;$EXIT_COLOR code $EXIT_CODE\\033[0m"
} 2>&1 | tee --append "$LOGFILE"
exit $(\
sed -n 's/^terminated with.*code \([0-9]*\).*$/\1/p' $LOGFILE \
| tail -n1
)
}
#####################################################################
__SELECT_SCRIPT() {
local SCRIPT
local SCRIPTS=$(__GET_AVAILABLE_SCRIPTS)
local SEARCH=($@)
[[ ${#SEARCH[@]} -eq 0 ]] && {
SCRIPT=$(echo $SCRIPTS | __FZF 'select a script')
}
[[ ${#SEARCH[@]} -eq 1 ]] && [ -f ./$SEARCH ] && {
SCRIPT=$SEARCH
}
[ ! $SCRIPT ] && [[ ${#SEARCH[@]} -gt 0 ]] && {
SCRIPT=$SCRIPTS
for PATTERN in $SEARCH
do
SCRIPT=$(echo $SCRIPT | grep $PATTERN)
done
[ ! $SCRIPT ] && __FAIL 2 "no script found by name '$@'"
[[ $(echo $SCRIPT | wc -l) -gt 1 ]] && {
__STATUS "more than one script matched '$@'"
SCRIPT=$(echo $SCRIPT | __FZF 'select a script')
}
}
echo $SCRIPT
}
__GET_RUN_STRING() {
local SCRIPT="$1"
local ENV_NAME="$2"
local TYPE=$(echo $SCRIPT | sed 's/\/.*$//')
local RUN_STRING
local _VIRTUALENV="$SCWRYPTS_VIRTUALENV_PATH/$TYPE/bin/activate"
[ -f $_VIRTUALENV ] && source $_VIRTUALENV
case $TYPE in
py ) __CHECK_DEPENDENCY python || return 1
RUN_STRING="python -m $(echo $SCRIPT | sed 's/\//./g; s/\.py$//; s/\.\.//')"
CURRENT_PYTHON_VERSION=$(python --version | sed 's/^[^0-9]*\(3\.[^.]*\).*$/\1/')
echo $__PREFERRED_PYTHON_VERSIONS | grep -q $CURRENT_PYTHON_VERSION || {
__WARNING "only tested on the following python versions: $(printf ', %s.x' ${__PREFERRED_PYTHON_VERSIONS[@]} | sed 's/^, //')"
__WARNING 'compatibility may vary'
}
;;
zsh ) __CHECK_DEPENDENCY zsh || return 1
RUN_STRING="./$SCRIPT"
;;
zx ) __CHECK_DEPENDENCY zx || return 1
RUN_STRING="FORCE_COLOR=3 ./$SCRIPT.mjs"
;;
* ) __ERROR "unsupported script type '$SCRIPT_TYPE'"
return 2
;;
esac
RUN_STRING="SCWRYPTS_ENV='$ENV_NAME' $RUN_STRING"
[ -f $_VIRTUALENV ] && RUN_STRING="source '$_VIRTUALENV'; $RUN_STRING"
echo $RUN_STRING
}
__CHECK_ENV_REQUIRED() {
[ $CI ] && return 1
echo $SCRIPT | grep -q 'zsh/scwrypts/logs' && return 1
return 0
}
__VALIDATE_UPSTREAM_TIMELINE() {
__STATUS "on '$ENV_NAME'; checking diff against origin/main"
git fetch --quiet origin main
local SYNC_STATUS=$?
git diff --exit-code origin/main -- . >&2
local DIFF_STATUS=$?
[[ $SYNC_STATUS -eq 0 ]] && [[ $DIFF_STATUS -eq 0 ]] && {
__SUCCESS 'up-to-date with origin/main'
} || {
__WARNING
[[ $SYNC_STATUS -ne 0 ]] && __WARNING 'unable to synchronize with origin/main'
[[ $DIFF_STATUS -ne 0 ]] && __WARNING 'your branch differs from origin/main (diff listed above)'
__WARNING
__yN 'continue?' || return 1
}
}
__GET_LOGFILE() {
local SCRIPT="$1"
[ $SUBSCWRYPT ] \
|| [[ $SCRIPT =~ scwrypts/logs ]] \
|| [[ $SCRIPT =~ interactive ]] \
&& return 0
echo "$SCWRYPTS_LOG_PATH/$(echo $SCRIPT | sed 's/^\.\///; s/\//\%/g').log"
}
#####################################################################
__RUN $@
source "${0:a:h}/run" $@

View File

@ -3,11 +3,11 @@ _DEPENDENCIES+=(
jq
)
_REQUIRED_ENV+=(
_AWS_ACCOUNT
_AWS_PROFILE
_AWS_REGION
AWS_ACCOUNT
AWS_PROFILE
AWS_REGION
)
source ${0:a:h}/../common.zsh
#####################################################################
_AWS() { aws --profile $_AWS_PROFILE --region $_AWS_REGION --output json $@; }
_AWS() { aws --profile $AWS_PROFILE --region $AWS_REGION --output json $@; }

View File

@ -9,6 +9,6 @@ __STATUS "performing AWS ECR docker login"
_AWS ecr get-login-password | docker login \
--username AWS \
--password-stdin \
"$_AWS_ACCOUNT.dkr.ecr.$_AWS_REGION.amazonaws.com" \
&& __SUCCESS "logged in to 'AWS:$_AWS_ACCOUNT:$_AWS_REGION'" \
|| __FAIL 1 "unable to login to '$_AWS_ACCOUNT' in '$_AWS_REGION'"
"$AWS_ACCOUNT.dkr.ecr.$AWS_REGION.amazonaws.com" \
&& __SUCCESS "logged in to 'AWS:$AWS_ACCOUNT:$AWS_REGION'" \
|| __FAIL 1 "unable to login to '$AWS_ACCOUNT' in '$AWS_REGION'"

6
zsh/aws/eks/common.zsh Normal file
View File

@ -0,0 +1,6 @@
_DEPENDENCIES+=(
kubectl
)
_REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
#####################################################################

19
zsh/aws/eks/login Executable file
View File

@ -0,0 +1,19 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
__STATUS "performing AWS ECR docker login"
CLUSTER_NAME=$(\
_AWS eks list-clusters \
| jq -r '.[] | .[]' \
| __FZF 'select a cluster'
)
[ ! $CLUSTER_NAME ] && __ABORT
__STATUS "updating kubeconfig for '$CLUSTER_NAME'"
_AWS eks update-kubeconfig --name $CLUSTER_NAME \
&& __SUCCESS "kubeconfig updated with '$CLUSTER_NAME'" \
|| __ERROR "failed to update kubeconfig; do you have permissions to access '$CLUSTER_NAME'?"

View File

@ -3,20 +3,128 @@ _REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
#####################################################################
__SELECT_CONNECTOR() {
local DB_TYPE="$1"
GET_DATABASE_CREDENTIALS() {
local PRINT_PASSWORD=0
local ERRORS=0
CLIENTS_postgresql=(pgcli psql)
local C CLIENT=none
for C in $(eval 'echo $CLIENTS_'$DB_TYPE)
while [[ $# -gt 0 ]]
do
__CHECK_DEPENDENCY $C >/dev/null 2>&1 && {
CLIENT=$C
__STATUS "detected '$CLIENT' for $DB_TYPE"
break
}
case $1 in
--print-password ) PRINT_PASSWORD=1 ;;
* )
__WARNING "unrecognized argument $1"
ERRORS+=1
;;
esac
shift 1
done
echo $CLIENT
__ERROR_CHECK
##########################################
local DATABASE=$(SELECT_DATABASE)
[ ! $DATABASE ] && __ABORT
DB_HOST="$(echo $DATABASE | jq -r '.host')"
[ ! $DB_HOST ] && { __ERROR 'unable to find host'; return 2; }
DB_PORT="$(echo $DATABASE | jq -r '.port')"
[ ! $DB_PORT ] && DB_PORT=5432
[[ $DB_PORT =~ ^null$ ]] && DB_PORT=5432
##########################################
local AUTH_METHOD=$(\
echo "iam\nsecretsmanager\nuser-input" \
| __FZF 'select an authentication method' \
)
[ ! $AUTH_METHOD ] && __ABORT
case $AUTH_METHOD in
iam ) GET_AUTH__IAM ;;
secretsmanager ) GET_AUTH__SECRETSMANAGER ;;
user-input ) GET_AUTH__USER_INPUT ;;
esac
__STATUS
__STATUS "host : $DB_HOST"
__STATUS "type : $DB_TYPE"
__STATUS "port : $DB_PORT"
__STATUS "database : $DB_NAME"
__STATUS "username : $DB_USER"
[[ $PRINT_PASSWORD -eq 1 ]] && __STATUS "password : $DB_PASS"
__STATUS
}
GET_AUTH__IAM() {
DB_PASS=$(\
_AWS rds generate-db-auth-token \
--hostname $DB_HOST \
--port $DB_PORT \
--username $DB_USER \
)
}
GET_AUTH__SECRETSMANAGER() {
local CREDENTIALS=$(GET_SECRETSMANAGER_CREDENTIALS)
echo $CREDENTIALS | jq -e '.pass' >/dev/null 2>&1 \
&& DB_PASS="'$(echo $CREDENTIALS | jq -r '.pass' | sed "s/'/'\"'\"'/g")'"
echo $CREDENTIALS | jq -e '.password' >/dev/null 2>&1 \
&& DB_PASS="'$(echo $CREDENTIALS | jq -r '.password' | sed "s/'/'\"'\"'/g")'"
echo $CREDENTIALS | jq -e '.user' >/dev/null 2>&1 \
&& DB_USER=$(echo $CREDENTIALS | jq -r '.user')
echo $CREDENTIALS | jq -e '.username' >/dev/null 2>&1 \
&& DB_USER=$(echo $CREDENTIALS | jq -r '.username')
echo $CREDENTIALS | jq -e '.name' >/dev/null 2>&1 \
&& DB_NAME=$(echo $CREDENTIALS | jq -r '.name')
echo $CREDENTIALS | jq -e '.dbname' >/dev/null 2>&1 \
&& DB_NAME=$(echo $CREDENTIALS | jq -r '.dbname')
}
GET_SECRETSMANAGER_CREDENTIALS() {
local ID=$(\
_AWS secretsmanager list-secrets \
| jq -r '.[] | .[] | .Name' \
| __FZF 'select a secret' \
)
[ ! $ID ] && return 1
_AWS secretsmanager get-secret-value --secret-id "$ID" \
| jq -r '.SecretString' | jq
}
SELECT_DATABASE() {
local DATABASES=$(GET_AVAILABLE_DATABASES)
[ ! $DATABASES ] && __FAIL 1 'no databases available'
local ID=$(\
echo $DATABASES | jq -r '.instance + " @ " + .cluster' \
| __FZF 'select a database (instance@cluster)' \
)
[ ! $ID ] && __ABORT
local INSTANCE=$(echo $ID | sed 's/ @ .*$//')
local CLUSTER=$(echo $ID | sed 's/^.* @ //')
echo $DATABASES | jq "select (.instance == \"$INSTANCE\" and .cluster == \"$CLUSTER\")"
}
GET_AVAILABLE_DATABASES() {
_AWS rds describe-db-instances \
| jq -r '.[] | .[] | {
instance: .DBInstanceIdentifier,
cluster: .DBClusterIdentifier,
type: .Engine,
host: .Endpoint.Address,
port: .Endpoint.Port,
user: .MasterUsername,
database: .DBName
}'
}

22
zsh/aws/rds/create-backup Executable file
View File

@ -0,0 +1,22 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
RDS_INTERACTIVE_LOGIN() {
local DB_HOST DB_PORT DB_NAME DB_USER DB_PASS
GET_DATABASE_CREDENTIALS $@ || return 1
__RUN_SCWRYPT 'zsh/db/postgres/pg_dump' -- \
--host $DB_HOST \
--port $DB_PORT \
--name $DB_NAME \
--user $DB_USER \
--pass $DB_PASS \
;
}
#####################################################################
RDS_INTERACTIVE_LOGIN $@

View File

@ -4,118 +4,19 @@ _REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
__CONNECT_TO_RDS() {
local DATABASE=$(__SELECT_DATABASE)
[ ! $DATABASE ] && __ABORT
local DB_HOST DB_USER DB_PORT DB_NAME DB_AUTH DB_TYPE
DB_HOST=$(echo $DATABASE | jq -r '.host')
DB_USER=$(echo $DATABASE | jq -r '.user')
DB_PORT=$(echo $DATABASE | jq -r '.port')
DB_TYPE=$(echo $DATABASE | jq -r '.type')
[[ $DB_PORT =~ null ]] && DB_PORT=5432
DB_NAME=postgres
local AUTH_METHODS=(iam secretsmanager user-input)
local AUTH_METHOD=$(\
echo $AUTH_METHODS | sed 's/\s\+/\n/g' \
| __FZF 'select an authentication method' \
)
[ ! $AUTH_METHOD ] && __ABORT
case $AUTH_METHOD in
iam )
DB_AUTH=$(\
_AWS rds generate-db-auth-token \
--hostname $DB_HOST \
--port $DB_PORT \
--username $DB_USER \
)
;;
secretsmanager )
CREDENTIALS=$(__GET_SECRETSMANAGER_CREDENTIALS)
echo $CREDENTIALS | jq -e '.pass' >/dev/null 2>&1 \
&& DB_AUTH="'$(echo $CREDENTIALS | jq -r '.pass' | sed "s/'/'\"'\"'/g")'"
echo $CREDENTIALS | jq -e '.password' >/dev/null 2>&1 \
&& DB_AUTH="'$(echo $CREDENTIALS | jq -r '.password' | sed "s/'/'\"'\"'/g")'"
echo $CREDENTIALS | jq -e '.user' >/dev/null 2>&1 \
&& DB_USER=$(echo $CREDENTIALS | jq -r '.user')
echo $CREDENTIALS | jq -e '.username' >/dev/null 2>&1 \
&& DB_USER=$(echo $CREDENTIALS | jq -r '.username')
echo $CREDENTIALS | jq -e '.name' >/dev/null 2>&1 \
&& DB_NAME=$(echo $CREDENTIALS | jq -r '.name')
echo $CREDENTIALS | jq -e '.dbname' >/dev/null 2>&1 \
&& DB_NAME=$(echo $CREDENTIALS | jq -r '.dbname')
;;
user-input )
;;
esac
__STATUS
__STATUS "host : $DB_HOST"
__STATUS "type : $DB_TYPE"
__STATUS "port : $DB_PORT"
__STATUS "database : $DB_NAME"
__STATUS "username : $DB_USER"
__STATUS
RDS_INTERACTIVE_LOGIN() {
local DB_HOST DB_PORT DB_NAME DB_USER DB_PASS
GET_DATABASE_CREDENTIALS $@ || return 1
__RUN_SCWRYPT 'zsh/db/interactive/postgres' -- \
--host $DB_HOST \
--port $DB_PORT \
--name $DB_NAME \
--user $DB_USER \
--pass $DB_AUTH \
--pass $DB_PASS \
;
}
__SELECT_DATABASE() {
local DATABASES=$(__GET_AVAILABLE_DATABASES)
[ ! $DATABASES ] && __FAIL 1 'no databases available'
local ID=$(\
echo $DATABASES | jq -r '.instance + " @ " + .cluster' \
| __FZF 'select a database (instance@cluster)' \
)
[ ! $ID ] && __ABORT
local INSTANCE=$(echo $ID | sed 's/ @ .*$//')
local CLUSTER=$(echo $ID | sed 's/^.* @ //')
echo $DATABASES | jq "select (.instance == \"$INSTANCE\" and .cluster == \"$CLUSTER\")"
}
__GET_AVAILABLE_DATABASES() {
_AWS rds describe-db-instances \
| jq -r '.[] | .[] | {
instance: .DBInstanceIdentifier,
cluster: .DBClusterIdentifier,
type: .Engine,
host: .Endpoint.Address,
port: .Endpoint.Port,
user: .MasterUsername,
database: .DBName
}'
}
__GET_SECRETSMANAGER_CREDENTIALS() {
local ID=$(\
_AWS secretsmanager list-secrets \
| jq -r '.[] | .[] | .Name' \
| __FZF 'select a secret' \
)
[ ! $ID ] && return 1
_AWS secretsmanager get-secret-value --secret-id "$ID" \
| jq -r '.SecretString' | jq
}
#####################################################################
__CONNECT_TO_RDS
RDS_INTERACTIVE_LOGIN $@

22
zsh/aws/rds/load-backup Executable file
View File

@ -0,0 +1,22 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
RDS_INTERACTIVE_LOGIN() {
local DB_HOST DB_PORT DB_NAME DB_USER DB_PASS
GET_DATABASE_CREDENTIALS $@ || return 1
__RUN_SCWRYPT 'zsh/db/postgres/pg_restore' -- \
--host $DB_HOST \
--port $DB_PORT \
--name $DB_NAME \
--user $DB_USER \
--pass $DB_PASS \
;
}
#####################################################################
RDS_INTERACTIVE_LOGIN $@

View File

@ -13,7 +13,7 @@ _ROUTE53_BACKUP() {
for DOMAIN in $(_ROUTE53_GET_DOMAINS)
do
( __STATUS "creating '$BACKUP_PATH/$DOMAIN.txt'" \
&& cli53 export --profile $_AWS_PROFILE $DOMAIN > "$BACKUP_PATH/$DOMAIN.txt" \
&& cli53 export --profile $AWS_PROFILE $DOMAIN > "$BACKUP_PATH/$DOMAIN.txt" \
&& __SUCCESS "backed up '$DOMAIN'" \
|| __ERROR "failed to back up '$DOMAIN'" \
) &
@ -25,7 +25,7 @@ _ROUTE53_BACKUP() {
}
_ROUTE53_GET_DOMAINS() {
cli53 list --profile $_AWS_PROFILE \
cli53 list --profile $AWS_PROFILE \
| awk '{print $2;}' \
| sed '1d; s/\.$//'\
;

View File

@ -24,7 +24,7 @@ __SYNC_MEDIA() {
local FLAGS=(${@:3})
__STATUS "${ACTION}ing $2"
_AWS s3 sync $REMOTE_TARGET $LOCAL_TARGET $FLAGS \
_AWS s3 sync $A $B $FLAGS \
&& __SUCCESS "$2 up-to-date" \
|| { __ERROR "unable to sync $2 (see above)"; return 1; }
}

View File

@ -1,21 +1,12 @@
#####################################################################
[ ! $SCWRYPTS_ROOT ] && SCWRYPTS_ROOT="$(dirname ${0:a:h})"
__PREFERRED_PYTHON_VERSIONS=(3.10 3.9)
__NODE_VERSION=18.0.0
__ENV_TEMPLATE=$SCWRYPTS_ROOT/.env.template
__SCWRYPT=1
source $SCWRYPTS_ROOT/.config
source ${0:a:h}/utils/utils.module.zsh || {
[ $DONT_EXIT ] && return 1 || exit 1
}
source ${0:a:h}/../global/common.zsh
source ${0:a:h}/utils/utils.module.zsh \
|| { [ $DONT_EXIT ] && return 1 || exit 1; }
#####################################################################
__GET_ENV_FILES() { find $SCWRYPTS_CONFIG_PATH/env -maxdepth 1 -type f | sort -r }
__GET_ENV_FILES() { ls $SCWRYPTS_CONFIG_PATH/env | sort -r }
[ ! "$(__GET_ENV_FILES)" ] && {
cp $__ENV_TEMPLATE "$SCWRYPTS_CONFIG_PATH/env/dev"
cp $__ENV_TEMPLATE "$SCWRYPTS_CONFIG_PATH/env/local"
@ -26,33 +17,15 @@ __GET_ENV_NAMES() { __GET_ENV_FILES | sed 's/.*\///'; }
__GET_ENV_FILE() { echo "$SCWRYPTS_CONFIG_PATH/env/$1"; }
__SELECT_OR_CREATE_ENV() { __GET_ENV_NAMES | __FZF_TAIL 'select/create an environment'; }
__SELECT_ENV() { __GET_ENV_NAMES | __FZF 'select an environment'; }
__SELECT_ENV() { __GET_ENV_NAMES | __FZF 'select an environment'; }
#####################################################################
__GET_AVAILABLE_SCRIPTS() {
cd $SCWRYPTS_ROOT;
find . -mindepth 2 -type f -executable \
| grep -v '\.git' \
| grep -v '\.env' \
| grep -v 'node_modules' \
| sed 's/^\.\///; s/\.[^.]*$//' \
;
}
#####################################################################
__RUN_SCWRYPT() {
# run a scwrypt inside a scwrypt w/stack-depth indicators
((SUBSCWRYPT+=1))
printf ' '; printf '--%.0s' {1..$SUBSCWRYPT}; printf " ($SUBSCWRYPT) "
echo " BEGIN SUBSCWRYPT : $(basename $1)"
SUBSCWRYPT=$SUBSCWRYPT SCWRYPTS_ENV=$ENV_NAME \
"$SCWRYPTS_ROOT/scwrypts" $@
EXIT_CODE=$?
printf ' '; printf '--%.0s' {1..$SUBSCWRYPT}; printf " ($SUBSCWRYPT) "
echo " END SUBSCWRYPT : $(basename $1)"
((SUBSCWRYPT-=1))
return $EXIT_CODE
}

14
zsh/config/common.zsh Normal file
View File

@ -0,0 +1,14 @@
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
DEFAULT_CONFIG="${0:a:h}/default.conf.zsh"
source ${0:a:h}/../common.zsh
#####################################################################
SAFE_SYMLINKS=1
# in case dotfiles.zsh is sourced... allow user to provide initial config ;)
[ ! $CONFIG__USER_SETTINGS ] \
&& CONFIG__USER_SETTINGS="$SCWRYPTS_CONFIG_PATH/dotfiles.zsh"
[ ! -f "$CONFIG__USER_SETTINGS" ] && cp "$DEFAULT_CONFIG" "$CONFIG__USER_SETTINGS"
source $CONFIG__USER_SETTINGS

View File

@ -0,0 +1,19 @@
#
# scwrypts dot-files config
#
#TERMINFO_PATH=/path/to/sourced/terminfo/files
#
# SAFE_SYMLINKS=1, makes a backup of config files that already exist
# SAFE_SYMLINKS=0, deletes existing config file
#
#SAFE_SYMLINKS=1
# lines which begin with '#' are ignored
SYMLINKS="
# fully qualified path ~/.config/THE-REST
# ---------------------------------------------
# /path/to/your/kitty.conf kitty/kitty.conf
"

6
zsh/config/settings Executable file
View File

@ -0,0 +1,6 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
__EDIT "$CONFIG__USER_SETTINGS"

36
zsh/config/symlinks Executable file
View File

@ -0,0 +1,36 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
SETUP_SYMLINKS() {
while read SYMLINK
do
SETUP_SYMLINK $(echo $SYMLINK | awk '{print $1;}') $(echo $SYMLINK | awk '{print $2}')
done < <(echo $SYMLINKS | sed -n '/^[^#]/p')
}
SETUP_SYMLINK() {
[ ! $2 ] && __FAIL 1 'must provide SOURCE_CONFIG and TARGET_CONFIG'
local SOURCE_CONFIG="$1"
[ ! -f "$SOURCE_CONFIG" ] && [ ! -d "$SOURCE_CONFIG" ] && __FAIL 2 "no such file or directory '$SOURCE_CONFIG'"
local TARGET_CONFIG="$HOME/.config/$2"
[ ! -d $(dirname "$TARGET_CONFIG") ] && mkdir -p $(dirname "$TARGET_CONFIG")
[[ $SAFE_SYMLINKS -eq 1 ]] \
&& mv "$TARGET_CONFIG" "$TARGET_CONFIG.bak" >/dev/null 2>&1
rm "$TARGET_CONFIG" >/dev/null 2>&1
ln -s "$SOURCE_CONFIG" "$TARGET_CONFIG" \
&& __SUCCESS "successfully linked '$(basename $(dirname $TARGET_CONFIG))/$(basename $TARGET_CONFIG)'" \
|| __FAIL 3 "failed to create link '$TARGET_CONFIG'" \
;
}
#####################################################################
SETUP_SYMLINKS $@

26
zsh/config/terminfo Executable file
View File

@ -0,0 +1,26 @@
#!/bin/zsh
_DEPENDENCIES+=(
tic
)
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
SETUP_TERMINFO() {
[ ! $TERMINFO_PATH ] && return 0
[ ! -d $TERMINFO_PATH ] && __FAIL 1 "TERMINFO_PATH='$TERMINFO_PATH' does not exist"
local ERRORS=0
for TERMINFO in $(find $TERMINFO_PATH -type f)
do
tic -x $TERMINFO >/dev/null 2>&1 \
&& __SUCCESS "added '$(basename $TERMINFO)'" \
|| __ERROR "failed to add '$(basename $TERMINFO)'" \
;
done
__ERROR_CHECK
}
#####################################################################
SETUP_TERMINFO $@

10
zsh/config/update Executable file
View File

@ -0,0 +1,10 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
__STATUS 'updating all config files and links'
__RUN_SCWRYPT zsh/config/symlinks || exit 1
__RUN_SCWRYPT zsh/config/terminfo || exit 2
__SUCCESS 'finished updating config files and links'

View File

@ -2,3 +2,23 @@ _DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
#####################################################################
GET_POSTGRES_LOGIN_ARGS() {
while [[ $# -gt 0 ]]
do
case $1 in
--host | -h ) _HOST="$2"; shift 2 ;;
--name | -d ) _NAME="$2"; shift 2 ;;
--pass | -w ) _PASS="$2"; shift 2 ;;
--port | -p ) _PORT="$2"; shift 2 ;;
--user | -U ) _USER="$2"; shift 2 ;;
* ) shift 1 ;;
esac
done
[ ! $_HOST ] && _HOST=127.0.0.1
[ ! $_NAME ] && _NAME=postgres
[ ! $_PORT ] && _PORT=5432
[ ! $_USER ] && _USER=postgres
}

View File

@ -8,23 +8,7 @@ source ${0:a:h}/common.zsh
_LOGIN_POSTGRES() {
local _HOST _NAME _PASS _PORT _USER
while [[ $# -gt 0 ]]
do
case $1 in
--host | -h ) _HOST="$2"; shift 2 ;;
--name | -d ) _NAME="$2"; shift 2 ;;
--pass | -w ) _PASS="$2"; shift 2 ;;
--port | -p ) _PORT="$2"; shift 2 ;;
--user | -U ) _USER="$2"; shift 2 ;;
* ) shift 1 ;;
esac
done
[ ! $_HOST ] && _HOST=127.0.0.1
[ ! $_NAME ] && _NAME=postgres
[ ! $_PORT ] && _PORT=5432
[ ! $_USER ] && _USER=postgres
GET_POSTGRES_LOGIN_ARGS $@
local DATA_DIR="$SCWRYPTS_DATA_PATH/db/$_HOST"
[ ! -d $DATA_DIR ] && mkdir -p $DATA_DIR

View File

@ -0,0 +1,4 @@
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
#####################################################################

44
zsh/db/postgres/pg_dump Executable file
View File

@ -0,0 +1,44 @@
#!/bin/zsh
_DEPENDENCIES+=(
pg_dump
)
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
BACKUP_POSTGRES() {
local _HOST _NAME _PASS _PORT _USER
GET_POSTGRES_LOGIN_ARGS $@
local DATA_DIR="$SCWRYPTS_DATA_PATH/db/$_HOST/$_NAME/pg_dump"
[ ! -d $DATA_DIR ] && mkdir -p $DATA_DIR
cd $DATA_DIR
local OUTPUT_FILE="$DATA_DIR/$_NAME.dump"
[ -f $OUTPUT_FILE ] && {
local BACKUP_COUNT=$(ls "$DATA_DIR/$_NAME."*".dump" | wc -l)
ls "$DATA_DIR/$_NAME."*".dump"
__INFO "discovered previous dump for '$_HOST/$_NAME'"
__INFO "backing up previous dump to '$_NAME.$BACKUP_COUNT.dump'"
mv "$OUTPUT_FILE" "$DATA_DIR/$_NAME.$BACKUP_COUNT.dump"
}
__STATUS "making backup of : $_USER@$_HOST:$_PORT/$_NAME"
__STATUS "output file : $OUTPUT_FILE"
PGPASSWORD="$_PASS" pg_dump \
--verbose \
--format custom \
--host "$_HOST" \
--port "$_PORT" \
--username "$_USER" \
--dbname "$_NAME" \
--file "$OUTPUT_FILE" \
&& { __SUCCESS "finished backup of '$_HOST/$_NAME'"; __SUCCESS "saved to '$OUTPUT_FILE'"; } \
|| { __ERROR "error creating backup for '$_HOST/$_NAME' (see above)"; return 1; }
}
#####################################################################
BACKUP_POSTGRES $@

55
zsh/db/postgres/pg_restore Executable file
View File

@ -0,0 +1,55 @@
#!/bin/zsh
_DEPENDENCIES+=(
pg_dump
)
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
BACKUP_POSTGRES() {
local _HOST _NAME _PASS _PORT _USER
GET_POSTGRES_LOGIN_ARGS $@
local DATA_DIR="$SCWRYPTS_DATA_PATH/db/$_HOST/$_NAME/pg_restore"
[ ! -d $DATA_DIR ] && mkdir -p $DATA_DIR
cd $DATA_DIR
local INPUT_FILE="$DATA_DIR/$_NAME.dump"
[ ! -f $INPUT_FILE ] && {
local DUMP="$(dirname $DATA_DIR)/pg_dump/$_NAME.dump"
__STATUS $DUMP
ls $DUMP
[ -f "$DUMP" ] && {
__SUCCESS "discovered previous scwrypts dump"
__SUCCESS "$DUMP"
__Yn 'restore from this backup?' && INPUT_FILE="$DUMP"
}
[ ! -f "$INPUT_FILE" ] && {
__STATUS 'place backup in the following location:'
__STATUS "$INPUT_FILE"
}
while [ ! -f $INPUT_FILE ]; do sleep 1; done
}
__STATUS "backup file : $DATA_DIR"
__STATUS "database : $_USER@$_HOST:$_PORT/$_NAME"
PGPASSWORD="$_PASS" pg_restore \
--verbose \
--single-transaction \
--format custom \
--host "$_HOST" \
--port "$_PORT" \
--username "$_USER" \
--dbname "$_NAME" \
"$INPUT_FILE" \
&& { __SUCCESS "finished restoring backup for '$_HOST/$_NAME'"; } \
|| { __ERROR "error restoring backup for '$_HOST/$_NAME' (see above)"; return 1; }
}
#####################################################################
BACKUP_POSTGRES $@

View File

@ -0,0 +1,4 @@
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
#####################################################################

72
zsh/db/run-sql/postgres Executable file
View File

@ -0,0 +1,72 @@
#!/bin/zsh
_DEPENDENCIES+=(
psql
)
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
_RUN_SQL_POSTGRES() {
local _HOST _NAME _PASS _PORT _USER INPUT_FILE
while [[ $# -gt 0 ]]
do
case $1 in
--host | -h ) _HOST="$2"; shift 2 ;;
--name | -d ) _NAME="$2"; shift 2 ;;
--pass | -w ) _PASS="$2"; shift 2 ;;
--port | -p ) _PORT="$2"; shift 2 ;;
--user | -U ) _USER="$2"; shift 2 ;;
--file | -i ) INPUT_FILE="$2"; shift 2 ;;
* ) shift 1 ;;
esac
done
[ ! $_HOST ] && _HOST=127.0.0.1
[ ! $_NAME ] && _NAME=postgres
[ ! $_PORT ] && _PORT=5432
[ ! $_USER ] && _USER=postgres
local SQL_DIR="$SCWRYPTS_DATA_PATH/sql"
[ ! -d $SQL_DIR ] && mkdir -p $SQL_DIR
cd $SQL_DIR
[[ $(ls "*.sql" 2>&1 | wc -l) -eq 0 ]] && {
__ERROR "you haven't made any SQL commands yet"
__REMINDER "add '.sql' files here: '$SQL_DIR/'"
exit 1
}
[ ! $INPUT_FILE ] && INPUT_FILE=$(\
__FZF 'select a sql file to run'
)
[ ! $INPUT_FILE ] && __ABORT
[ ! -f $INPUT_FILE ] && {
__FAIL 2 "no such sql file '$SQL_DIR/$INPUT_FILE'"
}
__STATUS "loading $INPUT_FILE preview..."
_LESS $INPUT_FILE
__STATUS "login : $_USER@$_HOST:$_PORT/$_NAME"
__STATUS "command : ./$INPUT_FILE"
__yN 'run this command?' || __ABORT
__STATUS "running './$INPUT_FILE'"
PGPASSWORD="$_PASS" psql \
-h $_HOST \
-p $_PORT \
-U $_USER \
-d $_NAME \
< $INPUT_FILE \
&& __SUCCESS "finished running './$INPUT_FILE'" \
|| __FAIL 3 "something went wrong running './$INPUT_FILE' (see above)"
}
#####################################################################
__WARNING
__WARNING 'this function is in a beta state'
__WARNING
_RUN_SQL_POSTGRES $@

6
zsh/git/common.zsh Normal file
View File

@ -0,0 +1,6 @@
_DEPENDENCIES+=(
git
)
_REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
#####################################################################

6
zsh/git/package/build Executable file
View File

@ -0,0 +1,6 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
__RUN_SCWRYPT zsh/git/package/install -- --only-build $@

View File

@ -0,0 +1,74 @@
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
#####################################################################
PACKAGE_INSTALL_DIR="$HOME/.local/share/source-packages"
[ ! -d "$PACKAGE_INSTALL_DIR" ] && mkdir -p "$PACKAGE_INSTALL_DIR"
#####################################################################
CLONE() {
cd "$PACKAGE_INSTALL_DIR"
__STATUS "downloading $NAME"
git clone "$TARGET" "$NAME" \
&& __SUCCESS "successfully downloaded '$NAME'" \
|| __FAIL 1 "failed to download '$NAME'" \
;
}
PULL() {
__STATUS "updating '$NAME'"
cd "$PACKAGE_INSTALL_DIR/$NAME"
git pull origin $(git rev-parse --abbrev-ref HEAD) \
&& __SUCCESS "successfully updated '$NAME'" \
|| __FAIL 1 "failed to update '$NAME'" \
;
}
#####################################################################
BUILD() {
cd "$PACKAGE_INSTALL_DIR/$NAME"
CHECK_MAKE && { MAKE && return 0 || return 1; }
CHECK_MAKEPKG && { MAKEPKG && return 0 || return 2; }
__WARNING 'could not detect supported installation method'
__REMINDER 'complete manual installation in the directory below:'
__REMINDER "$PACKAGE_INSTALL_DIR/$NAME"
}
CHECK_MAKE() { [ -f ./Makefile ]; }
CHECK_MAKEPKG() { [ -f ./PKGBUILD ]; }
MAKE() {
[[ $CLEAN -eq 1 ]] && {
__STATUS "cleaning '$NAME'"
make clean
}
__STATUS "building '$NAME'"
make \
&& __SUCCESS "finished building '$NAME'" \
|| __FAIL 1 "build failed for '$NAME' (see above)"\
;
__STATUS "installing '$NAME'"
__GETSUDO
sudo make install \
&& __SUCCESS "succesfully installed '$NAME'" \
|| __FAIL 2 "failed to install '$NAME' (see above)"\
;
}
MAKEPKG() {
__STATUS "installing '$NAME'"
yes | makepkg -si \
&& __SUCCESS "succesfully installed '$NAME'" \
|| __FAIL 1 "failed to install '$NAME' (see above)"\
;
}
#####################################################################

6
zsh/git/package/download Executable file
View File

@ -0,0 +1,6 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
__RUN_SCWRYPT zsh/git/package/install -- --only-pull $@

88
zsh/git/package/install Executable file
View File

@ -0,0 +1,88 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
INSTALL() {
local USAGE="
usage: [...options...]
options
-t, --target-url <string> target URL; required for first-time download
-n, --local-name <string> local name for package (optional)
-u, --update if package exists, update without prompt
-b, --only-build if package exists, skip update step and only build
-p, --only-pull skip the automated build step
-c, --clean for make, run make clean before build
-h, --help print this message and exit
"
local NAME
local TARGET
local SKIP_BUILD=0
local SKIP_PULL=0
local UPDATE=0
local CLEAN=0
while [[ $# -gt 0 ]]
do
case $1 in
-t | --target-url ) TARGET="$2"; shift 1 ;;
-n | --local-name ) NAME="$2"; shift 1 ;;
-u | --update ) UPDATE=1 ;;
-b | --only-build ) SKIP_PULL=1 ;;
-p | --only-pull ) SKIP_BUILD=1 ;;
-c | --clean ) CLEAN=1 ;;
-h | --help ) __USAGE; exit 0 ;;
-* ) __ERROR "unknown argument '$1'" ;;
* ) [ ! $TARGET ] && TARGET="$1" \
|| __ERROR "extra positional argument '$1'" \
;
;;
esac
shift 1
done
[[ $SKIP_PULL -eq 1 ]] && [[ $SKIP_BUILD -eq 1 ]] && __ERROR 'only one of [-b | -p] can be specified'
[ ! $TARGET ] && [ ! $NAME ] && {
[[ $SKIP_BUILD -eq 1 ]] && {
__ERROR 'cannot skip build without specifying package local-name'
} || {
UPDATE=1
NAME=$(ls "$PACKAGE_INSTALL_DIR" | __FZF 'select a package to update')
[ ! $NAME ] && __ERROR 'target-url required'
}
}
__ERROR_CHECK
####################################################
[ ! $NAME ] && {
NAME=$(echo $TARGET | sed 's/.*\///; s/\.git$//')
__INFO "using default name '$NAME'"
}
[ -d "$PACKAGE_INSTALL_DIR/$NAME" ] && [[ $SKIP_PULL -eq 0 ]] && {
[[ $UPDATE -eq 0 ]] && __Yn "package '$NAME' already exists; update now?" && UPDATE=1
[[ $UPDATE -eq 1 ]] && PULL || return 1
}
[ ! -d "$PACKAGE_INSTALL_DIR/$NAME" ] && {
CLONE || return 2
}
[[ $SKIP_BUILD -eq 1 ]] && return 0
BUILD
}
#####################################################################
INSTALL $@

6
zsh/git/package/update Executable file
View File

@ -0,0 +1,6 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
__RUN_SCWRYPT zsh/git/package/install -- --update $@

14
zsh/i3/common.zsh Normal file
View File

@ -0,0 +1,14 @@
_DEPENDENCIES+=(
i3
i3-msg
)
_REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
#####################################################################
[ ! $DISPLAY ] && export DISPLAY=:0
_NOTIFY() {
__CHECK_DEPENDENCY notify-send || return 0
notify-send "SCWRYPTS $SCWRYPT_NAME" $@
}

105
zsh/i3/create-local-font-override Executable file
View File

@ -0,0 +1,105 @@
#!/bin/zsh
_DEPENDENCIES+=(
diff
)
_REQUIRED_ENV+=(
I3__MODEL_CONFIG
)
source ${0:a:h}/common.zsh
__CHECK_ENV_VAR I3__GLOBAL_FONT_SIZE --optional
__CHECK_ENV_VAR I3__DMENU_FONT_SIZE --optional
__CHECK_ENV_VAR I3__BORDER_PIXEL_SIZE --optional
#####################################################################
REGEX_FONT='^\(font [^0-9]*\)\(.*\)'
REGEX_DMENU="^\\(.*dmenu_run .*-fn '[^0-9]*\\)\\([0-9]*\\)'"
REGEX_BORDER='^\(for_window.*border pixel \)\(.*\)'
INSTALL() {
local USAGE="
usage: [...options...]
options
-f, --force force replacement of existing i3config
-n, --no-link if output config and template are the same, don't create link
-h, --help print this message and exit
environment
I3__MODEL_CONFIG fully-qualified path to sourced i3config
I3__GLOBAL_FONT_SIZE global font size
I3__DMENU_FONT_SIZE (optional) font size for 'dmenu' command
I3__BORDER_PIXEL_SIZE (optional) pixel-width of window borders
I3 provides no way to include dynamic variables in your config.
The main difference I want between my i3 configurations is font-size
to match the current monitor. Since i3-msg provides no way to change
font size, I run this command to update those variables on a local
copy of my sourced config
"
local FORCE=0
local AUTOLINK=1
while [[ $# -gt 0 ]]
do
case $1 in
-f | --force ) FORCE=1 ;;
-n | --no-link ) AUTOLINK=0 ;;
-h | --help ) __USAGE; exit 0 ;;
esac
shift 1
done
__STATUS 'reading local i3config'
[[ ^$I3__MODEL_CONFIG$ =~ ^$HOME/.config/i3/config$ ]] && {
__STATUS "model configuration is default configuration"
I3__MODEL_CONFIG="$I3__MODEL_CONFIG.template"
[ ! -f "$I3__MODEL_CONFIG" ] && {
__STATUS "creating template"
cp "$HOME/.config/i3/config" "$I3__MODEL_CONFIG.template"
}
__STATUS "referring to '$I3__MODEL_CONFIG'"
}
local CONFIG=$(cat "$I3__MODEL_CONFIG")
[ ! $CONFIG ] && __FAIL 1 "failed to read config at '$I3__MODEL_CONFIG'"
local CONFIG_FILE="$HOME/.config/i3/config"
[ ! -d $(dirname "$CONFIG_FILE") ] && mkdir -p "$(dirname "$CONFIG_FILE")"
[ -f "$CONFIG_FILE" ] && mv "$CONFIG_FILE" "$CONFIG_FILE.bak"
[ $I3__GLOBAL_FONT_SIZE ] && {
__STATUS "setting global font size to '$I3__GLOBAL_FONT_SIZE'"
CONFIG=$(echo $CONFIG | sed "s/$REGEX_FONT/\\1$I3__GLOBAL_FONT_SIZE/")
}
[ $I3__DMENU_FONT_SIZE ] && {
__STATUS "setting dmenu font size to '$I3__DMENU_FONT_SIZE'"
CONFIG=$(echo $CONFIG | sed "s/$REGEX_DMENU/\\1$I3__DMENU_FONT_SIZE'/")
}
[ $I3__BORDER_PIXEL_SIZE ] && {
__STATUS "setting border pixel size to '$I3__BORDER_PIXEL_SIZE'"
CONFIG=$(echo $CONFIG | sed "s/$REGEX_BORDER/\\1$I3__BORDER_PIXEL_SIZE/")
}
echo $CONFIG > "$CONFIG_FILE"
[ -f "$CONFIG_FILE.bak" ] \
&& diff "$CONFIG_FILE" "$CONFIG_FILE.bak" -q >/dev/null \
&& mv "$CONFIG_FILE.bak" "$CONFIG_FILE" \
&& __INFO "no changes were made" \
;
[[ $AUTOLINK -eq 1 ]] \
&& diff "$CONFIG_FILE" "$I3__MODEL_CONFIG" -q >/dev/null \
&& rm "$CONFIG_FILE" \
&& ln -s "$I3__MODEL_CONFIG" "$CONFIG_FILE" \
&& __INFO "output is the same as model, i3config has been linked to model" \
;
[[ $FORCE -eq 1 ]] && rm "$CONFIG.bak" >/dev/null 2>&1
return 0
}
#####################################################################
INSTALL $@

114
zsh/i3/launch-or-show Executable file
View File

@ -0,0 +1,114 @@
#!/bin/zsh
_DEPENDENCIES+=(
xdotool
xrandr
i3-msg
)
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
LAUNCH_OR_SHOW() {
__INFO $@
local USAGE="
usage: <path-executable> [client-class] [...options...]
options
-c, --client <string> if different from the executable name, xprop CLIENT_CLASS
-s, --scale <value> (default: 0.8 or 0.5 if screen width >3000px)
-x, --x-offset <value> (default: 0.0)
-y, --y-offset <value> (default: 0.0)
-a, --always-launch invoke executable even if client-class exists
-n, --no-resize don't resize the window (ignores -sxy flags)
-h, --help print this message and exit
Makes it easy to bind appications to key shortcuts without having to
spin up redundant instances or cycle through the scratchpad queue.
Depending on state, performs one of three useful functions
1) starts application
2) adds application window to the scratchpad
3) pulls application from scratchpad to foreground on active screen
"
local APPLICATION CLIENT_CLASS
local XFFSET=0.0
local YFFSET=0.0
local SCALE=0.8
[[ $(xrandr | grep primary | awk '{print $4;}' | sed 's/x.*//') -gt 3000 ]] \
&& SCALE=0.5
local ALWAYS_LAUNCH=0
local RESIZE=1
while [[ $# -gt 0 ]]
do
case $1 in
-c | --client ) CLIENT_CLASS="$2"; shift 1 ;;
-x | --x-offset ) XFFSET=$2; shift 1 ;;
-y | --y-offset ) YFFSET=$2; shift 1 ;;
-s | --scale ) SCALE=$2; shift 1 ;;
-a | --always-launch ) ALWAYS_LAUNCH=1 ;;
-n | --no-resize ) RESIZE=0 ;;
-h | --help ) __USAGE; exit 0 ;;
* )
[ ! $APPLICATION ] && APPLICATION="$1" \
|| __ERROR "extra positional argument '$1'"
esac
shift 1
done
[ ! $APPLICATION ] && __ERROR 'path-executable required'
[ ! $CLIENT_CLASS ] && CLIENT_CLASS=$APPLICATION
[ $APPLICATION ] && {
__CHECK_DEPENDENCY $APPLICATION || {
__ERROR "$APPLICATION is not installed"
_NOTIFY "ERROR: $APPLICATION not found"
}
}
__ERROR_CHECK
local LAUNCH_APP=$ALWAYS_LAUNCH
__STATUS "looking for window process ids"
xdotool search --class $CLIENT_CLASS || LAUNCH_APP=1
[[ $LAUNCH_APP -eq 1 ]] && {
__STATUS 'launching application'
i3-msg "exec --no-startup-id $APPLICATION;"
sleep .5
}
__STATUS 'getting target window size'
WINDOW_SIZE=$(\
xrandr \
| grep 'connected primary' \
| sed 's/.*connected primary \([^x]*\)x\([^+]*\).*/\1 \2/' \
| awk -v f=$SCALE -v x=$XFFSET -v y=$YFFSET \
'{print int($1*f+x)," ",int($2*f+y);}'\
)
__INFO "window size: $WINDOW_SIZE"
__STATUS 'moving window to scratchpad'
i3-msg "[class=$CLIENT_CLASS] move scratchpad"
[[ $RESIZE -eq 1 ]] \
&& __STATUS 'resizing window' \
&& i3-msg "[class=$CLIENT_CLASS] resize set $WINDOW_SIZE"
__STATUS 'pulling window from scratchpad to foreground'
i3-msg "[class=$CLIENT_CLASS] scratchpad show"
__STATUS 'moving window to center of current screen'
i3-msg "[class=$CLIENT_CLASS] move position center"
}
#####################################################################
LAUNCH_OR_SHOW $@

31
zsh/latex/build-pdf Executable file
View File

@ -0,0 +1,31 @@
#!/bin/zsh
_DEPENDENCIES+=(
pdflatex
rg
)
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
PDFLATEX() {
[ ! $1 ] && __FAIL 1 'must provide filename'
local FILENAME=$(GET_MAIN_LATEX_FILENAME "$1")
local ARGS=(-interaction=nonstopmode)
ARGS+=("$FILENAME")
cd "$(dirname $FILENAME)"
__STATUS 'running compile (1/2)'
pdflatex ${ARGS[@]} \
|| __FAIL 2 'first compile failed (see above)'
__STATUS 'running compile (2/2)'
pdflatex ${ARGS[@]} >/dev/null 2>&1 \
|| __FAIL 3 'second compile failed :c'
__SUCCESS "created '$(echo $FILENAME | sed 's/\.[^.]*$/.pdf/')'"
}
#####################################################################
PDFLATEX $@

20
zsh/latex/cleanup Executable file
View File

@ -0,0 +1,20 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
CLEAN_LATEX_LOGFILES() {
local DIRECTORY=$(__GET_PATH_TO_RELATIVE_ARGUMENT ".")
[ $1 ] && DIRECTORY="$(dirname "$(GET_MAIN_LATEX_FILENAME "$1")")"
[ $DIRECTORY ] && [ -d $DIRECTORY ] \
|| __FAIL 1 'unable to parse valid directory'
cd $DIRECTORY
rm $(ls | grep '\.\(aux\)\|\(log\)\|\(pdf\)\|\(out\)\|\(dvi\)$')
__SUCCESS "cleaned up latex artifacts in '$DIRECTORY'"
}
#####################################################################
CLEAN_LATEX_LOGFILES $@

34
zsh/latex/common.zsh Normal file
View File

@ -0,0 +1,34 @@
_DEPENDENCIES+=(
rg
)
_REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
#####################################################################
GET_MAIN_LATEX_FILENAME() {
local FILENAME=$(__GET_PATH_TO_RELATIVE_ARGUMENT "$1")
local DIRNAME="$FILENAME"
for _ in {1..3}
do
CHECK_IS_MAIN_LATEX_FILE && return 0
DIRNAME="$(dirname "$FILENAME")"
__STATUS "checking '$DIRNAME'"
[[ $DIRNAME =~ ^$HOME$ ]] && break
FILENAME=$(
rg -l --max-depth 1 'documentclass' "$DIRNAME/" \
| grep '\.tex$' \
| head -n1 \
)
__STATUS "here is '$FILENAME'"
done
__WARNING 'unable to find documentclass; pdflatex will probably fail'
echo "$1"
}
CHECK_IS_MAIN_LATEX_FILE() {
[ ! $FILENAME ] && return 1
grep -q 'documentclass' $FILENAME 2>/dev/null && echo $FILENAME || return 3
}

63
zsh/latex/create-new Executable file
View File

@ -0,0 +1,63 @@
#!/bin/zsh
_DEPENDENCIES+=(
pdflatex
rg
)
_REQUIRED_ENV+=()
TEMPLATE_DIR="${0:a:h}/templates"
source ${0:a:h}/common.zsh
#####################################################################
CREATE_NEW_LATEX_DOCUMENT_FROM_TEMPLATE() {
local DOCUMENT_DIR="$EXECUTION_DIR"
local TEMPLATE=$(GET_TEMPLATES | __FZF 'select a template')
[ ! $TEMPLATE ] && __ABORT
__SUCCESS "selected template '$TEMPLATE'"
__INPUT DOC_TITLE 'document title' || __ABORT
local DOCUMENT_FILE="$DOCUMENT_DIR/$(SLUGIFY_TITLE).tex"
[ -f "$DOCUMENT_FILE" ] && __FAIL 1 "'$(basename $DOCUMENT_FILE)' already exists"
__INPUT DOC_ID 'document id/subtitle'
__INPUT AUTHOR 'author name'
__INPUT AUTHOR_ID 'author id/title'
{
PRINT_TITLE_INFO
cat "$TEMPLATE_DIR/$TEMPLATE/template.tex"
} > "$DOCUMENT_FILE"
cp "$TEMPLATE_DIR/gitignore" "$DOCUMENT_DIR/.gitignore"
for FILE in $(find "$TEMPLATE_DIR/$TEMPLATE" -type f | grep -v '/template.tex$')
do
cp "$FILE" "$DOCUMENT_DIR/" || return 2
done
[[ ! $TEMPLATE =~ ^basic$ ]] \
&& mkdir "$DOCUMENT_DIR/sections" "$DOCUMENT_DIR/graphics"
__SUCCESS "finished generating '$(basename $DOCUMENT_FILE)' from '$TEMPLATE'"
}
GET_TEMPLATES() {
find "$TEMPLATE_DIR" -type d | sed "s^$TEMPLATE_DIR/*^^; /^$/d"
}
PRINT_TITLE_INFO() {
local DATESTRING=$(date '+%B %_d, %Y' | sed 's/ \{1,\}/ /g')
sed "
s^LATEX-DOC-TITLE^$DOC_TITLE^
s^LATEX-DOC-DATE^$DATESTRING^
s^LATEX-DOC-ID^$DOC_ID^
s^LATEX-AUTHOR-NAME^$AUTHOR^
s^LATEX-AUTHOR-ID^$AUTHOR_ID^
" "$TEMPLATE_DIR/main.tex"
}
SLUGIFY_TITLE() {
echo $DOC_TITLE | sed "s^['\"\\/,\!@#\$%^&*()]*^^g; s^\s\+^-^g;"
}
#####################################################################
CREATE_NEW_LATEX_DOCUMENT_FROM_TEMPLATE $@

15
zsh/latex/get-pdf Executable file
View File

@ -0,0 +1,15 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
GET_PDF() {
local FILENAME=$(GET_MAIN_LATEX_FILENAME "$1" | sed 's/\.[^.]*$/.pdf/')
[ $FILENAME ] && [ -f $FILENAME ] || __FAIL 1 "no compiled pdf found for '$1'; have you run 'build-pdf'?"
__SUCCESS 'found main pdf'
echo $FILENAME
}
#####################################################################
GET_PDF $@

15
zsh/latex/open-pdf Executable file
View File

@ -0,0 +1,15 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
OPEN_PDF() {
local PDF=$(__RUN_SCWRYPT latex/get-pdf -n -- $1)
[ ! $PDF ] && return 1
__OPEN "$PDF"
}
#####################################################################
OPEN_PDF $@

View File

@ -0,0 +1,37 @@
\usepackage[margin=.75in,bottom=0.5in,top=1.0in]{geometry}
\usepackage{enumitem}
\usepackage{fancyhdr}
\usepackage{hyperref}
\usepackage{lastpage}
\newcommand{\headerL} {\documentTitle: \documentDate}
\newcommand{\headerC} {\documentId}
\newcommand{\headerR} {\authorName\ (\authorId)}
\newcommand{\pageOfTotal} {\thepage\ of~\pageref{LastPage}}
\pagestyle{fancy}
\fancypagestyle{plain}{%
\fancyhf{}
\fancyhead[L]{\headerL}\fancyhead[R]{\headerR}\fancyhead[C]{\headerC}
\fancyfoot[C]{\pageOfTotal}
}
\renewcommand{\baselinestretch}{1}
\setlength{\parskip}{0em}
\hyphenpenalty=5000%
\fancyhf{}
\fancyhead[L]{\headerL}\fancyhead[R]{\headerR}\fancyhead[C]{\headerC}
\fancyfoot[C]{\pageOfTotal}
\title{\documentTitle}
\author{\authorName\ \\ \authorId}
\date{\documentDate}
\begin{document}
\maketitle%
% ---------------------------------------------------------------------
% ---------------------------------------------------------------------
\end{document}

View File

@ -0,0 +1,5 @@
*.aux
*.log
*.out
*.pdf
*.dvi

View File

@ -0,0 +1,9 @@
\documentclass[letterpaper]{article}
\newcommand{\documentTitle} {LATEX-DOC-TITLE}
\newcommand{\documentDate} {LATEX-DOC-DATE}
\newcommand{\documentId} {LATEX-DOC-ID}
\newcommand{\authorName} {LATEX-AUTHOR-NAME}
\newcommand{\authorId} {LATEX-AUTHOR-ID}

View File

@ -0,0 +1,11 @@
\ProvidesPackage{code}
% ---------------------------------------------------------------------
\newcommand{\clispsnippet}[2]{%
\lstinputlisting[%
caption=#1,
language=Lisp,
showstringspaces=false,
numbers=left,
]{#2}
}

View File

@ -0,0 +1,46 @@
\ProvidesPackage{formatting}
% ---------------------------------------------------------------------
\newcommand{\headerLeft} {\documentTitle: \documentDate}
\newcommand{\headerCenter} {\documentId}
\newcommand{\headerRight} {\authorName\ (\authorId)}
\newcommand{\pageOfTotal} {\thepage\ of~\pageref{LastPage}}
\newtheorem{theorem}{Theorem}[section]
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{corollary}{Corollary}[theorem]
\RequirePackage[margin=1in,bottom=.5in,includefoot]{geometry}
\RequirePackage{lastpage}
\RequirePackage{fancyhdr}
% ---------------------------------------------------------------------
% Page 1
\pagestyle{fancy}
\fancypagestyle{plain}{%
\fancyhf{}
\fancyhead[L]{\headerLeft}
\fancyhead[R]{\headerRight}
\fancyhead[C]{\headerCenter}
\fancyfoot[C]{\pageOfTotal}
}
\renewcommand{\baselinestretch}{1}
\setlength{\parskip}{0em}
\setlength{\parindent}{0em}
% ---------------------------------------------------------------------
% Pages 2+
\fancyhf{}
\fancyhead[L]{\headerLeft}
\fancyhead[R]{\headerRight}
\fancyhead[C]{\headerCenter}
\fancyfoot[C]{\pageOfTotal}
% ---------------------------------------------------------------------
\title{\documentTitle}
\author{\authorName\ \\ \authorId}
\date{\documentDate}

View File

View File

@ -0,0 +1,16 @@
\ProvidesPackage{imports}
% ---------------------------------------------------------------------
\RequirePackage{amssymb} % "bold" math letters (e.g. set of integers )
\RequirePackage{amsmath} % advanced math symbols
\RequirePackage{listings} % code snippet styling block
\RequirePackage{tikz} % graphic drawing / generation
\usetikzlibrary{arrows,automata}
\usetikzlibrary{trees}
\RequirePackage{graphicx} % include images
\graphicspath{{./graphics/}}
\RequirePackage[english]{babel} % -- English compilation rules

View File

@ -0,0 +1,13 @@
\ProvidesPackage{shorthand}
% ---------------------------------------------------------------------
\newcommand{\egfcoefficient}{\ensuremath{\left[\frac{x^n}{n!}\right]}}
\newcommand{\ogfcoefficient}{\ensuremath{\left[x^n\right]}}
\newcommand{\falling}[1]{^{\underline{#1}}}
\newcommand{\divides}{\ensuremath{\;\backslash\;}}
\newcommand{\sumgz}{\ensuremath{\sum_{n\geq 0}}}
\newcommand{\sumdiv}{\ensuremath{\sum_{d\divides n}}}
\newcommand{\union}{\ensuremath{\cup}}
\newcommand{\intersect}{\ensuremath{\cap}}

View File

@ -0,0 +1,12 @@
\usepackage{imports}
\usepackage{formatting}
\usepackage{shorthand}
\usepackage{code}
\begin{document}
\maketitle
% ---------------------------------------------------------------------
% \input{sections/01.introduction.tex}
% \includegraphic{graphics/diagram-a.png}
% ---------------------------------------------------------------------
\end{document}

View File

@ -0,0 +1,7 @@
\ProvidesPackage{custom-headers}
% ---------------------------------------------------------------------
\newcommand{\firstH}[1] {\begin{large}\textbf{#1}\end{large}\par}
\newcommand{\secondH}[1] {\textbf{#1}\par}
\newcommand{\thirdH}[1] {\textbf{#1}. }
\newcommand{\fourthH}[1] {\textbf{\textit{#1}}. }

View File

@ -0,0 +1,31 @@
\ProvidesPackage{formatting}
% ---------------------------------------------------------------------
\newcommand{\horizontalHeader} {%
\authorName\hfill
\authorId\hfill
\documentId\hfill
\documentDate%
}
\RequirePackage[margin=1in]{geometry}
\RequirePackage{fancyhdr}
% ---------------------------------------------------------------------
\pagestyle{fancy}
\renewcommand{\headrulewidth}{0pt}
\fancyhead[C]{\horizontalHeader}
\fancyfoot[C]{\thepage}
\renewcommand{\baselinestretch}{1}
\setlength{\parskip}{1em}
\setlength{\parindent}{0em}
\raggedright%
% ---------------------------------------------------------------------
\newcommand{\insertTitle} {%
\centerline{\begin{large}\textbf{\documentTitle}\end{large}}
}

View File

@ -0,0 +1,11 @@
\ProvidesPackage{imports}
% ---------------------------------------------------------------------
\RequirePackage{times} % "Times New Roman" font
\RequirePackage{kantlipsum} % generate Kantian lorem ipsum
\RequirePackage{graphicx} % include images
\graphicspath{{./graphics/}}
\RequirePackage[english]{babel} % -- English compilation rules

View File

@ -0,0 +1,15 @@
\usepackage{imports}
\usepackage{formatting}
\usepackage{custom-headers}
\begin{document}
\insertTitle%
% ---------------------------------------------------------------------
% \input{sections/abstract.tex}
% \includgraphics{graphics/table-a.png}
\firstH{First-level Header}
\kant%
% ---------------------------------------------------------------------
\end{document}

19
zsh/memo/common.zsh Normal file
View File

@ -0,0 +1,19 @@
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
#####################################################################
set +o noglob
MEMO__FILETYPE=md
MEMO__DIR="$SCWRYPTS_DATA_PATH/memo"
[ ! -d $MEMO__DIR ] && mkdir -p $MEMO__DIR
LIST_MEMOS() { ls $MEMO__DIR | sed "s/\.$MEMO__FILETYPE$//" | sort; }
# TODO : remove deprecated migration
[ -d $HOME/.memos ] && {
__Yn 'detected legacy memos folder; upgrade now?' && {
mv $HOME/.memos/* $MEMO__DIR
rmdir "$HOME/.memos"
}
}

30
zsh/memo/open Executable file
View File

@ -0,0 +1,30 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
OPEN_MEMO() {
local MEMO_NAME=$(LIST_MEMOS | __FZF_TAIL 'select/create a memo')
[ ! "$MEMO_NAME" ] && __ABORT
MEMO_FILE="$MEMO__DIR/$MEMO_NAME.$MEMO__FILETYPE"
[ ! -f $MEMO_FILE ] && {
__STATUS "creating memo '$MEMO_NAME'"
echo "# $MEMO_NAME" > "$MEMO_FILE" \
&& __SUCCESS "created memo '$MEMO_NAME'" \
|| __FAIL 1 "failed to create '$MEMO_FILE'" \
;
}
DATESTRING="## $(date '+%A, %B %-d, %Y')"
grep -q "$DATESTRING" "$MEMO_FILE" || echo "$DATESTRING" >> "$MEMO_FILE"
__EDIT "$MEMO_FILE"
}
#####################################################################
OPEN_MEMO $@

32
zsh/memo/remove Executable file
View File

@ -0,0 +1,32 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
OPEN_MEMO() {
local MEMO_NAME=$(LIST_MEMOS | __FZF 'select a memo to delete')
local MEMO_FILE="$MEMO__DIR/$MEMO_NAME.$MEMO__FILETYPE"
[ "$MEMO_NAME" ] && [ -f "$MEMO_FILE" ] || __ABORT
__STATUS "--- START OF MEMO ---------------------------------------------------"
cat "$MEMO_FILE"
__STATUS "--- END OF MEMO -----------------------------------------------------"
__WARNING
__WARNING 'memos are not backed up by default; deletion is permanent!'
__WARNING
__yN 'are you sure you want to delete this memo?' || __ABORT
__STATUS "deleting memo '$MEMO_FILE'"
rm "$MEMO_FILE" \
&& __SUCCESS "removed memo '$MEMO_NAME'" \
|| __FAIL 1 "failed to remove memo '$MEMO_NAME'" \
;
}
#####################################################################
OPEN_MEMO $@

22
zsh/redis/common.zsh Normal file
View File

@ -0,0 +1,22 @@
_DEPENDENCIES+=(
redis-cli
)
_REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
[ ! $SCWRYPTS_CACHE_HOST ] && SCWRYPTS_CACHE_HOST=localhost
[ ! $SCWRYPTS_CACHE_PORT ] && SCWRYPTS_CACHE_PORT=6379
#####################################################################
_REDIS() {
local ARGS=()
ARGS+=(-h $SCWRYPTS_CACHE_HOST)
ARGS+=(-p $SCWRYPTS_CACHE_PORT)
[ $SCWRYPTS_CACHE_AUTH ] && ARGS+=(-a $SCWRYPTS_CACHE_AUTH)
redis-cli ${ARGS[@]} $@
}
CACHE_ENABLED=$(_REDIS ping 2>&1 | grep -qi pong && echo 1 || echo 0)

48
zsh/redis/curl Executable file
View File

@ -0,0 +1,48 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
CURL_WITH_CACHE() {
[ ! $TTL ] && TTL=10
[[ $CACHE_ENABLED -eq 0 ]] && {
curl $@
return $?
}
local ARGS=()
local URL
while [[ $# -gt 0 ]]
do
case $1 in
-- ) shift 1 ;;
--*= ) ARGS+=($1); shift 1 ;;
--* ) ARGS+=($1 $2); shift 2 ;;
-* ) ARGS+=($1); shift 1 ;;
* ) URL=$1; break ;;
esac
done
local KEY=$(GET_URL_KEY $URL)
local OUTPUT=$(_REDIS get $KEY 2>&1)
[ $OUTPUT ] && {
[[ ${#ARGS[@]} -gt 0 ]] && __WARN "cache hit found; ignoring arguments ($ARGS)"
echo $OUTPUT
return
}
local OUTPUT=$(curl -s $@)
[ ! $OUTPUT ] && return 1
_REDIS set $KEY "$OUTPUT" >/dev/null
_REDIS expire $KEY $TTL >/dev/null
echo $OUTPUT
}
GET_URL_KEY() { echo "scwrypts:curl:$1" | sed 's/\s\+/+/g'; }
#####################################################################
CURL_WITH_CACHE $@

View File

@ -31,6 +31,34 @@ Inherited values are denoted by `# inherited from <parent-name>` in the environm
Nested children will inherit values from all parents.
### Special Environment Variable Syntax
All environment variables which end in `__[a-z_]+` are ignored by the template file.
These environment variables *will propagate to children*, but will not be removed nor staged into the `.env.template`.
#### `__select` Environment Variables
Omit any variable, but provide a comma-separated list with the `__select` suffix, and the user will be prompted to select a value from the provided options.
In the following configuration, the user will be prompted to select an `AWS_REGION` once at the beginning of scwrypt execution:
```zsh
export AWS_REGION=
export AWS_REGION__select=us-east-1,us-east-2,us-west-1,us-west-2
```
Setting the `AWS_REGION` variable will cause scwrypts to ignore the `__select` syntax.
CI will fail on select, because CI fails on any FZF prompt.
#### `__override` Environment Variables
Override any variable with the indicated value.
This will take precedence over existing values *and* any other special environment variable types.
Examples of use:
- temporarily changing a single value in your current session (e.g. `export VARIABLE__override=value`)
- overriding a variable for a one-time command (e.g. `VARIABLE__override=value scwrypts ...`)
## Logs
Quickly view or clear Scwrypts logs.

View File

@ -13,7 +13,7 @@ source ${0:a:h}/common.zsh
echo '#'
echo '# configuration for scwrypts'
echo '#'
sed -n '1d; /^###/q; p' $SCWRYPTS_ROOT/.config | sed '$d'
sed -n '1d; /^###/q; p' $SCWRYPTS_ROOT/global/config.zsh | sed '$d'
} > $SCWRYPTS_CONFIG_PATH/config
__EDIT $SCWRYPTS_CONFIG_PATH/config
@ -29,9 +29,7 @@ source ${0:a:h}/common.zsh
__REMINDER '(equivalent to "npm install" or "pip install -r requirements.txt")'
__REMINDER
} || {
__STATUS 'opening local config for editing'
__EDIT $SCWRYPTS_CONFIG_PATH/config
__STATUS 'finished editing!'
}

View File

@ -6,6 +6,9 @@ source ${0:a:h}/../common.zsh
_SORT_ENV() {
local ENV_FILE="$1"
sed -i "s/^[A-Z]/export &/; s/^[^#=]\\+$/&=/" "$ENV_FILE"
_SED -i "/^# /d; /^$/d" "$ENV_FILE"
_SED -i "s/^[A-Z]/export &/; s/^[^#=]\\+$/&=/" "$ENV_FILE"
LC_COLLATE=C sort -uo "$ENV_FILE" "$ENV_FILE"
}
_SED() { sed --follow-symlinks $@; }

View File

@ -25,7 +25,7 @@ cp "$TEMPLATE_ENV_FILE" "$ENV_FILE" \
|| __FAIL 3 "unable to create '$ENV_NAME'"
__STATUS 'stripping inherited values'
sed -i 's/ # inherited from.*$//' "$ENV_FILE" 2>/dev/null
_SED -i 's/ # inherited from.*$//' "$ENV_FILE" 2>/dev/null
__RUN_SCWRYPT zsh/scwrypts/environment/synchronize -- --no-prompt \
|| __FAIL 4 'failed to run environment sync'

View File

@ -17,19 +17,17 @@ ENV_FILE=$(__GET_ENV_FILE $ENV_NAME)
[ ! -f $ENV_FILE ] && {
__STATUS "Creating '$ENV_NAME'..." \
&& cp $__ENV_TEMPLATE $ENV_FILE \
&& __SUCCESS 'created!' \
&& __RUN_SCWRYPT zsh/scwrypts/environment/synchronize -- --no-prompt \
&& __SUCCESS "created '$ENV_NAME'" \
|| { __ERROR "failed to create '$ENV_FILE'"; exit 1; }
}
__STATUS "opening '$ENV_NAME' for editing..."
__EDIT $ENV_FILE
sed -i "s/^[A-Z]/export &/; s/^[^#=]\\+$/&=/" $ENV_FILE
LC_COLLATE=C sort -uo $ENV_FILE $ENV_FILE
_SORT_ENV $ENV_FILE
__STATUS "finished editing; looking for new environment variables"
while read line
do
ENV_VAR=$(echo "$line" | sed 's/=.*$//; s/^export //')
ENV_VAR=$(echo "$line" | _SED 's/=.*$//; s/^export //')
grep -q "$ENV_VAR" $__ENV_TEMPLATE || {
((NEW_VAR+=1))
echo "export $ENV_VAR=" >> $__ENV_TEMPLATE

View File

@ -17,16 +17,19 @@ _SYNCHRONIZE() {
[ ! $SLIENT ] && {
__yN 'change the template before sync?' && __EDIT $__ENV_TEMPLATE
_SORT_ENV "$__ENV_TEMPLATE"
git add $__ENV_TEMPLATE >/dev/null 2>&1
}
_SORT_ENV "$__ENV_TEMPLATE"
_SED -i '/__[a-z_]\+=$/d' "$__ENV_TEMPLATE"
git add $__ENV_TEMPLATE >/dev/null 2>&1
ENVIRONMENTS=$(__GET_ENV_NAMES | sort -r)
_CLEAR_INHERITED_VARIABLES
_INSERT_NEW_VARIABLES
_REMOVE_OLD_VARIABLES
_SORT_AND_CASCADE
_ADD_DESCRIPTIONS
__SUCCESS 'finished sync!'
}
@ -37,7 +40,7 @@ _CLEAR_INHERITED_VARIABLES() {
for ENV_NAME in $(echo $ENVIRONMENTS)
do
ENV_FILE=$(__GET_ENV_FILE $ENV_NAME)
sed -i 's/ # inherited from.*//' "$ENV_FILE"
_SED -i 's/ # inherited from.*//' "$ENV_FILE"
done
}
@ -54,7 +57,7 @@ _INSERT_NEW_VARIABLES() {
echo $line >> $ENV_FILE && __STATUS "added '$line' to '$ENV_NAME'"
}
done
done < <(sed -n '/^./p' "$__ENV_TEMPLATE")
done < <(_SED -n '/^./p' "$__ENV_TEMPLATE")
}
_REMOVE_OLD_VARIABLES() {
@ -66,9 +69,11 @@ _REMOVE_OLD_VARIABLES() {
ENV_FILE=$(__GET_ENV_FILE $ENV_NAME)
while read line
do
ENV_VAR=$(echo "$line" | sed 's/=.*/=/')
ENV_VAR=$(echo "$line" | _SED 's/=.*/=/')
echo $ENV_VAR | grep -q '__[a-z_]\+=' && continue
grep -q "$ENV_VAR" "$__ENV_TEMPLATE" || {
sed -i "\\%$ENV_VAR%d" "$ENV_FILE"
_SED -i "\\%$ENV_VAR%d" "$ENV_FILE"
echo "$ENV_VAR" | grep -qv '^#' \
&& __WARNING "removed unwanted '$ENV_VAR' from '$ENV_NAME'"
}
@ -109,8 +114,8 @@ _CASCADE_ENVIRONMENT() {
while read PARENT_VAR
do
VAR_PATTERN=$(echo "$PARENT_VAR" | sed 's/=.*/=/; s/\//\/\//g')
__STATUS "propagating '$(echo $VAR_PATTERN | sed 's/^export \([^=]*\)=/\1/')' to children"
VAR_PATTERN=$(echo "$PARENT_VAR" | _SED 's/=.*/=/; s/\//\/\//g')
__STATUS "propagating '$(echo $VAR_PATTERN | _SED 's/^export \([^=]*\)=/\1/')' to children"
PARENT_VAR+=" # inherited from $PARENT_NAME"
@ -118,13 +123,32 @@ _CASCADE_ENVIRONMENT() {
do
CHILD_FILE=$(__GET_ENV_FILE $CHILD_NAME)
sed -i "/^$VAR_PATTERN/d" "$CHILD_FILE"
_SED -i "/^$VAR_PATTERN/d" "$CHILD_FILE"
echo $PARENT_VAR >> "$CHILD_FILE"
done
done < <(sed -n '/^[^#][^=]*=[^#]\+$/p' "$PARENT_FILE")
done < <(_SED -n '/^[^#][^=]*=[^#]\+$/p' "$PARENT_FILE")
__SUCCESS "finished '$PARENT_NAME' propagation"
}
_ADD_DESCRIPTIONS() {
__STATUS 'updating descriptions'
while read DESCRIPTION_LINE
do
ENV_VAR=$(echo $DESCRIPTION_LINE | _SED 's/ \+| .*$//')
DESCRIPTION=$(echo $DESCRIPTION_LINE | _SED 's/^.* | //')
for ENV_NAME in $(echo $ENVIRONMENTS)
do
_SED -i "/^export $ENV_VAR=/i # $DESCRIPTION" "$(__GET_ENV_FILE $ENV_NAME)"
done
done < <(_SED -n '/^[^ ]\+ \+| /p' "$__ENV_TEMPLATE.descriptions")
for ENV_NAME in $(echo $ENVIRONMENTS)
do
_SED -i "/^# /i \ " "$(__GET_ENV_FILE $ENV_NAME)"
_SED -i "s/^ $//" "$(__GET_ENV_FILE $ENV_NAME)"
done
}
#####################################################################
_SYNCHRONIZE $@

View File

@ -23,3 +23,22 @@ __WHITE='\033[1;37m'
__LIGHT_GRAY='\033[0;37m'
__COLOR_RESET='\033[0m'
__GET_RANDOM_COLOR() {
local COLORS=(
$__RED
$__LIGHT_RED
$__GREEN
$__LIGHT_GREEN
$__ORANGE
$__YELLOW
$__BLUE
$__DARK_BLUE
$__PURPLE
$__DARK_PURPLE
$__CYAN
$__DARK_CYAN
$__WHITE
)
print "$__COLOR_RESET${COLORS[$(shuf -i 1-${#COLORS[@]} -n 1)]}"
}

View File

@ -3,6 +3,7 @@ __CREDITS() {
[ ! $SCWRYPTS_ROOT ] && return 0
local COMMAND="$1"
[[ $COMMAND =~ - ]] && COMMAND=$(echo $COMMAND | sed 's/-/--/g')
cd $SCWRYPTS_ROOT
cat ./**/README.md \
| grep 'Generic Badge' \

View File

@ -17,7 +17,7 @@ __CHECK_DEPENDENCY() {
}
__CHECK_COREUTILS() {
local COREUTILS=(awk find grep sed)
local COREUTILS=(awk find grep sed readlink)
local MISSING_DEPENDENCY_COUNT=0
local NON_GNU_DEPENDENCY_COUNT=0

View File

@ -8,12 +8,24 @@ __CHECK_ENV_VAR() {
local NAME="$1"
[ ! $NAME ] && return 1
local OVERRIDE_VALUE=$(eval echo '$'$NAME'__override')
[ $OVERRIDE_VALUE ] && export $NAME=$OVERRIDE_VALUE && return 0
local OPTIONAL="$2"
local DEFAULT_VALUE="$3"
local VALUE=$(eval echo '$'$NAME)
[ $VALUE ] && return 0
local SELECTION_VALUES=$(eval echo '$'$NAME'__select' | sed 's/,/\n/g')
[ $SELECTION_VALUES ] && {
local SELECTION=$(echo $SELECTION_VALUES | __FZF "select a value for '$NAME'")
[ $SELECTION ] && {
export $NAME=$SELECTION
return 0
}
}
[ $VALUE ] && return 0
[ $__SCWRYPT ] && {
# scwrypts exclusive (missing vars staged in env.template)

View File

@ -8,7 +8,8 @@ __PRINT() {
printf "${COLOR}${MESSAGE}${__COLOR_RESET}${LINE_END}"
}
__ERROR() { __PRINT $__RED "ERROR ✖ : $@" >&2; }
[ ! $ERRORS ] && export ERRORS=0
__ERROR() { __PRINT $__RED "ERROR ✖ : $@" >&2; ((ERRORS+=1)); }
__SUCCESS() { __PRINT $__GREEN "SUCCESS ✔ : $@" >&2; }
__WARNING() { __PRINT $__ORANGE "WARNING  : $@" >&2; }
__STATUS() { __PRINT $__BLUE "STATUS : $@" >&2; }
@ -23,6 +24,35 @@ __PROMPT() {
__FAIL() { __ERROR "${@:2}"; exit $1; }
__ABORT() { __FAIL 69 'user abort'; }
__ERROR_CHECK() {
[ ! $ERRORS ] && ERRORS=0
[[ $ERRORS -ne 0 ]] && __USAGE
[[ $ERRORS -eq 0 ]] || exit $ERRORS
}
__USAGE() {
[ ! $USAGE ] && return 0
USAGE=$(echo $USAGE | sed "s/^\t\+//; s/\s\+$//")
local USAGE_LINE=$(\
echo $USAGE \
| grep -i '^ *usage *:' \
| sed "s;^[^:]*:;& scwrypts $SCWRYPT_NAME --;" \
| sed 's/ \{2,\}/ /g; s/scwrypts -- scwrypts/scwrypts/' \
)
local THE_REST=$(echo $USAGE | grep -vi '^ *usage *:' | sed 'N;/^\n$/D;P;D;')
{ echo; __PRINT $__DARK_BLUE "$USAGE_LINE"; echo $THE_REST; echo } >&2
}
__INPUT() {
__PROMPT "${@:2}"
__READ $1
local VALUE=$(eval echo '$'$1)
[ $VALUE ]
}
__Yn() {
__PROMPT "$@ [Yn]"
[ $CI ] && { echo y; return 0; }
@ -56,23 +86,29 @@ __FZF() {
exit 1
}
fzf -i --height=30% --layout=reverse --prompt "$1 : " ${@:2}
local SELECTION=$(fzf -i --height=30% --layout=reverse --prompt "$1 : " ${@:2})
__PROMPT "$1"
echo $SELECTION >&2
echo $SELECTION
}
__FZF_HEAD() { __FZF $@ --print-query | sed '/^$/d' | head -n1; } # prefer user input over selected
__FZF_TAIL() { __FZF $@ --print-query | sed '/^$/d' | tail -n1; } # prefer selected over user input
__READ() {
[ $CI ] && {
__ERROR 'currently in CI, but __READ explicitly requires terminal input'
return 1
__INFO 'currently in CI, skipping __READ'
return 0
}
read $@ </dev/tty
}
__EDIT() {
[ $CI ] && {
__ERROR 'currently in CI, but __EDIT explicitly requires terminal input'
return 1
__INFO 'currently in CI, skipping __EDIT'
return 0
}
__STATUS "opening '$1' for editing"
$EDITOR $@ </dev/tty >/dev/tty
__SUCCESS "finished editing '$1'!"
}

View File

@ -14,12 +14,6 @@ source ${0:a:h}/credits.zsh
IMPORT_ERROR=0
[ $CI ] && {
export _AWS_PROFILE="$AWS_PROFILE"
export _AWS_ACCOUNT="$AWS_ACCOUNT"
export _AWS_REGION="$AWS_REGION"
}
source ${0:a:h}/dependencies.zsh
_DEP_ERROR=0
_DEPENDENCIES=($(echo $_DEPENDENCIES | sort -u))

8
zsh/vim/common.zsh Normal file
View File

@ -0,0 +1,8 @@
_DEPENDENCIES+=(
vim
)
_REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
#####################################################################
_VIM() { vim $@ </dev/tty >/dev/tty; }

49
zsh/vim/vundle/common.zsh Normal file
View File

@ -0,0 +1,49 @@
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
#####################################################################
VUNDLE_PLUGIN_DIR="$HOME/.vim/bundle"
VUNDLE_BUILD_DEFINITIONS="$SCWRYPTS_CONFIG_PATH/vundle.zsh"
[ ! -f $VUNDLE_BUILD_DEFINITIONS ] && {
{
echo -e "#\n# Scwrypts Build Definitions\n#\n"
} > $VUNDLE_BUILD_DEFINITIONS
}
VUNDLE_PLUGIN_LIST=$(ls $VUNDLE_PLUGIN_DIR | grep -v 'Vundle.vim' | grep -v 'build.zsh')
source $VUNDLE_BUILD_DEFINITIONS
for PLUGIN in $(echo $VUNDLE_PLUGIN_LIST)
do
typeset -f VUNDLE_BUILD__$PLUGIN >/dev/null 2>/dev/null || {
echo -e "\nVUNDLE_BUILD__$PLUGIN() {\n # ... build steps from $HOME/.vim/$PLUGIN \n}" \
>> $VUNDLE_BUILD_DEFINITIONS
VUNDLE_BUILD__$PLUGIN() {}
}
done
#####################################################################
VUNDLE_PLUGIN_INSTALL() {
_VIM +PluginInstall +qall \
&& __SUCCESS 'successfully installed Vundle.vim plugins' \
|| __FAIL 1 'failed to install Vundle.vim plugins'
}
VUNDLE_REBUILD_PLUGINS() {
local ERRORS=0
local PLUGIN
for PLUGIN in $(echo $VUNDLE_PLUGIN_LIST)
do
cd "$VUNDLE_PLUGIN_DIR/$PLUGIN"
__STATUS "building '$PLUGIN'"
VUNDLE_BUILD__$PLUGIN \
&& __SUCCESS "finished building '$PLUGIN'" \
|| __ERROR "failed to build '$PLUGIN' (see above)" \
;
done
return $ERRORS
}

View File

@ -0,0 +1,6 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
__EDIT "$VUNDLE_BUILD_DEFINITIONS"

13
zsh/vim/vundle/install Executable file
View File

@ -0,0 +1,13 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
PLUGIN_INSTALL() {
VUNDLE_PLUGIN_INSTALL || return 1
VUNDLE_REBUILD_PLUGINS || return 2
}
#####################################################################
PLUGIN_INSTALL $@

6
zsh/vim/vundle/rebuild Executable file
View File

@ -0,0 +1,6 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
VUNDLE_REBUILD_PLUGINS $@

5
zsh/youtube/README.md Normal file
View File

@ -0,0 +1,5 @@
# ZSH Scwrypts
[![Generic Badge](https://img.shields.io/badge/ytdl--org-youtube--dl-informational.svg)](https://github.com/ytdl-org/youtube-dl)
<br>
Quick wrappers for downloading and trimming YouTube videos.

45
zsh/youtube/common.zsh Normal file
View File

@ -0,0 +1,45 @@
_DEPENDENCIES+=(
youtube-dl
ffmpeg
)
_REQUIRED_ENV+=()
source ${0:a:h}/../common.zsh
#####################################################################
YT__GLOBAL_ARGS=(
--no-call-home
--restrict-filenames
)
YT__OUTPUT_DIR="$SCWRYPTS_DATA_PATH/youtube"
YT__GET_INFO() {
youtube-dl --dump-json ${YT__GLOBAL_ARGS[@]} $@
}
YT__GET_FILENAME() {
YT__GET_INFO $@ \
| jq -r '._filename' \
| sed 's/\.[^.]*$/\.mp4/' \
;
}
YT__DOWNLOAD() {
local OUTPUT_DIR="$SCWRYPTS_DATA_PATH/youtube"
[ ! -d $YT__OUTPUT_DIR ] && mkdir -p $YT__OUTPUT_DIR
cd "$YT__OUTPUT_DIR"
youtube-dl ${YT__GLOBAL_ARGS[@]} $@ \
--format 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/mp4' \
;
}
GET_VIDEO_LENGTH() {
local FILENAME="$1"
ffprobe \
-v quiet \
-show_entries format=duration \
-of default=noprint_wrappers=1:nokey=1 \
-i $FILENAME \
;
}

25
zsh/youtube/download Executable file
View File

@ -0,0 +1,25 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
DOWNLOAD_VIDEO() {
local URLS=($@)
[[ ${#URLS[@]} -eq 0 ]] && URLS=($(echo '' | __FZF_HEAD 'enter URL'))
[[ ${#URLS[@]} -eq 0 ]] && __ABORT
local FILENAME=$(YT__GET_FILENAME $URLS)
[ ! $FILENAME ] && __ERROR "unable to download '$URLS'"
__SUCCESS "Found '$FILENAME'"
__Yn "Proceed with download?" || return 1
YT__DOWNLOAD $URLS \
&& __SUCCESS "downloaded to '$YT__OUTPUT_DIR/$FILENAME'" \
|| { __ERROR "failed to download '$FILENAME'"; return 2; }
}
#####################################################################
DOWNLOAD_VIDEO $@

51
zsh/youtube/get-audio-clip Executable file
View File

@ -0,0 +1,51 @@
#!/bin/zsh
_DEPENDENCIES+=()
_REQUIRED_ENV+=()
source ${0:a:h}/common.zsh
#####################################################################
GET_AUDIO_CLIP() {
local URLS=($@)
[[ ${#URLS[@]} -eq 0 ]] && URLS=($(echo '' | __FZF_HEAD 'enter URL'))
[[ ${#URLS[@]} -eq 0 ]] && __ABORT
local FILENAME=$(YT__GET_FILENAME $URLS)
[ ! $FILENAME ] && __ERROR "unable to download '$URLS'"
INPUT_FILE="$YT__OUTPUT_DIR/$FILENAME"
[ ! -f "$INPUT_FILE" ] && {
__RUN_SCWRYPT youtube/download -- $URLS || return 1
}
__SUCCESS "video download '$FILENAME' detected!"
LENGTH=$(GET_VIDEO_LENGTH "$INPUT_FILE")
[ ! $LENGTH ] && { __ERROR "unable to determine video length for '$INPUT_FILE'"; return 2; }
START_TIME=$(echo 0 | __FZF_HEAD "enter start time (0 ≤ t < $LENGTH)")
[ ! $START_TIME ] && __ABORT
END_TIME=$(echo $LENGTH | __FZF_HEAD "enter end time ($START_TIME > t ≥ $LENGTH)")
[ ! $END_TIME ] && __ABORT
__STATUS
__STATUS "video : $FILENAME"
__STATUS "start time : $START_TIME"
__STATUS "end time : $END_TIME"
__STATUS
OUTPUT_FILE=$(echo '' \
| __FZF_HEAD 'what should I call this clip? (.mp3)' \
| sed 's/\.mp3$//' \
)
[ ! $OUTPUT_FILE ] && __ABORT
OUTPUT_FILE="$YT__OUTPUT_DIR/$OUTPUT_FILE.mp3"
ffmpeg -i "$INPUT_FILE" -q:a 0 -map a \
-ss $START_TIME -t $(($END_TIME - $START_TIME))\
"$OUTPUT_FILE" \
&& __SUCCESS "created clip '$OUTPUT_FILE'" \
|| { __ERROR "error creating clip '$(basename $OUTPUT_FILE)' (see above)"; return 3; }
}
#####################################################################
GET_AUDIO_CLIP $@