Skip to content

Instantly share code, notes, and snippets.

@aravindkumarsvg
Last active December 9, 2021 18:31
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save aravindkumarsvg/6169b8812b6e96f54737128a6f24fe4c to your computer and use it in GitHub Desktop.
Save aravindkumarsvg/6169b8812b6e96f54737128a6f24fe4c to your computer and use it in GitHub Desktop.
Generates npm audit report for multiple directories and searching for multiple package.json inside those given directories
#!/bin/bash
# Global variable declarations
format="plain"
directories=()
current_directory=`pwd`
report_directory="${current_directory}/report/"
fresh_report_directory="0"
# usage
# @description - prints the help text
usage () {
echo -e "--format | -f <value>\tvalues - plain (default), json, html - optional"
echo -e "--directory | -d <value>\tvalue - any valid directory - multiple - if not given, current director will be choosen"
echo -e "--help | -h\t\t\tHelp text"
}
# dep_checker
# @description - checks for the dependencies
dep_checker () {
# Checks for npm
which npm >/dev/null 2>&1
if [ "$?" != "0" ]; then
echo -e "\nnpm or which command not available!!!!\n"
exit 2
fi
# Checks for npm audit
local npm_audit=$(npm --help | grep audit)
if [ "$npm_audit" == "" ]; then
echo -e "\nnpm audit command not available. Please update npm!!!!\n"
exit 2
fi
if [ "$format" == "html" ]; then
# Checks for the npm-audit-html node.js module
which npm-audit-html >/dev/null 2>&1
if [ "$?" != "0" ]; then
echo -e "\nnpm-audit-html command is not found!!!! npm install -g npm-audit-html\n"
exit 2
fi
fi
}
# format_checker
# @description - checks for the format
format_checker () {
if [ "$1" == "html" -o "$1" == "plain" -o "$1" == "json" ]; then
if [ "$1" == "html" ]; then
echo -e "\nhtml formatter works better till npm version - 6\n"
fi
return
else
echo -e "\nInvalid format!!!!\n"
usage
exit 1
fi
}
# parser
# @description - parses the command line arguments
parser () {
while [ "$1" != "" ]; do
case $1 in
-f | --format) shift
format_checker $1
format=$1
;;
-d | --directory) shift
directories+=($1)
;;
-h | --help) usage
exit 0
;;
*) usage
exit 1
esac
shift
done
}
# create_report_directory
# @description Creates the report directory
create_report_directory () {
mkdir "${report_directory}" > /dev/null 2>&1
fresh_report_directory=$?
if [ ! -d "${report_directory}" ]; then
echo -e "\nReport Directory creation failed - ${report_directory} !!!\n"
exit 1
fi
}
# delete_report_directory
# @description - Deletes the report directory
delete_report_directory () {
if [ "$fresh_report_directory" -eq "0" ]; then
rm -rf "$report_directory"
fi
}
# npm_install_fix
# @description - fixes npm installation
npm_install_fix () {
echo -e "\nrunning npm install - $1"
local npm_install_error=$( { npm install >/dev/null; } 2>&1 )
local npm_install_error_codes="(ENOENT|EAUDITNOLOCK|ENOPACKAGEJSON|ENOSPC|EACCES|ENOTEMPTY)"
if [[ $npm_install_error =~ $npm_install_error_codes ]]; then
echo -e "\nPlease fix the npm errors and rerun the script - $1 \n"
exit 1
fi
}
# html_report_generator
# @description - Generates html reports
html_report_generator () {
local npm_audit_error=$( { npm audit --json | npm-audit-html --output "$3$4.html" >/dev/null; } 2>&1 )
if [ "$npm_audit_error" != "" ]; then
rm -f "$3$4.html" >/dev/null 2>&1
npm_install_fix "$1"
local npm_audit_error=$( { npm audit --json | npm-audit-html --output "$3$4.html" >/dev/null; } 2>&1 )
if [ "$npm_audit_error" != "" ]; then
rm -f "$3$4.html" >/dev/null 2>&1
echo -e "\nPlease fix the npm errors and rerun the script - $1 \n"
exit 1
fi
fi
sed -i "s@<div class=\"container\">@<div class=\"container\"><div class=\"row jumbotron\"><div class=\"col-md-3\" style=\"color: #007bff;\"><b>package.json path</b></div><div class=\"col-md-9\"><b>"$2"</b></div></div>@" "$3$4.html"
}
# json_report_generator
# @description - Generates json reports
json_report_generator () {
local npm_audit_error=$( { npm audit --json > "$3$4.json"; } 2>&1 )
if [ "$npm_audit_error" != "" ]; then
rm -f "$3$4.json" >/dev/null 2>&1
npm_install_fix "$1"
local npm_audit_error=$( { npm audit --json > "$3$4.json"; } 2>&1 )
if [ "$npm_audit_error" != "" ]; then
rm -f "$3$4.json" >/dev/null 2>&1
echo -e "\nPlease fix the npm errors and rerun the script - $1 \n"
exit 1
fi
fi
sed -i "0,/{/s#{#{\"package_json_path\": \""$2"\"#" "$3$4.json"
}
# plain_report_generator
# @description - Generates plain reports
plain_report_generator () {
local npm_audit_error=$( { npm audit > "$3$4.out"; } 2>&1 )
if [ "$npm_audit_error" != "" ]; then
rm -f "$3$4.out" >/dev/null 2>&1
npm_install_fix "$1"
local npm_audit_error=$( { npm audit > "$3$4.out"; } 2>&1 )
if [ "$npm_audit_error" != "" ]; then
rm -f "$3$4.out" >/dev/null 2>&1
echo -e "\nPlease fix the npm errors and rerun the script - $1 \n"
exit 1
fi
fi
sed -i "0,/{/s#{#{\"package_out_path\": \""$2"\"#" "$3$4.out"
}
# report_worker
# @description - Worker to generate the reports
report_worker () {
package_json="$1"
# Prints the message
echo -e "Auditing - ${package_json}"
# Extracts the directory
local package_json_directory=${package_json%package.json}
# Goes to that directory
cd "${package_json_directory}"
# Epoch time in milliseconds
local report_file_name=`date +'%s%N'`
case $format in
html) html_report_generator "$package_json_directory" "$package_json" "$report_directory" "$report_file_name"
;;
json) json_report_generator "$package_json_directory" "$package_json" "$report_directory" "$report_file_name"
;;
plain) plain_report_generator "$package_json_directory" "$package_json" "$report_directory" "$report_file_name"
;;
esac
}
# generate_report
# @description - generates the report
generate_report () {
local directories_given=0
# Creates the report directory
create_report_directory
# Loops through the given input directories
for directory in ${directories[@]}; do
# Checks for the existence of directory
if [ ! -d "${directory}" ]; then
echo -e "\nDirectory not found - ${directory} !!!! \n"
exit 2
fi
for package_json in `find ${directory} -name package.json | grep -v node_modules`; do
report_worker "$package_json"
done
directories_given=1
done
# Generates report for the current directory
if [ $directories_given == 0 ]; then
for package_json in `find ${current_directory} -name package.json | grep -v node_modules`; do
report_worker "$package_json"
done
fi
}
# finisher
# @description - executed at the end of execution
finisher () {
echo -e "\nPlease check the reports directory - ${report_directory} \n"
}
# main
# @description - starting point of execution
main () {
# Parses the input arguments
parser $@
# Checks for the dependencies
dep_checker
# Generates the audit report
generate_report
# Finishes the execution
finisher
}
# starts the execution
main $@
# Exits with code - 0
exit 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment