contracts 0.6.8

Design-by-contract attributes
Documentation
#!/usr/bin/env bash

# Updates GitHub release notes from crate changelogs.

set -eEuo pipefail

WORKSPACE_METADATA="$(cargo metadata --format-version=1 --no-deps)"

function package_dir_for() {
    local package_name="$1"
    local manifest_path

    manifest_path="$(
        echo "$WORKSPACE_METADATA" \
            | jq -r --arg package_name "$package_name" '.packages[] | select(.name == $package_name) | .manifest_path' \
            | head -n 1
    )"

    if [[ -z "$manifest_path" || "$manifest_path" == "null" ]]; then
        echo "Could not determine package directory for $package_name" >&2
        return 1
    fi

    dirname "$manifest_path"
}

function update_release_notes() {
    local package_dir="$1"
    local version="$2"
    local tag="$3"
    local changelog_file="${package_dir}/CHANGELOG.md"

    if [[ ! -f "$changelog_file" ]]; then
        echo "Skipping ${tag}: no ${changelog_file}"
        return 0
    fi

    echo "Updating ${tag} using ${changelog_file}"

    local notes
    notes="$(
        awk -v version="$version" '
            $0 == "## " version {
                in_section = 1
                next
            }

            in_section && /^## / {
                exit
            }

            in_section {
                lines[++count] = $0
            }

            END {
                first = 1
                while (first <= count && lines[first] ~ /^[[:space:]]*$/) {
                    first++
                }

                last = count
                while (last >= first && lines[last] ~ /^[[:space:]]*$/) {
                    last--
                }

                for (i = first; i <= last; i++) {
                    print lines[i]
                }
            }
        ' "$changelog_file"
    )"

    if [[ -z "${notes//[[:space:]]/}" ]]; then
        notes="- No significant changes since the previous release."
    fi

    gh release edit "$tag" --notes="$notes"
}

RELEASE_PLZ_RELEASES_JSON="$1"

specs="$(echo "$RELEASE_PLZ_RELEASES_JSON" | jq -r '.[] | "\(.package_name):\(.version):\(.tag)"')"

for spec in $specs; do
    name="$(echo "$spec" | cut -d: -f1)"
    version="$(echo "$spec" | cut -d: -f2)"
    tag="$(echo "$spec" | cut -d: -f3)"
    package_dir="$(package_dir_for "$name")"

    update_release_notes "$package_dir" "$version" "$tag"
done