containers/apps/ci-os/packages/merge-diff/default.nix

131 lines
3.6 KiB
Nix
Raw Normal View History

{ pkgs, lib, gitSvPkg, ... }:
with pkgs;
writeShellApplication rec {
name = "merge-diff";
runtimeInputs = [ gitFull jq coreutils gnugrep gawk gitSvPkg ];
# Define the shell script
text = ''
#!/usr/bin/env bash
set -euo pipefail
# Function to display usage
usage() {
echo "Usage: $0 -p <path_pattern> -d <directory depth>"
echo " -p, --pattern Path pattern to filter changed files (can be specified multiple times)"
echo " -d, --depth Depth of changeset (default is 2)"
echo " -h, --help Display this help message"
exit 1
}
# Parse command-line arguments
PATTERNS=()
DEPTH=2
while [[ $# -gt 0 ]]; do
case "$1" in
-p|--pattern)
PATTERNS+=("$2")
shift 2
;;
-d|--depth)
DEPTH="$2"
shift 2
;;
-h|--help)
usage
;;
*)
echo "Unknown option: $1"
usage
;;
esac
done
if [ ''${#PATTERNS[@]} -eq 0 ]; then
echo "Error: At least one path pattern must be specified."
usage
fi
# Get the current commit SHA
CURRENT_SHA=$(git rev-parse HEAD)
# Get parent commits
PARENT_COUNT=$(git rev-list --parents -n 1 "$CURRENT_SHA" | wc -w)
if [ "$PARENT_COUNT" -gt 2 ]; then
echo "This is a merge commit with $((PARENT_COUNT - 1)) parents."
# For simplicity, comparing with the first parent
PARENT_SHA=$(git rev-parse HEAD^1)
elif [ "$PARENT_COUNT" -eq 2 ]; then
# Regular commit with one parent
PARENT_SHA=$(git rev-parse HEAD^1)
else
echo "Single commit with no parents. Listing all changes."
PARENT_SHA=HEAD~1
fi
# List changed files between parent and current commit
CHANGED_FILES=$(git diff --name-only "$PARENT_SHA" "$CURRENT_SHA")
#echo "Changed files:"
#echo "$CHANGED_FILES"
# Initialize an empty array for filtered changes
FILTERED_CHANGES=()
# Iterate over each pattern and filter changed files
for pattern in "''${PATTERNS[@]}"; do
while IFS= read -r file; do
if [[ "$file" =~ $pattern ]]; then
file=$(echo "$file"| cut -d/ -f1-"$DEPTH")
FILTERED_CHANGES+=("$file")
fi
done <<< "$CHANGED_FILES"
done
# Remove duplicates
UNIQUE_FILTERED_CHANGES=$(printf "%s\n" "''${FILTERED_CHANGES[@]}" | sort -u)
#echo "Filtered changed files:"
#echo "$UNIQUE_FILTERED_CHANGES"
# Determine semantic version bump using git-sv
# Ensure that git-sv is available
if ! command -v git-sv &> /dev/null; then
echo "Error: git-sv is not installed or not in PATH."
exit 1
fi
# Get the semantic version bump
VERSION_BUMP=$(git-sv next-version)
# Validate the version bump
#if [[ "$VERSION_BUMP" =~ ^(patch|minor|major)$ ]]; then
# echo "Version bump: $VERSION_BUMP"
#else
# echo "Error: Unexpected version bump value: $VERSION_BUMP"
# exit 1
#fi
# Convert to JSON
RESULTS=$(jq -n \
--argjson filteredChanges "$(printf '%s\n' "$UNIQUE_FILTERED_CHANGES" | jq -R -s -c 'split("\n") | map(select(length > 0))')" \
--arg versionBump "$VERSION_BUMP" \
'{filteredChanges: $filteredChanges, versionBump: $versionBump}')
# Output results
echo "$RESULTS"
'';
# Metadata for the package
meta = with lib; {
homepage = "https://code.252.no/tommy/containers";
description = "Identify Merge Commit and List Changed Files with Flexible Filtering and Semantic Versioning";
license = licenses.mit;
maintainers = with maintainers; [ "tommy-skaug" ];
};
}