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 copy
|
||||||
import glob
|
import glob
|
||||||
|
import inspect
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import psutil
|
import psutil
|
||||||
@ -11,13 +12,15 @@ import time
|
|||||||
class _VersionSpec:
|
class _VersionSpec:
|
||||||
minimum_version = None
|
minimum_version = None
|
||||||
maximum_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.minimum_version = minimum_version
|
||||||
self.maximum_version = maximum_version
|
self.maximum_version = maximum_version
|
||||||
|
self.options = options
|
||||||
|
|
||||||
def __str__(self):
|
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:
|
class _Dependency:
|
||||||
name: str = ''
|
name: str = ''
|
||||||
@ -53,12 +56,19 @@ def _find_recipe(env: Environment, recipe_name: str):
|
|||||||
env['SPP_RECIPES'][recipe_name] = recipe
|
env['SPP_RECIPES'][recipe_name] = recipe
|
||||||
return 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):
|
def _cook(env: Environment, recipe_name: str):
|
||||||
dependency = env['SPP_DEPENDENCIES'].get(recipe_name)
|
dependency = env['SPP_DEPENDENCIES'].get(recipe_name)
|
||||||
if not dependency:
|
if not dependency:
|
||||||
raise Exception(f'Cannot cook {recipe_name} as it was not listed as a dependency.')
|
raise Exception(f'Cannot cook {recipe_name} as it was not listed as a dependency.')
|
||||||
if not dependency.cook_result:
|
_run_cook(dependency)
|
||||||
dependency.cook_result = dependency.recipe.cook(env, dependency.version)
|
|
||||||
return dependency.cook_result
|
return dependency.cook_result
|
||||||
|
|
||||||
def _module(env: Environment, file: str):
|
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']:
|
for inner_dependency in dependency['DEPENDENCIES']:
|
||||||
_inject_dependency(inner_dependency, kwargs, False)
|
_inject_dependency(inner_dependency, kwargs, False)
|
||||||
elif isinstance(dependency, _Dependency):
|
elif isinstance(dependency, _Dependency):
|
||||||
if not dependency.cook_result:
|
_run_cook(dependency)
|
||||||
dependency.cook_result = dependency.recipe.cook(env, dependency.version)
|
|
||||||
_inject_list(kwargs, dependency.cook_result, 'CPPPATH')
|
_inject_list(kwargs, dependency.cook_result, 'CPPPATH')
|
||||||
_inject_list(kwargs, dependency.cook_result, 'CPPDEFINES')
|
_inject_list(kwargs, dependency.cook_result, 'CPPDEFINES')
|
||||||
_inject_list(kwargs, dependency.cook_result, 'LIBPATH')
|
_inject_list(kwargs, dependency.cook_result, 'LIBPATH')
|
||||||
@ -185,8 +194,35 @@ def _error(env: Environment, message: str):
|
|||||||
print(message, file=sys.stderr)
|
print(message, file=sys.stderr)
|
||||||
env.Exit(1)
|
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:
|
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 versionA.minimum_version is not None:
|
||||||
if versionB.minimum_version is not None:
|
if versionB.minimum_version is not None:
|
||||||
result_version.minimum_version = max(versionA.minimum_version, versionB.minimum_version)
|
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
|
return result_version
|
||||||
|
|
||||||
def _parse_version_spec(version_spec: dict) -> _VersionSpec:
|
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:
|
def _can_add_dependency(env: Environment, name: str, version_spec: _VersionSpec) -> bool:
|
||||||
if name not in env['SPP_DEPENDENCIES']:
|
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):
|
def _find_version(env: Environment, dependency: _Dependency):
|
||||||
for update in (False, True):
|
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)
|
_sort_versions(versions)
|
||||||
for version in versions:
|
for version in versions:
|
||||||
if _version_matches(version, dependency.version_spec):
|
if _version_matches(version, dependency.version_spec):
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
from git import Repo
|
from git import Repo
|
||||||
from git.exc import GitError
|
from git.exc import GitError
|
||||||
import hashlib
|
import hashlib
|
||||||
import re
|
|
||||||
from SCons.Script import *
|
from SCons.Script import *
|
||||||
|
|
||||||
Import('env')
|
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)
|
_tag_pattern = _make_callable(tag_pattern)
|
||||||
versions_cb = versions and _make_callable(versions)
|
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)
|
pattern = _tag_pattern(env)
|
||||||
if pattern:
|
if pattern:
|
||||||
tags = env.GitTags(repo_name = _repo_name(env), remote_url = _repo_url(env), force_fetch=update)
|
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':
|
def _dependencies(env: Environment, version) -> 'dict':
|
||||||
return dependencies
|
return dependencies
|
||||||
|
|
||||||
def _cook(env: Environment, version) -> dict:
|
def _cook(env: Environment, version, options: dict = {}) -> dict:
|
||||||
if tag_fn:
|
if 'ref' in options:
|
||||||
|
git_ref = options['ref']
|
||||||
|
elif tag_fn:
|
||||||
git_ref = f'refs/tags/{tag_fn(version)}'
|
git_ref = f'refs/tags/{tag_fn(version)}'
|
||||||
else:
|
else:
|
||||||
assert ref_fn
|
assert ref_fn
|
||||||
|
Loading…
x
Reference in New Issue
Block a user