Skip to content

Commit

Permalink
small refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
pustotnik committed Feb 15, 2022
1 parent f28b5c2 commit c024833
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 93 deletions.
58 changes: 49 additions & 9 deletions src/zenmake/zm/features/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@

from zm.pyutils import struct, cached
from zm.pypkg import PkgPath
from zm.utils import loadPyModule
from zm.error import ZenMakeError
from zm.utils import loadPyModule, toListSimple, uniqueListWithOrder
from zm.error import ZenMakeError, ZenMakeConfError

# private cache
_cache = {}
Expand Down Expand Up @@ -243,6 +243,53 @@ def decorator(func):
#######################################################################
## Others

def detectTaskFeatures(taskParams):
"""
Detect missed features for task
"""

detectFeaturesFuncs = _local.get('detect-features-funcs')
if not detectFeaturesFuncs:
detectFeaturesFuncs = _getFeatureDetectFuncs()
_local['detect-features-funcs'] = detectFeaturesFuncs

features = toListSimple(taskParams.get('features', []))

detected = [ TASK_TARGET_FEATURES_TO_LANG.get(x, '') for x in features ]
features = detected + features
features = [x for x in features if x]

taskParams['features'] = features
for func in detectFeaturesFuncs:
features.extend(func(taskParams))

taskParams['features'] = features = uniqueListWithOrder(features)
return features

def validateTaskFeatures(taskParams):
"""
Check that all task features are valid
"""

features = taskParams['features']
unknown = [x for x in features if x not in SUPPORTED_TASK_FEATURES]
if unknown:
if len(unknown) == 1:
msg = "Feature %r in task %r is not supported." % \
(unknown[0], taskParams['name'])
else:
msg = "Features '%s' in task %r are not supported." % \
(', '.join(unknown), taskParams['name'])
raise ZenMakeConfError(msg)

if not features and taskParams.get('source'):
msg = "There is no way to proccess task %r" % taskParams['name']
msg += " with empty 'features'."
msg += " You need to specify 'features' for this task."
raise ZenMakeConfError(msg)

return features

def loadFeatures(tasksList):
"""
Load modules for selected features. Not existing modules are ignored.
Expand All @@ -256,18 +303,11 @@ def loadFeatures(tasksList):
modules = _local.setdefault('feature-modules', {})
allModuleNames = set(_allModuleNames())

detectFeaturesFuncs = _local.get('detect-features-funcs')
if not detectFeaturesFuncs:
detectFeaturesFuncs = _getFeatureDetectFuncs()
_local['detect-features-funcs'] = detectFeaturesFuncs

# gather unique features
features = set()
for tasks in tasksList:
for taskParams in tasks.values():
features.update(taskParams['features'])
for func in detectFeaturesFuncs:
features.update(func(tasks))

# ignore not existing modules
features &= allModuleNames
Expand Down
12 changes: 4 additions & 8 deletions src/zenmake/zm/features/runcmd_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,13 @@ def handleParam(bconf, param):

return [('run', handleParam)]

def detectFeatures(tasks):
def detectFeatures(taskParams):
"""
Function to detect features in buildconfig.
It's used by zm.features.loadFeatures.
Function to detect missed features in buildconfig.
It should return a list of detected features.
"""

for taskParams in tasks.values():
if 'runcmd' in taskParams['features']:
return ['runcmd']
if 'run' in taskParams:
return ['runcmd']
if 'run' in taskParams and 'runcmd' not in taskParams['features']:
return ['runcmd']

return []
51 changes: 2 additions & 49 deletions src/zenmake/zm/waf/assist.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@
from zm.pyutils import _unicode, _encode
from zm.autodict import AutoDict as _AutoDict
from zm.pathutils import getNodesFromPathsConf
from zm.error import ZenMakeError, ZenMakeConfError
from zm.error import ZenMakePathNotFoundError, ZenMakeDirNotFoundError
from zm.features import TASK_TARGET_FEATURES_TO_LANG, TASK_TARGET_FEATURES
from zm.features import SUPPORTED_TASK_FEATURES, ToolchainVars
from zm.error import ZenMakeError, ZenMakePathNotFoundError, ZenMakeDirNotFoundError
from zm.features import TASK_TARGET_FEATURES, ToolchainVars
from zm import utils, log, version, db, installdirvars

joinpath = os.path.join
Expand Down Expand Up @@ -312,51 +310,6 @@ def convertTaskParamNamesForWaf(taskParams):
if val is not None:
taskParams[wafKey] = val

def detectTaskFeatures(taskParams):
"""
Detect all features for task
Param 'ctx' is used only if an alias exists in features.
"""

features = toListSimple(taskParams.get('features', []))

detected = [ TASK_TARGET_FEATURES_TO_LANG.get(x, '') for x in features ]
features = detected + features

if 'run' in taskParams:
features.append('runcmd')

features = utils.uniqueListWithOrder(features)
if '' in features:
features.remove('')
taskParams['features'] = features

return features

def validateTaskFeatures(taskParams):
"""
Check all features are valid
"""

features = taskParams['features']
unknown = [x for x in features if x not in SUPPORTED_TASK_FEATURES]
if unknown:
if len(unknown) == 1:
msg = "Feature %r in task %r is not supported." % \
(unknown[0], taskParams['name'])
else:
msg = "Features '%s' in task %r are not supported." % \
(', '.join(unknown), taskParams['name'])
raise ZenMakeConfError(msg)

if not features and taskParams.get('source'):
msg = "There is no way to proccess task %r" % taskParams['name']
msg += " with empty 'features'."
msg += " You need to specify 'features' for this task."
raise ZenMakeConfError(msg)

return features

def handleTaskLibPathParams(taskParams):
"""
Make valid 'libpath','stlibpath' for a build task
Expand Down
8 changes: 4 additions & 4 deletions src/zenmake/zm/waf/launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
from zm.constants import WAF_LOCKFILE
from zm import log, utils, cli
from zm.error import ZenMakeConfError
from zm.waf import wscriptimpl, assist
from zm.waf import wscriptimpl
from zm.waf.options import setupOptionVerbose

