mirror of
https://github.com/denisidoro/navi
synced 2024-11-21 19:13:07 +00:00
Minor refactor (#57)
- [x] Define OPTIONS as global in opts::eval - [x] Add script - [x] Minor changes
This commit is contained in:
parent
2ee253a56e
commit
36cd52f93d
13 changed files with 187 additions and 37 deletions
|
@ -3,16 +3,16 @@
|
|||
# Print resource documentation
|
||||
kubectl explain <resource>
|
||||
|
||||
# Get nodes (add option `-o wide` for details)
|
||||
# Get nodes (add option '-o wide' for details)
|
||||
kubectl get nodes
|
||||
|
||||
# Get namespaces
|
||||
kubectl get namespaces
|
||||
|
||||
# Get pods from namespace (add option `-o wide` for details)
|
||||
# Get pods from namespace (add option '-o wide' for details)
|
||||
kubectl get pods -n <namespace>
|
||||
|
||||
# Get pods from all namespace (add option `-o wide` for details)
|
||||
# Get pods from all namespace (add option '-o wide' for details)
|
||||
kubectl get pods --all-namespaces
|
||||
|
||||
# Get services from namespace
|
||||
|
|
10
navi
10
navi
|
@ -35,13 +35,7 @@ source "${SCRIPT_DIR}/src/main.sh"
|
|||
##? full docs
|
||||
##? Please refer to the README at https://github.com/denisidoro/navi
|
||||
|
||||
VERSION="0.9.1"
|
||||
VERSION="0.9.2"
|
||||
|
||||
# workaround while dict::* can't handle newlines
|
||||
case "${1:-}" in
|
||||
help|--help) opts::extract_help "$0" && exit 0 ;;
|
||||
esac
|
||||
|
||||
OPTIONS="$(opts::eval "$@")"
|
||||
export NAVI_PATH="$(dict::get "$OPTIONS" path)"
|
||||
opts::eval "$@"
|
||||
main "$@"
|
||||
|
|
21
scripts/docker
Executable file
21
scripts/docker
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
debian="${1:-false}"
|
||||
|
||||
if $debian; then
|
||||
docker run \
|
||||
-it \
|
||||
--entrypoint /bin/bash \
|
||||
-v "$(pwd):/navi" \
|
||||
debian \
|
||||
-c 'apt update; apt install -y git curl; git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf && yes | ~/.fzf/install; export PATH=$PATH:/navi; bash'
|
||||
else
|
||||
docker run \
|
||||
-it \
|
||||
--entrypoint /bin/bash \
|
||||
-v "$(pwd):/navi" \
|
||||
ellerbrock/alpine-bash-git \
|
||||
-c 'git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf && yes | ~/.fzf/install; export PATH=$PATH:/navi; bash'
|
||||
fi
|
||||
|
|
@ -8,6 +8,8 @@ script() {
|
|||
echo "${SCRIPT_DIR}/navi" '"$@"'
|
||||
}
|
||||
|
||||
BIN="/usr/local/bin/navi"
|
||||
script > "$BIN"
|
||||
chmod +x "$BIN"
|
||||
folder="${1:-/usr/local/bin}"
|
||||
bin="${folder}/navi"
|
||||
|
||||
script > "$bin"
|
||||
chmod +x "$bin"
|
10
src/arg.sh
10
src/arg.sh
|
@ -1,11 +1,13 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
ARG_REGEX="<[0-9a-zA-Z_]+>"
|
||||
ARG_DELIMITER="£"
|
||||
ARG_DELIMITER="\f"
|
||||
|
||||
arg::dict() {
|
||||
local -r fn="$(awk -F'---' '{print $1}')"
|
||||
local -r opts="$(awk -F'---' '{print $2}')"
|
||||
local -r input="$(cat)"
|
||||
|
||||
local -r fn="$(echo "$input" | awk -F'---' '{print $1}')"
|
||||
local -r opts="$(echo "$input" | awk -F'---' '{print $2}')"
|
||||
|
||||
dict::new fn "$fn" opts "$opts"
|
||||
}
|
||||
|
@ -34,7 +36,7 @@ arg::deserialize() {
|
|||
local -r out="$arg"
|
||||
fi
|
||||
|
||||
echo "$out" | sed "s/${ARG_DELIMITER}/ /g"
|
||||
echo "$out" | tr "${ARG_DELIMITER}" " "
|
||||
}
|
||||
|
||||
# TODO: separation of concerns
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# for an explanation behind this namespace, please check
|
||||
# https://medium.com/@den.isidoro/dictionaries-in-shell-scripts-61d34e1c91c6
|
||||
|
||||
# LIMITATIONS:
|
||||
# values with non-trivial whitespaces (newlines, subsequent spaces, etc)
|
||||
# aren't handled very well
|
||||
|
||||
DICT_DELIMITER='\f'
|
||||
|
||||
dict::_post() {
|
||||
|
@ -64,7 +71,7 @@ dict::get() {
|
|||
if [ $matches -gt 1 ]; then
|
||||
echo "$result" | dict::_unescape_value
|
||||
else
|
||||
echo "$result" | sed -E "s/${prefix}//" | dict::_unescape_value
|
||||
echo "$result" | sed -E "s/${prefix}//" | dict::_unescape_value | sed -E 's/^[[:space:]]*//'
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
20
src/main.sh
20
src/main.sh
|
@ -1,5 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
if ${NAVI_FORCE_GNU:-false}; then
|
||||
source "${DOTFILES}/scripts/core/main.sh"
|
||||
fi
|
||||
|
||||
source "${SCRIPT_DIR}/src/arg.sh"
|
||||
source "${SCRIPT_DIR}/src/cheat.sh"
|
||||
source "${SCRIPT_DIR}/src/dict.sh"
|
||||
|
@ -56,8 +60,12 @@ handler::preview() {
|
|||
[ -n "$cheat" ] && selection::cmd "$selection" "$cheat"
|
||||
}
|
||||
|
||||
handler::text() {
|
||||
dict::get "$OPTIONS" text
|
||||
handler::help() {
|
||||
echo "$TEXT"
|
||||
}
|
||||
|
||||
handler::version() {
|
||||
echo "${VERSION:-unknown}"
|
||||
}
|
||||
|
||||
main() {
|
||||
|
@ -66,6 +74,7 @@ main() {
|
|||
local -r query="$(dict::get "$OPTIONS" query)"
|
||||
handler::preview "$query" \
|
||||
|| echo "Unable to find command for '$query'"
|
||||
echo "$NAVI_PATH"
|
||||
;;
|
||||
search)
|
||||
health::fzf
|
||||
|
@ -73,8 +82,11 @@ main() {
|
|||
search::save "$query" || true
|
||||
handler::main
|
||||
;;
|
||||
text)
|
||||
handler::text
|
||||
version)
|
||||
handler::version
|
||||
;;
|
||||
help)
|
||||
handler::help
|
||||
;;
|
||||
*)
|
||||
health::fzf
|
||||
|
|
|
@ -25,8 +25,8 @@ opts::eval() {
|
|||
case $arg in
|
||||
--print) print=true ;;
|
||||
--no-interpolation) interpolation=false ;;
|
||||
--version|version) dict::new entry_point "text" text "${VERSION:-unknown}" && exit 0 ;;
|
||||
help|--help) dict::new entry_point "text" text "$(opts::extract_help "$0")" && exit 0 ;;
|
||||
--version|version) entry_point="version" ;;
|
||||
help|--help) entry_point="help"; TEXT="$(opts::extract_help "$0")" ;;
|
||||
--command-for) wait_for="command-for" ;;
|
||||
--no-preview) preview=false ;;
|
||||
--path) wait_for="path" ;;
|
||||
|
@ -36,5 +36,6 @@ opts::eval() {
|
|||
esac
|
||||
done
|
||||
|
||||
dict::new entry_point "$entry_point" print "$print" interpolation "$interpolation" preview "$preview" query "${query:-}" path "$path"
|
||||
OPTIONS="$(dict::new entry_point "$entry_point" print "$print" interpolation "$interpolation" preview "$preview" query "${query:-}")"
|
||||
export NAVI_PATH="$path"
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ selection::dict() {
|
|||
local -r tags="$(echo "$str" | awk -F'[' '{print $NF}' | tr -d ']')"
|
||||
local -r core="$(echo "$str" | sed -e "s/ \[${tags}\]$//")"
|
||||
|
||||
dict::new core "$core" tags "$tags"
|
||||
dict::new core "$core" tags "$tags" | sed "s/'''/'/g"
|
||||
}
|
||||
|
||||
selection::core_is_comment() {
|
||||
|
|
|
@ -29,3 +29,9 @@ str::last_paragraph_line() {
|
|||
str::first_word() {
|
||||
awk '{print $1}'
|
||||
}
|
||||
|
||||
str::index_last_occurrence() {
|
||||
local -r char="$1"
|
||||
|
||||
awk 'BEGIN{FS=""}{ for(i=1;i<=NF;i++){ if($i=="'"$char"'"){ p=i } }}END{ print p }'
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
test::run "We can find at least one known cheatsheet" \
|
||||
'cheat::find | grep -q "docker.cheat"'
|
||||
assert_docker_cheat() {
|
||||
cheat::find | grep -q "docker.cheat"
|
||||
}
|
||||
|
||||
test::run "We can find at least one known cheatsheet" assert_docker_cheat
|
||||
|
|
16
test/core.sh
16
test/core.sh
|
@ -1,27 +1,27 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source "${SCRIPT_DIR}/src/main.sh"
|
||||
source "${SCRIPT_DIR}/test/log.sh"
|
||||
|
||||
OPTIONS="$(opts::eval "$@")"
|
||||
export NAVI_PATH="$(dict::get "$OPTIONS" path)"
|
||||
opts::eval "$@"
|
||||
|
||||
PASSED=0
|
||||
FAILED=0
|
||||
|
||||
test::success() {
|
||||
PASSED=$((PASSED+1))
|
||||
echo "Test passed!"
|
||||
log::success "Test passed!"
|
||||
}
|
||||
|
||||
test::fail() {
|
||||
FAILED=$((FAILED+1))
|
||||
echo "Test failed..."
|
||||
log::error "Test failed..."
|
||||
return
|
||||
}
|
||||
|
||||
test::run() {
|
||||
echo
|
||||
echo "-> $1"
|
||||
log::note "$1"
|
||||
shift
|
||||
eval "$*" && test::success || test::fail
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ test::equals() {
|
|||
local -r expected="$(echo "${1:-}" | tr -d '\n' | sed 's/\\n//g')"
|
||||
|
||||
if [[ "$actual" != "$expected" ]]; then
|
||||
echo "Expected '${expected}' but got '${actual}'"
|
||||
log::success "Expected '${expected}' but got '${actual}'"
|
||||
return 2
|
||||
fi
|
||||
}
|
||||
|
@ -39,10 +39,10 @@ test::equals() {
|
|||
test::finish() {
|
||||
echo
|
||||
if [ $FAILED -gt 0 ]; then
|
||||
echo "${PASSED} tests passed but ${FAILED} failed... :("
|
||||
log::error "${PASSED} tests passed but ${FAILED} failed... :("
|
||||
exit "${FAILED}"
|
||||
else
|
||||
echo "All ${PASSED} tests passed! :)"
|
||||
log::success "All ${PASSED} tests passed! :)"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
|
102
test/log.sh
Normal file
102
test/log.sh
Normal file
|
@ -0,0 +1,102 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
_export_colors() {
|
||||
if ! ${DOT_COLORS_EXPORTED:-false}; then
|
||||
if [ -z ${TERM:-} ] || [ $TERM = "dumb" ]; then
|
||||
bold=""
|
||||
underline=""
|
||||
freset=""
|
||||
purple=""
|
||||
red=""
|
||||
green=""
|
||||
tan=""
|
||||
blue=""
|
||||
else
|
||||
bold=$(tput bold)
|
||||
underline=$(tput sgr 0 1)
|
||||
freset=$(tput sgr0)
|
||||
purple=$(tput setaf 171)
|
||||
red=$(tput setaf 1)
|
||||
green=$(tput setaf 76)
|
||||
tan=$(tput setaf 3)
|
||||
blue=$(tput setaf 38)
|
||||
fi
|
||||
|
||||
log_black=30
|
||||
log_red=31
|
||||
log_green=32
|
||||
log_yellow=33
|
||||
log_blue=34
|
||||
log_purple=35
|
||||
log_cyan=36
|
||||
log_white=37
|
||||
|
||||
log_regular=0
|
||||
log_bold=1
|
||||
log_underline=4
|
||||
|
||||
readonly DOT_COLORS_EXPORTED=true
|
||||
fi
|
||||
}
|
||||
|
||||
log::color() {
|
||||
_export_colors
|
||||
local bg=false
|
||||
case "$@" in
|
||||
*reset*) echo "\e[0m"; exit 0 ;;
|
||||
*black*) color=$log_black ;;
|
||||
*red*) color=$log_red ;;
|
||||
*green*) color=$log_green ;;
|
||||
*yellow*) color=$log_yellow ;;
|
||||
*blue*) color=$log_blue ;;
|
||||
*purple*) color=$log_purple ;;
|
||||
*cyan*) color=$log_cyan ;;
|
||||
*white*) color=$log_white ;;
|
||||
esac
|
||||
case "$@" in
|
||||
*regular*) mod=$log_regular ;;
|
||||
*bold*) mod=$log_bold ;;
|
||||
*underline*) mod=$log_underline ;;
|
||||
esac
|
||||
case "$@" in
|
||||
*background*) bg=true ;;
|
||||
*bg*) bg=true ;;
|
||||
esac
|
||||
|
||||
if $bg; then
|
||||
echo "\e[${color}m"
|
||||
else
|
||||
echo "\e[${mod:-$log_regular};${color}m"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -z ${LOG_FILE+x} ]; then
|
||||
readonly LOG_FILE="/tmp/$(basename "$0").log"
|
||||
fi
|
||||
|
||||
_log() {
|
||||
local template=$1
|
||||
shift
|
||||
if ${log_to_file:-false}; then
|
||||
echo -e $(printf "$template" "$@") | tee -a "$LOG_FILE" >&2
|
||||
else
|
||||
echo -e $(printf "$template" "$@")
|
||||
fi
|
||||
}
|
||||
|
||||
_header() {
|
||||
local TOTAL_CHARS=60
|
||||
local total=$TOTAL_CHARS-2
|
||||
local size=${#1}
|
||||
local left=$((($total - $size) / 2))
|
||||
local right=$(($total - $size - $left))
|
||||
printf "%${left}s" '' | tr ' ' =
|
||||
printf " $1 "
|
||||
printf "%${right}s" '' | tr ' ' =
|
||||
}
|
||||
|
||||
log::header() { _export_colors && _log "\n${bold}${purple}$(_header "$1")${freset}\n"; }
|
||||
log::success() { _export_colors && _log "${green}✔ %s${freset}\n" "$@"; }
|
||||
log::error() { _export_colors && _log "${red}✖ %s${freset}\n" "$@"; }
|
||||
log::warning() { _export_colors && _log "${tan}➜ %s${freset}\n" "$@"; }
|
||||
log::note() { _export_colors && _log "${blue}➜ %s${freset}\n" "$@"; }
|
Loading…
Reference in a new issue