Example #1
0
    def complete_scopes(
            cls,
            scope_infos: Iterable[ScopeInfo]) -> FrozenOrderedSet[ScopeInfo]:
        """Expand a set of scopes to include all enclosing scopes.

        E.g., if the set contains `foo.bar.baz`, ensure that it also contains `foo.bar` and `foo`.

        Also adds any deprecated scopes.
        """
        ret: OrderedSet[ScopeInfo] = OrderedSet()
        original_scopes: Dict[str, ScopeInfo] = {}
        for si in sorted(scope_infos, key=lambda si: si.scope):
            ret.add(si)
            if si.scope in original_scopes:
                raise cls.DuplicateScopeError(
                    "Scope `{}` claimed by {}, was also claimed by {}.".format(
                        si.scope, si, original_scopes[si.scope]))
            original_scopes[si.scope] = si
            if si.deprecated_scope:
                ret.add(
                    ScopeInfo(si.deprecated_scope, si.category,
                              si.optionable_cls))
                original_scopes[si.deprecated_scope] = si

        # TODO: Once scope name validation is enforced (so there can be no dots in scope name
        # components) we can replace this line with `for si in scope_infos:`, because it will
        # not be possible for a deprecated_scope to introduce any new intermediate scopes.
        for si in copy.copy(ret):
            for scope in all_enclosing_scopes(si.scope, allow_global=False):
                if scope not in original_scopes:
                    ret.add(ScopeInfo(scope, ScopeInfo.INTERMEDIATE))
        return FrozenOrderedSet(ret)
Example #2
0
def known_scope_infos() -> list[ScopeInfo]:
    return [
        ScopeInfo("check", is_goal=True),
        ScopeInfo("test", is_goal=True),
        ScopeInfo("jvm", is_goal=False),
        ScopeInfo("reporting", is_goal=False),
    ]
Example #3
0
 def known_scope_infos(cls):
   """Yields ScopeInfo for all known scopes for this task, in no particular order."""
   # The task's own scope.
   yield ScopeInfo(cls.options_scope, ScopeInfo.TASK)
   # The scopes of any task-specific subsystems it uses.
   for subsystem in cls.task_subsystems():
     yield ScopeInfo(subsystem.subscope(cls.options_scope), ScopeInfo.TASK_SUBSYSTEM)
Example #4
0
    def test_options_pantsrc_files(self) -> None:
        def create_options_bootstrapper(*config_paths: str) -> OptionsBootstrapper:
            return OptionsBootstrapper.create(
                env={},
                args=[f"--pantsrc-files={cp}" for cp in config_paths],
                allow_pantsrc=True,
            )

        with temporary_file(binary_mode=False) as fp:
            fp.write(
                dedent(
                    """
                    [resolver]
                    resolver = "coursier"
                    """
                )
            )
            fp.close()
            bootstrapped_options = create_options_bootstrapper(fp.name)
            opts_single_config = bootstrapped_options.full_options_for_scopes(
                known_scope_infos=[
                    ScopeInfo(""),
                    ScopeInfo("resolver"),
                ]
            )
            opts_single_config.register("", "--pantsrc-files", type=list)
            opts_single_config.register("resolver", "--resolver")
            self.assertEqual("coursier", opts_single_config.for_scope("resolver").resolver)
