bash-my-aws
bash-my-aws copied to clipboard
Tool to format awscli commands
I edit with vim. Life would be easier with a command to format an AWSCLI to fit the standard pattern that has evolved for this project.
aws s3api copy-object \
--copy-source "${example/release-$BUILD_NUMBER/index.html" \
--bucket "${DEPLOYMENT_BUCKET}" \
--key "search/" \
--content-type text/html \
--cache-control public,max-age=60,s-maxage=60 \
--metadata-directive REPLACE
Lint-my-Bash-my-AWS
This would be a nice tool to check out. If it works as expected, it could be used as a pre-commit hook so new contributions would be formatted correctly.
https://github.com/mvdan/sh
This would be a nice tool to check out. If it works as expected, it could be used as a pre-commit hook so new contributions would be formatted correctly.
https://github.com/mvdan/sh
I would be curious to see the output of the formatter on this codebase...
For a chuckle, here's an imperfect bash
y solution:
# Load up an example variable
str='aws s3api copy-object --copy-source "${example}/release-$BUILD_NUMBER/index.html" --bucket "${DEPLOYMENT_BUCKET}" --key "search/" --content-type text/html --cache-control public,max-age=60,s-maxage=60 --metadata-directive REPLACE'
# Search for a leading space and a dash, to capture ` -a` and `--arg` style options
# Replace with a newline and two space indentation, slurp each line into an array
mapfile -t < <(sed 's/ -/\n -/g' <<< "$str")
# Get the length of the longest line
right_bound=$(for element in "${MAPFILE[@]}"; do printf -- '%d\n' "${#element}"; done | sort -n | tail -n 1)
# Pad it
right_bound=$(( right_bound + 2 ))
# Behold, the mighty printf!
for element in "${MAPFILE[@]}"; do printf -- '%s%*s%s\n' "${element}" $(( right_bound - "${#element}" )) '\'; done
aws s3api copy-object \
--copy-source "${example}/release-$BUILD_NUMBER/index.html" \
--bucket "${DEPLOYMENT_BUCKET}" \
--key "search/" \
--content-type text/html \
--cache-control public,max-age=60,s-maxage=60 \
--metadata-directive REPLACE \
To get that last line to behave might require something a little more involved e.g.
for (( i=0; i<"${#MAPFILE[@]}"; i++ )); do
if (( i == ("${#MAPFILE[@]}" - 1) )); then
printf -- '%s\n' "${MAPFILE[i]}"
else
printf -- '%s%*s%s\n' "${MAPFILE[i]}" $(( right_bound - "${#MAPFILE[i]}" )) '\'
fi
done
Result:
aws s3api copy-object \
--copy-source "${example}/release-$BUILD_NUMBER/index.html" \
--bucket "${DEPLOYMENT_BUCKET}" \
--key "search/" \
--content-type text/html \
--cache-control public,max-age=60,s-maxage=60 \
--metadata-directive REPLACE
If we throw all of that into a function:
code_block() {
# Search for a leading space and a dash, to capture ` -a` and `--arg` style options
# Replace with a newline and two space indentation, slurp each line into an array
mapfile -t < <(sed 's/ -/\n -/g' <<< "${*}")
# Get the length of the longest line
right_bound=$(for element in "${MAPFILE[@]}"; do printf -- '%d\n' "${#element}"; done | sort -n | tail -n 1)
# Pad it
right_bound=$(( right_bound + 2 ))
# Generate our output
for (( i=0; i<"${#MAPFILE[@]}"; i++ )); do
if (( i == ("${#MAPFILE[@]}" - 1) )); then
printf -- '%s\n' "${MAPFILE[i]}"
else
printf -- '%s%*s%s\n' "${MAPFILE[i]}" $(( right_bound - "${#MAPFILE[i]}" )) '\'
fi
done
}
We get behaviour like this:
$ code_block 'aws s3api copy-object --copy-source "${example}/release-$BUILD_NUMBER/index.html" --bucket "${DEPLOYMENT_BUCKET}" --key "search/" --content-type text/html --cache-control public,max-age=60,s-maxage=60 --metadata-directive REPLACE'
aws s3api copy-object \
--copy-source "${example}/release-$BUILD_NUMBER/index.html" \
--bucket "${DEPLOYMENT_BUCKET}" \
--key "search/" \
--content-type text/html \
--cache-control public,max-age=60,s-maxage=60 \
--metadata-directive REPLACE
$ code_block 'ssh -t -i "${BMA_SSH_DIR:-~/.ssh}/${keyname}" -o LogLevel=error -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -l "${ssh_user}" "${private_ip}"'
ssh \
-t \
-i "${BMA_SSH_DIR:-~/.ssh}/${keyname}" \
-o LogLevel=error \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
-l "${ssh_user}" "${private_ip}"
Noting the single quotes to keep it all literal.