Skip to content

Commit

Permalink
(Linux) CLI: bash completion
Browse files Browse the repository at this point in the history
  • Loading branch information
stenya committed Dec 6, 2023
1 parent 770b4de commit 8f9c9bc
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 7 deletions.
79 changes: 79 additions & 0 deletions cli/References/Linux/bash-completion-generator-ivpn-cli.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/bin/bash

# Bash completion generator for ivpn CLI
# (generates a bash completion script for the `ivpn` CLI)
# https://github.com/jordan-ivpn/bash-completion-generator-ivpn-cli/
#
# Usage:
# Install the ivpn CLI package first: https://www.ivpn.net/apps-linux/
#
# $ bash-completion-generator-ivpn-cli.sh > ivpn.bash
# $ source ivpn.bash
# $ sudo mv ivpn.bash /usr/share/bash-completion/completions/ivpn
# $ sudo chown root:root /usr/share/bash-completion/completions/ivpn
#
# Info:
# 1) The recommended directory is `completionsdir`, which you can get with `pkg-config --variable=completionsdir bash-completion`
# https://github.com/scop/bash-completion
#

# exit on error
set -e

# By default, the source command is `ivpn`.
# Also you can specify custom path to IVPN CLI binary in the first argument to this script (e.g. `bash-completion-generator-ivpn-cli.sh /usr/local/bin/ivpn`)
cli="ivpn"
if [ ! -z "$1" ]
then
cli="$1"
fi

# Check if the command/binary exists
if ! command -v "$cli" > /dev/null 2>&1; then
echo "Error: $cli not found or not executable"
exit 1
fi

# print header
echo "# bash completion for ivpn"
echo ""
echo "_ivpn()"
echo "{"
echo ' local cur opts'
echo ' COMPREPLY=()'
echo ' cur="${COMP_WORDS[COMP_CWORD]}" # current word'
echo ' cmd="${COMP_WORDS[1]}" # next word after "ivpn", e.g.: $ ivpn <cmd> ...'
echo ""

# determine command list and print list
# first awk bit from: https://stackoverflow.com/a/22222219
COMMAND_LIST=$( $cli -h | grep -Ev ^$ | awk '/Tips:/{f=0} f; /COMMANDS:/{f=1}' | awk '{ print $1 }')

echo " opts="'"'$COMMAND_LIST" -h"'"'
echo ""
echo ' case "${cmd}" in'

# iterate over commands and print case entries for sub-commands
for i in $COMMAND_LIST; do
echo " "$i")"
SUB_LIST=$($cli $i -h | grep -E '^ -' | awk '{ print $1 }' | tr "|" " ")
echo " local "$i"_opts="'"'$SUB_LIST" -h"'"'
echo " COMPREPLY=( \$(compgen -W "'"'"\${"$i"_opts}"'"'" -- \${cur}) )"
echo " return 0"
echo " ;;"
done


# print footer
echo " -*)"
echo " return 0"
echo " ;;"
echo " esac"
echo ""
echo ' COMPREPLY=($(compgen -W "${opts}" -- ${cur}))'
echo " return 0"
echo "}"
echo "complete -F _ivpn ivpn"
echo ""

exit 0
1 change: 1 addition & 0 deletions cli/References/Linux/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ CreatePackage()
$DAEMON_REPO_ABS_PATH/References/common/etc=/opt/ivpn/ \
$DAEMON_REPO_ABS_PATH/References/Linux/scripts/_out_bin/ivpn-service=/usr/bin/ \
$OUT_DIR/ivpn=/usr/bin/ \
$OUT_DIR/ivpn.bash-completion=/opt/ivpn/etc/ivpn.bash-completion \
$OBFSPXY_BIN=/opt/ivpn/obfsproxy/obfs4proxy \
$V2RAY_BIN=/opt/ivpn/v2ray/v2ray \
$WG_QUICK_BIN=/opt/ivpn/wireguard-tools/wg-quick \
Expand Down
9 changes: 8 additions & 1 deletion cli/References/Linux/compile-cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ cd "$(dirname "$0")"
SCRIPT_DIR="$( cd "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )"
OUT_DIR="$SCRIPT_DIR/_out_bin"
OUT_FILE="$OUT_DIR/ivpn"
OUT_BASH_COMPLETION_SCRIPT=$OUT_DIR/ivpn.bash-completion

