summaryrefslogtreecommitdiff
path: root/expand
blob: 523437943ae241e69fc72685eada176018e1cedb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/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