Skip to content

Instantly share code, notes, and snippets.

@ephrin
Last active November 26, 2024 07:50
Show Gist options
  • Save ephrin/1f30ff7f243ea2391c3db6c09ea27c15 to your computer and use it in GitHub Desktop.
Save ephrin/1f30ff7f243ea2391c3db6c09ea27c15 to your computer and use it in GitHub Desktop.
update package.json with versions from package-lock.json
#!/bin/bash
# Function to update package.json with versions from package-lock.json
update_package_json_with_lock_versions() {
local dir=$1
local package_json_path="$dir/package.json"
local package_lock_json_path="$dir/package-lock.json"
if [ ! -f "$package_json_path" ]; then
echo "Error: $package_json_path not found."
exit 1
fi
if [ ! -f "$package_lock_json_path" ]; then
echo "Error: $package_lock_json_path not found."
exit 1
fi
# Extract locked versions from the packages section of package-lock.json
local dependencies=$(jq -r '
.packages |
to_entries |
map(select(.key != "")) |
map(select(.value.version != null)) |
map(
select(.key != null) |
select(.key | startswith("node_modules/")) |
{
key: (.key |
ltrimstr("node_modules/") |
if startswith("@") then
split("/") | [.[0], .[1]] | join("/")
else
split("/") | .[0]
end
),
value: .value.version
} |
select(.key != null)
) |
group_by(.key) |
map(.[0]) |
map({(.key): .value}) |
add // {}' "$package_lock_json_path")
if [ $? -ne 0 ] || [ -z "$dependencies" ]; then
echo "Error extracting dependencies from package-lock.json"
exit 1
fi
# Update package.json, replacing "latest" with locked versions
jq --argjson versions "$dependencies" '
if has("dependencies") then
.dependencies |= with_entries(
if .value == "latest" and $versions[.key] then
.value = $versions[.key]
else . end
)
else . end |
if has("devDependencies") then
.devDependencies |= with_entries(
if .value == "latest" and $versions[.key] then
.value = $versions[.key]
else . end
)
else . end
' "$package_json_path" > tmp.$$.json && mv tmp.$$.json "$package_json_path"
}
# Print usage if --help is specified
if [ "$1" == "--help" ]; then
echo "Usage: $0 [directory]..."
echo "Updates package.json with exact versions from package-lock.json"
echo ""
echo "If no directory is specified, the current directory will be used."
echo "Multiple directories can be specified to process multiple projects."
echo ""
echo "Examples:"
echo " $0 # Process current directory"
echo " $0 frontend backend # Process frontend and backend directories"
echo " $0 . # Process current directory explicitly"
exit 0
fi
# If no arguments provided, use current directory
if [ $# -eq 0 ]; then
dirs=(".")
else
dirs=("$@")
fi
# Process each specified directory
for dir in "${dirs[@]}"; do
if [ ! -d "$dir" ]; then
echo "Error: Directory '$dir' not found."
exit 1
fi
echo "Processing directory: $dir"
update_package_json_with_lock_versions "$dir"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment