#!/bin/bash TRIGGER_COPR_CONFIG=${TRIGGER_COPR_CONFIG:-} TRIGGER_COPR_PKGNAME=${TRIGGER_COPR_PKGNAME:-} warn() { echo "$1" >&2 } die() { warn "fatal: $1" exit 3 } usage() { warn "usage: $0 [options] MODE" warn "" warn "Options:" warn "" warn " -b BRN build from branch BRN (default: last tag)" warn " -c COPR_PROJECT COPR project name" warn " -C CONF config file" warn " -n dry mode, don't do anything (just show" warn " what would be done)" warn " -r REL use REL as Release number in SPEC file" warn " -v VER use VER as Version number in SPEC file" warn " -u URL use URL as base (to get last tag and" warn " compose Source0 in SPEC file)" warn "" warn "If -b is not used, build is launched from last tag available" warn "in the GitHub repo. In that case, Release is '1' and Version" warn "is deduced from the tag by removing the initial 'v'." warn "" warn "If -b is used, the project repo is temporarily cloned, and" warn "both Version and Release are found by consulting git-describe" warn "on the specified branch." warn "" warn "If MODE is 'scratch' (default), Release is pre-fixed by string" warn "'0.scratch.' and build is triggered in scratch COPR project." exit 2 } last_version() { git ls-remote --tag "$UrlBase" \ | grep '/tags/' \ | cut -d/ -f3 \ | grep -v '[^0-9a-z.]' \ | sort -V \ | tail -1 \ | sed "s/^v//" } mkspec() { local self_version local cl_date self_version="$(basename "$0") $(git describe --tags)" cl_date=$(LC_ALL=C date +"%a %b %d %Y") sed -e " s|__APP_VERSION__|$Version| s|__APP_RELEASE__|$Release| s|__APP_URLBASE__|$UrlBase| s|__APP_BUILDSCRIPT_VERSION__|$self_version| s|__APP_DATE__|$cl_date| " <"$PkgName.spec.in" } git_guess() { # # Print git-guessed $1 # local what=$1 # what we want (ver|rel) local describe # full git-describe output local xtra= # extra part (-N-gHASH) local num=0 # num. of commits since tag (N) local sha= # '.g'+sha1 of this commit (gHASH) describe=$(git describe --tags --always HEAD) case $describe in *-*) # v1.2.3-21-g654cba tag=${describe%%-*} # tag=v1.2.3 xtra=${describe#$tag-} # xtra=-21-g654cba num=${xtra%%-*} # num=21 sha=.${xtra#$num-} # sha=.g654cba ;; *) tag=$describe ;; esac case $what in ver) echo "${tag#v}" ;; rel) echo "$((num + 1))$sha" ;; esac } choose_relpfx() { # # Choose COPR project based on $Mode # test "$Mode" == scratch && echo 0.scratch. return 0 } read_conffile() { # # Read item T # local what=$1 local fieldn case $what in urlbase) fieldn=2 ;; copr) fieldn=3 ;; esac grep -v '^[[:blank:]]*#' "$ConfFile" \ | grep "^ *$Mode\>" \ | sed 's/ */ /g' \ | cut -d' ' -f$fieldn } choose_conffile() { # # Find config file and echo its name # find . -name '*.trigger' \ | cut -d/ -f2 \ | grep . } do_action() { local url case $Action in build) copr build "$CoprProject" "$Tmp/$PkgName.spec" printf '\a' ;; demo) warn "demo mode active, we would build:" warn " at $CoprProject" test -n "$Branch" && warn " using branch $Branch" test -n "$Branch" || warn " using last tag" warn " from $UrlBase" warn " yielding $PkgName-$Version-$Release.*.rpm" warn "" warn "===== BEGIN $PkgName.spec =====" cat "$Tmp/$PkgName.spec" warn "===== END $PkgName.spec =====" return 1 ;; mkspec) cat "$Tmp/$PkgName.spec" ;; rpmstuff) url=$( grep -o 'Source.*:.*http.*' "$Tmp/$PkgName.spec" \ | sed " s/.*http/http/ s/ *$// s/%{version}/$Version/g s/%{name}/$PkgName/g " ) wget --quiet "$url" cat "$Tmp/$PkgName.spec" > "$PkgName.spec" ;; esac } main() { local Version # Version in SPEC file local Release # Release in SPEC file local CoprProject # COPR project local UrlBase # GitHub URL base local Tmp # our temp local Branch # branch to use, if empty, tags are considered local Mode=scratch # implies COPR project and release prefix local Action=build # what to do local ConfFile # config file to use local PkgName # package name local es=0 # exit status which copr >/dev/null \ || die "copr not found, try 'sudo install copr-cli'" Tmp=$(mktemp -d) while true; do case $1 in -C) ConfFile=$2; shift 2 || usage ;; -a) Action=$2; shift 2 || usage ;; -b) Branch=$2; shift 2 || usage ;; -c) CoprProject=$2; shift 2 || usage ;; -u) UrlBase=$2; shift 2 || usage ;; -r) Release=$2; shift 2 || usage ;; -v) Version=${2#v}; shift 2 || usage ;; -n) Action=demo; shift ;; -*) usage ;; *) break ;; esac done Mode=${1:-$Mode} case $Action in build|demo|mkspec|rpmstuff) : ;; *) usage ;; esac test -n "$ConfFile" || ConfFile=$TRIGGER_COPR_CONFIG test -n "$ConfFile" || ConfFile=$(choose_conffile) test -n "$ConfFile" || die "could not find config file" test -r "$ConfFile" || die "could not read config file" test -n "$PkgName" || PkgName=$TRIGGER_COPR_PKGNAME test -n "$PkgName" || PkgName=${ConfFile%.trigger} test -n "$CoprProject" || CoprProject=$(read_conffile copr) test -n "$UrlBase" || UrlBase=$(read_conffile urlbase) if test -n "$Branch"; then die "not implemented" test -n "$Version" || Version=$(git_guess ver) test -n "$Release" || Release=$(git_guess rel) else test -n "$Version" || Version=$(last_version) test -n "$Release" || Release=1 fi Release=$(choose_relpfx)$Release mkspec >"$Tmp/$PkgName.spec" do_action rm -rf "$Tmp" return $es } main "$@"