Skip to content

Commit

Permalink
feat(aws-cli): πŸ§‘β€πŸ’» add aws-cli completion (devcontainers#1083)
Browse files Browse the repository at this point in the history
* feat(aws-cli): πŸ§‘β€πŸ’» add aws completion

aws supports bash and zsh command completion.

* test(aws-cli): βœ… test aws bash completion

* chore(aws-cli): πŸ”§ update feature version

* fix(aws-cli): cp command fix

* refactor(aws-cli): move vendor scripts to specific folder

* docs(aws-cli): add README to vendor scripts

* build(aws-cli): automate aws-cli vendor completer scripts updates

* chore(aws-cli): update vendor completer scripts

* build(aws-cli): update message

* chore(aws-cli): remove some code remainders
  • Loading branch information
rubensa authored Aug 28, 2024
1 parent 878a900 commit 6123e41
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 8 deletions.
58 changes: 58 additions & 0 deletions .github/workflows/update-aws-cli-completer-scripts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: "Updates vendor 'aws_bash_completer' and 'aws_zsh_completer.sh' scripts"
on:
workflow_dispatch:
schedule:
- cron: '0 0 * * 0' # Runs every Sunday at midnight UTC (adjust as needed)

jobs:
fetch-latest-aws-completer-scripts:
runs-on: ubuntu-latest
environment: documentation # grants access to secrets.PAT, for creating pull requests
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v3

- name: Run fetch-latest-completer-scripts.sh
run: src/aws-cli/scripts/fetch-latest-completer-scripts.sh

- name: Create a PR for completer scripts
id: push_image_info
env:
GITHUB_TOKEN: ${{ secrets.PAT }}
run: |
set -e
echo "Start."
# Configure git and Push updates
git config --global user.email [email protected]
git config --global user.name github-actions
git config pull.rebase false
branch=automated-script-update-$GITHUB_RUN_ID
git checkout -b $branch
message='[Updates] Automated vendor 'aws-cli' completer scripts'
# Add / update and commit
git add src/aws-cli/scripts/vendor/aws_bash_completer
git add src/aws-cli/scripts/vendor/aws_zsh_completer.sh
git commit -m 'Automated completer scripts update' || export NO_UPDATES=true
# Bump version and push
if [ "$NO_UPDATES" != "true" ] ; then
echo "$(jq --indent 4 '.version = (.version | split(".") | map(tonumber) | .[2] += 1 | join("."))' src/aws-cli/devcontainer-feature.json)" > src/aws-cli/devcontainer-feature.json
git add src/aws-cli/devcontainer-feature.json
git commit -m 'Bump version'
git push origin "$branch"
gh api \
--method POST \
-H "Accept: application/vnd.github+json" \
/repos/${GITHUB_REPOSITORY}/pulls \
-f title="$message" \
-f body="$message" \
-f head="$branch" \
-f base="$GITHUB_REF_NAME"
fi
2 changes: 1 addition & 1 deletion src/aws-cli/devcontainer-feature.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "aws-cli",
"version": "1.0.7",
"version": "1.1.0",
"name": "AWS CLI",
"documentationURL": "https://github.com/devcontainers/features/tree/main/src/aws-cli",
"description": "Installs the AWS CLI along with needed dependencies. Useful for base Dockerfiles that often are missing required install dependencies like gpg.",
Expand Down
24 changes: 17 additions & 7 deletions src/aws-cli/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,24 +52,23 @@ fi

apt_get_update()
{
echo "Running apt-get update..."
apt-get update -y
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update -y
fi
}

# Checks if packages are installed and installs them if not
check_packages() {
if ! dpkg -s "$@" > /dev/null 2>&1; then
if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then
echo "Running apt-get update..."
apt-get update -y
fi
apt_get_update
apt-get -y install --no-install-recommends "$@"
fi
}

export DEBIAN_FRONTEND=noninteractive

check_packages curl ca-certificates gnupg2 dirmngr unzip
check_packages curl ca-certificates gnupg2 dirmngr unzip bash-completion

verify_aws_cli_gpg_signature() {
local filePath=$1
Expand Down Expand Up @@ -114,6 +113,17 @@ install() {
unzip "${scriptZipFile}"
./aws/install

# kubectl bash completion
mkdir -p /etc/bash_completion.d
cp ./scripts/vendor/aws_bash_completer /etc/bash_completion.d/aws

# kubectl zsh completion
if [ -e "${USERHOME}/.oh-my-zsh" ]; then
mkdir -p "${USERHOME}/.oh-my-zsh/completions"
cp ./scripts/vendor/aws_zsh_completer.sh "${USERHOME}/.oh-my-zsh/completions/_aws"
chown -R "${USERNAME}" "${USERHOME}/.oh-my-zsh"
fi

rm -rf ./aws
}

Expand Down
20 changes: 20 additions & 0 deletions src/aws-cli/scripts/fetch-latest-completer-scripts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash
#-------------------------------------------------------------------------------------------------------------
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#-------------------------------------------------------------------------------------------------------------
#
# Docs: https://github.com/devcontainers/features/tree/main/src/aws-cli
# Maintainer: The Dev Container spec maintainers
#
# Run this script to replace aws_bash_completer and aws_zsh_completer.sh with the latest and greatest available version
#
COMPLETER_SCRIPTS=$(dirname "${BASH_SOURCE[0]}")
BASH_COMPLETER_SCRIPT="$COMPLETER_SCRIPTS/vendor/aws_bash_completer"
ZSH_COMPLETER_SCRIPT="$COMPLETER_SCRIPTS/vendor/aws_zsh_completer.sh"

wget https://raw.githubusercontent.com/aws/aws-cli/v2/bin/aws_bash_completer -O "$BASH_COMPLETER_SCRIPT"
chmod +x "$BASH_COMPLETER_SCRIPT"

wget https://raw.githubusercontent.com/aws/aws-cli/v2/bin/aws_zsh_completer.sh -O "$ZSH_COMPLETER_SCRIPT"
chmod +x "$ZSH_COMPLETER_SCRIPT"
12 changes: 12 additions & 0 deletions src/aws-cli/scripts/vendor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
### **IMPORTANT NOTE**

Scripts in this directory are sourced externally and not maintained by the Dev Container spec maintainers. Do not make changes directly as they might be overwritten at any moment.

## aws_bash_completer

`aws_bash_completer` is a copy of <https://raw.githubusercontent.com/aws/aws-cli/v2/bin/aws_bash_completer>.

## aws_zsh_completer.sh

`aws_zsh_completer.sh` is a copy of <https://raw.githubusercontent.com/aws/aws-cli/v2/bin/aws_zsh_completer.sh>.

6 changes: 6 additions & 0 deletions src/aws-cli/scripts/vendor/aws_bash_completer
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Typically that would be added under one of the following paths:
# - /etc/bash_completion.d
# - /usr/local/etc/bash_completion.d
# - /usr/share/bash-completion/completions

complete -C aws_completer aws
60 changes: 60 additions & 0 deletions src/aws-cli/scripts/vendor/aws_zsh_completer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Source this file to activate auto completion for zsh using the bash
# compatibility helper. Make sure to run `compinit` before, which should be
# given usually.
#
# % source /path/to/zsh_complete.sh
#
# Typically that would be called somewhere in your .zshrc.
#
# Note, the overwrite of _bash_complete() is to export COMP_LINE and COMP_POINT
# That is only required for zsh <= edab1d3dbe61da7efe5f1ac0e40444b2ec9b9570
#
# https://github.com/zsh-users/zsh/commit/edab1d3dbe61da7efe5f1ac0e40444b2ec9b9570
#
# zsh releases prior to that version do not export the required env variables!

autoload -Uz bashcompinit
bashcompinit -i

_bash_complete() {
local ret=1
local -a suf matches
local -x COMP_POINT COMP_CWORD
local -a COMP_WORDS COMPREPLY BASH_VERSINFO
local -x COMP_LINE="$words"
local -A savejobstates savejobtexts

(( COMP_POINT = 1 + ${#${(j. .)words[1,CURRENT]}} + $#QIPREFIX + $#IPREFIX + $#PREFIX ))
(( COMP_CWORD = CURRENT - 1))
COMP_WORDS=( $words )
BASH_VERSINFO=( 2 05b 0 1 release )

savejobstates=( ${(kv)jobstates} )
savejobtexts=( ${(kv)jobtexts} )

[[ ${argv[${argv[(I)nospace]:-0}-1]} = -o ]] && suf=( -S '' )

matches=( ${(f)"$(compgen $@ -- ${words[CURRENT]})"} )

if [[ -n $matches ]]; then
if [[ ${argv[${argv[(I)filenames]:-0}-1]} = -o ]]; then
compset -P '*/' && matches=( ${matches##*/} )
compset -S '/*' && matches=( ${matches%%/*} )
compadd -Q -f "${suf[@]}" -a matches && ret=0
else
compadd -Q "${suf[@]}" -a matches && ret=0
fi
fi

if (( ret )); then
if [[ ${argv[${argv[(I)default]:-0}-1]} = -o ]]; then
_default "${suf[@]}" && ret=0
elif [[ ${argv[${argv[(I)dirnames]:-0}-1]} = -o ]]; then
_directories "${suf[@]}" && ret=0
fi
fi

return ret
}

complete -C aws_completer aws
27 changes: 27 additions & 0 deletions test/aws-cli/checkBashCompletion.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash

command=$1
expected=$2

echo -e "Checking completion for command '$command'..."

# Send command as a character stream, followed by two tab characters, into an interactive bash shell.
# Also note the 'y' which responds to the possible Bash question "Display all xxx possibilities? (y or n)".
# Bash produces the autocompletion output on stderr, so redirect that to stdout.
# The sed bit captures the lines between Header and Footer (used as output delimiters).
# The first grep removes the "Display all" message (that is atomatically answered to "y" by the script).
# The last grep filters the output to lines containing the expected result.
COMPLETE_OUTPUT=$(echo if false\; then "Header"\; $command$'\t'$'\t'y\; "Footer" fi | bash -i 2>&1 | sed -n '/Header/{:a;n;/Footer/q;p;ba}' | grep -v ^'Display all ')
echo -e "\nCompletion output:\n"
echo -e "$COMPLETE_OUTPUT"
echo -e "\n"

FILTERED_COMPLETE_OUTPUT=$(echo "$COMPLETE_OUTPUT" | grep "$expected")

if [ -z "$FILTERED_COMPLETE_OUTPUT" ]; then
echo -e "Completion output does not contains '$expected'."
exit 1
else
echo -e "Completion output contains '$expected'."
exit 0
fi
10 changes: 10 additions & 0 deletions test/aws-cli/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,15 @@ source dev-container-features-test-lib
# Definition specific tests
check "version" aws --version

# By default bash complete is disabled for the root user
# Enable it by replacing current ~/.bashrc with the /etc/skel/.bashrc file
mv ~/.bashrc ~/.bashrc.bak
cp /etc/skel/.bashrc ~/

check "aws-bash-completion-contains-version-option" ./checkBashCompletion.sh "aws --" "version"

# Restore original ~/.bashrc
mv ~/.bashrc.bak ~/.bashrc

# Report result
reportResults

0 comments on commit 6123e41

Please sign in to comment.