visidata: add installer and optional deps list
This commit is contained in:
3
config/visidata/.gitignore
vendored
Normal file
3
config/visidata/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
__pycache__/
|
||||||
|
plugins/__pycache__/
|
||||||
|
*.pyc
|
||||||
129
config/visidata/install.sh
Executable file
129
config/visidata/install.sh
Executable file
@@ -0,0 +1,129 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
mode="link" # link|copy
|
||||||
|
do_deps=0
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'USAGE'
|
||||||
|
Usage: ./install.sh [--link|--copy] [--deps]
|
||||||
|
|
||||||
|
Installs this repo's VisiData config and plugins into standard per-user locations:
|
||||||
|
- config.py in the user config dir (VisiData 3.3+ default)
|
||||||
|
- ~/.visidatarc (legacy fallback)
|
||||||
|
- plugins into $VD_DIR/plugins (default ~/.visidata/plugins)
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--link Symlink files into place (default)
|
||||||
|
--copy Copy files into place
|
||||||
|
--deps Install requirements.txt into $VD_DIR/plugins-deps using pip --target
|
||||||
|
-h,--help Show this help
|
||||||
|
USAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--link) mode="link"; shift ;;
|
||||||
|
--copy) mode="copy"; shift ;;
|
||||||
|
--deps) do_deps=1; shift ;;
|
||||||
|
-h|--help) usage; exit 0 ;;
|
||||||
|
*) echo "Unknown arg: $1" >&2; usage; exit 2 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
|
||||||
|
src_rc="${script_dir}/visidatarc"
|
||||||
|
src_plugins_dir="${script_dir}/plugins"
|
||||||
|
src_reqs="${script_dir}/requirements.txt"
|
||||||
|
|
||||||
|
if [[ ! -f "${src_rc}" ]]; then
|
||||||
|
echo "Missing ${src_rc}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
timestamp() { date +"%Y%m%d-%H%M%S"; }
|
||||||
|
|
||||||
|
backup_if_needed() {
|
||||||
|
local dst="$1"
|
||||||
|
if [[ -L "$dst" ]]; then
|
||||||
|
# If it's already a symlink to our source (absolute), keep it.
|
||||||
|
local cur
|
||||||
|
cur="$(readlink "$dst" || true)"
|
||||||
|
if [[ "$cur" == "$2" ]]; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if [[ -e "$dst" || -L "$dst" ]]; then
|
||||||
|
mv "$dst" "${dst}.bak.$(timestamp)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_one() {
|
||||||
|
local src="$1"
|
||||||
|
local dst="$2"
|
||||||
|
mkdir -p "$(dirname "$dst")"
|
||||||
|
backup_if_needed "$dst" "$src"
|
||||||
|
if [[ "$mode" == "copy" ]]; then
|
||||||
|
cp -f "$src" "$dst"
|
||||||
|
else
|
||||||
|
ln -s "$src" "$dst"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
os="$(uname -s)"
|
||||||
|
if [[ "$os" == "Darwin" ]]; then
|
||||||
|
config_dir="${HOME}/Library/Preferences/visidata"
|
||||||
|
else
|
||||||
|
config_dir="${XDG_CONFIG_HOME:-${HOME}/.config}/visidata"
|
||||||
|
fi
|
||||||
|
dst_config_py="${config_dir}/config.py"
|
||||||
|
dst_visidatarc="${HOME}/.visidatarc"
|
||||||
|
|
||||||
|
vd_dir="${VD_DIR:-${HOME}/.visidata}"
|
||||||
|
dst_plugins_dir="${vd_dir}/plugins"
|
||||||
|
dst_deps_dir="${vd_dir}/plugins-deps"
|
||||||
|
|
||||||
|
# Config file(s)
|
||||||
|
install_one "$src_rc" "$dst_config_py"
|
||||||
|
install_one "$src_rc" "$dst_visidatarc"
|
||||||
|
|
||||||
|
# Plugins
|
||||||
|
mkdir -p "$dst_plugins_dir"
|
||||||
|
if [[ -d "$src_plugins_dir" ]]; then
|
||||||
|
for src_plugin in "${src_plugins_dir}"/*.py; do
|
||||||
|
[[ -e "$src_plugin" ]] || continue
|
||||||
|
install_one "$src_plugin" "${dst_plugins_dir}/$(basename "$src_plugin")"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$do_deps" -eq 1 ]]; then
|
||||||
|
if [[ ! -f "$src_reqs" ]]; then
|
||||||
|
echo "Missing ${src_reqs}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
mkdir -p "$dst_deps_dir"
|
||||||
|
|
||||||
|
# Prefer the python used by the `vd` entrypoint (if available).
|
||||||
|
pip_py=""
|
||||||
|
if command -v vd >/dev/null 2>&1; then
|
||||||
|
vd_bin="$(command -v vd)"
|
||||||
|
pip_py="$(sed -n '1{s/^#!//p;}' "$vd_bin" || true)"
|
||||||
|
fi
|
||||||
|
if [[ -z "$pip_py" ]]; then
|
||||||
|
pip_py="$(command -v python3 || true)"
|
||||||
|
fi
|
||||||
|
if [[ -z "$pip_py" ]]; then
|
||||||
|
echo "No python found to run pip." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
"$pip_py" -m pip install --upgrade --target "$dst_deps_dir" -r "$src_reqs"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Installed:"
|
||||||
|
echo " ${dst_config_py}"
|
||||||
|
echo " ${dst_visidatarc}"
|
||||||
|
echo " ${dst_plugins_dir}/"
|
||||||
|
if [[ "$do_deps" -eq 1 ]]; then
|
||||||
|
echo " ${dst_deps_dir}/"
|
||||||
|
fi
|
||||||
21
config/visidata/requirements.txt
Normal file
21
config/visidata/requirements.txt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Optional deps used by /Users/tabledevil/gists/config/visidata/visidatarc.
|
||||||
|
# Install into VisiData's per-user deps dir (recommended):
|
||||||
|
# ./install.sh --deps
|
||||||
|
#
|
||||||
|
# Or manually:
|
||||||
|
# python -m pip install --target ~/.visidata/plugins-deps -r requirements.txt
|
||||||
|
#
|
||||||
|
# Core HTTP / scraping
|
||||||
|
requests
|
||||||
|
beautifulsoup4
|
||||||
|
lxml
|
||||||
|
#
|
||||||
|
# Data parsing
|
||||||
|
PyYAML
|
||||||
|
#
|
||||||
|
# DNS lookups
|
||||||
|
dnspython
|
||||||
|
#
|
||||||
|
# Enrichment helpers
|
||||||
|
mac-vendor-lookup
|
||||||
|
virus_total_apis
|
||||||
Reference in New Issue
Block a user