Example #5
0
    def complete_scopes(cls, scope_infos):
        """Expand a set of scopes to include all enclosing scopes.

    E.g., if the set contains `foo.bar.baz`, ensure that it also contains `foo.bar` and `foo`.

    Also adds any deprecated scopes.
    """
        ret = {GlobalOptionsRegistrar.get_scope_info()}
        original_scopes = set()
        for si in scope_infos:
            ret.add(si)
            original_scopes.add(si.scope)
            if si.deprecated_scope:
                ret.add(
                    ScopeInfo(si.deprecated_scope, si.category,
                              si.optionable_cls))
                original_scopes.add(si.deprecated_scope)

        # TODO: Once scope name validation is enforced (so there can be no dots in scope name
        # components) we can replace this line with `for si in scope_infos:`, because it will
        # not be possible for a deprecated_scope to introduce any new intermediate scopes.
        for si in copy.copy(ret):
            scope = si.scope
            while scope != '':
                if scope not in original_scopes:
                    ret.add(ScopeInfo(scope, ScopeInfo.INTERMEDIATE))
                scope = enclosing_scope(scope)
        return ret
    def test_create_bootstrapped_options(self):
        # Check that we can set a bootstrap option from a cmd-line flag and have that interpolate
        # correctly into regular config.
        with temporary_file() as fp:
            fp.write(
                dedent("""
      [foo]
      bar: %(pants_workdir)s/baz

      [fruit]
      apple: %(pants_supportdir)s/banana
      """))
            fp.close()
            bootstrapper = OptionsBootstrapper(
                env={'PANTS_SUPPORTDIR': '/pear'},
                configpath=fp.name,
                args=['--pants-workdir=/qux'])
            opts = bootstrapper.get_full_options(known_scope_infos=[
                ScopeInfo('', ScopeInfo.GLOBAL),
                ScopeInfo('foo', ScopeInfo.TASK),
                ScopeInfo('fruit', ScopeInfo.TASK)
            ])
            opts.register(
                '',
                '--pants-workdir')  # So we don't choke on it on the cmd line.
            opts.register('foo', '--bar')
            opts.register('fruit', '--apple')
        self.assertEquals('/qux/baz', opts.for_scope('foo').bar)
        self.assertEquals('/pear/banana', opts.for_scope('fruit').apple)
Example #7
0
  def complete_scopes(cls, scope_infos):
    """Expand a set of scopes to include all enclosing scopes.

    E.g., if the set contains `foo.bar.baz`, ensure that it also contains `foo.bar` and `foo`.

    Also adds any deprecated scopes.
    """
    ret = {GlobalOptionsRegistrar.get_scope_info()}
    original_scopes = dict()
    for si in scope_infos:
      ret.add(si)
      if si.scope in original_scopes:
        raise cls.DuplicateScopeError('Scope `{}` claimed by {}, was also claimed by {}.'.format(
            si.scope, si, original_scopes[si.scope]
          ))
      original_scopes[si.scope] = si
      if si.deprecated_scope:
        ret.add(ScopeInfo(si.deprecated_scope, si.category, si.optionable_cls))
        original_scopes[si.deprecated_scope] = si

    # TODO: Once scope name validation is enforced (so there can be no dots in scope name
    # components) we can replace this line with `for si in scope_infos:`, because it will
    # not be possible for a deprecated_scope to introduce any new intermediate scopes.
    for si in copy.copy(ret):
      for scope in all_enclosing_scopes(si.scope, allow_global=False):
        if scope not in original_scopes:
          ret.add(ScopeInfo(scope, ScopeInfo.INTERMEDIATE))
    return ret
Example #8
0
    def test_create_bootstrapped_options(self) -> None:
        # Check that we can set a bootstrap option from a cmd-line flag and have that interpolate
        # correctly into regular config.
        with temporary_file(binary_mode=False) as fp:
            fp.write(
                dedent("""
                    [foo]
                    bar: %(pants_workdir)s/baz

                    [fruit]
                    apple: %(pants_supportdir)s/banana
                    """))
            fp.close()
            args = ["--pants-workdir=/qux"] + self._config_path(fp.name)
            bootstrapper = OptionsBootstrapper.create(
                env={"PANTS_SUPPORTDIR": "/pear"}, args=args)
            opts = bootstrapper.get_full_options(known_scope_infos=[
                ScopeInfo("", ScopeInfo.GLOBAL),
                ScopeInfo("foo", ScopeInfo.TASK),
                ScopeInfo("fruit", ScopeInfo.TASK),
            ])
            # So we don't choke on these on the cmd line.
            opts.register("", "--pants-workdir")
            opts.register("", "--pants-config-files")

            opts.register("foo", "--bar")
            opts.register("fruit", "--apple")
        self.assertEqual("/qux/baz", opts.for_scope("foo").bar)
        self.assertEqual("/pear/banana", opts.for_scope("fruit").apple)
