v1.0.0
===================================================================== Finally decided to port personal scripts into a standalone library. --- Release Notes ------------------------ - added support for python, zsh, and zx scripts - added support for "interactive" scripts which drop the user to a REPL - added support for passing arguments to commands - added support for python/node virtualenv management through scwrypts - added contributing and usage docs - updated zsh plugin to write commands to history - licensed under GPLv3 --- New Scripts -------------------------- zsh/scwrypts ) - configure - environment/copy - environment/delete - environment/edit - environment/synchronize - logs/clear - logs/view zsh ) - aws/ecr/login - aws/efs/mount - aws/efs/unmount - aws/route53/backup - aws/s3/media-sync/pull - aws/s3/media-sync/push python ) - redis/interactive
This commit is contained in:
20
zsh/README.md
Normal file
20
zsh/README.md
Normal file
@ -0,0 +1,20 @@
|
||||
# ZSH Scwrypts
|
||||
[](https://1password.com/downloads/command-line)
|
||||
[](https://github.com/BurntSushi/ripgrep)
|
||||
[](https://github.com/junegunn/fzf)
|
||||
[](https://github.com/mikefarah/yq)
|
||||
[](https://github.com/stedolan/jq)
|
||||
<br>
|
||||
|
||||
Since they emulate direct user interaction, shell scripts are often the straightforward choice for task automation.
|
||||
|
||||
## 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
|
5
zsh/aws/README.md
Normal file
5
zsh/aws/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Amazon Web Services
|
||||
[](https://github.com/barnybug/cli53)
|
||||
<br>
|
||||
|
||||
- relies on AWS-CLI 2.x
|
16
zsh/aws/common.zsh
Normal file
16
zsh/aws/common.zsh
Normal file
@ -0,0 +1,16 @@
|
||||
source ${0:a:h}/../common.zsh
|
||||
|
||||
__CHECK_DEPENDENCIES \
|
||||
aws \
|
||||
jq \
|
||||
;
|
||||
|
||||
__CHECK_ENV_VARS \
|
||||
_AWS_ACCOUNT \
|
||||
_AWS_PROFILE \
|
||||
_AWS_REGION \
|
||||
;
|
||||
|
||||
#####################################################################
|
||||
|
||||
_AWS() { aws --profile $_AWS_PROFILE --region $_AWS_REGION --output json $@; }
|
10
zsh/aws/ecr/common.zsh
Normal file
10
zsh/aws/ecr/common.zsh
Normal file
@ -0,0 +1,10 @@
|
||||
source ${0:a:h}/../common.zsh
|
||||
|
||||
__CHECK_DEPENDENCIES \
|
||||
docker \
|
||||
;
|
||||
|
||||
__CHECK_ENV_VARS \
|
||||
;
|
||||
|
||||
#####################################################################
|
13
zsh/aws/ecr/login
Executable file
13
zsh/aws/ecr/login
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
__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'"
|
10
zsh/aws/efs/common.zsh
Normal file
10
zsh/aws/efs/common.zsh
Normal file
@ -0,0 +1,10 @@
|
||||
source ${0:a:h}/../common.zsh
|
||||
|
||||
__CHECK_DEPENDENCIES \
|
||||
;
|
||||
|
||||
__CHECK_ENV_VARS \
|
||||
AWS__EFS__LOCAL_MOUNT_POINT \
|
||||
;
|
||||
|
||||
#####################################################################
|
64
zsh/aws/efs/mount
Executable file
64
zsh/aws/efs/mount
Executable file
@ -0,0 +1,64 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
_EFS_CONNECT() {
|
||||
__GETSUDO || exit 1
|
||||
[ ! -d $AWS__EFS__LOCAL_MOUNT_POINT ] && {
|
||||
sudo mkdir $AWS__EFS__LOCAL_MOUNT_POINT \
|
||||
&& __STATUS "created local mount point '$AWS__EFS__LOCAL_MOUNT_POINT'"
|
||||
}
|
||||
|
||||
local FS_ID=$(\
|
||||
_AWS efs describe-file-systems \
|
||||
| jq -r '.[] | .[] | .FileSystemId' \
|
||||
| __FZF 'select a filesystem to mount' \
|
||||
)
|
||||
[ ! $FS_ID ] && __ABORT
|
||||
|
||||
local MOUNT_POINT="$AWS__EFS__LOCAL_MOUNT_POINT/$FS_ID"
|
||||
[ -d "$MOUNT_POINT" ] && {
|
||||
__STATUS "$FS_ID is already mounted"
|
||||
exit 0
|
||||
}
|
||||
|
||||
local MOUNT_TARGETS=$(_AWS efs describe-mount-targets --file-system-id $FS_ID)
|
||||
local ZONE=$(\
|
||||
echo $MOUNT_TARGETS \
|
||||
| jq -r '.[] | .[] | .AvailabilityZoneName' \
|
||||
| sort -u | __FZF 'select availability zone'\
|
||||
)
|
||||
[ ! $ZONE ] && __ABORT
|
||||
|
||||
local MOUNT_IP=$(\
|
||||
echo $MOUNT_TARGETS \
|
||||
| jq -r ".[] | .[] | select (.AvailabilityZoneName == \"$ZONE\") | .IpAddress" \
|
||||
| head -n1 \
|
||||
)
|
||||
|
||||
__SUCCESS 'ready to mount!'
|
||||
__REMINDER 'your device must be connected to the appropriate VPN'
|
||||
|
||||
__STATUS "file system id : $FS_ID"
|
||||
__STATUS "availability zone : $ZONE"
|
||||
__STATUS "file system ip : $MOUNT_IP"
|
||||
__STATUS "local mount point : $MOUNT_POINT"
|
||||
|
||||
__Yn 'proceed?' || __ABORT
|
||||
|
||||
sudo mkdir $MOUNT_POINT \
|
||||
&& sudo mount \
|
||||
-t nfs4 \
|
||||
-o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport \
|
||||
$MOUNT_IP:/ \
|
||||
"$MOUNT_POINT" \
|
||||
&& __SUCCESS "mounted at '$MOUNT_POINT'" \
|
||||
|| {
|
||||
sudo rmdir $MOUNT_POINT >/dev/null 2>&1
|
||||
__FAIL 2 "unable to mount '$FS_ID'"
|
||||
}
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
_EFS_CONNECT
|
33
zsh/aws/efs/unmount
Executable file
33
zsh/aws/efs/unmount
Executable file
@ -0,0 +1,33 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
_EFS_DISCONNECT() {
|
||||
[ ! -d "$AWS__EFS__LOCAL_MOUNT_POINT" ] && {
|
||||
__STATUS 'no efs currently mounted'
|
||||
exit 0
|
||||
}
|
||||
|
||||
local MOUNTED=$(ls "$AWS__EFS__LOCAL_MOUNT_POINT")
|
||||
[ ! $MOUNTED ] && {
|
||||
__STATUS 'no efs currently mounted'
|
||||
exit 0
|
||||
}
|
||||
|
||||
__GETSUDO || exit 1
|
||||
|
||||
|
||||
local SELECTED=$(echo $MOUNTED | __FZF 'select a file system to unmount')
|
||||
[ ! $SELECTED ] && __ABORT
|
||||
|
||||
local EFS="$AWS__EFS__LOCAL_MOUNT_POINT/$SELECTED"
|
||||
__STATUS "unmounting '$SELECTED'"
|
||||
sudo umount $EFS >/dev/null 2>&1
|
||||
sudo rmdir $EFS \
|
||||
&& __SUCCESS "done" \
|
||||
|| __FAIL 2 "failed to unmount '$EFS'"
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
_EFS_DISCONNECT
|
34
zsh/aws/route53/backup
Executable file
34
zsh/aws/route53/backup
Executable file
@ -0,0 +1,34 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
_ROUTE53_BACKUP() {
|
||||
local BACKUP_PATH="$SCWRYPTS_OUTPUT_PATH/$ENV_NAME/aws-dns-backup/$(date '+%Y-%m-%d')"
|
||||
mkdir -p $BACKUP_PATH >/dev/null 2>&1
|
||||
|
||||
local DOMAIN
|
||||
local JOBS=()
|
||||
for DOMAIN in $(_ROUTE53_GET_DOMAINS)
|
||||
do
|
||||
( __STATUS "creating '$BACKUP_PATH/$DOMAIN.txt'" \
|
||||
&& cli53 export --profile $_AWS_PROFILE $DOMAIN > "$BACKUP_PATH/$DOMAIN.txt" \
|
||||
&& __SUCCESS "backed up '$DOMAIN'" \
|
||||
|| __ERROR "failed to back up '$DOMAIN'" \
|
||||
) &
|
||||
JOBS+=$!
|
||||
done
|
||||
|
||||
local P
|
||||
for P in ${JOBS[@]}; do wait $P >/dev/null 2>&1; done
|
||||
}
|
||||
|
||||
_ROUTE53_GET_DOMAINS() {
|
||||
cli53 list --profile $_AWS_PROFILE \
|
||||
| awk '{print $2;}' \
|
||||
| sed '1d; s/\.$//'\
|
||||
;
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
_ROUTE53_BACKUP
|
10
zsh/aws/route53/common.zsh
Normal file
10
zsh/aws/route53/common.zsh
Normal file
@ -0,0 +1,10 @@
|
||||
source ${0:a:h}/../common.zsh
|
||||
|
||||
__CHECK_DEPENDENCIES \
|
||||
cli53 \
|
||||
;
|
||||
|
||||
__CHECK_ENV_VARS \
|
||||
;
|
||||
|
||||
#####################################################################
|
9
zsh/aws/s3/common.zsh
Normal file
9
zsh/aws/s3/common.zsh
Normal file
@ -0,0 +1,9 @@
|
||||
source ${0:a:h}/../common.zsh
|
||||
|
||||
__CHECK_DEPENDENCIES \
|
||||
;
|
||||
|
||||
__CHECK_ENV_VARS \
|
||||
;
|
||||
|
||||
#####################################################################
|
34
zsh/aws/s3/media-sync/common.zsh
Normal file
34
zsh/aws/s3/media-sync/common.zsh
Normal file
@ -0,0 +1,34 @@
|
||||
source ${0:a:h}/../common.zsh
|
||||
|
||||
__CHECK_DEPENDENCIES \
|
||||
;
|
||||
|
||||
__CHECK_ENV_VARS \
|
||||
AWS__S3__MEDIA_TARGETS \
|
||||
AWS__S3__MEDIA_BUCKET \
|
||||
;
|
||||
|
||||
AWS__S3__MEDIA_TARGETS=($(echo $AWS__S3__MEDIA_TARGETS | sed 's/,/\n/g'))
|
||||
|
||||
#####################################################################
|
||||
|
||||
__SYNC_MEDIA() {
|
||||
local ACTION="$1"
|
||||
local REMOTE_TARGET="s3://$AWS__S3__MEDIA_BUCKET/$2"
|
||||
local LOCAL_TARGET="$HOME/$2"
|
||||
|
||||
local A B
|
||||
case $ACTION in
|
||||
push ) A="$LOCAL_TARGET"; B="$REMOTE_TARGET" ;;
|
||||
pull ) A="$REMOTE_TARGET"; B="$LOCAL_TARGET" ;;
|
||||
|
||||
* ) __ERROR "unknown action '$1'"; return 1 ;;
|
||||
esac
|
||||
|
||||
local FLAGS=(${@:3})
|
||||
|
||||
__STATUS "${ACTION}ing $2"
|
||||
_AWS s3 sync $REMOTE_TARGET $LOCAL_TARGET $FLAGS \
|
||||
&& __SUCCESS "$2 up-to-date" \
|
||||
|| { __ERROR "unable to sync $2 (see above)"; return 1; }
|
||||
}
|
26
zsh/aws/s3/media-sync/pull
Executable file
26
zsh/aws/s3/media-sync/pull
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
__PULL_ALL_MEDIA() {
|
||||
local FLAGS=($@)
|
||||
local FAILED_COUNT=0
|
||||
|
||||
__STATUS 'starting media download from s3'
|
||||
|
||||
local TARGET
|
||||
for TARGET in $AWS__S3__MEDIA_TARGETS
|
||||
do
|
||||
__SYNC_MEDIA pull $TARGET $FLAGS || ((FAILED_COUNT+=1))
|
||||
done
|
||||
|
||||
[[ $FAILED_COUNT -eq 0 ]] \
|
||||
&& __SUCCESS 'local media files now up-to-date' \
|
||||
|| __FAIL $FAILED_COUNT 'unable to download one or more targets' \
|
||||
;
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
|
||||
__PULL_ALL_MEDIA $@
|
26
zsh/aws/s3/media-sync/push
Executable file
26
zsh/aws/s3/media-sync/push
Executable file
@ -0,0 +1,26 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
__PUSH_ALL_MEDIA() {
|
||||
local FLAGS=($@)
|
||||
local FAILED_COUNT=0
|
||||
|
||||
__STATUS 'starting media upload to s3'
|
||||
|
||||
local TARGET
|
||||
for TARGET in $AWS__S3__MEDIA_TARGETS
|
||||
do
|
||||
__SYNC_MEDIA push $TARGET $FLAGS || ((FAILED_COUNT+=1))
|
||||
done
|
||||
|
||||
[[ $FAILED_COUNT -eq 0 ]] \
|
||||
&& __SUCCESS 's3 media files now up-to-date' \
|
||||
|| __FAIL $FAILED_COUNT 'unable to upload one or more targets' \
|
||||
;
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
|
||||
__PUSH_ALL_MEDIA $@
|
58
zsh/common.zsh
Normal file
58
zsh/common.zsh
Normal file
@ -0,0 +1,58 @@
|
||||
[ ! $SCWRYPTS_ROOT ] && SCWRYPTS_ROOT="$(dirname ${0:a:h})"
|
||||
|
||||
source $SCWRYPTS_ROOT/.config
|
||||
[ -f $SCWRYPTS_CONFIG_PATH/config ] && source $SCWRYPTS_CONFIG_PATH/config
|
||||
|
||||
[ ! -d $SCWRYPTS_CONFIG_PATH ] && mkdir -p $SCWRYPTS_CONFIG_PATH
|
||||
[ ! -d $SCWRYPTS_ENV_PATH ] && mkdir -p $SCWRYPTS_ENV_PATH
|
||||
[ ! -d $SCWRYPTS_LOG_PATH ] && mkdir -p $SCWRYPTS_LOG_PATH
|
||||
|
||||
__PREFERRED_PYTHON_VERSIONS=(3.10 3.9)
|
||||
__NODE_VERSION=18.0.0
|
||||
|
||||
#####################################################################
|
||||
|
||||
__DEPENDENCY_ERROR=0
|
||||
__ENVIRONMENT_ERROR=0
|
||||
|
||||
source ${0:a:h}/utils/io.zsh
|
||||
source ${0:a:h}/utils/os.zsh
|
||||
source ${0:a:h}/utils/credits.zsh
|
||||
source ${0:a:h}/utils/dependencies.zsh
|
||||
source ${0:a:h}/utils/environment.zsh
|
||||
|
||||
#####################################################################
|
||||
|
||||
__CHECK_IMPORTS() {
|
||||
[[ $__DEPENDENCY_ERROR -eq 0 ]] \
|
||||
&& [[ $__ENVIRONMENT_ERROR -eq 0 ]] \
|
||||
|| __FAIL 1 'import error (see output above)' \
|
||||
;
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
|
||||
__ENV_TEMPLATE=$SCWRYPTS_ROOT/.template.env
|
||||
|
||||
__GET_ENV_FILES() { find $SCWRYPTS_CONFIG_PATH/env -maxdepth 1 -type f; }
|
||||
[ ! "$(__GET_ENV_FILES)" ] && {
|
||||
cp $__ENV_TEMPLATE "$SCWRYPTS_CONFIG_PATH/env/dev"
|
||||
cp $__ENV_TEMPLATE "$SCWRYPTS_CONFIG_PATH/env/local"
|
||||
cp $__ENV_TEMPLATE "$SCWRYPTS_CONFIG_PATH/env/prod"
|
||||
}
|
||||
|
||||
__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'; }
|
||||
|
||||
__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/\.[^.]*$//' \
|
||||
;
|
||||
}
|
6
zsh/hello-world
Executable file
6
zsh/hello-world
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
__SUCCESS 'hello world!'
|
31
zsh/scwrypts/README.md
Normal file
31
zsh/scwrypts/README.md
Normal file
@ -0,0 +1,31 @@
|
||||
# Meta Scwrypts
|
||||
|
||||
The fastest way to configure scwrypts is through scwrypts!
|
||||
The ZSH scripts in this library are used to manage Scwrypts artifacts.
|
||||
|
||||
|
||||
## Configure
|
||||
**Great for first-time setup!**
|
||||
|
||||
It is simple to edit the local dot-config and restart your terminal.
|
||||
It is much faster to hit `CTRL+W` and select `config/edit` through a fuzzy search.
|
||||
This will immediately open your custom configuration file and reload any necessary resources on save.
|
||||
|
||||
## Environment
|
||||
If you use Scwrypts, **you should use these commands all the time**.
|
||||
This is your gateway to managing scwrypts sandboxed environments.
|
||||
|
||||
Command | Description
|
||||
------------- | ---------------------------------------------------------------------------------------
|
||||
`edit` | edit an existing environment; synchronizes environments if new variables are added
|
||||
`copy` | copy an existing environment to a new one
|
||||
`delete` | permanently delete an environment by name
|
||||
`synchronize` | uses [template](../../.template.env) to add missing and remove extemporaneous variables
|
||||
|
||||
## Logs
|
||||
Quickly view or clear Scwrypts logs.
|
||||
|
||||
## Virtualenv
|
||||
In addition to the custom environment sandbox, scwrypts will load the appropriate virtual environment for the current script.
|
||||
Update / create the environment with `update-all`.
|
||||
Drop and recreate the environment with `refresh`.
|
9
zsh/scwrypts/common.zsh
Normal file
9
zsh/scwrypts/common.zsh
Normal file
@ -0,0 +1,9 @@
|
||||
source ${0:a:h}/../common.zsh
|
||||
|
||||
__CHECK_DEPENDENCIES \
|
||||
;
|
||||
|
||||
__CHECK_ENV_VARS \
|
||||
;
|
||||
|
||||
#####################################################################
|
34
zsh/scwrypts/configure
vendored
Executable file
34
zsh/scwrypts/configure
vendored
Executable file
@ -0,0 +1,34 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
[ ! -f $SCWRYPTS_CONFIG_PATH/config ] && {
|
||||
__STATUS 'first-time setup detected; creating local configuration override...'
|
||||
cp $SCWRYPTS_ROOT/.config $SCWRYPTS_CONFIG_PATH/config \
|
||||
&& __SUCCESS 'created!' \
|
||||
|| __FAIL 1 "unable to create config at '$SCWRYPTS_CONFIG_PATH/config'"
|
||||
|
||||
__STATUS 'attempting to build virtual environments'
|
||||
$SCWRYPTS_ROOT/zsh/scwrypts/virutalenv/update-all \
|
||||
&& __SUCCESS 'finished updating virtualenvs' \
|
||||
|| __WARNING 'unable to create one or more virtualenv (see above)' \
|
||||
;
|
||||
|
||||
__REMINDER
|
||||
__REMINDER 'use "zsh/scwrypts/virtualenv/update-all" to update environments'
|
||||
__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!'
|
||||
|
||||
which __SCWRYPTS >/dev/null 2>&1 && {
|
||||
__STATUS 'reloading configuration for current session'
|
||||
source $SCWRYPTS_ROOT/zsh/common.zsh \
|
||||
|| __FAIL 2 'unable to reload configuration :c'
|
||||
}
|
||||
|
||||
__SUCCESS 'saved new configuration'
|
9
zsh/scwrypts/environment/common.zsh
Normal file
9
zsh/scwrypts/environment/common.zsh
Normal file
@ -0,0 +1,9 @@
|
||||
source ${0:a:h}/../common.zsh
|
||||
|
||||
__CHECK_DEPENDENCIES \
|
||||
;
|
||||
|
||||
__CHECK_ENV_VARS \
|
||||
;
|
||||
|
||||
#####################################################################
|
24
zsh/scwrypts/environment/copy
Executable file
24
zsh/scwrypts/environment/copy
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
__PROMPT 'choose an environment to copy'
|
||||
TEMPLATE_ENV_NAME=$(__SELECT_ENV)
|
||||
[ ! $TEMPLATE_ENV_NAME ] && __ABORT
|
||||
|
||||
__STATUS "selected '$TEMPLATE_ENV_NAME'"
|
||||
|
||||
__PROMPT 'enter new environment name'
|
||||
ENV_NAME=$(__FZF_HEAD 'new environment')
|
||||
[ ! $ENV_NAME ] && __ABORT
|
||||
|
||||
TEMPLATE_ENV_FILE=$(__GET_ENV_FILE $TEMPLATE_ENV_NAME)
|
||||
ENV_FILE=$(__GET_ENV_FILE $ENV_NAME)
|
||||
|
||||
[ -f "$ENV_FILE" ] && __FAIL 2 "'$ENV_NAME' already exists"
|
||||
|
||||
__STATUS "creating environment"
|
||||
cp "$TEMPLATE_ENV_FILE" "$ENV_FILE" \
|
||||
&& __SUCCESS "created '$ENV_NAME'" \
|
||||
|| __FAIL 3 "unable to create '$ENV_NAME'"
|
24
zsh/scwrypts/environment/delete
Executable file
24
zsh/scwrypts/environment/delete
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
__PROMPT 'choose an environment to delete'
|
||||
ENV_NAME=$(__SELECT_ENV)
|
||||
[ ! $ENV_NAME ] && __ABORT
|
||||
|
||||
ENV_FILE=$(__GET_ENV_FILE $ENV_NAME)
|
||||
|
||||
__STATUS "preparing to remove '$ENV_NAME'"
|
||||
|
||||
__WARNING
|
||||
__WARNING "the '$ENV_NAME' environment will be removed"
|
||||
__WARNING 'configured options and stored credentials will be lost forever'
|
||||
__WARNING
|
||||
|
||||
__yN 'continue?' || __ABORT
|
||||
|
||||
__STATUS "removing environment"
|
||||
rm "$ENV_FILE" \
|
||||
&& __SUCCESS "removed '$ENV_NAME'" \
|
||||
|| __FAIL 3 "unable to remove '$ENV_FILE'; is it protected?"
|
49
zsh/scwrypts/environment/edit
Executable file
49
zsh/scwrypts/environment/edit
Executable file
@ -0,0 +1,49 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
[ $SCWRYPTS_ENV ] \
|
||||
&& ENV_NAME=$SCWRYPTS_ENV \
|
||||
|| ENV_NAME=$(__SELECT_OR_CREATE_ENV)
|
||||
[ ! $ENV_NAME ] && __ABORT
|
||||
|
||||
ENV_FILE=$(__GET_ENV_FILE $ENV_NAME)
|
||||
[ ! -f $ENV_FILE ] && {
|
||||
__STATUS "Creating '$ENV_NAME'..." \
|
||||
&& cp $__ENV_TEMPLATE $ENV_FILE \
|
||||
&& __SUCCESS 'created!' \
|
||||
|| { __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
|
||||
|
||||
__STATUS "finished editing; looking for new environment variables"
|
||||
while read line
|
||||
do
|
||||
ENV_VAR=$(echo "$line" | sed 's/=.*$//; s/^export //')
|
||||
grep -q "$ENV_VAR" $__ENV_TEMPLATE || {
|
||||
((NEW_VAR+=1))
|
||||
echo "export $ENV_VAR=" >> $__ENV_TEMPLATE
|
||||
__STATUS "detected new variable '$ENV_VAR'"
|
||||
}
|
||||
done < $ENV_FILE
|
||||
|
||||
[ $NEW_VAR ] && {
|
||||
LC_COLLATE=C sort -uo $__ENV_TEMPLATE $__ENV_TEMPLATE
|
||||
NOPROMPT=1 ${0:a:h}/synchronize
|
||||
git add $__ENV_TEMPLATE \
|
||||
&& __SUCCESS "auto-staged the $(basename $__ENV_TEMPLATE) changes" \
|
||||
|| {
|
||||
__WARNING "unable to stage $(basename $__ENV_TEMPLATE) changes"
|
||||
__REMINDER "don't forget to commit changes to $(basename $__ENV_TEMPLATE)"
|
||||
}
|
||||
true
|
||||
} || {
|
||||
__STATUS 'no new environment variables'
|
||||
}
|
||||
|
||||
__SUCCESS "environment '$ENV_NAME' successfully modified"
|
6
zsh/scwrypts/environment/stage-variables
Executable file
6
zsh/scwrypts/environment/stage-variables
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
__CHECK_ENV_VARS $@ || NOPROMPT=1 $SCWRYPTS_ROOT/zsh/scwrypts/environment/synchronize
|
46
zsh/scwrypts/environment/synchronize
Executable file
46
zsh/scwrypts/environment/synchronize
Executable file
@ -0,0 +1,46 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
[ ! $NOPROMPT ] && {
|
||||
__yN 'change the template before sync?' && __EDIT $__ENV_TEMPLATE
|
||||
sed -i "s/^[A-Z]/export &/; s/^[^#=]\\+$/&=/; s/=.*$/=/" $__ENV_TEMPLATE
|
||||
LC_COLLATE=C sort -uo $__ENV_TEMPLATE $__ENV_TEMPLATE
|
||||
git add $__ENV_TEMPLATE >/dev/null 2>&1
|
||||
}
|
||||
|
||||
ENVIRONMENTS=$(__GET_ENV_FILES)
|
||||
|
||||
__STATUS 'inserting new environment variables...'
|
||||
while read line
|
||||
do
|
||||
for ENV_FILE in $(echo $ENVIRONMENTS)
|
||||
do
|
||||
grep -q "^$line" $ENV_FILE || {
|
||||
echo $line >> $ENV_FILE && __STATUS "added '$line' to '$ENV_FILE'"
|
||||
}
|
||||
done
|
||||
done < <(sed -n '/^./p' $__ENV_TEMPLATE)
|
||||
|
||||
__STATUS 'removing old environment variables...'
|
||||
for ENV_FILE in $(echo $ENVIRONMENTS)
|
||||
do
|
||||
while read line
|
||||
do
|
||||
ENV_VAR=$(echo "$line" | sed 's/=.*/=/')
|
||||
grep -q "$ENV_VAR" $__ENV_TEMPLATE || {
|
||||
sed -i "\\%$ENV_VAR%d" $ENV_FILE
|
||||
__WARNING "removed unwanted '$ENV_VAR' from '$ENV_FILE'"
|
||||
}
|
||||
done < $ENV_FILE
|
||||
done
|
||||
|
||||
for ENV_FILE in $(echo $ENVIRONMENTS)
|
||||
do
|
||||
sed -i "s/^[A-Z]/export &/; s/^[^#=]\\+$/&=/" $ENV_FILE
|
||||
LC_COLLATE=C sort -uo $ENV_FILE $ENV_FILE
|
||||
done
|
||||
LC_COLLATE=C sort -uo $__ENV_TEMPLATE $__ENV_TEMPLATE
|
||||
|
||||
__SUCCESS 'finished sync!'
|
20
zsh/scwrypts/logs/clear
Executable file
20
zsh/scwrypts/logs/clear
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
cd $SCWRYPTS_ROOT
|
||||
|
||||
__STATUS "Found $(ls $SCWRYPTS_LOG_PATH | wc -l) log files"
|
||||
__WARNING
|
||||
__WARNING 'this will permanently clear all local cloud script logs found in'
|
||||
__WARNING "'$SCWRYPTS_LOG_PATH'"
|
||||
__WARNING
|
||||
|
||||
__yN 'continue?' || __ABORT
|
||||
|
||||
__STATUS 'removing logfiles'
|
||||
rm -rf $SCWRYPTS_LOG_PATH/* \
|
||||
&& __SUCCESS 'done' \
|
||||
|| { __ERROR 'failed :c'; exit 2; }\
|
||||
;
|
9
zsh/scwrypts/logs/common.zsh
Normal file
9
zsh/scwrypts/logs/common.zsh
Normal file
@ -0,0 +1,9 @@
|
||||
source ${0:a:h}/../common.zsh
|
||||
|
||||
__CHECK_DEPENDENCIES \
|
||||
;
|
||||
|
||||
__CHECK_ENV_VARS \
|
||||
;
|
||||
|
||||
#####################################################################
|
13
zsh/scwrypts/logs/view
Executable file
13
zsh/scwrypts/logs/view
Executable file
@ -0,0 +1,13 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
cd $SCWRYPTS_ROOT
|
||||
__PROMPT 'select a script log'
|
||||
LOG_FILE=$(ls $SCWRYPTS_LOG_PATH | __FZF 'logfile')
|
||||
[ ! $LOG_FILE ] && { __ERROR 'user abort'; exit 1; }
|
||||
|
||||
__STATUS 'opening logfile'
|
||||
__LESS "$SCWRYPTS_LOG_PATH/$LOG_FILE"
|
||||
__SUCCESS 'done'
|
128
zsh/scwrypts/virtualenv/common.zsh
Normal file
128
zsh/scwrypts/virtualenv/common.zsh
Normal file
@ -0,0 +1,128 @@
|
||||
source ${0:a:h}/../common.zsh
|
||||
|
||||
__CHECK_DEPENDENCIES \
|
||||
virtualenv \
|
||||
nodeenv \
|
||||
;
|
||||
|
||||
__CHECK_ENV_VARS \
|
||||
;
|
||||
|
||||
#####################################################################
|
||||
|
||||
__AVAILABLE_VIRTUALENVS=(python node)
|
||||
|
||||
#####################################################################
|
||||
|
||||
__REFRESH_VIRTUALENV() {
|
||||
local TYPE="$1"
|
||||
[ ! $TYPE ] && {
|
||||
__ERROR 'no virtualenv type specified'
|
||||
return 1
|
||||
}
|
||||
__STATUS "refreshing $TYPE virtual environment"
|
||||
__DELETE_VIRTUALENV $TYPE \
|
||||
&& __UPDATE_VIRTUALENV $TYPE \
|
||||
&& __SUCCESS 'successfully refreshed virtual environment' \
|
||||
|| { ERROR 'something went wrong during refresh (see above)'; return 1; } \
|
||||
;
|
||||
}
|
||||
|
||||
__UPDATE_VIRTUALENV() {
|
||||
local TYPE="$1"
|
||||
[ ! $TYPE ] && {
|
||||
__ERROR 'no virtualenv type specified'
|
||||
return 1
|
||||
}
|
||||
|
||||
local VIRTUALENV_PATH=$(__GET_VIRTUALENV_PATH $TYPE)
|
||||
|
||||
[ ! -d $VIRTUALENV_PATH ] && __CREATE_VIRTUALENV_$TYPE $VIRTUALENV_PATH
|
||||
|
||||
__STATUS "updating $TYPE virtual environment"
|
||||
|
||||
source $VIRTUALENV_PATH/bin/activate || {
|
||||
__ERROR 'failed to activate virtualenv; did create fail?'
|
||||
return 1
|
||||
}
|
||||
|
||||
cd $VIRTUALENV_PATH/../
|
||||
local UPDATE_CODE=0
|
||||
case $TYPE in
|
||||
python ) pip install -r requirements.txt; UPDATE_CODE=$? ;;
|
||||
node ) npm install ;
|
||||
esac
|
||||
UPDATE_CODE=$?
|
||||
[[ $UPDATE_CODE -eq 0 ]] \
|
||||
&& __SUCCESS "$TYPE virtual environment up-to-date" \
|
||||
|| __ERROR "failed to update $TYPE virtual environment (see errors above)" \
|
||||
;
|
||||
|
||||
deactivate_node >/dev/null 2>&1
|
||||
deactivate >/dev/null 2>&1
|
||||
return $UPDATE_CODE
|
||||
}
|
||||
|
||||
__DELETE_VIRTUALENV() {
|
||||
local TYPE="$1"
|
||||
local VIRTUALENV_PATH="$(__GET_VIRTUALENV_PATH $TYPE)"
|
||||
|
||||
__STATUS "dropping $TYPE virtual environment artifacts"
|
||||
|
||||
[ ! -d $VIRTUALENV_PATH ] && {
|
||||
__SUCCESS "no $TYPE environment detected"
|
||||
return 0
|
||||
}
|
||||
|
||||
rm -rf $VIRTUALENV_PATH \
|
||||
&& __SUCCESS "succesfully cleaned up $TYPE virtual environment" \
|
||||
|| { __ERROR "unabled to remove '$VIRTUALENV_PATH'"; return 1; }
|
||||
}
|
||||
|
||||
__GET_VIRTUALENV_PATH() {
|
||||
local TYPE="$1"
|
||||
case $TYPE in
|
||||
python ) echo "$SCWRYPTS_ROOT/py/.env" ;;
|
||||
node ) echo "$SCWRYPTS_ROOT/zx/.env" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
|
||||
__CREATE_VIRTUALENV_python() {
|
||||
local VIRTUALENV_PATH="$1"
|
||||
|
||||
__STATUS 'creating python virtual environment'
|
||||
local PY PYTHON
|
||||
for PY in $(echo $__PREFERRED_PYTHON_VERSIONS)
|
||||
do
|
||||
which python$PY >/dev/null 2>&1 && {
|
||||
PYTHON=$(which python$PY)
|
||||
break
|
||||
}
|
||||
done
|
||||
[ ! $PYTHON ] && {
|
||||
__ERROR 'python>=3.9 not available; skipping python env'
|
||||
return 1
|
||||
}
|
||||
|
||||
__STATUS 'setting up virtualenv'
|
||||
virtualenv $VIRTUALENV_PATH --python="$PYTHON" \
|
||||
&& __SUCCESS 'python virtualenv created' \
|
||||
|| {
|
||||
__ERROR "unable to create '$VIRTUALENV_PATH' with '$PYTHON'"
|
||||
return 2
|
||||
}
|
||||
}
|
||||
|
||||
__CREATE_VIRTUALENV_node() {
|
||||
local VIRTUALENV_PATH="$1"
|
||||
|
||||
__STATUS 'setting up nodeenv'
|
||||
nodeenv $VIRTUALENV_PATH --node=$__NODE_VERSION \
|
||||
&& __SUCCESS 'node virtualenv created' \
|
||||
|| {
|
||||
__ERROR "unable to create '$VIRTUALENV_PATH' with '$__NODE_VERSION'"
|
||||
return 2
|
||||
}
|
||||
}
|
17
zsh/scwrypts/virtualenv/refresh
Executable file
17
zsh/scwrypts/virtualenv/refresh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
ENV_TYPE=$(echo $__AVAILABLE_VIRTUALENVS | sed 's/ \+/\n/' | __FZF 'select an environment to refresh')
|
||||
[ ! $ENV_TYPE ] && __ABORT
|
||||
|
||||
__REMINDER
|
||||
__REMINDER "this will permanently remove all artifacts for the scwrypts $ENV_TYPE environment"
|
||||
__REMINDER "(safe unless you have put something important in $(__GET_VIRTUALENV_PATH $ENV_TYPE))"
|
||||
__REMINDER
|
||||
|
||||
|
||||
__Yn "drop and recreate $ENV_TYPE virtual environment?" || __ABORT
|
||||
|
||||
__REFRESH_VIRTUALENV $ENV_TYPE
|
17
zsh/scwrypts/virtualenv/update-all
Executable file
17
zsh/scwrypts/virtualenv/update-all
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/zsh
|
||||
source ${0:a:h}/common.zsh
|
||||
__CHECK_IMPORTS
|
||||
#####################################################################
|
||||
|
||||
__STATUS 'beginning update for all environments'
|
||||
|
||||
FAILED_COUNT=0
|
||||
|
||||
for ENV_TYPE in $(echo $__AVAILABLE_VIRTUALENVS)
|
||||
do
|
||||
__UPDATE_VIRTUALENV $ENV_TYPE || ((FAILED_COUNT+=1))
|
||||
done
|
||||
|
||||
[[ $FAILED_COUNT -eq 0 ]] \
|
||||
&& __SUCCESS 'all environments up-to-date' \
|
||||
|| __FAIL $FAILED_COUNT 'failed to update one or more environments'
|
7
zsh/utils/credits.zsh
Normal file
7
zsh/utils/credits.zsh
Normal file
@ -0,0 +1,7 @@
|
||||
__CREDITS() {
|
||||
local COMMAND="$1"
|
||||
cd $SCWRYPTS_ROOT
|
||||
cat ./**/README.md \
|
||||
| grep 'Generic Badge' \
|
||||
| sed -n "s/.*Generic Badge.*-$COMMAND-.*(/(/p"
|
||||
}
|
45
zsh/utils/dependencies.zsh
Normal file
45
zsh/utils/dependencies.zsh
Normal file
@ -0,0 +1,45 @@
|
||||
__CHECK_DEPENDENCIES() {
|
||||
local DEPENDENCY
|
||||
for DEPENDENCY in $*
|
||||
do
|
||||
__CHECK_DEPENDENCY $DEPENDENCY || ((__DEPENDENCY_ERROR+=1))
|
||||
done
|
||||
|
||||
__CHECK_COREUTILS || ((__DEPENDENCY_ERROR+=$?))
|
||||
|
||||
return $__DEPENDENCY_ERROR
|
||||
}
|
||||
|
||||
__CHECK_DEPENDENCY() {
|
||||
local DEPENDENCY="$1"
|
||||
[ ! $DEPENDENCY ] && return 1
|
||||
|
||||
command -v $DEPENDENCY >/dev/null 2>&1 || {
|
||||
__ERROR "'$1' required but not installed. $(__CREDITS $1)"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
__CHECK_COREUTILS() {
|
||||
local COREUTILS=(awk find grep sed)
|
||||
local MISSING_DEPENDENCY_COUNT=0
|
||||
local NON_GNU_DEPENDENCY_COUNT=0
|
||||
|
||||
local UTIL
|
||||
for UTIL in $(echo $COREUTILS)
|
||||
do
|
||||
__CHECK_DEPENDENCY $UTIL || { ((MISSING_DEPENDENCY_COUNT+=1)); continue; }
|
||||
|
||||
$UTIL --version 2>&1 | grep -q 'GNU' || {
|
||||
__WARNING "non-GNU version of $UTIL detected"
|
||||
((NON_GNU_DEPENDENCY_COUNT+=1))
|
||||
}
|
||||
done
|
||||
|
||||
[[ $NON_GNU_DEPENDENCY_COUNT -gt 0 ]] && {
|
||||
__WARNING 'scripts rely on GNU coreutils; functionality may be limited'
|
||||
__IS_MACOS && __REMINDER 'GNU coreutils can be installed and linked through Homebrew'
|
||||
}
|
||||
|
||||
return $MISSING_DEPENDENCY_COUNT
|
||||
}
|
45
zsh/utils/environment.zsh
Normal file
45
zsh/utils/environment.zsh
Normal file
@ -0,0 +1,45 @@
|
||||
__CHECK_ENV_VARS() {
|
||||
local OPTIONAL=0
|
||||
[[ $1 =~ ^--optional$ ]] && { shift 1; OPTIONAL=1; }
|
||||
|
||||
local VAR_NAME
|
||||
for VAR_NAME in $*
|
||||
do
|
||||
__CHECK_ENV_VAR $VAR_NAME $OPTIONAL || ((__ENVIRONMENT_ERROR+=1))
|
||||
done
|
||||
|
||||
return $__ENVIRONMENT_ERROR
|
||||
}
|
||||
|
||||
__CHECK_ENV_VAR() {
|
||||
local NAME="$1"
|
||||
local OPTIONAL="$2"
|
||||
local DEFAULT_VALUE="$3"
|
||||
|
||||
local VALUE=$(eval echo '$'$NAME)
|
||||
[ $VALUE ] && return 0
|
||||
|
||||
local LINE="export $NAME="
|
||||
local TEMPLATE="$SCWRYPTS_ROOT/.template.env"
|
||||
|
||||
grep -q -- "^$LINE" "$TEMPLATE" || {
|
||||
__STATUS 'staging new variable in template'
|
||||
|
||||
echo "$LINE" >> "$TEMPLATE" \
|
||||
&& NOPROMPT=1 $SCWRYPTS_ROOT/zsh/scwrypts/environment/synchronize \
|
||||
&& git add $TEMPLATE >/dev/null 2>&1 \
|
||||
&& __SUCCESS "staged '$NAME'" \
|
||||
|| {
|
||||
__WARNING "failed to stage '$NAME'"
|
||||
__REMINDER "add/commit '$NAME' to template manually"
|
||||
}
|
||||
}
|
||||
|
||||
[ $OPTIONAL ] && {
|
||||
__ERROR "'$NAME' required"
|
||||
return 1
|
||||
} || {
|
||||
[ $DEFAULT_VALUE ] && $NAME="$DEFAULT_VALUE"
|
||||
return 0
|
||||
}
|
||||
}
|
44
zsh/utils/io.zsh
Normal file
44
zsh/utils/io.zsh
Normal file
@ -0,0 +1,44 @@
|
||||
__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; }
|
||||
__PROMPT() {
|
||||
echo "\\033[1;36mPROMPT : $@\\033[0m" >&2
|
||||
printf "\\033[1;36mUSER : \\033[0m" >&2
|
||||
}
|
||||
|
||||
__Yn() {
|
||||
__PROMPT "$@ [Yn]"
|
||||
local Yn; __READ -k Yn; echo
|
||||
[[ $Yn =~ [nN] ]] && return 1 || return 0
|
||||
}
|
||||
|
||||
__yN() {
|
||||
__PROMPT "$@ [yN]"
|
||||
local yN; __READ -k yN; echo
|
||||
[[ $yN =~ [yY] ]] && return 0 || return 1
|
||||
}
|
||||
|
||||
__FAIL() { __ERROR "${@:2}"; exit $1; }
|
||||
|
||||
__ABORT() { __FAIL 69 'user abort'; }
|
||||
|
||||
#####################################################################
|
||||
|
||||
__GETSUDO() {
|
||||
echo "\\033[1;36mPROMPT : checking sudo password...\\033[0m" >&2
|
||||
sudo echo hi >/dev/null 2>&1 </dev/tty \
|
||||
&& __SUCCESS '...authenticated!' \
|
||||
|| { __ERROR 'failed :c'; return 1; }
|
||||
}
|
||||
|
||||
__LESS() { less -R $@ </dev/tty >/dev/tty; }
|
||||
|
||||
__FZF() { fzf -i --height=30% --layout=reverse --prompt "$@ : "; }
|
||||
__FZF_HEAD() { fzf -i --height=30% --layout=reverse --print-query --prompt "$@ : " | head -n1; }
|
||||
__FZF_TAIL() { fzf -i --height=30% --layout=reverse --print-query --prompt "$@ : " | tail -n1; }
|
||||
|
||||
__READ() { read $@ </dev/tty; }
|
||||
|
||||
__EDIT() { $EDITOR $@ </dev/tty >/dev/tty; }
|
12
zsh/utils/os.zsh
Normal file
12
zsh/utils/os.zsh
Normal file
@ -0,0 +1,12 @@
|
||||
__IS_MACOS() { uname -s | grep -q 'Darwin'; }
|
||||
|
||||
__OPEN() {
|
||||
local OPEN=''
|
||||
{
|
||||
command -v xdg-open && OPEN=xdg-open
|
||||
command -v open && OPEN=open
|
||||
} >/dev/null 2>&1
|
||||
|
||||
[ ! $OPEN ] && { __ERROR 'unable to detect default open command (e.g. xdg-open)'; return 1 }
|
||||
$OPEN $@
|
||||
}
|
Reference in New Issue
Block a user