{ 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 -d " 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" ]; }; }