Example #9
0
def known_scope_infos() -> list[ScopeInfo]:
    return [
        ScopeInfo("check", is_goal=True),
        ScopeInfo("test", is_goal=True),
        ScopeInfo("jvm", is_goal=False),
        ScopeInfo("reporting", is_goal=False),
        # TODO: move help related tests closer to `pants.goal.help` to avoid this cludge.
        *(goal.get_scope_info() for goal in builtin_goals()),
    ]
Example #10
0
    def test_full_options_caching(self) -> None:
        with temporary_file_path() as config:
            args = self._config_path(config)
            bootstrapper = OptionsBootstrapper.create(env={}, args=args, allow_pantsrc=False)

            opts1 = bootstrapper.full_options_for_scopes(
                known_scope_infos=[
                    ScopeInfo(""),
                    ScopeInfo("foo"),
                ]
            )
            opts2 = bootstrapper.full_options_for_scopes(
                known_scope_infos=[
                    ScopeInfo("foo"),
                    ScopeInfo(""),
                ]
            )
            assert opts1 is opts2

            opts3 = bootstrapper.full_options_for_scopes(
                known_scope_infos=[
                    ScopeInfo(""),
                    ScopeInfo("foo"),
                    ScopeInfo(""),
                ]
            )
            assert opts1 is opts3

            opts4 = bootstrapper.full_options_for_scopes(known_scope_infos=[ScopeInfo("")])
            assert opts1 is not opts4

            opts5 = bootstrapper.full_options_for_scopes(known_scope_infos=[ScopeInfo("")])
            assert opts4 is opts5
            assert opts1 is not opts5
Example #11
0
    def test_full_options_caching(self) -> None:
        with temporary_file_path() as config:
            args = self._config_path(config)
            bootstrapper = OptionsBootstrapper.create(env={}, args=args)

            opts1 = bootstrapper.get_full_options(known_scope_infos=[
                ScopeInfo("", ScopeInfo.GLOBAL),
                ScopeInfo("foo", ScopeInfo.TASK),
            ])
            opts2 = bootstrapper.get_full_options(known_scope_infos=[
                ScopeInfo("foo", ScopeInfo.TASK),
                ScopeInfo("", ScopeInfo.GLOBAL),
            ])
            assert opts1 is opts2

            opts3 = bootstrapper.get_full_options(known_scope_infos=[
                ScopeInfo("", ScopeInfo.GLOBAL),
                ScopeInfo("foo", ScopeInfo.TASK),
                ScopeInfo("", ScopeInfo.GLOBAL),
            ])
            assert opts1 is opts3

            opts4 = bootstrapper.get_full_options(
                known_scope_infos=[ScopeInfo("", ScopeInfo.GLOBAL)])
            assert opts1 is not opts4

            opts5 = bootstrapper.get_full_options(
                known_scope_infos=[ScopeInfo("", ScopeInfo.GLOBAL)])
            assert opts4 is opts5
            assert opts1 is not opts5
    def test_full_options_caching(self):
        with temporary_file_path() as config:
            bootstrapper = OptionsBootstrapper(env={},
                                               configpath=config,
                                               args=[])

            opts1 = bootstrapper.get_full_options(known_scope_infos=[
                ScopeInfo('', ScopeInfo.GLOBAL),
                ScopeInfo('foo', ScopeInfo.TASK)
            ])
            opts2 = bootstrapper.get_full_options(known_scope_infos=[
                ScopeInfo('foo', ScopeInfo.TASK),
                ScopeInfo('', ScopeInfo.GLOBAL)
            ])
            self.assertIs(opts1, opts2)

            opts3 = bootstrapper.get_full_options(known_scope_infos=[
                ScopeInfo('', ScopeInfo.GLOBAL),
                ScopeInfo('foo', ScopeInfo.TASK),
                ScopeInfo('', ScopeInfo.GLOBAL)
            ])
            self.assertIs(opts1, opts3)

            opts4 = bootstrapper.get_full_options(
                known_scope_infos=[ScopeInfo('', ScopeInfo.GLOBAL)])
            self.assertIsNot(opts1, opts4)

            opts5 = bootstrapper.get_full_options(
                known_scope_infos=[ScopeInfo('', ScopeInfo.GLOBAL)])
            self.assertIs(opts4, opts5)
            self.assertIsNot(opts1, opts5)
