I wrote a script which updates project's dependencies (only minors and patches). I wanted to automate the upgrading process as all versions are precise and as far as I know there is no way to hint npm update
that I want to bump everything regardless.
In a nutshell, it takes an output of running npm outdated
, builds a list of packages according to criteria and feeds it to npm install
at the very end. Everything works as intended, however I was wondering if it could be written in a more concise way, for example without creating a temporary text file? I'm also looking for some general feedback.
P.S. I'm just starting out with bash scripting, so please spare me :D Your advice is very much appreciated!
Here is a sample output of npm outdated
:
Package Current Wanted Latest Location
@commitlint/cli 7.5.0 ..... 8.0.0 .....
@commitlint/config-conventional 7.5.0 ..... 8.0.0 .....
eslint 5.13.0 ..... 6.0.1 .....
eslint-plugin-jsx-a11y 6.2.0 ..... 6.2.3 .....
eslint-plugin-react 7.12.4 ..... 7.14.2 .....
eslint-plugin-react-hooks 1.6.0 ..... 1.6.1 .....
Here is the code:
# Temporary file to hold output of `npm outdated` command
OUTPUT=updates.log
PACKAGES_TO_UPDATE=()
function get_major_version { echo $(echo $1 | grep -o -E '^[0-9]{1,2}'); }
# https://stackoverflow.com/questions/1527049/how-can-i-join-elements-of-an-array-in-bash
function join_by { local d=$1; shift; echo -n "$1"; shift; printf "%s" "${@/#/$d}"; }
# Redirect output once.
{
npm outdated
} > $OUTPUT
wait
{
# Skip first line as it contains column headers.
read
while read package current wanted latest location
do
# Filter out major updates.
if [ "$(get_major_version $current)" = "$(get_major_version $latest)" ]; then
PACKAGES_TO_UPDATE+=("${package}@latest")
fi
done
} < $OUTPUT
npm install "${PACKAGES_TO_UPDATE[@]}"
rm $OUTPUT