trigger_copr 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #!/bin/bash
  2. TRIGGER_COPR_CONFIG=${TRIGGER_COPR_CONFIG:-}
  3. TRIGGER_COPR_PKGNAME=${TRIGGER_COPR_PKGNAME:-}
  4. warn() {
  5. echo "$1" >&2
  6. }
  7. die() {
  8. warn "fatal: $1"
  9. exit 3
  10. }
  11. usage() {
  12. warn "usage: $0 [options] MODE"
  13. warn ""
  14. warn "Options:"
  15. warn ""
  16. warn " -b BRN build from branch BRN (default: last tag)"
  17. warn " -c COPR_PROJECT COPR project name"
  18. warn " -C CONF config file"
  19. warn " -n dry mode, don't do anything (just show"
  20. warn " what would be done)"
  21. warn " -r REL use REL as Release number in SPEC file"
  22. warn " -v VER use VER as Version number in SPEC file"
  23. warn " -u URL use URL as base (to get last tag and"
  24. warn " compose Source0 in SPEC file)"
  25. warn ""
  26. warn "If -b is not used, build is launched from last tag available"
  27. warn "in the GitHub repo. In that case, Release is '1' and Version"
  28. warn "is deduced from the tag by removing the initial 'v'."
  29. warn ""
  30. warn "If -b is used, the project repo is temporarily cloned, and"
  31. warn "both Version and Release are found by consulting git-describe"
  32. warn "on the specified branch."
  33. warn ""
  34. warn "If MODE is 'scratch' (default), Release is pre-fixed by string"
  35. warn "'0.scratch.' and build is triggered in scratch COPR project."
  36. exit 2
  37. }
  38. last_version() {
  39. # git ls-remote --tag "$UrlBase" \
  40. # | grep '/tags/' \
  41. # | cut -d/ -f3 \
  42. # | grep -v '[^0-9a-z.]' \
  43. # | sort -V \
  44. # | tail -1 \
  45. # | sed "s/^v//"
  46. git ls-remote --tag "$UrlBase" \
  47. | grep /tags \
  48. | cut -d/ -f3 \
  49. | grep -E '[0-9]+[.][0-9.]+$' \
  50. | grep -v ^v \
  51. | sort -V \
  52. | tail -1
  53. }
  54. mkspec() {
  55. local self_version
  56. local cl_date
  57. self_version="$(basename "$0") $(git describe --tags)"
  58. cl_date=$(LC_ALL=C date +"%a %b %d %Y")
  59. sed -e "
  60. s|__APP_VERSION__|$Version|
  61. s|__APP_RELEASE__|$Release|
  62. s|__APP_URLBASE__|$UrlBase|
  63. s|__APP_BUILDSCRIPT_VERSION__|$self_version|
  64. s|__APP_DATE__|$cl_date|
  65. " <"$PkgName.spec.in"
  66. }
  67. git_guess() {
  68. #
  69. # Print git-guessed $1
  70. #
  71. local what=$1 # what we want (ver|rel)
  72. local describe # full git-describe output
  73. local xtra= # extra part (-N-gHASH)
  74. local num=0 # num. of commits since tag (N)
  75. local sha= # '.g'+sha1 of this commit (gHASH)
  76. describe=$(git describe --tags --always HEAD)
  77. case $describe in
  78. *-*) # v1.2.3-21-g654cba
  79. tag=${describe%%-*} # tag=v1.2.3
  80. xtra=${describe#$tag-} # xtra=-21-g654cba
  81. num=${xtra%%-*} # num=21
  82. sha=.${xtra#$num-} # sha=.g654cba
  83. ;;
  84. *)
  85. tag=$describe
  86. ;;
  87. esac
  88. case $what in
  89. ver) echo "${tag#v}" ;;
  90. rel) echo "$((num + 1))$sha" ;;
  91. esac
  92. }
  93. choose_relpfx() {
  94. #
  95. # Choose COPR project based on $Mode
  96. #
  97. test "$Mode" == scratch && echo 0.scratch.
  98. return 0
  99. }
  100. read_conffile() {
  101. #
  102. # Read item T
  103. #
  104. local what=$1
  105. local fieldn
  106. case $what in
  107. urlbase) fieldn=2 ;;
  108. copr) fieldn=3 ;;
  109. esac
  110. grep -v '^[[:blank:]]*#' "$ConfFile" \
  111. | grep "^ *$Mode\>" \
  112. | sed 's/ */ /g' \
  113. | cut -d' ' -f$fieldn
  114. }
  115. choose_conffile() {
  116. #
  117. # Find config file and echo its name
  118. #
  119. find . -name '*.trigger' \
  120. | cut -d/ -f2 \
  121. | grep .
  122. }
  123. do_action() {
  124. local url
  125. case $Action in
  126. build)
  127. copr build "$CoprProject" "$Tmp/$PkgName.spec"
  128. printf '\a'
  129. ;;
  130. demo)
  131. warn "demo mode active, we would build:"
  132. warn " at $CoprProject"
  133. test -n "$Branch" && warn " using branch $Branch"
  134. test -n "$Branch" || warn " using last tag"
  135. warn " from $UrlBase"
  136. warn " yielding $PkgName-$Version-$Release.*.rpm"
  137. warn ""
  138. warn "===== BEGIN $PkgName.spec ====="
  139. cat "$Tmp/$PkgName.spec"
  140. warn "===== END $PkgName.spec ====="
  141. return 1
  142. ;;
  143. mkspec)
  144. cat "$Tmp/$PkgName.spec"
  145. ;;
  146. rpmstuff)
  147. url=$(
  148. grep -o 'Source.*:.*http.*' "$Tmp/$PkgName.spec" \
  149. | sed "
  150. s/.*http/http/
  151. s/ *$//
  152. s/%{version}/$Version/g
  153. s/%{name}/$PkgName/g
  154. "
  155. )
  156. wget --quiet "$url"
  157. cat "$Tmp/$PkgName.spec" > "$PkgName.spec"
  158. ;;
  159. esac
  160. }
  161. main() {
  162. local Version # Version in SPEC file
  163. local Release # Release in SPEC file
  164. local CoprProject # COPR project
  165. local UrlBase # GitHub URL base
  166. local Tmp # our temp
  167. local Branch # branch to use, if empty, tags are considered
  168. local Mode=scratch # implies COPR project and release prefix
  169. local Action=build # what to do
  170. local ConfFile # config file to use
  171. local PkgName # package name
  172. local es=0 # exit status
  173. which copr >/dev/null \
  174. || die "copr not found, try 'sudo install copr-cli'"
  175. Tmp=$(mktemp -d)
  176. while true; do case $1 in
  177. -C) ConfFile=$2; shift 2 || usage ;;
  178. -a) Action=$2; shift 2 || usage ;;
  179. -b) Branch=$2; shift 2 || usage ;;
  180. -c) CoprProject=$2; shift 2 || usage ;;
  181. -u) UrlBase=$2; shift 2 || usage ;;
  182. -r) Release=$2; shift 2 || usage ;;
  183. -v) Version=${2#v}; shift 2 || usage ;;
  184. -n) Action=demo; shift ;;
  185. -*) usage ;;
  186. *) break ;;
  187. esac done
  188. Mode=${1:-$Mode}
  189. case $Action in
  190. build|demo|mkspec|rpmstuff) : ;;
  191. *) usage ;;
  192. esac
  193. test -n "$ConfFile" || ConfFile=$TRIGGER_COPR_CONFIG
  194. test -n "$ConfFile" || ConfFile=$(choose_conffile)
  195. test -n "$ConfFile" || die "could not find config file"
  196. test -r "$ConfFile" || die "could not read config file"
  197. test -n "$PkgName" || PkgName=$TRIGGER_COPR_PKGNAME
  198. test -n "$PkgName" || PkgName=${ConfFile%.trigger}
  199. test -n "$CoprProject" || CoprProject=$(read_conffile copr)
  200. test -n "$UrlBase" || UrlBase=$(read_conffile urlbase)
  201. if test -n "$Branch"; then
  202. die "not implemented"
  203. test -n "$Version" || Version=$(git_guess ver)
  204. test -n "$Release" || Release=$(git_guess rel)
  205. else
  206. test -n "$Version" || Version=$(last_version)
  207. test -n "$Release" || Release=1
  208. fi
  209. Release=$(choose_relpfx)$Release
  210. mkspec >"$Tmp/$PkgName.spec"
  211. do_action
  212. rm -rf "$Tmp"
  213. return $es
  214. }
  215. main "$@"