Example #13
0
 def test_complete_scopes(self):
   _global = ScopeInfo.for_global_scope()
   self.assertEquals({_global, intermediate('foo'), intermediate('foo.bar'), task('foo.bar.baz')},
                     Options.complete_scopes({task('foo.bar.baz')}))
   self.assertEquals({_global, intermediate('foo'), intermediate('foo.bar'), task('foo.bar.baz')},
                     Options.complete_scopes({ScopeInfo.for_global_scope(), task('foo.bar.baz')}))
   self.assertEquals({_global, goal('foo'), intermediate('foo.bar'), task('foo.bar.baz')},
                     Options.complete_scopes({goal('foo'), task('foo.bar.baz')}))
   self.assertEquals({_global, intermediate('foo'), intermediate('foo.bar'), task('foo.bar.baz'),
                      intermediate('qux'), task('qux.quux')},
                     Options.complete_scopes({task('foo.bar.baz'), task('qux.quux')}))
Example #14
0
                def known_scope_infos(cls):
                    """Yields ScopeInfos for all known scopes for this task, in no particular order."""
                    # We need this because task.py initializes a cache factory for every task type,
                    # even if it's never used. This is slightly icky, but is better than forcing tasks
                    # to explicitly call a cache setup method. And we want to kill GroupTask anyway.
                    yield ScopeInfo(cls.options_scope, ScopeInfo.TASK)
                    for subsystem in cls.task_subsystems():
                        yield ScopeInfo(subsystem.subscope(cls.options_scope),
                                        ScopeInfo.TASK_SUBSYSTEM)

                    for member_type in cls._member_types():
                        for scope in member_type.known_scope_infos():
                            yield scope
Example #15
0
 def get_scope_info(cls):
     """Returns a ScopeInfo instance representing this Optionable's options scope."""
     if cls.options_scope is None or cls.options_scope_category is None:
         raise OptionsError(
             '{} must set options_scope and options_scope_category.'.format(
                 cls.__name__))
     return ScopeInfo(cls.options_scope, cls.options_scope_category, cls)
Example #16
0
    def collect_scope_infos(optionable_cls, scoped_to, removal_version=None, removal_hint=None):
      if optionable_cls in optionables_path:
        raise cls.CycleException(list(optionables_path) + [optionable_cls])
      optionables_path.add(optionable_cls)

      scope = (optionable_cls.options_scope if scoped_to == GLOBAL_SCOPE
               else optionable_cls.subscope(scoped_to))
      scope_info = ScopeInfo(
          scope,
          optionable_cls.options_scope_category,
          optionable_cls,
          removal_version=removal_version,
          removal_hint=removal_hint
        )

      if scope_info not in known_scope_infos:
        known_scope_infos.add(scope_info)
        for dep in scope_info.optionable_cls.subsystem_dependencies_iter():
          # A subsystem always exists at its global scope (for the purpose of options
          # registration and specification), even if in practice we only use it scoped to
          # some other scope.
          #
          # NB: We do not apply deprecations to this implicit global copy of the scope, because if
          # the intention was to deprecate the entire scope, that could be accomplished by
          # deprecating all options in the scope.
          collect_scope_infos(dep.subsystem_cls, GLOBAL_SCOPE)
          if not dep.is_global():
            collect_scope_infos(dep.subsystem_cls,
                                scope,
                                removal_version=dep.removal_version,
                                removal_hint=dep.removal_hint)

      optionables_path.remove(scope_info.optionable_cls)
