Added options to version specs and allow specifying a git ref to build instead of a version.
This commit is contained in:
parent
bdf063a16c
commit
1b8d6e175b
58
SConscript
58
SConscript
@ -1,6 +1,7 @@
|
||||
|
||||
import copy
|
||||
import glob
|
||||
import inspect
|
||||
import json
|
||||
import os
|
||||
import psutil
|
||||
@ -11,13 +12,15 @@ import time
|
||||
class _VersionSpec:
|
||||
minimum_version = None
|
||||
maximum_version = None
|
||||
options = {}
|
||||
|
||||
def __init__(self, minimum_version = None, maximum_version = None):
|
||||
def __init__(self, minimum_version = None, maximum_version = None, options = {}):
|
||||
self.minimum_version = minimum_version
|
||||
self.maximum_version = maximum_version
|
||||
self.options = options
|
||||
|
||||
def __str__(self):
|
||||
return f'Min: {self.minimum_version}, Max: {self.maximum_version}'
|
||||
return f'Min: {self.minimum_version}, Max: {self.maximum_version}, Options: {self.options}'
|
||||
|
||||
class _Dependency:
|
||||
name: str = ''
|
||||
@ -53,12 +56,19 @@ def _find_recipe(env: Environment, recipe_name: str):
|
||||
env['SPP_RECIPES'][recipe_name] = recipe
|
||||
return recipe
|
||||
|
||||
def _run_cook(dependency: _Dependency):
|
||||
if not dependency.cook_result:
|
||||
cook_signature = inspect.signature(dependency.recipe.cook)
|
||||
kwargs = {}
|
||||
if 'options' in cook_signature.parameters:
|
||||
kwargs['options'] = dependency.version_spec.options
|
||||
dependency.cook_result = dependency.recipe.cook(env, dependency.version, **kwargs)
|
||||
|
||||
def _cook(env: Environment, recipe_name: str):
|
||||
dependency = env['SPP_DEPENDENCIES'].get(recipe_name)
|
||||
if not dependency:
|
||||
raise Exception(f'Cannot cook {recipe_name} as it was not listed as a dependency.')
|
||||
if not dependency.cook_result:
|
||||
dependency.cook_result = dependency.recipe.cook(env, dependency.version)
|
||||
_run_cook(dependency)
|
||||
return dependency.cook_result
|
||||
|
||||
def _module(env: Environment, file: str):
|
||||
@ -90,8 +100,7 @@ def _inject_dependency(dependency, kwargs: dict, add_sources: bool = True) -> No
|
||||
for inner_dependency in dependency['DEPENDENCIES']:
|
||||
_inject_dependency(inner_dependency, kwargs, False)
|
||||
elif isinstance(dependency, _Dependency):
|
||||
if not dependency.cook_result:
|
||||
dependency.cook_result = dependency.recipe.cook(env, dependency.version)
|
||||
_run_cook(dependency)
|
||||
_inject_list(kwargs, dependency.cook_result, 'CPPPATH')
|
||||
_inject_list(kwargs, dependency.cook_result, 'CPPDEFINES')
|
||||
_inject_list(kwargs, dependency.cook_result, 'LIBPATH')
|
||||
@ -185,8 +194,35 @@ def _error(env: Environment, message: str):
|
||||
print(message, file=sys.stderr)
|
||||
env.Exit(1)
|
||||
|
||||
def _try_merge_dicts(dictA: dict, dictB: dict) -> 'dict|None':
|
||||
result = {}
|
||||
for key, valueA in dictA.items():
|
||||
if key in dictB:
|
||||
valueB = dictB[key]
|
||||
if type(valueA) != type(valueB):
|
||||
return None
|
||||
elif type(valueA) == list:
|
||||
result[key] = valueA + valueB
|
||||
elif type(valueA) == dict:
|
||||
mergedValue = _try_merge_dicts(valueA, valueB)
|
||||
if mergedValue is None:
|
||||
return None
|
||||
result[key] = mergedValue
|
||||
elif valueA != valueB:
|
||||
return None
|
||||
else:
|
||||
result[key] = valueA
|
||||
for key, valueB in dictB.items():
|
||||
if key not in result:
|
||||
result[key] = valueB
|
||||
return result
|
||||
|
||||
|
||||
def _find_common_depenency_version(name: str, versionA: _VersionSpec, versionB: _VersionSpec) -> _VersionSpec:
|
||||
result_version = _VersionSpec()
|
||||
options = _try_merge_dicts(versionA.options, versionB.options)
|
||||
if options is None:
|
||||
return None
|
||||
result_version = _VersionSpec(options=options)
|
||||
if versionA.minimum_version is not None:
|
||||
if versionB.minimum_version is not None:
|
||||
result_version.minimum_version = max(versionA.minimum_version, versionB.minimum_version)
|
||||
@ -209,7 +245,7 @@ def _find_common_depenency_version(name: str, versionA: _VersionSpec, versionB:
|
||||
return result_version
|
||||
|
||||
def _parse_version_spec(version_spec: dict) -> _VersionSpec:
|
||||
return _VersionSpec(version_spec.get('min'), version_spec.get('max'))
|
||||
return _VersionSpec(version_spec.get('min'), version_spec.get('max'), version_spec.get('options', {}))
|
||||
|
||||
def _can_add_dependency(env: Environment, name: str, version_spec: _VersionSpec) -> bool:
|
||||
if name not in env['SPP_DEPENDENCIES']:
|
||||
@ -256,7 +292,11 @@ def _version_matches(version, version_spec: _VersionSpec) -> bool:
|
||||
|
||||
def _find_version(env: Environment, dependency: _Dependency):
|
||||
for update in (False, True):
|
||||
versions = dependency.recipe.versions(env, update=update)
|
||||
versions_signature = inspect.signature(dependency.recipe.versions)
|
||||
kwargs = {}
|
||||
if 'options' in versions_signature.parameters:
|
||||
kwargs['options'] = dependency.version_spec.options
|
||||
versions = dependency.recipe.versions(env, update=update, **kwargs)
|
||||
_sort_versions(versions)
|
||||
for version in versions:
|
||||
if _version_matches(version, dependency.version_spec):
|
||||
|
@ -2,7 +2,6 @@
|
||||
from git import Repo
|
||||
from git.exc import GitError
|
||||
import hashlib
|
||||
import re
|
||||
from SCons.Script import *
|
||||
|
||||
Import('env')
|
||||
@ -56,7 +55,9 @@ def _git_recipe(env: Environment, globals: dict, repo_name, repo_url, cook_fn, v
|
||||
_tag_pattern = _make_callable(tag_pattern)
|
||||
versions_cb = versions and _make_callable(versions)
|
||||
|
||||
def _versions(env: Environment, update: bool = False):
|
||||
def _versions(env: Environment, update: bool = False, options: dict = {}):
|
||||
if 'ref' in options:
|
||||
return [(0, 0, 0)] # no versions if compiling from a branch
|
||||
pattern = _tag_pattern(env)
|
||||
if pattern:
|
||||
tags = env.GitTags(repo_name = _repo_name(env), remote_url = _repo_url(env), force_fetch=update)
|
||||
@ -76,8 +77,10 @@ def _git_recipe(env: Environment, globals: dict, repo_name, repo_url, cook_fn, v
|
||||
def _dependencies(env: Environment, version) -> 'dict':
|
||||
return dependencies
|
||||
|
||||
def _cook(env: Environment, version) -> dict:
|
||||
if tag_fn:
|
||||
def _cook(env: Environment, version, options: dict = {}) -> dict:
|
||||
if 'ref' in options:
|
||||
git_ref = options['ref']
|
||||
elif tag_fn:
|
||||
git_ref = f'refs/tags/{tag_fn(version)}'
|
||||
else:
|
||||
assert ref_fn
|
||||
|
Loading…
x
Reference in New Issue
Block a user