Clean up SConstruct global namespace
This commit is contained in:
parent
7bb3a5605b
commit
63c5b5f9ea
148
SConstruct
148
SConstruct
|
@ -2836,7 +2836,7 @@ class DXXCommon(LazyObjectConstructor):
|
|||
return ['%s%s%s' % (p, '_' if p else '', name) for p in prefix]
|
||||
def __init__(self,program=None):
|
||||
self._program = program
|
||||
def register_variables(self,prefix,variables):
|
||||
def register_variables(self,prefix,variables,filtered_help):
|
||||
self.known_variables = []
|
||||
append_known_variable = self.known_variables.append
|
||||
add_variable = variables.Add
|
||||
|
@ -3669,7 +3669,7 @@ class DXXProgram(DXXCommon):
|
|||
extend(self.platform_settings.platform_objects)
|
||||
return value
|
||||
|
||||
def __init__(self,prefix,variables):
|
||||
def __init__(self,prefix,variables,filtered_help):
|
||||
self.variables = variables
|
||||
self._argument_prefix_list = prefix
|
||||
DXXCommon.__init__(self)
|
||||
|
@ -3679,7 +3679,7 @@ class DXXProgram(DXXCommon):
|
|||
extra_version += ' ' + git_describe_version
|
||||
print('===== %s %s =====' % (self.PROGRAM_NAME, extra_version))
|
||||
self.user_settings = user_settings = self.UserSettings(program=self)
|
||||
user_settings.register_variables(prefix=prefix, variables=variables)
|
||||
user_settings.register_variables(prefix, variables, filtered_help)
|
||||
|
||||
def init(self,substenv):
|
||||
self.user_settings.read_variables(self.variables, substenv)
|
||||
|
@ -3690,6 +3690,7 @@ class DXXProgram(DXXCommon):
|
|||
self.prepare_environment(archive)
|
||||
self.process_user_settings()
|
||||
self.register_program()
|
||||
return self.variables.GenerateHelpText(self.env)
|
||||
|
||||
def prepare_environment(self,archive,
|
||||
_DXX_VERSION_SEQ=('DXX_VERSION_SEQ', ','.join([str(VERSION_MAJOR), str(VERSION_MINOR), str(VERSION_MICRO)]))
|
||||
|
@ -3727,30 +3728,30 @@ class DXXProgram(DXXCommon):
|
|||
self._register_install(self.shortname, exe_target)
|
||||
|
||||
@classmethod
|
||||
def compute_extra_version(cls):
|
||||
def compute_extra_version(cls,_Git_spcall=Git.spcall):
|
||||
c = cls._computed_extra_version
|
||||
if c is None:
|
||||
s = ds = None
|
||||
v = cls._compute_extra_version()
|
||||
if v:
|
||||
s = Git.spcall(['status', '--short', '--branch'])
|
||||
ds = Git.spcall(['diff', '--stat', 'HEAD'])
|
||||
s = _Git_spcall(['status', '--short', '--branch'])
|
||||
ds = _Git_spcall(['diff', '--stat', 'HEAD'])
|
||||
cls._computed_extra_version = c = (v or '', s, ds)
|
||||
return c
|
||||
|
||||
@staticmethod
|
||||
def _compute_extra_version():
|
||||
def _compute_extra_version(_Git_pcall=Git.pcall):
|
||||
try:
|
||||
g = Git.pcall(['describe', '--tags', '--abbrev=12'], stderr=subprocess.PIPE)
|
||||
g = _Git_pcall(['describe', '--tags', '--abbrev=12'], stderr=subprocess.PIPE)
|
||||
except OSError as e:
|
||||
if e.errno == errno.ENOENT:
|
||||
return None
|
||||
raise
|
||||
if g.returncode:
|
||||
return None
|
||||
c = Git.pcall(['diff', '--quiet', '--cached']).returncode
|
||||
d = Git.pcall(['diff', '--quiet']).returncode
|
||||
return g.out.split('\n')[0] + ('+' if c else '') + ('*' if d else '')
|
||||
return None \
|
||||
if g.returncode else \
|
||||
(g.out.split('\n')[0] + \
|
||||
('*' if _Git_pcall(['diff', '--quiet']).returncode else '') + \
|
||||
('+' if _Git_pcall(['diff', '--quiet', '--cached']).returncode else ''))
|
||||
|
||||
def _register_program(self,exe_target):
|
||||
env = self.env
|
||||
|
@ -3843,9 +3844,6 @@ class DXXProgram(DXXCommon):
|
|||
icon_file=os.path.join(cocoa, '%s-rebirth.icns' % dxxstr),
|
||||
resources=[[os.path.join(self.srcdir, s), s] for s in ['English.lproj/InfoPlist.strings']])
|
||||
|
||||
def GenerateHelpText(self):
|
||||
return self.variables.GenerateHelpText(self.env)
|
||||
|
||||
class D1XProgram(DXXProgram):
|
||||
PROGRAM_NAME = 'D1X-Rebirth'
|
||||
target = \
|
||||
|
@ -3924,42 +3922,71 @@ class D2XProgram(DXXProgram):
|
|||
value.extend(__get_dsx_objects_editor(self))
|
||||
return value
|
||||
|
||||
variables = Variables([v for (k,v) in ARGLIST if k == 'site'] or ['site-local.py'], ARGUMENTS)
|
||||
filtered_help = FilterHelpText()
|
||||
variables.FormatVariableHelpText = filtered_help.FormatVariableHelpText
|
||||
def _filter_duplicate_prefix_elements(e,s):
|
||||
r = e not in s
|
||||
s.add(e)
|
||||
return r
|
||||
def register_program(program,other_program):
|
||||
def register_program(program,other_program,variables,filtered_help,_itertools_product=itertools.product):
|
||||
s = program.shortname
|
||||
l = [v for (k,v) in ARGLIST if k == s or k == 'dxx'] or [other_program.shortname not in ARGUMENTS]
|
||||
# Fallback case: build the regular configuration.
|
||||
# Legacy case: build one configuration.
|
||||
if len(l) == 1:
|
||||
try:
|
||||
r = int(l[0])
|
||||
if not int(l[0]):
|
||||
# If the user specifies an integer that evaluates to
|
||||
# False, this configuration is disabled. This allows
|
||||
# the user to build only one game, instead of both.
|
||||
return []
|
||||
# Coerce to an empty string, then reuse the case for stacked
|
||||
# profiles. This is slightly less efficient, but reduces
|
||||
# maintenance by keeping avoiding multiple sites that call
|
||||
# program().
|
||||
l = ['']
|
||||
except ValueError:
|
||||
# If not an integer, treat this as a configuration profile.
|
||||
pass
|
||||
else:
|
||||
return [program((s,''), variables)] if r else []
|
||||
r = []
|
||||
append = r.append
|
||||
seen = set()
|
||||
for e in l:
|
||||
for prefix in itertools.product(*[v.split('+') for v in e.split(',')]):
|
||||
add_seen = seen.add
|
||||
for prefix in _itertools_product(*[
|
||||
v.split('+') \
|
||||
for e in l \
|
||||
for v in e.split(',')
|
||||
]):
|
||||
duplicates = set()
|
||||
prefix = tuple(p for p in prefix if _filter_duplicate_prefix_elements(p, duplicates))
|
||||
# This would be simpler if set().add(V) returned the result
|
||||
# of `V not in self`, as seen before the add. Instead, it
|
||||
# always returns None.
|
||||
#
|
||||
# Test for presence, then add if not present. add() always
|
||||
# returns None, which coerces to False in boolean context.
|
||||
# This is slightly inefficient since we know the right hand
|
||||
# side will always be True after negation, so we ought to be
|
||||
# able to skip testing its truth value. However, the
|
||||
# alternative is to use a wrapper function that checks
|
||||
# membership, adds the value, and returns the result of the
|
||||
# test. Calling such a function is even less efficient.
|
||||
#
|
||||
# In most cases, this loop is not run often enough for the
|
||||
# efficiency to matter.
|
||||
prefix = tuple([
|
||||
p for p in prefix \
|
||||
if (p not in duplicates and not duplicates.add(p))
|
||||
])
|
||||
if prefix in seen:
|
||||
continue
|
||||
seen.add(prefix)
|
||||
prefix = tuple('%s%s%s' % (s, '_' if p else '', p) for p in prefix) + prefix
|
||||
r.append(program(prefix, variables))
|
||||
add_seen(prefix)
|
||||
append(program(tuple(('%s%s%s' % (s, '_' if p else '', p) for p in prefix)) + prefix, variables, filtered_help))
|
||||
return r
|
||||
d1x = register_program(D1XProgram, D2XProgram)
|
||||
d2x = register_program(D2XProgram, D1XProgram)
|
||||
|
||||
def main(register_program):
|
||||
variables = Variables([v for k, v in ARGLIST if k == 'site'] or ['site-local.py'], ARGUMENTS)
|
||||
filtered_help = FilterHelpText()
|
||||
dxx = \
|
||||
register_program(D1XProgram, D2XProgram, variables, filtered_help) + \
|
||||
register_program(D2XProgram, D1XProgram, variables, filtered_help)
|
||||
substenv = SCons.Environment.SubstitutionEnvironment()
|
||||
variables.FormatVariableHelpText = filtered_help.FormatVariableHelpText
|
||||
variables.Update(substenv)
|
||||
# show some help when running scons -h
|
||||
h = """DXX-Rebirth, SConstruct file help:
|
||||
Help("""DXX-Rebirth, SConstruct file help:
|
||||
|
||||
Type 'scons' to build the binary.
|
||||
Type 'scons install' to build (if it hasn't been done) and install.
|
||||
|
@ -3971,29 +3998,30 @@ h = """DXX-Rebirth, SConstruct file help:
|
|||
d2x=[0/1] Disable/enable D2X-Rebirth
|
||||
d2x=prefix-list Enable D2X-Rebirth with prefix-list modifiers
|
||||
dxx=VALUE Equivalent to d1x=VALUE d2x=VALUE
|
||||
"""
|
||||
substenv = SCons.Environment.SubstitutionEnvironment()
|
||||
variables.Update(substenv)
|
||||
dxx = d1x + d2x
|
||||
for d in dxx:
|
||||
d.init(substenv)
|
||||
h += '%s.%d:\n%s' % (d.PROGRAM_NAME, d.program_instance, d.GenerateHelpText())
|
||||
Help(h)
|
||||
unknown = variables.UnknownVariables()
|
||||
# Delete known unregistered variables
|
||||
unknown.pop('d1x', None)
|
||||
unknown.pop('d2x', None)
|
||||
unknown.pop('dxx', None)
|
||||
unknown.pop('site', None)
|
||||
ignore_unknown_variables = unknown.pop('ignore_unknown_variables', '0')
|
||||
if dxx and unknown:
|
||||
try:
|
||||
ignore_unknown_variables = int(ignore_unknown_variables)
|
||||
except ValueError:
|
||||
ignore_unknown_variables = False
|
||||
if not ignore_unknown_variables:
|
||||
raise SCons.Errors.StopError('Unknown values specified on command line.' +
|
||||
""" + \
|
||||
''.join(['%s.%d:\n%s' % (d.PROGRAM_NAME, d.program_instance, d.init(substenv)) for d in dxx])
|
||||
)
|
||||
if not dxx:
|
||||
return
|
||||
unknown = variables.UnknownVariables()
|
||||
# Delete known unregistered variables
|
||||
unknown.pop('d1x', None)
|
||||
unknown.pop('d2x', None)
|
||||
unknown.pop('dxx', None)
|
||||
unknown.pop('site', None)
|
||||
ignore_unknown_variables = unknown.pop('ignore_unknown_variables', '0')
|
||||
if unknown:
|
||||
# Protect user from misspelled options by reporting an error.
|
||||
# Provide a way for the user to override the check, which might
|
||||
# be necessary if the user is setting an option that is only
|
||||
# understood by older (or newer) versions of SConstruct.
|
||||
try:
|
||||
ignore_unknown_variables = int(ignore_unknown_variables)
|
||||
except ValueError:
|
||||
ignore_unknown_variables = False
|
||||
if not ignore_unknown_variables:
|
||||
raise SCons.Errors.StopError('Unknown values specified on command line.' +
|
||||
''.join(['\n\t%s' % k for k in unknown.keys()]) +
|
||||
'\nRemove unknown values or set ignore_unknown_variables=1 to continue.')
|
||||
|
||||
#EOF
|
||||
main(register_program)
|
||||
|
|
Loading…
Reference in a new issue