def prepare_task(self, config=None, args=None, targets=None, build_graph=None, build_file_parser=None, address_mapper=None, console_outstream=None, workspace=None): """Prepares a Task for execution. task_type: The class of the Task to create. config: An optional string representing the contents of a pants.ini config. args: optional list of command line flags, these should be prefixed with '--test-'. targets: optional list of Target objects passed on the command line. Returns a new Task ready to execute. """ task_type = self.task_type() assert issubclass( task_type, Task), 'task_type must be a Task subclass, got %s' % task_type config = create_config(config or '') workdir = os.path.join(config.getdefault('pants_workdir'), 'test', task_type.__name__) bootstrap_options = OptionsBootstrapper().get_bootstrap_options() options = Options(env={}, config=config, known_scopes=['', 'test'], args=args or []) # A lot of basic code uses these options, so always register them. register_bootstrap_options(options.register_global) # We need to wrap register_global (can't set .bootstrap attr on the bound instancemethod). def register_global_wrapper(*args, **kwargs): return options.register_global(*args, **kwargs) register_global_wrapper.bootstrap = bootstrap_options.for_global_scope( ) register_global_options(register_global_wrapper) task_type.options_scope = 'test' task_type.register_options_on_scope(options) run_tracker = create_run_tracker() context = Context(config, options, run_tracker, targets or [], build_graph=build_graph, build_file_parser=build_file_parser, address_mapper=address_mapper, console_outstream=console_outstream, workspace=workspace) return task_type(context, workdir)
def register_options(self): # Add a 'bootstrap' attribute to the register function, so that register_global can # access the bootstrap option values. def register_global(*args, **kwargs): return self.options.register_global(*args, **kwargs) register_global.bootstrap = self.options.bootstrap_option_values() register_global_options(register_global) for goal in Goal.all(): goal.register_options(self.options)
def gen_glopts_reference_data(): option_parser = Parser(env={}, config={}, scope='', help_request=None, parent_parser=None) def register(*args, **kwargs): option_parser.register(*args, **kwargs) register.bootstrap = bootstrap_option_values() register_bootstrap_options(register, buildroot='<buildroot>') register_global_options(register) argparser = option_parser._help_argparser return oref_template_data_from_options(Options.GLOBAL_SCOPE, argparser)
def register_options(self): # Add a 'bootstrap' attribute to the register function, so that register_global can # access the bootstrap option values. def register_global(*args, **kwargs): return self.new_options.register_global(*args, **kwargs) register_global.bootstrap = self.new_options.bootstrap_option_values() register_global_options(register_global) for goal in Goal.all(): goal.register_options(self.new_options)
def prepare_task(self, config=None, args=None, targets=None, build_graph=None, build_file_parser=None, address_mapper=None, console_outstream=None, workspace=None): """Prepares a Task for execution. task_type: The class of the Task to create. config: An optional string representing the contents of a pants.ini config. args: optional list of command line flags, these should be prefixed with '--test-'. targets: optional list of Target objects passed on the command line. Returns a new Task ready to execute. """ task_type = self.task_type() assert issubclass(task_type, Task), 'task_type must be a Task subclass, got %s' % task_type config = create_config(config or '') workdir = os.path.join(config.getdefault('pants_workdir'), 'test', task_type.__name__) bootstrap_options = OptionsBootstrapper().get_bootstrap_options() options = Options(env={}, config=config, known_scopes=['', 'test'], args=args or []) # A lot of basic code uses these options, so always register them. register_bootstrap_options(options.register_global) # We need to wrap register_global (can't set .bootstrap attr on the bound instancemethod). def register_global_wrapper(*args, **kwargs): return options.register_global(*args, **kwargs) register_global_wrapper.bootstrap = bootstrap_options.for_global_scope() register_global_options(register_global_wrapper) task_type.options_scope = 'test' task_type.register_options_on_scope(options) run_tracker = create_run_tracker() context = Context(config, options, run_tracker, targets or [], build_graph=build_graph, build_file_parser=build_file_parser, address_mapper=address_mapper, console_outstream=console_outstream, workspace=workspace) return task_type(context, workdir)
def register_subsystem_options(self, global_subsystems): # Standalone global options. register_global_options(self.options.registration_function_for_global_scope()) # Options for global-level subsystems. for subsystem_type in global_subsystems: subsystem_type.register_options_on_scope(self.options, Options.GLOBAL_SCOPE) # TODO(benjy): Should Goals be subsystems? Or should the entire goal-running mechanism # be a subsystem? for goal in Goal.all(): # Register task options (including per-task subsystem options). goal.register_options(self.options)
def register_options(self, subsystems): # Standalone global options. register_global_options(self.options.registration_function_for_global_scope()) # Options for subsystems. for subsystem in subsystems: subsystem.register_options_on_scope(self.options) # TODO(benjy): Should Goals be subsystems? Or should the entire goal-running mechanism # be a subsystem? for goal in Goal.all(): # Register task options. goal.register_options(self.options)
def register_options(self): # Add a 'bootstrap' attribute to the register function, so that register_global can # access the bootstrap option values. def register_global(*args, **kwargs): return self.options.register_global(*args, **kwargs) register_global.bootstrap = self.options.bootstrap_option_values() register_global_options(register_global) # This is the first case we have of non-task, non-global options. # The current implementation special-cases RunTracker, and is temporary. # In the near future it will be replaced with a 'Subsystem' abstraction. # But for now this is useful for kicking the tires. def register_run_tracker(*args, **kwargs): self.options.register('run-tracker', *args, **kwargs) RunTracker.register_options(register_run_tracker) for goal in Goal.all(): goal.register_options(self.options)
def context(self, for_task_types=None, options=None, target_roots=None, console_outstream=None, workspace=None): for_task_types = for_task_types or [] options = options or {} option_values = defaultdict(dict) registered_global_subsystems = set() bootstrap_option_values = None # We fill these in after registering bootstrap options. # We provide our own test-only registration implementation, bypassing argparse. # When testing we set option values directly, so we don't care about cmd-line flags, config, # env vars etc. In fact, for test isolation we explicitly don't want to look at those. # All this does is make the names available in code, with the default values. # Individual tests can then override the option values they care about. def register_func(on_scope): def register(*rargs, **rkwargs): scoped_options = option_values[on_scope] default = rkwargs.get('default') if default is None and rkwargs.get('action') == 'append': default = [] for flag_name in rargs: option_name = flag_name.lstrip('-').replace('-', '_') scoped_options[option_name] = default register.bootstrap = bootstrap_option_values register.scope = on_scope return register # TODO: This sequence is a bit repetitive of the real registration sequence. # Register bootstrap options and grab their default values for use in subsequent registration. register_bootstrap_options(register_func(Options.GLOBAL_SCOPE), self.build_root) bootstrap_option_values = create_option_values(copy.copy(option_values[Options.GLOBAL_SCOPE])) # Now register the remaining global scope options. register_global_options(register_func(Options.GLOBAL_SCOPE)) # Now register task and subsystem options for relevant tasks. for task_type in for_task_types: scope = task_type.options_scope if scope is None: raise TaskError('You must set a scope on your task type before using it in tests.') task_type.register_options(register_func(scope)) for subsystem in (set(task_type.global_subsystems()) | self._build_configuration.subsystem_types()): if subsystem not in registered_global_subsystems: subsystem.register_options(register_func(subsystem.qualify_scope(Options.GLOBAL_SCOPE))) registered_global_subsystems.add(subsystem) for subsystem in task_type.task_subsystems(): subsystem.register_options(register_func(subsystem.qualify_scope(scope))) # Now default option values override with any caller-specified values. # TODO(benjy): Get rid of the options arg, and require tests to call set_options. for scope, opts in options.items(): for key, val in opts.items(): option_values[scope][key] = val for scope, opts in self.options.items(): for key, val in opts.items(): option_values[scope][key] = val # Make inner scopes inherit option values from their enclosing scopes. # Iterating in sorted order guarantees that we see outer scopes before inner scopes, # and therefore only have to inherit from our immediately enclosing scope. for scope in sorted(option_values.keys()): if scope != Options.GLOBAL_SCOPE: enclosing_scope = scope.rpartition('.')[0] opts = option_values[scope] for key, val in option_values.get(enclosing_scope, {}).items(): if key not in opts: # Inner scope values override the inherited ones. opts[key] = val context = create_context(options=option_values, target_roots=target_roots, build_graph=self.build_graph, build_file_parser=self.build_file_parser, address_mapper=self.address_mapper, console_outstream=console_outstream, workspace=workspace) Subsystem._options = context.options return context
def register_options(self): register_global_options(self.new_options.register_global) for goal in Goal.all(): goal.register_options(self.new_options)