joinpath = os.path.join
Expand Down Expand Up @@ -53,16 +53,16 @@ def loadFeatureModules(bconfManager):
Load modules for all features from current build tasks.
"""

from zm.features import loadFeatures
from zm.features import detectTaskFeatures, validateTaskFeatures, loadFeatures

tasksList = [bconf.tasks for bconf in bconfManager.configs]

try:
# process all actual features from buildconf(s)
for i, tasks in enumerate(tasksList):
for taskParams in tasks.values():
assist.detectTaskFeatures(taskParams)
assist.validateTaskFeatures(taskParams)
detectTaskFeatures(taskParams)
validateTaskFeatures(taskParams)
except ZenMakeConfError as ex:
if not ex.confpath:
origMsg = ex.msg
Expand Down
4 changes: 2 additions & 2 deletions tests/func_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from zm.buildconf.processing import ConfManager as BuildConfManager
from zm.constants import ZENMAKE_BUILDMETA_FILENAME, PLATFORM, APPNAME
from zm.constants import BUILDOUTNAME, WAF_CONFIG_LOG, PYTHON_EXE
from zm.features import TASK_TARGET_FEATURES
from zm.features import TASK_TARGET_FEATURES, detectTaskFeatures
from zm.buildconf.scheme import KNOWN_CONF_PARAM_NAMES

import tests.common as cmn
Expand Down Expand Up @@ -249,7 +249,7 @@ def getCachedTargetPattern(testSuit, taskName, features):
return result

def handleTaskFeatures(testSuit, taskParams):
assist.detectTaskFeatures(taskParams)
detectTaskFeatures(taskParams)
assert isinstance(taskParams['features'], list)

def getBuildTasks(confManager):
Expand Down
21 changes: 21 additions & 0 deletions tests/test_features.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,24 @@ def testInitModules():
for param in spec:
assert param not in scheme
scheme.update(spec)

def testDetectTaskFeatures():
taskParams = {}
assert features.detectTaskFeatures(taskParams) == []

taskParams = { 'features' : '' }
assert features.detectTaskFeatures(taskParams) == []

for ftype in ('stlib', 'shlib', 'program'):
for lang in ('c', 'cxx'):
fulltype = '%s%s' % (lang, ftype)

taskParams = { 'features' : fulltype }
assert sorted(features.detectTaskFeatures(taskParams)) == sorted([
lang, fulltype
])

taskParams = { 'features' : [lang, fulltype] }
assert sorted(features.detectTaskFeatures(taskParams)) == sorted([
lang, fulltype
])
21 changes: 0 additions & 21 deletions tests/test_waf_assist.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,27 +149,6 @@ def testSetTaskEnvVars():
assert envkey in env
assert env[envkey] == utils.toList(val)

def testDetectTaskFeatures():
taskParams = {}
assert assist.detectTaskFeatures(taskParams) == []

taskParams = { 'features' : '' }
assert assist.detectTaskFeatures(taskParams) == []

for ftype in ('stlib', 'shlib', 'program'):
for lang in ('c', 'cxx'):
fulltype = '%s%s' % (lang, ftype)

taskParams = { 'features' : fulltype }
assert sorted(assist.detectTaskFeatures(taskParams)) == sorted([
lang, fulltype
])

taskParams = { 'features' : [lang, fulltype] }
assert sorted(assist.detectTaskFeatures(taskParams)) == sorted([
lang, fulltype
])

def testHandleTaskIncludesParam():

rootdir = abspath(joinpath(os.getcwd(), 'testroot')) # just any abs path
Expand Down

0 comments on commit c024833

Please sign in to comment.