Example #17
0
  def complete_scopes(cls, scope_infos):
    """Expand a set of scopes to include all enclosing scopes.

    E.g., if the set contains `foo.bar.baz`, ensure that it also contains `foo.bar` and `foo`.
    """
    ret = {ScopeInfo.for_global_scope()}
    for scope_info in scope_infos:
      ret.add(scope_info)

    original_scopes = {si.scope for si in scope_infos}
    for scope_info in scope_infos:
      scope = scope_info.scope
      while scope != '':
        if scope not in original_scopes:
          ret.add(ScopeInfo(scope, ScopeInfo.INTERMEDIATE))
        scope = scope.rpartition('.')[0]
    return ret
Example #18
0
def test_goal_scope_flag() -> None:
    class DummyGoal(GoalSubsystem):
        name = "dummy"

    dummy = create_goal_subsystem(DummyGoal)
    assert dummy.get_scope_info() == ScopeInfo(scope="dummy",
                                               subsystem_cls=DummyGoal,
                                               is_goal=True)
 def test_options_pantsrc_files(self) -> None:
   def create_options_bootstrapper(*config_paths: str) -> OptionsBootstrapper:
     return OptionsBootstrapper.create(args=[f'--pantsrc-files={cp}' for cp in config_paths])
   with temporary_file(binary_mode=False) as fp:
     fp.write(dedent("""
     [resolver]
     resolver: coursier
     """))
     fp.close()
     bootstrapped_options = create_options_bootstrapper(fp.name)
     opts_single_config = bootstrapped_options.get_full_options(known_scope_infos=[
       ScopeInfo('', ScopeInfo.GLOBAL),
       ScopeInfo('resolver', ScopeInfo.TASK),
     ])
     opts_single_config.register('', '--pantsrc-files', type=list)
     opts_single_config.register('resolver', '--resolver')
     self.assertEqual('coursier', opts_single_config.for_scope('resolver').resolver)
    def assert_config_read_correctly(
      options_bootstrapper: OptionsBootstrapper, *, expected_worker_count: int,
    ) -> None:
      options = options_bootstrapper.get_full_options(
        known_scope_infos=[
          ScopeInfo('', ScopeInfo.GLOBAL),
          ScopeInfo('compile.apt', ScopeInfo.TASK),
          ScopeInfo('fruit', ScopeInfo.TASK),
        ],
      )
      # So we don't choke on these on the cmd line.
      options.register('', '--pants-config-files', type=list)
      options.register('', '--config-override', type=list)
      options.register('compile.apt', '--worker-count')
      options.register('fruit', '--apple')

      self.assertEqual(str(expected_worker_count), options.for_scope('compile.apt').worker_count)
      self.assertEqual('red', options.for_scope('fruit').apple)
Example #21
0
def test_banned_alias_names() -> None:
    cli_alias = CliAlias.from_dict({"fmt": "--cleverness format"})
    with pytest.raises(
            CliAliasInvalidError,
            match=
        (r"Invalid alias in `\[cli\]\.alias` option: 'fmt'\. This is already a registered goal\."
         ),
    ):
        cli_alias.check_name_conflicts({"fmt": ScopeInfo("fmt", is_goal=True)})
