From 26ccd10b1078d1b6d84b280c7171651587af29fe Mon Sep 17 00:00:00 2001 From: Purnendu Date: Sun, 12 Jan 2025 01:46:33 +0530 Subject: [PATCH] added scripts in deps folder --- deps/analyze-dependencies.sh | 112 +++++++++++++++++++++++++++++++++++ deps/move-from-diff.sh | 112 +++++++++++++++++++++++++++++++++++ package.json | 3 +- 3 files changed, 226 insertions(+), 1 deletion(-) create mode 100755 deps/analyze-dependencies.sh create mode 100755 deps/move-from-diff.sh diff --git a/deps/analyze-dependencies.sh b/deps/analyze-dependencies.sh new file mode 100755 index 00000000000..dddb72aaa1b --- /dev/null +++ b/deps/analyze-dependencies.sh @@ -0,0 +1,112 @@ +#!/bin/sh + +# ============================================== +# README +# ============================================== +# This script analyzes the difference between production and development dependencies +# in a Node.js project. It generates files containing top-level dependencies for both +# production-only and all dependencies (production + development) using `npm ls` and `jq`. +# The results are saved in a `deps` folder, and a comparison is performed to identify +# differences between the two sets of dependencies. +# +# Purpose: +# - To identify dev-only and prod-only dependencies. +# - To provide insight into potential misclassified dependencies. +# +# Prerequisites: +# 1. Ensure `jq` is installed on your system. If not installed, the script will attempt +# to install it using your system's package manager (`apk`, `apt-get`, or `yum`). +# +# 2. Ensure the script has execute permissions: +# ```sh +# chmod +x ./deps/analyze-dependencies.sh +# ``` +# +# 3. Ensure `npm` is installed and properly set up in the current environment. +# +# Usage: +# 1. Navigate to the root of your Node.js project where `package.json` is located. +# 2. Run the script: +# ```sh +# ./deps/analyze-dependencies.sh +# ``` +# 3. The script will: +# - Generate files for production and dev+prod dependencies in the `deps` folder. +# - Sort and compare the dependency lists for differences. +# +# Output: +# - The following files will be created in the `deps` folder: +# - `prod-deps.json`: Top-level production dependencies. +# - `dev-deps.json`: Top-level dev+prod dependencies. +# - `prod-deps-keys.json`: Keys of production dependencies. +# - `dev-deps-keys.json`: Keys of dev+prod dependencies. +# - A `diff` will be displayed showing the differences between production and dev dependencies. +# +# Notes: +# - Modify the script if your codebase structure differs or if additional processing is required. +# ============================================== + +set -e + +# Function to check and install jq +install_jq_if_missing() { + echo "Checking if jq is installed..." + if ! command -v jq >/dev/null 2>&1; then + echo "jq is not installed. Installing jq..." + if [ -x "$(command -v apk)" ]; then + apk add --no-cache jq + elif [ -x "$(command -v apt-get)" ]; then + apt-get update && apt-get install -y jq + elif [ -x "$(command -v yum)" ]; then + yum install -y jq + else + echo "Error: Could not determine package manager to install jq." + exit 1 + fi + echo "jq installed successfully." + else + echo "jq is already installed." + fi +} + +# Run the jq installation check +install_jq_if_missing + +echo "Checking if package.json exists..." +if [ ! -f "package.json" ]; then + echo "Error: No package.json found in the current directory." + exit 1 +fi + +# Create the deps folder if it does not exist +DEPS_FOLDER="deps" +echo "Creating the $DEPS_FOLDER folder for storing dependency files..." +mkdir -p "$DEPS_FOLDER" + +echo "Installing dependencies (if necessary) to ensure npm ls commands run accurately..." +npm install + +echo "Generating list of production dependencies (top-level only)..." +npm ls --omit=dev --json > "$DEPS_FOLDER/prod-deps.json" + +echo "Generating list of dev+prod dependencies (top-level only)..." +npm ls --prod=false --json > "$DEPS_FOLDER/dev-deps.json" + +# Extract just the top-level dependencies' keys. If a key is absent, we fall back to an empty object "{}". +echo "Extracting top-level dependencies from prod-deps.json..." +jq '.dependencies? // {} | keys' "$DEPS_FOLDER/prod-deps.json" > "$DEPS_FOLDER/prod-deps-keys.json" +echo "Extracting top-level dependencies from dev-deps.json..." +jq '.dependencies? // {} | keys' "$DEPS_FOLDER/dev-deps.json" > "$DEPS_FOLDER/dev-deps-keys.json" + +# Sort them and compare side by side. We'll use textual diff to highlight any differences. +echo "Comparing top-level production vs. dev dependencies..." +sort "$DEPS_FOLDER/prod-deps-keys.json" -o "$DEPS_FOLDER/prod-deps-keys.json" +sort "$DEPS_FOLDER/dev-deps-keys.json" -o "$DEPS_FOLDER/dev-deps-keys.json" +diff "$DEPS_FOLDER/prod-deps-keys.json" "$DEPS_FOLDER/dev-deps-keys.json" || true + +echo "" +echo "==========================================" +echo "Finished analyzing dependencies." +echo "$DEPS_FOLDER/prod-deps-keys.json: top-level prod deps." +echo "$DEPS_FOLDER/dev-deps-keys.json: top-level dev+prod deps." +echo "Use 'diff $DEPS_FOLDER/prod-deps-keys.json $DEPS_FOLDER/dev-deps-keys.json' for side-by-side comparison." diff --git a/deps/move-from-diff.sh b/deps/move-from-diff.sh new file mode 100755 index 00000000000..8ffaf3fe345 --- /dev/null +++ b/deps/move-from-diff.sh @@ -0,0 +1,112 @@ +#!/bin/sh + +# ============================================== +# README +# ============================================== +# This script analyzes the difference between production and development dependencies +# in a Node.js project. It identifies dev-only dependencies that are used in the +# production code and moves them from `devDependencies` to `dependencies` in the +# project's `package.json` file. +# +# Purpose: +# - To ensure all required production dependencies are correctly categorized. +# - To prevent runtime errors in production due to missing dependencies. +# +# Prerequisites: +# 1. Ensure `analyze-dependencies.sh` has been run beforehand. This script generates: +# - `prod-deps-keys.json`: Contains top-level production dependencies. +# - `dev-deps-keys.json`: Contains top-level dev+prod dependencies. +# These files must exist in the `deps` folder. +# +# 2. Ensure the script has execute permissions: +# ```sh +# chmod +x ./deps/move-from-diff.sh +# ``` +# +# 3. Ensure `jq` is installed on the system. If it is missing, install it using the +# appropriate package manager (e.g., `apt-get`, `yum`, or `apk`). +# +# Usage: +# 1. Navigate to the project root directory where `package.json` is located. +# 2. Execute this script: +# ```sh +# ./deps/move-from-diff.sh +# ``` +# 3. The script will: +# - Analyze the diff between `prod-deps-keys.json` and `dev-deps-keys.json`. +# - Identify dev-only dependencies used in production code. +# - Move required dependencies from `devDependencies` to `dependencies`. +# +# Output: +# - Any required dependencies will be moved to `dependencies` in `package.json`. +# - A confirmation message will be displayed upon successful execution. +# +# Note: +# - Ensure your production code resides in `./src`, `./lib`, or `./app` folders. +# - Modify the script if your codebase structure differs. +# ============================================== + +set -e + +# Define the folder where dependency files are stored +DEPS_FOLDER="deps" + +echo "Analyzing dependencies from diff output..." + +# Check if the necessary files exist in the deps folder +if [ ! -f "$DEPS_FOLDER/prod-deps-keys.json" ] || [ ! -f "$DEPS_FOLDER/dev-deps-keys.json" ]; then + echo "Error: prod-deps-keys.json or dev-deps-keys.json not found in the $DEPS_FOLDER folder. Run analyze-dependencies.sh first." + exit 1 +fi + +# Generate the diff and extract dev-only packages +DIFF_OUTPUT=$(diff "$DEPS_FOLDER/prod-deps-keys.json" "$DEPS_FOLDER/dev-deps-keys.json" || true) +DEV_ONLY_PACKAGES=$(echo "$DIFF_OUTPUT" | grep '^>' | sed 's/^> //' | tr -d '",') + +if [ -z "$DEV_ONLY_PACKAGES" ]; then + echo "No dev-only dependencies found to check." + exit 0 +fi + +echo "Found dev-only dependencies to check for production usage:" +echo "$DEV_ONLY_PACKAGES" + +# Temporary file to store required production dependencies +REQUIRED_FOR_PRODUCTION_FILE=$(mktemp) + +for PACKAGE in $DEV_ONLY_PACKAGES; do + echo "Checking if $PACKAGE is used in production..." + + # Use grep to check if the package name appears in the production code + if grep -qr "$PACKAGE" ./src ./lib ./app; then + echo "$PACKAGE is required in production." + echo "$PACKAGE" >> "$REQUIRED_FOR_PRODUCTION_FILE" + else + echo "$PACKAGE is not used in production." + fi +done + +if [ ! -s "$REQUIRED_FOR_PRODUCTION_FILE" ]; then + echo "No dev dependencies are required in production." + rm -f "$REQUIRED_FOR_PRODUCTION_FILE" + exit 0 +fi + +echo "The following dev dependencies are required in production:" +cat "$REQUIRED_FOR_PRODUCTION_FILE" + +# Move required dependencies to production dependencies +while IFS= read -r PACKAGE; do + echo "Moving $PACKAGE to dependencies..." + + # First, remove the package from devDependencies + npm uninstall "$PACKAGE" --save-dev + + # Install as a production dependency + npm install "$PACKAGE" --save-prod +done < "$REQUIRED_FOR_PRODUCTION_FILE" + +# Clean up +rm -f "$REQUIRED_FOR_PRODUCTION_FILE" + +echo "Required dev dependencies successfully moved to production dependencies." diff --git a/package.json b/package.json index 217ce7af6b7..e38e46d79c2 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,8 @@ "import:sample-data": "tsx ./src/utilities/loadSampleData.ts", "import:sample-data:prod": "node ./build/utilities/loadSampleData.js", "gen:schema": "graphql-inspector introspect ./src/typeDefs/**/**/*.ts --write ./schema.graphql ", - "update:toc": "node scripts/githooks/update-toc.js" + "update:toc": "node scripts/githooks/update-toc.js", + "move-and-prune": "./deps/analyze-dependencies.sh && ./deps/move-from-diff.sh && npm prune --omit=dev" }, "repository": { "type": "git",