#!/bin/bash set -e version="$1" type="$2" ### CONFIGURATION OPTIONS # Profiles to package in addition to the profile releng for the make target "dist-branches" branches_dist_branches=(baseline gnome toolkit) # Profiles to package in addition to the profile releng for the make target "dist" branches_dist=(baseline) ### END OF CONFIGURATION OPTIONS error() { echo "${@}. Stop." >&2 exit 1 } dist_branches() { branches="${branches_dist_branches}" # Refs to package (the branches) refs="${branches[@]}" # Ref of the releng profile to package releng="master" # Release branch. This branch only has commits to prepare the package. release_branch="release-branches" # Release ref. It is a branch for dist_branches. The package is created from this ref. release="${release_branch}" # Refs that should exist for the make target dist-branches. This branches will be packaged. allrefs=( ${releng} ${branches[@]} ) } dist() { branches="${branches_dist}" # Refs to package (branch names appending the date, like "baseline/2013.08.12") refs="${branches_dist[@]/%//${version}}" # Ref of the releng profile to package releng="master/${version}" # Release branch. This branch only has commits to prepare the package. release_branch="release" # Release ref. Tag of commit in release_branch. The package is created from this ref. release="release/${version}" # These refs should exist to package for the make target dist. allrefs=( ${releng} ${refs[@]} ) } expand() { ref="$1" dir="$2" GIT_INDEX_FILE="${index}" git read-tree --empty GIT_INDEX_FILE="${index}".release git read-tree --empty # Find the current head of ${ref} head="$(git show-ref --hash "refs/${ref_type}/${ref}")" # Find the current head of the release branch. head_release="$(git show-ref --hash refs/heads/"${release_branch}")" if [[ $dir == releng ]] ; then # Read the tree of "$ref" with profile path rename into an index file. git ls-tree -z -r "${head}" | sed -z "s|configs/profile|configs/${dir}|" | GIT_INDEX_FILE="${index}" git update-index -z --index-info # Remove the master branch from the release index, that is, leave everything from configs/ excluding configs/releng git ls-tree -z -r "${head_release}" | grep -zZP 'configs/(?!releng)' | GIT_INDEX_FILE="${index}".release git update-index -z --index-info # This combines the two indexes (obtained in the last two commands). GIT_INDEX_FILE="${index}".release git ls-files -z -s | GIT_INDEX_FILE="${index}" git update-index -z --add --index-info else # Read only paths configs/profile of "$ref" with profile path rename into an index file. git ls-tree -z -r "${head}" -- configs/profile | sed -z "s|configs/profile|configs/${dir}|" | GIT_INDEX_FILE="${index}" git update-index -z --index-info # Remove configs/${dir} from the release index. git ls-tree -z -r "${head_release}" | grep -zZv configs/"${dir}" | GIT_INDEX_FILE="${index}".release git update-index -z --index-info # This combines the two indexes (obtained in the last two commands). GIT_INDEX_FILE="${index}".release git ls-files -z -s | GIT_INDEX_FILE="${index}" git update-index -z --add --index-info fi # Write the index file into the repo as a tree. tree="$(GIT_INDEX_FILE="${index}" git write-tree)" # Write a commit to the repo. commit="$(echo "Update profile ${dir}" | git commit-tree "$tree" -p "${head_release}")" # Update the head of the repository to be the new commit. git update-ref refs/heads/"${release_branch}" "$commit" "${head_release}" } expand_empty() { ref="${releng}" dir="releng" GIT_INDEX_FILE="${index}" git read-tree --empty # Find the current head of ${ref} head="$(git show-ref --hash "refs/${ref_type}/${ref}")" # Read the tree of "$ref" with profile path rename into an index file. git ls-tree -z -r "${head}" | sed -z "s|configs/profile|configs/${dir}|" | GIT_INDEX_FILE="${index}" git update-index -z --index-info # Write the index file into the repo as a tree. tree="$(GIT_INDEX_FILE="${index}" git write-tree)" # Write a commit to the repo. commit="$(echo "Update profile ${dir}" | git commit-tree "$tree")" # Update the head of the repository to be the new commit. git update-ref refs/heads/"${release_branch}" "$commit" 0000000000000000000000000000000000000000 } ref_test() { es=0 git show-ref --quiet "$1" || es=$? if [[ $es == 1 ]] ; then error "$2" elif [[ $es > 1 ]] ; then error "$3" fi } ref_test_negative() { es=0 git show-ref --quiet "$1" || es=$? if [[ $es == 0 ]] ; then error "$2" elif [[ $es > 1 ]] ; then error "$3" fi } release_prepare() { ref_test_negative "refs/tags/${release}" "Release tag ${release} can not be created because it already exists" "Error testing the release tag" } show_ref() { for ref in ${allrefs[@]} ; do ref_test "refs/${ref_type}/${ref}" "Git reference refs/${ref_type}/${ref} should exist" "Error testing git reference refs/${ref_type}/${ref}" done } archive_ref() { git archive --format=tar.gz --prefix=parabolaiso-"${version}"/ "refs/${ref_type}/${release}" > parabolaiso-"${version}".tar.gz } archive() { git tag -s -m "tag ${release}" "${release}" "${release_branch}" archive_ref gpg --detach-sign --use-agent parabolaiso-"${version}".tar.gz } dist_expand() { index="$(mktemp)" es=0 git show-ref --quiet "refs/heads/${release_branch}" || es=$? if [[ $es == 0 ]] ; then expand "${releng}" releng elif [[ $es == 1 ]] ; then expand_empty echo "Release branch created." elif [[$es > 1 ]] ; then error "Error testing the release branch" fi for i in ${!branches[@]} ; do expand ${refs[$i]} ${branches[$i]} done } if [[ ${type} == dist ]] ; then ref_type="tags" dist release_prepare show_ref dist_expand archive elif [[ ${type} == dist-branches ]] ; then ref_type="heads" dist_branches show_ref dist_expand archive_ref else error "Second argument is not correct" fi