Example #22
0
        def assert_config_read_correctly(
            options_bootstrapper: OptionsBootstrapper,
            *,
            expected_worker_count: int,
        ) -> None:
            options = options_bootstrapper.get_full_options(known_scope_infos=[
                ScopeInfo(""),
                ScopeInfo("compile.apt"),
                ScopeInfo("fruit"),
            ], )
            # So we don't choke on these on the cmd line.
            options.register("", "--pants-config-files", type=list)
            options.register("", "--config-override", type=list)
            options.register("compile.apt", "--worker-count")
            options.register("fruit", "--apple")

            self.assertEqual(str(expected_worker_count),
                             options.for_scope("compile.apt").worker_count)
            self.assertEqual("red", options.for_scope("fruit").apple)
Example #23
0
    def _print_options_help(self):
        """Print a help screen.

    Assumes that self._help_request is an instance of OptionsHelp.

    Note: Ony useful if called after options have been registered.
    """
        show_all_help = self._help_request.all_scopes
        if show_all_help:
            help_scopes = list(self._options.known_scope_to_info.keys())
        else:
            # The scopes explicitly mentioned by the user on the cmd line.
            help_scopes = set(
                self._options.scope_to_flags.keys()) - {GLOBAL_SCOPE}

        scope_infos = list(
            ScopeInfoIterator(
                self._options.known_scope_to_info).iterate(help_scopes))
        if scope_infos:
            for scope_info in scope_infos:
                help_str = self._format_help(scope_info)
                if help_str:
                    print(help_str)
            return
        else:
            print(pants_release())
            print('\nUsage:')
            print(
                f'  {self.bin_name} [option ...] [goal ...] [target...]  Attempt the specified goals.'
            )
            print(
                f'  {self.bin_name} help                                 Get help.'
            )
            print(
                f'  {self.bin_name} help [goal]                          Get help for a goal.'
            )
            print(
                f'  {self.bin_name} help-advanced [goal]                 Get help for a goal\'s advanced options.'
            )
            print(
                f'  {self.bin_name} help-all                             Get help for all goals.'
            )
            print(
                f'  {self.bin_name} goals                                List all installed goals.'
            )
            print('')
            print('  [target] accepts two special forms:')
            print(
                '    dir:  to include all targets in the specified directory.')
            print(
                '    dir:: to include all targets found recursively under the directory.'
            )
            print('\nFriendly docs:\n  http://pantsbuild.org/')

            print(self._format_help(ScopeInfo(GLOBAL_SCOPE, ScopeInfo.GLOBAL)))
            def bootstrap_options_from_config(config):
                bootstrap_options = Options(
                    env=self._env,
                    config=config,
                    known_scope_infos=[ScopeInfo.for_global_scope()],
                    args=bargs)

                def register_global(*args, **kwargs):
                    bootstrap_options.register(GLOBAL_SCOPE, *args, **kwargs)

                GlobalOptionsRegistrar.register_bootstrap_options(
                    register_global)
                return bootstrap_options
Example #25
0
 def test_complete_scopes(self):
     _global = ScopeInfo.for_global_scope()
     self.assertEquals(
         {
             _global,
             intermediate('foo'),
             intermediate('foo.bar'),
             task('foo.bar.baz')
         }, Options.complete_scopes({task('foo.bar.baz')}))
     self.assertEquals(
         {
             _global,
             intermediate('foo'),
             intermediate('foo.bar'),
             task('foo.bar.baz')
         },
         Options.complete_scopes(
             {ScopeInfo.for_global_scope(),
              task('foo.bar.baz')}))
     self.assertEquals(
         {
             _global,
             intermediate('foo'),
             intermediate('foo.bar'),
             task('foo.bar.baz')
         },
         Options.complete_scopes({intermediate('foo'),
                                  task('foo.bar.baz')}))
     self.assertEquals(
         {
             _global,
             intermediate('foo'),
             intermediate('foo.bar'),
             task('foo.bar.baz'),
             intermediate('qux'),
             task('qux.quux')
         }, Options.complete_scopes({task('foo.bar.baz'),
                                     task('qux.quux')}))