set -e

Expand Down Expand Up @@ -82,6 +83,12 @@ else
go build -o "$OUT_FILE" -trimpath -ldflags "-s -w -X github.com/ivpn/desktop-app/daemon/version._version=$VERSION -X github.com/ivpn/desktop-app/daemon/version._commit=$COMMIT -X github.com/ivpn/desktop-app/daemon/version._time=$DATE"
fi

echo "Compiled CLI binary: '$OUT_FILE'"
# generate bash-completion script
$SCRIPT_DIR/bash-completion-generator-ivpn-cli.sh "$OUT_FILE" > "$OUT_BASH_COMPLETION_SCRIPT"
bash -n "$OUT_BASH_COMPLETION_SCRIPT" # check bash-completion script syntax


echo "Compiled CLI binary : '$OUT_FILE'"
echo "Bash-completion script: '$OUT_BASH_COMPLETION_SCRIPT'"

set +e
21 changes: 15 additions & 6 deletions cli/References/Linux/package_scripts/after-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,6 @@

echo "[*] After install (<%= version %> : <%= pkg %> : $1)"

# When removing package: $1==0 for RPM; $1 == "remove" for DEB
_IS_REMOVE=0
if [ "$1" = "remove" -o "$1" = "0" ]; then
_IS_REMOVE=1
fi

NEED_TO_SAVE_INSTRUCTIONS=true
IVPN_OPT="/opt/ivpn"
IVPN_ETC="/opt/ivpn/etc"
Expand Down Expand Up @@ -49,6 +43,19 @@ try_systemd_install() {
fi
}

install_bash_completion() {
# get bash completion folder (according to https://github.com/scop/bash-completion)
bash_competion_folder=$(pkg-config --variable=completionsdir bash-completion 2>&1)
if [ $? -eq 0 ] && [ ! -z $bash_competion_folder ] ; then
completion_file=${bash_competion_folder}/ivpn
echo "[+] Installing bash completion (into '${completion_file}')"
silent cp "$IVPN_ETC/ivpn.bash-completion" "${completion_file}"
silent chmod 644 "${completion_file}"
else
echo "[ ] Installing bash completion - SKIPPED"
fi
}

echo "[+] Defining access rights for files ..."
silent chmod 0400 $IVPN_ETC/* # can read only owner (root)
silent chmod 0600 $IVPN_ETC/servers.json # can read/wrire only owner (root)
Expand Down Expand Up @@ -88,6 +95,8 @@ if $NEED_TO_SAVE_INSTRUCTIONS == true ; then
echo "[!] Service start instructions saved into file: '$INSTRUCTIONS_FILE'"
fi

install_bash_completion

# ########################################################################################
#
# Next lines is in use only for compatibility with old package versions (v3.8.20 and older)
Expand Down
14 changes: 14 additions & 0 deletions cli/References/Linux/package_scripts/after-remove.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,23 @@ try_systemd_stop() {
fi
}

uninstall_bash_completion() {
# get bash completion folder (according to https://github.com/scop/bash-completion)
bash_competion_folder=$(pkg-config --variable=completionsdir bash-completion 2>&1)
if [ $? -eq 0 ] && [ ! -z $bash_competion_folder ] ; then
completion_file=${bash_competion_folder}/ivpn
if [ -f ${completion_file} ] ; then
echo "[+] Uninstalling bash completion ('${completion_file}')"
rm "${completion_file}"
fi
fi
}

# stop & disable service
try_systemd_stop

uninstall_bash_completion

PLEASERUN_DIR="/usr/share/pleaserun/ivpn-service"
if [ -d $PLEASERUN_DIR ] ; then
echo "[+] Service cleanup (pleaserun) ..."
Expand Down

0 comments on commit 8f9c9bc

Please sign in to comment.