prepare-release 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #!/bin/sh
  2. set -e
  3. cd "$(readlink -f $(dirname $0))"
  4. if [ -n "${GBP_BUILD_DIR}" ]; then
  5. cd "$GBP_BUILD_DIR"
  6. fi
  7. VERSION=$(dpkg-parsechangelog | sed -n -e '/^Version:/s/^Version: //p')
  8. DISTRIBUTION=$(dpkg-parsechangelog | sed -n -e '/^Distribution:/s/^Distribution: //p')
  9. LIBAPTPKGVERSION="$(awk -v ORS='.' '/^\#define APT_PKG_M/ {print $3}' apt-pkg/contrib/macros.h | sed 's/\.$//')"
  10. LIBAPTINSTVERSION="$(sed -nr 's/set\(MAJOR ([^)]*)\)/\1/p' apt-inst/CMakeLists.txt)"
  11. librarysymbolsfromfile() {
  12. local MISSING="$(grep '^+#MISSING' "$1")"
  13. local SYMVER="$2"
  14. echo '=== Missing optional symbols:'
  15. echo -n "$MISSING" | grep '|optional=' || true
  16. echo '=== Missing required symbols:'
  17. echo -n "$MISSING" | grep -v '|optional=' || true
  18. echo '=== New symbols:'
  19. grep '^+ ' "$1" | grep -v '^+ (c++' | cut -d' ' -f 2 | cut -d'@' -f 1 | c++filt | while read line; do
  20. echo " (c++)\"${line}@${SYMVER}\" $VERSION"
  21. done | sort -u
  22. }
  23. test_deb_control() {
  24. echo "Package: apt-test-depends"
  25. echo "Version: 1.0"
  26. echo "Architecture: all"
  27. printf "Depends:"
  28. (
  29. for i in Build-Depends Build-Depends-Indep Build-Depends-Arch; do
  30. grep-dctrl -ns $i -S apt ./debian/control && echo ,
  31. done
  32. grep-dctrl -ns Depends -F Tests run-tests ./debian/tests/control
  33. ) | tr '\n' ' '\
  34. | sed -r -e 's#<[^,<>()@]*>##g' \
  35. -e 's#@[^,<>()@]*@##g' \
  36. -e 's#dpkg-dev \([^)]*\)#dpkg-dev#g' \
  37. -e 's#debhelper \([^)]*\)#debhelper#g' \
  38. -e 's#@##g' \
  39. -e 's#,(\s+,)+#, #g' \
  40. -e 's#\s+# #g'
  41. }
  42. if [ "$1" = 'pre-export' ]; then
  43. libraryversioncheck() {
  44. local LIBRARY="$1"
  45. local VERSION="$2"
  46. if [ ! -e "debian/${LIBRARY}${VERSION}.symbols" ]; then
  47. echo >&2 "Library ${LIBRARY} in version ${VERSION} has no symbols file! (maybe forgot to rename?)"
  48. exit 1
  49. fi
  50. if [ "$(head -n1 "debian/${LIBRARY}${VERSION}.symbols")" != "${LIBRARY}.so.${VERSION} ${LIBRARY}${VERSION} #MINVER#" ]; then
  51. echo >&2 "Library ${LIBRARY}${VERSION} has incorrect version in symbol header! (»$(head -n1 "debian/${LIBRARY}${VERSION}.symbols")«)"
  52. exit 2
  53. fi
  54. }
  55. libraryversioncheck 'libapt-pkg' "$LIBAPTPKGVERSION"
  56. libraryversioncheck 'libapt-inst' "$LIBAPTINSTVERSION"
  57. if [ "$DISTRIBUTION" = 'sid' ]; then
  58. echo >&2 '»sid« is not a valid distribution. Replace it with »unstable« for you'
  59. sed -i -e 's/) sid; urgency=/) unstable; urgency=/' debian/changelog
  60. DISTRIBUTION='unstable'
  61. elif [ "$DISTRIBUTION" = 'UNRELEASED' ]; then
  62. echo >&2 'WARNING: Remember to change to a valid distribution for release'
  63. VERSION="$VERSION~$(date +%Y%m%d)"
  64. fi
  65. sed -i -e "s/^set(PACKAGE_VERSION \".*\")$/set(PACKAGE_VERSION \"${VERSION}\")/" CMakeLists.txt
  66. sed -i -e "s/^<!ENTITY apt-product-version \".*\">$/<!ENTITY apt-product-version \"${VERSION}\">/" doc/apt-verbatim.ent
  67. # update the last-modification field of manpages based on git changes
  68. grep --files-with-matches '<date>' doc/*.xml | while read file; do \
  69. LASTMOD="$(date -d "@$(git log --format='%at' --max-count=1 --invert-grep --fixed-strings --grep 'review
  70. typo
  71. release
  72. Git-Dch: Ignore' "$file")" '+%Y-%m-%dT00:00:00Z')"
  73. sed -i -e "s#^\([ ]\+\)<date>.*</date>\$#\1<date>$LASTMOD</date>#" "$file"
  74. done
  75. if [ "$(date +%Y-%m-%d)" != "$(grep --max-count=1 '^"POT-Creation-Date: .*\n"$' po/apt-all.pot | cut -d' ' -f 2)" -o \
  76. "$(date +%Y-%m-%d)" != "$(grep --max-count=1 '^"POT-Creation-Date: .*\n"$' doc/po/apt-doc.pot | cut -d' ' -f 2)" ]; then
  77. echo >&2 'POT files are not up-to-date. Execute »make update-po« for you…'
  78. [ -e build ] || mkdir build
  79. ( cd build && cmake .. )
  80. cmake --build build --target update-po -- -j 4
  81. fi
  82. elif [ "$1" = 'pre-build' ]; then
  83. if [ "$DISTRIBUTION" = "UNRELEASED" ]; then
  84. echo 'BUILDING AN UNRELEASED VERSION'
  85. else
  86. CONFVERSION="$(sed -ne "s/^set(PACKAGE_VERSION \"\(.*\)\")$/\1/p" CMakeLists.txt)"
  87. if [ "$VERSION" != "$CONFVERSION" ]; then
  88. echo "changelog (${VERSION}) and CMakeLists.txt (${CONFVERSION}) talk about different versions!"
  89. echo "You probably want to run »./prepare-release pre-export« to fix this."
  90. exit 1
  91. fi
  92. fi
  93. elif [ "$1" = 'post-build' ]; then
  94. if [ "$DISTRIBUTION" != "UNRELEASED" ]; then
  95. echo >&2 "REMEMBER: Tag this release with »git tag -s ${VERSION}« if you are satisfied"
  96. else
  97. echo >&2 'REMEMBER: Change to a valid distribution before release'
  98. fi
  99. dpkg-checkbuilddeps -d 'libxml2-utils'
  100. HEADERBLUEPRINT="$(mktemp)"
  101. sed -n '1,/^$/p' doc/apt.8.xml > "$HEADERBLUEPRINT"
  102. find doc -mindepth 1 -maxdepth 1 -type f -name '*.xml' | while read FILE; do
  103. if ! sed -n '1,/^$/p' "$FILE" | cmp "$HEADERBLUEPRINT" - >/dev/null 2>&1; then
  104. echo >&2 "WARNING: Manpage $FILE has not the usual header! (see diff below)"
  105. sed -n '1,/^$/p' "$FILE" | diff -u "$HEADERBLUEPRINT" - || true
  106. fi
  107. done
  108. sed -n '1,/^$/p' doc/guide.dbk > "$HEADERBLUEPRINT"
  109. find doc -mindepth 1 -maxdepth 1 -type f -name '*.dbk' | while read FILE; do
  110. if ! sed -n '1,/^$/p' "$FILE" | cmp "$HEADERBLUEPRINT" - >/dev/null 2>&1; then
  111. echo >&2 "WARNING: Documentation $FILE has not the usual header (see diff below)!"
  112. sed -n '1,/^$/p' "$FILE" | diff -u "$HEADERBLUEPRINT" - || true
  113. fi
  114. done
  115. rm "$HEADERBLUEPRINT"
  116. # check the manpages with each vendor for vendor-specific errors…
  117. find vendor -mindepth 1 -maxdepth 1 -type d | cut -d'/' -f 2 | while read DISTRO; do
  118. ln -sf ../vendor/${DISTRO}/apt-vendor.ent doc
  119. if ! xmllint --nonet --valid --noout $(find doc/ -maxdepth 1 -name '*.xml'); then
  120. echo >&2 "WARNING: original docbook manpages have errors with vendor ${DISTRO}!"
  121. fi
  122. done
  123. # lets assume we will always have a german manpage translation
  124. if [ -e */doc/de/ -o -e doc/de ]; then
  125. # … but check the translations only with one vendor for translation-specific errors
  126. if ! xmllint --path /vendor/$(./vendor/getinfo current)/ \
  127. --path doc/ \
  128. --nonet --valid --noout $(find doc/ */doc/ -mindepth 2 -maxdepth 2 -name '*.xml'); then
  129. echo >&2 "WARNING: translated docbook manpages have errors!"
  130. fi
  131. else
  132. echo >&2 "ERROR: translated manpages need to be build before they can be checked!"
  133. fi
  134. rm -f doc/apt-vendor.ent
  135. elif [ "$1" = 'library' ]; then
  136. librarysymbols() {
  137. local libname=$(echo "${1}" | cut -c 4-)
  138. local buildlib="build/bin/${1}.so.${2}"
  139. for dir in $libname */$libname; do
  140. local new_buildlib="$dir/${1}.so.${2}"
  141. if [ -r "${new_buildlib}" ] && [ ! -e "$buildlib" -o "$new_buildlib" -nt "$buildlib" ]; then
  142. local buildlib="${new_buildlib}"
  143. fi
  144. done
  145. if [ ! -r "$buildlib" ]; then
  146. echo "ERROR: The library ${1} has to be built before symbols can be checked!"
  147. return
  148. fi
  149. echo "Checking $1 in version $2 build at $(stat -L -c '%y' "$buildlib")"
  150. local tmpfile=$(mktemp)
  151. dpkg-gensymbols -p${1}${2} -e${buildlib} -Idebian/${1}${2}.symbols -O/dev/null 2> /dev/null > $tmpfile || true
  152. librarysymbolsfromfile "$tmpfile" "$(echo "${1}" | cut -c 4- | tr -d '-' | tr 'a-z' 'A-Z')_${2}"
  153. rm -f $tmpfile
  154. }
  155. librarysymbols 'libapt-pkg' "${LIBAPTPKGVERSION}"
  156. echo
  157. librarysymbols 'libapt-inst' "${LIBAPTINSTVERSION}"
  158. elif [ "$1" = 'buildlog' ]; then
  159. while [ -n "$2" ]; do
  160. librarysymbolsfromfile "$2" 'UNKNOWN'
  161. shift
  162. done
  163. elif [ "$1" = 'travis-ci' ]; then
  164. apt-get install -qy --no-install-recommends dctrl-tools equivs gdebi-core moreutils
  165. test_deb_control > test-control
  166. equivs-build test-control
  167. gdebi -n apt-test-depends_1.0_all.deb
  168. elif [ "$1" = 'coverage' ]; then
  169. DIR="${2:-./coverage}"
  170. git clean -dfX # remove ignored build artefacts for a clean start
  171. make CFLAGS+='--coverage' CXXFLAGS+='--coverage'
  172. LCOVRC='--rc geninfo_checksum=1 --rc lcov_branch_coverage=1'
  173. mkdir "$DIR"
  174. lcov --no-external --directory . --capture --initial --output-file "${DIR}/apt.coverage.init" ${LCOVRC}
  175. make test || true
  176. ./test/integration/run-tests -q || true
  177. lcov --no-external --directory . --capture --output-file "${DIR}/apt.coverage.run" ${LCOVRC}
  178. lcov -a "${DIR}/apt.coverage.init" -a "${DIR}/apt.coverage.run" -o "${DIR}/apt.coverage.total" ${LCOVRC}
  179. cp "${DIR}/apt.coverage.total" "${DIR}/apt.coverage.fixed"
  180. rewritefile() {
  181. file="$1"
  182. shift
  183. name="$(basename "$file")"
  184. while [ -n "$1" ]; do
  185. if [ -r "$1/$name" ]; then
  186. sed -i "s#$file#$1/$name#" "${DIR}/apt.coverage.fixed"
  187. break
  188. fi
  189. shift
  190. done
  191. if [ -z "$1" ]; then
  192. echo >&2 "Coverage data captured for unknown file $file"
  193. fi
  194. }
  195. grep 'build/include/' "${DIR}/apt.coverage.fixed" | sed "s#^SF:$(pwd)/##" | while read file; do
  196. rewritefile "$file" 'apt-pkg' 'apt-pkg/deb' 'apt-pkg/edsp' 'apt-pkg/contrib' \
  197. 'apt-inst' 'apt-inst/deb' 'apt-inst/contrib' 'apt-private'
  198. done
  199. genhtml --output-directory "${DIR}" "${DIR}/apt.coverage.fixed" ${LCOVRC}
  200. else
  201. echo >&1 "Usage:\t$0 pre-export
  202. \t$0 pre-build
  203. \t$0 post-build
  204. Updating po-files and versions as well as some basic checks are done
  205. by »pre-export« which needs to be run before package building.
  206. If you use »gbp buildpackage« you will be notified if you forget.
  207. »pre-build« and »post-build« can be used to run some more or less
  208. useful checks automatically run by »gbp« otherwise.
  209. \t$0 library
  210. \t$0 buildlog filename…
  211. »library« and »buildlog« aren't run automatically but can be useful for
  212. maintaining the (more or less experimental) symbols files we provide.
  213. »library« displays the diff between advertised symbols and the once provided
  214. by the libraries, while »buildlog« extracts this diff from the buildlogs.
  215. Both will format the diff properly.
  216. \t$0 travis-ci
  217. \t$0 coverage [output-dir]
  218. »travis-ci« is a shortcut to install all build- as well as test-dependencies
  219. used by .travis.yml.
  220. »coverage« does a clean build with the right flags for coverage reporting,
  221. runs all tests and generates a html report in the end.
  222. "
  223. fi