Example #26
0
  def complete_scopes(cls, scope_infos):
    """Expand a set of scopes to include all enclosing scopes.

    E.g., if the set contains `foo.bar.baz`, ensure that it also contains `foo.bar` and `foo`.
    """
    ret = {ScopeInfo.for_global_scope()}
    for scope_info in scope_infos:
      ret.add(scope_info)

    original_scopes = {si.scope for si in scope_infos}
    for scope_info in scope_infos:
      scope = scope_info.scope
      while scope != '':
        if scope not in original_scopes:
          ret.add(ScopeInfo(scope, ScopeInfo.INTERMEDIATE))
        scope = scope.rpartition('.')[0]
    return ret
Example #27
0
  def do_test_create_bootstrapped_multiple_config(self, create_options_bootstrapper):
    # check with multiple config files, the latest values always get taken
    # in this case worker_count will be overwritten, while fruit stays the same
    with temporary_file() as fp:
      fp.write(dedent("""
      [compile.apt]
      worker_count: 1

      [fruit]
      apple: red
      """))
      fp.close()

      bootstrapper_single_config = create_options_bootstrapper(fp.name)

      opts_single_config = bootstrapper_single_config.get_full_options(known_scope_infos=[
          ScopeInfo('', ScopeInfo.GLOBAL),
          ScopeInfo('compile.apt', ScopeInfo.TASK),
          ScopeInfo('fruit', ScopeInfo.TASK),
      ])
      # So we don't choke on these on the cmd line.
      opts_single_config.register('', '--pants-config-files', type=list)
      opts_single_config.register('', '--config-override', type=list)

      opts_single_config.register('compile.apt', '--worker-count')
      opts_single_config.register('fruit', '--apple')

      self.assertEquals('1', opts_single_config.for_scope('compile.apt').worker_count)
      self.assertEquals('red', opts_single_config.for_scope('fruit').apple)

      with temporary_file() as fp2:
        fp2.write(dedent("""
        [compile.apt]
        worker_count: 2
        """))
        fp2.close()

        bootstrapper_double_config = create_options_bootstrapper(fp.name, fp2.name)

        opts_double_config = bootstrapper_double_config.get_full_options(known_scope_infos=[
          ScopeInfo('', ScopeInfo.GLOBAL),
          ScopeInfo('compile.apt', ScopeInfo.TASK),
          ScopeInfo('fruit', ScopeInfo.TASK),
        ])
        # So we don't choke on these on the cmd line.
        opts_double_config.register('', '--pants-config-files', type=list)
        opts_double_config.register('', '--config-override', type=list)
        opts_double_config.register('compile.apt', '--worker-count')
        opts_double_config.register('fruit', '--apple')

        self.assertEquals('2', opts_double_config.for_scope('compile.apt').worker_count)
        self.assertEquals('red', opts_double_config.for_scope('fruit').apple)
Example #28
0
    def collect_scope_infos(optionable_cls, scoped_to):
      if optionable_cls in optionables_path:
        raise cls.CycleException(list(optionables_path) + [optionable_cls])
      optionables_path.add(optionable_cls)

      scope = (optionable_cls.options_scope if scoped_to == GLOBAL_SCOPE
               else optionable_cls.subscope(scoped_to))
      scope_info = ScopeInfo(scope, optionable_cls.options_scope_category, optionable_cls)

      if scope_info not in known_scope_infos:
        known_scope_infos.add(scope_info)
        for dep in scope_info.optionable_cls.subsystem_dependencies_iter():
          # A subsystem always exists at its global scope (for the purpose of options
          # registration and specification), even if in practice we only use it scoped to
          # some other scope.
          collect_scope_infos(dep.subsystem_cls, GLOBAL_SCOPE)
          if not dep.is_global():
            collect_scope_infos(dep.subsystem_cls, scope)

      optionables_path.remove(scope_info.optionable_cls)
