Tamarin/hooks/prebuild/eole/create-changelog

268 lines
8.1 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
cd src
if [ -f debian/changelog ] || [ ! -d .git ]; then
tamarin_info "Not a Git repository or Debian changelog already exists !"
exit
else
tamarin_info "Creating changelog with commits information."
fi
# Get pkg tags as tie points in commit history
pkg_tags="$(git for-each-ref --format '%(refname)' refs/tags | tac)"
# Set starting commit
ceiling_commit=$(git describe --match "build/*" --abbrev=0 2>/dev/null)
if [ -z "$ceiling_commit" ]
then
ceiling_commit="HEAD"
fi
first_commit=$(git rev-list --max-parents=0 origin/master)
# Get commits log as changelog
current_release_tag=$(git describe --match "release/*" --abbrev=0 2>/dev/null)
if [[ -z ${current_release_tag} ]]
then
tamarin_warn "No release tag found, you repo should have a tag like 'release/*'"
tamarin_info "Assuming tag release/0.0.0 on first commit of branch master"
current_release="release/0.0.0"
current_release_tag=${first_commit}
else
current_release=$current_release_tag
fi
touch debian/changelog
project_name=$(tamarin_db get project_name)
distribution=$(tamarin_db get distribution UNRELEASED)
urgency=$(tamarin_db get urgency low)
package_level=$(tamarin_db get package_level dev)
function get_hash {
# Return commit hash from various pointer
pointer="$1"
echo "$(git log -n1 --format=%H ${pointer})"
}
function get_short_hash {
# Return commit short hash from various pointer
pointer="$1"
echo "$(git log -n1 --format=%h ${pointer})"
}
function get_previous_pkg_tag {
# Return previous pkg/* tag or current tag if no previous pkg/* exists.
commit="$1"
echo "$(git describe --abbrev=0 --match='pkg/*' $commit 2>/dev/null)"
}
function parse_tag {
tag="$1"
flavor="${tag%%/*}"
extended_version="${tag##*/}"
if [ "$flavor" = "pkg" ]
then
exploded_version="$(echo $extended_version | sed "s/\([a-z0-9.]\+\)-\([0-9]\+\)\(-[a-z]\++[0-9]\+\)\?\(-\([0-9]\+\)-\(g[a-z0-9]\+\)\)\?$/version:\1 revision:\2 modification:\3 distance:\5 anchor:\6/")"
elif [ "$flavor" = "release" ]
then
exploded_version="$(echo $extended_version | sed "s/\([a-z0-9.]\+\)\(-\([0-9]\+\)-\(g[a-z0-9]\+\)\)\?$/version:\1 distance:\3 anchor:\4/")"
fi
echo $exploded_version
}
function get_distance_from_tag {
description_tag="$1"
tag=${description_tag%-*-*}
anchor="$2"
if [[ "$(get_hash $tag)" =~ "$(get_hash $anchor)" ]]
then
echo 0
else
distance="$(parse_tag $description_tag)"
distance="${distance#*distance:}"
distance="${distance%% *}"
echo $distance
fi
}
function get_upstream_version_from_tag {
tag="$1"
upstream="$(parse_tag $tag)"
upstream="${upstream#*version:}"
upstream="${upstream%% *}"
echo "$upstream"
}
function get_package_version_from_tag {
tag="$1"
package="$(parse_tag $tag)"
package="${package#*revision:}"
package="${package%% *}"
echo "$package"
}
function get_distribution_from_tag {
# tag pkg like pkg/<level>/<distrib>/<version>
# <distrib> may be composed
tag="$1"
distribution="${tag#pkg/*/}"
distribution="${distribution%/*}"
distribution="${distribution/\//-}"
echo $distribution
}
function get_previous_release_tag {
# Return previous pkg/* tag or current tag if no previous pkg/* exists.
commit="$1"
echo "$(git describe --abbrev=0 --always --match='release/*' $commit)"
}
function on_pkg_tag {
# Return 1 if current commit is tagged with pkg/* tag.
commit="$1"
nearest_old_pkg_tag="$(get_previous_pkg_tag $commit)"
if [ -n "${nearest_old_pkg_tag}" ] && [ "$(get_hash ${commit})" = "$(get_hash ${nearest_old_pkg_tag})" ]
then
return 0
else
return 1
fi
}
function next_step {
# Return previous pkg/* tag or first commit if no pkg/* tag exists
commit="$1"
if [ "$(get_hash $commit)" = "$(get_hash $first_commit)" ]
then
echo $commit
elif on_pkg_tag $commit
then
nearest_old_pkg_tag="$(get_previous_pkg_tag ${commit}^1)"
else
nearest_old_pkg_tag="$(get_previous_pkg_tag ${commit})"
fi
if [[ "$nearest_old_pkg_tag" =~ 'pkg/' ]]
then
echo $nearest_old_pkg_tag
else
echo $first_commit
fi
}
function date_from_commit {
# Return date suitable for changelog entry signature
commit="$1"
if [ "$(get_hash ${commit})" = "$(get_hash HEAD)" ]
then
package_date=$(date --rfc-2822)
else
maintainer_commit="$(get_previous_pkg_tag $commit)"
package_date="$(git tag -l --format='%(creator)' ${maintainer_commit})"
package_date="${package_date##*> }"
package_date="$(date --rfc-2822 -d @${package_date% *})"
fi
echo "$package_date"
}
function packager_from_commit {
# Return Name <mail> id format, suitable for changelog entry signature
commit="$1"
if on_pkg_tag "${commit}"
then
maintainer_commit="$(get_previous_pkg_tag $commit)"
maintainer="$(git tag -l --format='%(creator)' ${maintainer_commit})"
maintainer="${maintainer%>*}>"
else
maintainer="$(git log -n1 --format='%cn <%ce>')"
fi
maintainer=$(tamarin_db get maintainer "${maintainer}")
echo "$maintainer"
}
function next_version {
commit="$1"
# upstream version is given by most recent of release or pkg tag
previous_pkg="$(git describe --long --match='pkg/*' $commit 2>/dev/null)"
previous_release="$(git describe --long --match='release/*' $commit 2>/dev/null)"
if [ -n "$previous_release" ] && [ -n "$previous_pkg" ]
then
distance_from_pkg=$(get_distance_from_tag "$previous_pkg" "$commit")
distance_from_release=$(get_distance_from_tag "$previous_release" "$commit")
if [ $distance_from_release -le $distance_from_pkg ]
then
distance=$distance_from_release
version="$(get_upstream_version_from_tag $previous_release)-1"
else
distance=$distance_from_pkg
version="$(get_upstream_version_from_tag $previous_pkg)-$(expr $(get_package_version_from_tag $previous_pkg) + 1)"
fi
elif [ -n "$previous_release" ]
then
distance_from_release=$(get_distance_from_tag "$previous_release" "$commit")
distance=$distance_from_release
version="$(get_upstream_version_from_tag $previous_release)-1"
elif [ -n "$previous_pkg" ]
then
distance=$distance_from_pkg
version="$(get_upstream_version_from_tag $previous_pkg)-$(expr $(get_package_version_from_tag $previous_pkg) + 1)"
else
distance=$(git rev-list --no-merges --count ${commit}..${first_commit})
version="0.0.0-1"
fi
if [ "$package_level" = 'dev' ] || [ "$package_level" = 'staging' ]
then
version="${version}~${package_level}+${distance}~$(get_short_hash $commit)"
fi
echo $version
}
function gen_changelog_entry {
ceiling_commit=$1
floor_commit="$(next_step "${ceiling_commit}")"
if [ "$(get_hash ${ceiling_commit})" = "$(get_hash ${floor_commit})" ]
then
return 1
fi
if on_pkg_tag $ceiling_commit
then
ceiling_commit="$(get_previous_pkg_tag $ceiling_commit)"
version="$(get_upstream_version_from_tag $ceiling_commit)-$(get_package_version_from_tag $ceiling_commit)"
distribution="$(get_distribution_from_tag $ceiling_commit)"
else
tamarin_info "current commit $ceiling_commit"
version=$(next_version $ceiling_commit)
distribution="UNRELEASED"
fi
#current_release="$(git describe --abbrev=0 --always --match='release/*' $ceiling_commit)"
tamarin_info "Création de lentrée de changelog entre ${ceiling_commit} et ${floor_commit}"
maintainer="$(packager_from_commit ${ceiling_commit})"
package_date="$(date_from_commit ${ceiling_commit})"
version=${version/_/-}
changelog_entry="${project_name} (${version}) ${distribution}; urgency=${urgency}"
echo "$changelog_entry" >> debian/changelog
echo >> debian/changelog
for commit in $(git log --no-merges --format='%H' ${floor_commit}..${ceiling_commit})
do
subject="$(git log -n1 --format=%s ${commit})"
echo " * ${subject}" >> debian/changelog
#ceiling_commit="$(git log -n1 --format='%H' ${commit}^1)"
done
echo >> debian/changelog
changelog_sign=" -- ${maintainer} ${package_date}"
echo "$changelog_sign" >> debian/changelog
echo >> debian/changelog
ceiling_commit=${floor_commit}
}
function gen_changelog() {
while gen_changelog_entry $ceiling_commit
do
echo $changelog_entry
done
}
gen_changelog
cp debian/changelog /dist/changelog