Skip to content

Instantly share code, notes, and snippets.

@kolewu kolewu/
Created Dec 18, 2017

What would you like to do?
Pathformatter that creates predictable names
# Path formatter plugin to get human readable paths
# This plugin introduces these new properties to a recipe:
# - checkoutDir: optional string
# - buildDir: optional string
# - packageDir: optional string
import os.path
from bob.errors import ParseError
from bob.input import PluginState, PluginProperty
from string import Template
def commonFormatter(step, states):
s = states['pathFmt']
stepEnv = step.getEnv()
if step.isCheckoutStep():
base = step.getPackage().getRecipe().getName()
ext = s.getCheckoutDir()
if ext:
# reformat to readable name without slashes in case the "rev" key
# is used to specify the SCM version
ext = ext.replace('refs/heads/', 'branch_')
ext = ext.replace('refs/tags/', 'tag_')
ext = ext.replace('/', '+')
ret = base+"-"+ext
ret = base
buildtype = {}
base = step.getPackage().getName()
if step.isBuildStep():
pattern = s.getBuildDir()
pattern = s.getPackageDir()
if pattern:
ext = Template(pattern).substitute(stepEnv)
ext = pattern
ret = os.path.join(base, ext) if ext else base
if buildtype:
ret += "-" + str(buildtype)
return ret.replace('::', "/")
def releaseFormatter(step, states):
return os.path.join("work", commonFormatter(step, states), step.getLabel())
def developFormatter(step, states):
return os.path.join("dev", step.getLabel(), commonFormatter(step, states))
def jenkinsFormatter(step, states):
return os.path.join(commonFormatter(step, states), step.getLabel())
def developPersister(wrapFmt):
dirs = {}
def fmt(step, props):
baseDir = wrapFmt(step, props)
digest = step.getVariantId()
if digest in dirs:
res = dirs[digest]
num = dirs.setdefault(baseDir, 0) + 1
if (num != 1):
res = os.path.join(baseDir, str(num))
res = baseDir
num = 0
dirs[baseDir] = num
dirs[digest] = res
return res
return fmt
class PathFmtState(PluginState):
def __init__(self):
self._checkoutDir = None
self._buildDir = None
self._packageDir = None
def onEnter(self, env, tools, properties):
# checkoutDir is taken from current recipe only
self._checkoutDir = properties['checkoutDir'].getValue()
if self._checkoutDir is not None:
self._checkoutDir = env.substitute(self._checkoutDir, "checkoutDir")
# buildDir and packageDir are taken from current recipe only
# or a default is used
for propname in ['buildDir', 'packageDir']:
property = properties[propname]
if property.isPresent():
value = env.substitute(property.getValue(), propname)
n = []
if 'CONFIG_NAME' in env:
if 'BUILD_TYPE' in env:
value = "/".join(n)
setattr(self, "_" + propname, value)
def getCheckoutDir(self):
return self._checkoutDir
def getBuildDir(self):
return self._buildDir
def getPackageDir(self):
return self._packageDir
class StringProperty(PluginProperty):
def validate(data):
return isinstance(data, str)
manifest = {
'apiVersion': "0.3",
'hooks': {
'developNamePersister': developPersister,
'releaseNameFormatter': releaseFormatter,
'developNameFormatter': developFormatter,
'jenkinsNameFormatter': jenkinsFormatter
'properties': {
"checkoutDir": StringProperty,
"buildDir": StringProperty,
"packageDir": StringProperty
'state': {
"pathFmt": PathFmtState
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.