Example #29
0
def subsystem(scope):
    return ScopeInfo(scope, ScopeInfo.SUBSYSTEM)
Example #30
0
def intermediate(scope):
    return ScopeInfo(scope, ScopeInfo.INTERMEDIATE)
Example #31
0
def task(scope):
    return ScopeInfo(scope, ScopeInfo.TASK)
Example #32
0
 def get_scope_info(cls):
     """Returns a ScopeInfo instance representing this Optionable's options scope."""
     if cls.options_scope is None:
         raise OptionsError(f"{cls.__name__} must set options_scope.")
     return ScopeInfo(cls.options_scope, cls)
Example #33
0
  def setup(self):
    options_bootstrapper = OptionsBootstrapper()
    bootstrap_options = options_bootstrapper.get_bootstrap_options()

    # Get logging setup prior to loading backends so that they can log as needed.
    self._setup_logging(bootstrap_options.for_global_scope())

    # Add any extra paths to python path (eg for loading extra source backends)
    for path in bootstrap_options.for_global_scope().pythonpath:
      sys.path.append(path)
      pkg_resources.fixup_namespace_packages(path)

    # Load plugins and backends.
    plugins = bootstrap_options.for_global_scope().plugins
    backend_packages = bootstrap_options.for_global_scope().backend_packages
    build_configuration = load_plugins_and_backends(plugins, backend_packages)

    # Now that plugins and backends are loaded, we can gather the known scopes.
    self.targets = []

    known_scope_infos = [ScopeInfo.for_global_scope()]

    # Add scopes for all needed subsystems.
    subsystems = (set(self.subsystems) | Goal.subsystems() | build_configuration.subsystems())
    for subsystem in subsystems:
      known_scope_infos.append(ScopeInfo(subsystem.options_scope, ScopeInfo.GLOBAL_SUBSYSTEM))

    # Add scopes for all tasks in all goals.
    for goal in Goal.all():
      known_scope_infos.extend(filter(None, goal.known_scope_infos()))

    # Now that we have the known scopes we can get the full options.
    self.options = options_bootstrapper.get_full_options(known_scope_infos)
    self.register_options(subsystems)

    # Make the options values available to all subsystems.
    Subsystem._options = self.options

    # Now that we have options we can instantiate subsystems.
    self.run_tracker = RunTracker.global_instance()
    self.reporting = Reporting.global_instance()
    report = self.reporting.initial_reporting(self.run_tracker)
    self.run_tracker.start(report)
    url = self.run_tracker.run_info.get_info('report_url')
    if url:
      self.run_tracker.log(Report.INFO, 'See a report at: {}'.format(url))
    else:
      self.run_tracker.log(Report.INFO, '(To run a reporting server: ./pants server)')

    self.build_file_parser = BuildFileParser(build_configuration=build_configuration,
                                             root_dir=self.root_dir,
                                             run_tracker=self.run_tracker)

    rev = self.options.for_global_scope().build_file_rev
    if rev:
      ScmBuildFile.set_rev(rev)
      ScmBuildFile.set_scm(get_scm())
      build_file_type = ScmBuildFile
    else:
      build_file_type = FilesystemBuildFile
    self.address_mapper = BuildFileAddressMapper(self.build_file_parser, build_file_type)
    self.build_graph = BuildGraph(run_tracker=self.run_tracker,
                                  address_mapper=self.address_mapper)

    # TODO(John Sirois): Kill when source root registration is lifted out of BUILD files.
    with self.run_tracker.new_workunit(name='bootstrap', labels=[WorkUnit.SETUP]):
      source_root_bootstrapper = SourceRootBootstrapper.global_instance()
      source_root_bootstrapper.bootstrap(self.address_mapper, self.build_file_parser)

    self._expand_goals_and_specs()

    # Now that we've parsed the bootstrap BUILD files, and know about the SCM system.
    self.run_tracker.run_info.add_scm_info()