Compare commits
16 Commits
Author | SHA1 | Date | |
---|---|---|---|
187a467092 | |||
a1256bb0af | |||
73e26a2ecb | |||
20b7cc32eb | |||
22dd6f8112 | |||
710d42e248 | |||
244c188deb | |||
5c882597da | |||
4047aad29e | |||
6333a2f6b8 | |||
a740a66870 | |||
96992e9344 | |||
e8bb889789 | |||
89e899d49d | |||
f7eec633ef | |||
db0d0092db |
@ -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=
|
||||
|
17
.env.template.descriptions
Normal file
17
.env.template.descriptions
Normal 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 |
|
@ -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
42
global/common.zsh
Normal 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.
@ -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
269
run
Executable 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 $@
|
209
scwrypts
209
scwrypts
@ -1,209 +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"
|
||||
|
||||
[ $CI ] \
|
||||
|| [ $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" $@
|
||||
|
@ -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 $@; }
|
||||
|
@ -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'"
|
||||
|
@ -19,6 +19,7 @@ _EFS_CONNECT() {
|
||||
[ ! $FS_ID ] && __ABORT
|
||||
|
||||
local MOUNT_POINT="$AWS__EFS__LOCAL_MOUNT_POINT/$FS_ID"
|
||||
[ -d "$MOUNT_POINT" ] && sudo rmdir "$MOUNT_POINT" >/dev/null 2>&1
|
||||
[ -d "$MOUNT_POINT" ] && {
|
||||
__STATUS "$FS_ID is already mounted"
|
||||
exit 0
|
||||
|
6
zsh/aws/eks/common.zsh
Normal file
6
zsh/aws/eks/common.zsh
Normal file
@ -0,0 +1,6 @@
|
||||
_DEPENDENCIES+=(
|
||||
kubectl
|
||||
)
|
||||
_REQUIRED_ENV+=()
|
||||
source ${0:a:h}/../common.zsh
|
||||
#####################################################################
|
19
zsh/aws/eks/login
Executable file
19
zsh/aws/eks/login
Executable 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'?"
|
@ -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
22
zsh/aws/rds/create-backup
Executable 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 $@
|
@ -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')
|
||||
|
||||
echo $CREDENTIALS | jq -e '.password' >/dev/null 2>&1 \
|
||||
&& DB_AUTH=$(echo $CREDENTIALS | jq -r '.password')
|
||||
|
||||
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
22
zsh/aws/rds/load-backup
Executable 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 $@
|
@ -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/\.$//'\
|
||||
;
|
||||
|
@ -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; }
|
||||
}
|
||||
|
@ -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
14
zsh/config/common.zsh
Normal 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
|
19
zsh/config/default.conf.zsh
Normal file
19
zsh/config/default.conf.zsh
Normal 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
6
zsh/config/settings
Executable 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
36
zsh/config/symlinks
Executable 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
26
zsh/config/terminfo
Executable 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
10
zsh/config/update
Executable 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'
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
4
zsh/db/postgres/common.zsh
Normal file
4
zsh/db/postgres/common.zsh
Normal file
@ -0,0 +1,4 @@
|
||||
_DEPENDENCIES+=()
|
||||
_REQUIRED_ENV+=()
|
||||
source ${0:a:h}/../common.zsh
|
||||
#####################################################################
|
44
zsh/db/postgres/pg_dump
Executable file
44
zsh/db/postgres/pg_dump
Executable 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
55
zsh/db/postgres/pg_restore
Executable 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 $@
|
4
zsh/db/run-sql/common.zsh
Normal file
4
zsh/db/run-sql/common.zsh
Normal file
@ -0,0 +1,4 @@
|
||||
_DEPENDENCIES+=()
|
||||
_REQUIRED_ENV+=()
|
||||
source ${0:a:h}/../common.zsh
|
||||
#####################################################################
|
72
zsh/db/run-sql/postgres
Executable file
72
zsh/db/run-sql/postgres
Executable 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
6
zsh/git/common.zsh
Normal file
@ -0,0 +1,6 @@
|
||||
_DEPENDENCIES+=(
|
||||
git
|
||||
)
|
||||
_REQUIRED_ENV+=()
|
||||
source ${0:a:h}/../common.zsh
|
||||
#####################################################################
|
6
zsh/git/package/build
Executable file
6
zsh/git/package/build
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/zsh
|
||||
_DEPENDENCIES+=()
|
||||
_REQUIRED_ENV+=()
|
||||
source ${0:a:h}/common.zsh
|
||||
#####################################################################
|
||||
__RUN_SCWRYPT zsh/git/package/install -- --only-build $@
|
74
zsh/git/package/common.zsh
Normal file
74
zsh/git/package/common.zsh
Normal 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
6
zsh/git/package/download
Executable 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
88
zsh/git/package/install
Executable 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
6
zsh/git/package/update
Executable 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
14
zsh/i3/common.zsh
Normal 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
105
zsh/i3/create-local-font-override
Executable 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
114
zsh/i3/launch-or-show
Executable 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
31
zsh/latex/build-pdf
Executable 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
20
zsh/latex/cleanup
Executable 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
34
zsh/latex/common.zsh
Normal 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
63
zsh/latex/create-new
Executable 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
15
zsh/latex/get-pdf
Executable 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
15
zsh/latex/open-pdf
Executable 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 $@
|
37
zsh/latex/templates/basic/template.tex
Normal file
37
zsh/latex/templates/basic/template.tex
Normal 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}
|
5
zsh/latex/templates/gitignore
Normal file
5
zsh/latex/templates/gitignore
Normal file
@ -0,0 +1,5 @@
|
||||
*.aux
|
||||
*.log
|
||||
*.out
|
||||
*.pdf
|
||||
*.dvi
|
9
zsh/latex/templates/main.tex
Normal file
9
zsh/latex/templates/main.tex
Normal 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}
|
||||
|
11
zsh/latex/templates/math/code.sty
Normal file
11
zsh/latex/templates/math/code.sty
Normal file
@ -0,0 +1,11 @@
|
||||
\ProvidesPackage{code}
|
||||
% ---------------------------------------------------------------------
|
||||
|
||||
\newcommand{\clispsnippet}[2]{%
|
||||
\lstinputlisting[%
|
||||
caption=#1,
|
||||
language=Lisp,
|
||||
showstringspaces=false,
|
||||
numbers=left,
|
||||
]{#2}
|
||||
}
|
46
zsh/latex/templates/math/formatting.sty
Normal file
46
zsh/latex/templates/math/formatting.sty
Normal 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}
|
0
zsh/latex/templates/math/gitignore
Normal file
0
zsh/latex/templates/math/gitignore
Normal file
16
zsh/latex/templates/math/imports.sty
Normal file
16
zsh/latex/templates/math/imports.sty
Normal 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
|
13
zsh/latex/templates/math/shorthand.sty
Normal file
13
zsh/latex/templates/math/shorthand.sty
Normal 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}}
|
12
zsh/latex/templates/math/template.tex
Normal file
12
zsh/latex/templates/math/template.tex
Normal 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}
|
@ -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}}. }
|
31
zsh/latex/templates/times-new-roman-12/formatting.sty
Normal file
31
zsh/latex/templates/times-new-roman-12/formatting.sty
Normal 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}}
|
||||
}
|
||||
|
11
zsh/latex/templates/times-new-roman-12/imports.sty
Normal file
11
zsh/latex/templates/times-new-roman-12/imports.sty
Normal 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
|
15
zsh/latex/templates/times-new-roman-12/template.tex
Normal file
15
zsh/latex/templates/times-new-roman-12/template.tex
Normal 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
19
zsh/memo/common.zsh
Normal 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
30
zsh/memo/open
Executable 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
32
zsh/memo/remove
Executable 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
22
zsh/redis/common.zsh
Normal 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
48
zsh/redis/curl
Executable 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 $@
|
@ -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.
|
||||
|
||||
|
4
zsh/scwrypts/configure
vendored
4
zsh/scwrypts/configure
vendored
@ -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!'
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 $@; }
|
||||
|
@ -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'
|
||||
|
@ -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
|
||||
|
@ -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 $@
|
||||
|
@ -55,17 +55,3 @@ _REQUIRED_ENV+=(
|
||||
source ./path/to/utils.plugin.zsh
|
||||
echo "missing $ENV_ERROR_COUNT required environment variables"
|
||||
```
|
||||
|
||||
io.zsh
|
||||
os.zsh
|
||||
|
||||
## Basic Utilities
|
||||
|
||||
One of my biggest pet-peeves with scripting is when every line of a *(insert-language-here)* program is escaped to shell.
|
||||
This kind of program, which doesn't use language features, should be a shell script.
|
||||
While there are definitely unavoidable limitations to shell scripting, we can minimize a variety of problems with a modern shell and shared utilities library.
|
||||
|
||||
Loaded by `common.zsh`, the [`utils/` library](./utils) provides:
|
||||
- common function wrappers to unify flags and context
|
||||
- lazy dependency and environment variable validation
|
||||
- consistent (and pretty) user input / output
|
||||
|
44
zsh/utils/colors.zsh
Normal file
44
zsh/utils/colors.zsh
Normal file
@ -0,0 +1,44 @@
|
||||
__BLACK='\033[0;30m'
|
||||
__DARK_GRAY='\033[1;30m'
|
||||
|
||||
__RED='\033[0;31m'
|
||||
__LIGHT_RED='\033[1;31m'
|
||||
|
||||
__GREEN='\033[0;32m'
|
||||
__LIGHT_GREEN='\033[1;32m'
|
||||
|
||||
__ORANGE='\033[0;33m'
|
||||
__YELLOW='\033[1;33m'
|
||||
|
||||
__BLUE='\033[1;34m'
|
||||
__DARK_BLUE='\033[0;34m'
|
||||
|
||||
__PURPLE='\033[1;35m'
|
||||
__DARK_PURPLE='\033[0;35m'
|
||||
|
||||
__CYAN='\033[1;36m'
|
||||
__DARK_CYAN='\033[0;36m'
|
||||
|
||||
__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)]}"
|
||||
}
|
@ -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' \
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
@ -1,12 +1,56 @@
|
||||
__ERROR() { echo "\\033[1;31mERROR ✖ : $@\\033[0m" >&2; }
|
||||
__SUCCESS() { echo "\\033[1;32mSUCCESS ✔ : $@\\033[0m" >&2; }
|
||||
__WARNING() { echo "\\033[1;33mWARNING : $@\\033[0m" >&2; }
|
||||
__STATUS() { echo "\\033[1;34mSTATUS : $@\\033[0m" >&2; }
|
||||
__REMINDER() { echo "\\033[1;35mREMINDER : $@\\033[0m" >&2; }
|
||||
__PRINT() {
|
||||
local COLOR="$1"
|
||||
local MESSAGE="$2"
|
||||
|
||||
local LINE_END
|
||||
[ $3 ] && LINE_END='' || LINE_END='\n'
|
||||
|
||||
printf "${COLOR}${MESSAGE}${__COLOR_RESET}${LINE_END}"
|
||||
}
|
||||
|
||||
[ ! $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; }
|
||||
__REMINDER() { __PRINT $__PURPLE "REMINDER : $@" >&2; }
|
||||
__INFO() { __PRINT $__WHITE "INFO : $@" >&2; }
|
||||
|
||||
__PROMPT() {
|
||||
echo "\\033[1;36mPROMPT : $@\\033[0m" >&2
|
||||
printf "\\033[1;36mUSER : \\033[0m" >&2
|
||||
__PRINT $__CYAN "PROMPT : $@" >&2
|
||||
__PRINT $__CYAN "USER : " --no-end >&2
|
||||
}
|
||||
|
||||
__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() {
|
||||
@ -25,10 +69,6 @@ __yN() {
|
||||
[[ $yN =~ [yY] ]] && return 0 || return 1
|
||||
}
|
||||
|
||||
__FAIL() { __ERROR "${@:2}"; exit $1; }
|
||||
|
||||
__ABORT() { __FAIL 69 'user abort'; }
|
||||
|
||||
#####################################################################
|
||||
|
||||
__GETSUDO() {
|
||||
@ -46,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'!"
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ _REQUIRED_ENV+=() # (extensible) list of required environment variables
|
||||
|
||||
#####################################################################
|
||||
|
||||
source ${0:a:h}/colors.zsh
|
||||
source ${0:a:h}/io.zsh
|
||||
source ${0:a:h}/os.zsh
|
||||
source ${0:a:h}/credits.zsh
|
||||
@ -13,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
8
zsh/vim/common.zsh
Normal 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
49
zsh/vim/vundle/common.zsh
Normal 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
|
||||
}
|
6
zsh/vim/vundle/edit-build-actions
Executable file
6
zsh/vim/vundle/edit-build-actions
Executable 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
13
zsh/vim/vundle/install
Executable 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
6
zsh/vim/vundle/rebuild
Executable 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
5
zsh/youtube/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# ZSH Scwrypts
|
||||
[](https://github.com/ytdl-org/youtube-dl)
|
||||
<br>
|
||||
|
||||
Quick wrappers for downloading and trimming YouTube videos.
|
45
zsh/youtube/common.zsh
Normal file
45
zsh/youtube/common.zsh
Normal 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
25
zsh/youtube/download
Executable 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
51
zsh/youtube/get-audio-clip
Executable 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 $@
|
Reference in New Issue
Block a user