1*4882a593Smuzhiyun# gitpkgv.bbclass provides a GITPKGV and GITPKGVTAG variables to be 2*4882a593Smuzhiyun# used in PKGV, as described bellow: 3*4882a593Smuzhiyun# 4*4882a593Smuzhiyun# - GITPKGV which is a sortable version with the format NN+GITHASH, to 5*4882a593Smuzhiyun# be used in PKGV, where 6*4882a593Smuzhiyun# 7*4882a593Smuzhiyun# NN equals the total number of revs up to SRCREV 8*4882a593Smuzhiyun# GITHASH is SRCREV's (full) hash 9*4882a593Smuzhiyun# 10*4882a593Smuzhiyun# - GITPKGVTAG which is the output of 'git describe --tags --exact-match' 11*4882a593Smuzhiyun# allowing for automatic versioning 12*4882a593Smuzhiyun# 13*4882a593Smuzhiyun# gitpkgv.bbclass assumes the git repository has been cloned, and 14*4882a593Smuzhiyun# contains SRCREV. So ${GITPKGV} and ${GITPKGVTAG} should never be 15*4882a593Smuzhiyun# used in PV, only in PKGV. It can handle SRCREV = ${AUTOREV}, as 16*4882a593Smuzhiyun# well as SRCREV = "<some fixed git hash>". 17*4882a593Smuzhiyun# 18*4882a593Smuzhiyun# WARNING: if upstream repository is always using consistent and 19*4882a593Smuzhiyun# sortable tag name scheme you can get sortable version including tag 20*4882a593Smuzhiyun# name with ${GITPKGVTAG}, but be aware that ie tag sequence "v1.0, 21*4882a593Smuzhiyun# v1.2, xtest, v2.0" will force you to increment PE to get upgradeable 22*4882a593Smuzhiyun# path to v2.0 revisions 23*4882a593Smuzhiyun# 24*4882a593Smuzhiyun# use example: 25*4882a593Smuzhiyun# 26*4882a593Smuzhiyun# inherit gitpkgv 27*4882a593Smuzhiyun# 28*4882a593Smuzhiyun# PV = "1.0+gitr${SRCPV}" # expands to something like 1.0+gitr3+4c1c21d7dbbf93b0df336994524313dfe0d4963b 29*4882a593Smuzhiyun# PKGV = "1.0+gitr${GITPKGV}" # expands also to something like 1.0+gitr31337+4c1c21d7d 30*4882a593Smuzhiyun# 31*4882a593Smuzhiyun# or 32*4882a593Smuzhiyun# 33*4882a593Smuzhiyun# inherit gitpkgv 34*4882a593Smuzhiyun# 35*4882a593Smuzhiyun# PV = "1.0+gitr${SRCPV}" # expands to something like 1.0+gitr3+4c1c21d7dbbf93b0df336994524313dfe0d4963b 36*4882a593Smuzhiyun# PKGV = "${GITPKGVTAG}" # expands to something like 1.0-31337+g4c1c21d 37*4882a593Smuzhiyun# if there is tag v1.0 before this revision or 38*4882a593Smuzhiyun# ver1.0-31337+g4c1c21d if there is tag ver1.0 39*4882a593Smuzhiyun 40*4882a593SmuzhiyunGITPKGV = "${@get_git_pkgv(d, False)}" 41*4882a593SmuzhiyunGITPKGVTAG = "${@get_git_pkgv(d, True)}" 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun# This regexp is used to drop unwanted parts of the found tags. Any matching 44*4882a593Smuzhiyun# groups will be concatenated to yield the final version. 45*4882a593SmuzhiyunGITPKGV_TAG_REGEXP ??= "v(\d.*)" 46*4882a593Smuzhiyun 47*4882a593Smuzhiyundef gitpkgv_drop_tag_prefix(d, version): 48*4882a593Smuzhiyun import re 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun m = re.match(d.getVar('GITPKGV_TAG_REGEXP'), version) 51*4882a593Smuzhiyun if m: 52*4882a593Smuzhiyun return ''.join(group for group in m.groups() if group) 53*4882a593Smuzhiyun else: 54*4882a593Smuzhiyun return version 55*4882a593Smuzhiyun 56*4882a593Smuzhiyundef get_git_pkgv(d, use_tags): 57*4882a593Smuzhiyun import os 58*4882a593Smuzhiyun import bb 59*4882a593Smuzhiyun from pipes import quote 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun src_uri = d.getVar('SRC_URI').split() 62*4882a593Smuzhiyun fetcher = bb.fetch2.Fetch(src_uri, d) 63*4882a593Smuzhiyun ud = fetcher.ud 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun # 66*4882a593Smuzhiyun # If SRCREV_FORMAT is set respect it for tags 67*4882a593Smuzhiyun # 68*4882a593Smuzhiyun format = d.getVar('SRCREV_FORMAT') 69*4882a593Smuzhiyun if not format: 70*4882a593Smuzhiyun names = [] 71*4882a593Smuzhiyun for url in ud.values(): 72*4882a593Smuzhiyun if url.type == 'git' or url.type == 'gitsm': 73*4882a593Smuzhiyun names.extend(url.revisions.keys()) 74*4882a593Smuzhiyun if len(names) > 0: 75*4882a593Smuzhiyun format = '_'.join(names) 76*4882a593Smuzhiyun else: 77*4882a593Smuzhiyun format = 'default' 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun found = False 80*4882a593Smuzhiyun for url in ud.values(): 81*4882a593Smuzhiyun if url.type == 'git' or url.type == 'gitsm': 82*4882a593Smuzhiyun for name, rev in url.revisions.items(): 83*4882a593Smuzhiyun if not os.path.exists(url.localpath): 84*4882a593Smuzhiyun return None 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun found = True 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun vars = { 'repodir' : quote(url.localpath), 89*4882a593Smuzhiyun 'rev' : quote(rev) } 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun rev = bb.fetch2.get_srcrev(d).split('+')[1] 92*4882a593Smuzhiyun rev_file = os.path.join(url.localpath, "oe-gitpkgv_" + rev) 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun if not os.path.exists(rev_file) or os.path.getsize(rev_file)==0: 95*4882a593Smuzhiyun commits = bb.fetch2.runfetchcmd( 96*4882a593Smuzhiyun "git --git-dir=%(repodir)s rev-list %(rev)s -- 2>/dev/null | wc -l" 97*4882a593Smuzhiyun % vars, d, quiet=True).strip().lstrip('0') 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun if commits != "": 100*4882a593Smuzhiyun oe.path.remove(rev_file, recurse=False) 101*4882a593Smuzhiyun with open(rev_file, "w") as f: 102*4882a593Smuzhiyun f.write("%d\n" % int(commits)) 103*4882a593Smuzhiyun else: 104*4882a593Smuzhiyun commits = "0" 105*4882a593Smuzhiyun else: 106*4882a593Smuzhiyun with open(rev_file, "r") as f: 107*4882a593Smuzhiyun commits = f.readline(128).strip() 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun if use_tags: 110*4882a593Smuzhiyun try: 111*4882a593Smuzhiyun output = bb.fetch2.runfetchcmd( 112*4882a593Smuzhiyun "git --git-dir=%(repodir)s describe %(rev)s --tags --exact-match 2>/dev/null" 113*4882a593Smuzhiyun % vars, d, quiet=True).strip() 114*4882a593Smuzhiyun ver = gitpkgv_drop_tag_prefix(d, output) 115*4882a593Smuzhiyun except Exception: 116*4882a593Smuzhiyun ver = "0.0-%s-g%s" % (commits, vars['rev'][:7]) 117*4882a593Smuzhiyun else: 118*4882a593Smuzhiyun ver = "%s+%s" % (commits, vars['rev'][:7]) 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun format = format.replace(name, ver) 121*4882a593Smuzhiyun 122*4882a593Smuzhiyun if found: 123*4882a593Smuzhiyun return format 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun return '0+0' 126