Esempio n. 1
0
  def test_env_type_int(self):
    options = Options.create(env={'PANTS_FOO_BAR': "['123','456']"},
                             config=self._create_config({}),
                             known_scope_infos=OptionsTest._known_scope_infos,
                             args=shlex.split('./pants'),
                             option_tracker=OptionTracker())
    options.register(GLOBAL_SCOPE, '--foo-bar', type=list, member_type=int)
    self.assertEqual([123, 456], options.for_global_scope().foo_bar)

    options = Options.create(env={'PANTS_FOO_BAR': '123'},
                             config=self._create_config({}),
                             known_scope_infos=OptionsTest._known_scope_infos,
                             args=shlex.split('./pants'),
                             option_tracker=OptionTracker())
    options.register(GLOBAL_SCOPE, '--foo-bar', type=int)
    self.assertEqual(123, options.for_global_scope().foo_bar)
Esempio n. 2
0
  def test_env_type_int(self):
    options = Options.create(env={'PANTS_FOO_BAR': "['123','456']"},
                             config=self._create_config({}),
                             known_scope_infos=OptionsTest._known_scope_infos,
                             args=shlex.split('./pants'),
                             option_tracker=OptionTracker())
    options.register(GLOBAL_SCOPE, '--foo-bar', type=list, member_type=int)
    self.assertEqual([123, 456], options.for_global_scope().foo_bar)

    options = Options.create(env={'PANTS_FOO_BAR': '123'},
                             config=self._create_config({}),
                             known_scope_infos=OptionsTest._known_scope_infos,
                             args=shlex.split('./pants'),
                             option_tracker=OptionTracker())
    options.register(GLOBAL_SCOPE, '--foo-bar', type=int)
    self.assertEqual(123, options.for_global_scope().foo_bar)
Esempio n. 3
0
 def bootstrap_options_from_config(config):
   bootstrap_options = Options.create(env=self._env, config=config,
       known_scope_infos=[GlobalOptionsRegistrar.get_scope_info()], args=bargs)
   def register_global(*args, **kwargs):
     bootstrap_options.register(GLOBAL_SCOPE, *args, **kwargs)
   GlobalOptionsRegistrar.register_bootstrap_options(register_global)
   return bootstrap_options
Esempio n. 4
0
 def test_double_registration(self):
   options = Options.create(env={},
                            config=self._create_config({}),
                            known_scope_infos=OptionsTest._known_scope_infos,
                            args=shlex.split('./pants'),
                            option_tracker=OptionTracker())
   options.register(GLOBAL_SCOPE, '--foo-bar')
   self.assertRaises(OptionAlreadyRegistered, lambda: options.register(GLOBAL_SCOPE, '--foo-bar'))
Esempio n. 5
0
 def test_double_registration(self):
   options = Options.create(env={},
                            config=self._create_config({}),
                            known_scope_infos=OptionsTest._known_scope_infos,
                            args=shlex.split('./pants'),
                            option_tracker=OptionTracker())
   options.register(GLOBAL_SCOPE, '--foo-bar')
   self.assertRaises(OptionAlreadyRegistered, lambda: options.register(GLOBAL_SCOPE, '--foo-bar'))
Esempio n. 6
0
 def _full_options(self, known_scope_infos):
     bootstrap_option_values = self.get_bootstrap_options(
     ).for_global_scope()
     return Options.create(self.env,
                           self.config,
                           known_scope_infos,
                           args=self.args,
                           bootstrap_option_values=bootstrap_option_values)
Esempio n. 7
0
 def test_deprecated_option_past_removal(self):
   with self.assertRaises(PastRemovalVersionError):
     options = Options.create(env={},
                              config=self._create_config({}),
                              known_scope_infos=OptionsTest._known_scope_infos,
                              args="./pants")
     options.register(GLOBAL_SCOPE, '--too-old-option', deprecated_version='0.0.24',
                      deprecated_hint='The semver for this option has already passed.')
Esempio n. 8
0
 def test_frozen_registration(self):
     options = Options.create(args=[],
                              env={},
                              config=self._create_config({}),
                              known_scope_infos=[task('foo')],
                              option_tracker=OptionTracker())
     options.register('foo', '--arg1')
     with self.assertRaises(FrozenRegistration):
         options.register(GLOBAL_SCOPE, '--arg2')
Esempio n. 9
0
 def _parse(self, args_str, env=None, config=None, bootstrap_option_values=None):
   args = shlex.split(str(args_str))
   options = Options.create(env=env or {},
                            config=self._create_config(config or {}),
                            known_scope_infos=OptionsTest._known_scope_infos,
                            args=args,
                            bootstrap_option_values=bootstrap_option_values)
   self._register(options)
   return options
Esempio n. 10
0
 def assertError(expected_error, *args, **kwargs):
     with self.assertRaises(expected_error):
         options = Options.create(args=[],
                                  env={},
                                  config=self._create_config({}),
                                  known_scope_infos=[],
                                  option_tracker=OptionTracker())
         options.register(GLOBAL_SCOPE, *args, **kwargs)
         options.for_global_scope()
Esempio n. 11
0
 def _parse(self, args_str, env=None, config=None, bootstrap_option_values=None):
   args = shlex.split(str(args_str))
   options = Options.create(env=env or {},
                            config=self._create_config(config or {}),
                            known_scope_infos=OptionsTest._known_scope_infos,
                            args=args,
                            bootstrap_option_values=bootstrap_option_values,
                            option_tracker=OptionTracker())
   self._register(options)
   return options
Esempio n. 12
0
 def _parse_type_int(self, args_str, env=None, config=None, bootstrap_option_values=None,
                     action=None):
   args = shlex.split(str(args_str))
   options = Options.create(env=env or {},
                            config=self._create_config(config or {}),
                            known_scope_infos=OptionsTest._known_scope_infos,
                            args=args,
                            bootstrap_option_values=bootstrap_option_values)
   options.register(GLOBAL_SCOPE, '--config-override', action=action, type=int)
   return options
Esempio n. 13
0
 def test_deprecated_option_past_removal(self):
   with self.assertRaises(PastRemovalVersionError):
     options = Options.create(env={},
                              config=self._create_config({}),
                              known_scope_infos=OptionsTest._known_scope_infos,
                              args='./pants',
                              option_tracker=OptionTracker())
     options.register(GLOBAL_SCOPE, '--too-old-option', deprecated_version='0.0.24',
                      deprecated_hint='The semver for this option has already passed.')
     options.for_global_scope()
Esempio n. 14
0
 def test_deprecated_option_past_removal(self):
     with self.assertRaises(PastRemovalVersionError):
         options = Options.create({}, FakeConfig({}),
                                  OptionsTest._known_scope_infos, "./pants")
         options.register(
             GLOBAL_SCOPE,
             '--too-old-option',
             deprecated_version='0.0.24',
             deprecated_hint='The semver for this option has already passed.'
         )
Esempio n. 15
0
 def test_shadowing(self):
     options = Options.create(
         env={},
         config=self._create_config({}),
         known_scope_infos=[task("foo")],
         args="./pants",
         option_tracker=OptionTracker(),
     )
     options.register("", "--bar")
     with self.assertRaises(RegistrationError):
         options.register("foo", "--bar")
Esempio n. 16
0
 def _parse_type_int(self, args_str, env=None, config=None, bootstrap_option_values=None,
                     action=None):
   args = shlex.split(str(args_str))
   options = Options.create(env=env or {},
                            config=self._create_config(config or {}),
                            known_scope_infos=OptionsTest._known_scope_infos,
                            args=args,
                            bootstrap_option_values=bootstrap_option_values,
                            option_tracker=OptionTracker())
   options.register(GLOBAL_SCOPE, '--config-override', action=action, type=int)
   return options
Esempio n. 17
0
    def parse_bootstrap_options(
        env: Mapping[str, str], args: Sequence[str], config: Config
    ) -> Options:
        bootstrap_options = Options.create(
            env=env, config=config, known_scope_infos=[GlobalOptions.get_scope_info()], args=args,
        )

        def register_global(*args, **kwargs):
            # Only use of Options.register?
            bootstrap_options.register(GLOBAL_SCOPE, *args, **kwargs)

        GlobalOptions.register_bootstrap_options(register_global)
        return bootstrap_options
Esempio n. 18
0
def test_register_options_blessed(caplog) -> None:
    class GoodToGo(Subsystem):
        options_scope = "good-to-go"

    options = Options.create(
        env={},
        config=Config.load([]),
        known_scope_infos=[GoodToGo.get_scope_info()],
        args=["./pants"],
        bootstrap_option_values=None,
    )
    GoodToGo.register_options_on_scope(options)

    assert not caplog.records, "The current blessed means of registering options should never warn."
    def parse_bootstrap_options(env, args, config):
        bootstrap_options = Options.create(
            env=env,
            config=config,
            known_scope_infos=[GlobalOptionsRegistrar.get_scope_info()],
            args=args,
        )

        def register_global(*args, **kwargs):
            ## Only use of Options.register?
            bootstrap_options.register(GLOBAL_SCOPE, *args, **kwargs)

        GlobalOptionsRegistrar.register_bootstrap_options(register_global)
        return bootstrap_options
Esempio n. 20
0
  def parse_bootstrap_options(env, args, config):
    bootstrap_options = Options.create(
      env=env,
      config=config,
      known_scope_infos=[GlobalOptionsRegistrar.get_scope_info()],
      args=args,
    )

    def register_global(*args, **kwargs):
      ## Only use of Options.register?
      bootstrap_options.register(GLOBAL_SCOPE, *args, **kwargs)

    GlobalOptionsRegistrar.register_bootstrap_options(register_global)
    return bootstrap_options
Esempio n. 21
0
 def _parse(self,
            args_str,
            env=None,
            config=None,
            bootstrap_option_values=None):
     args = shlex.split(str(args_str))
     options = Options.create(
         env or {},
         FakeConfig(config or {}),
         OptionsTest._known_scope_infos,
         args,
         bootstrap_option_values=bootstrap_option_values)
     self._register(options)
     return options
Esempio n. 22
0
    def parse_bootstrap_options(env: Mapping[str, str], args: Sequence[str],
                                config: Config) -> Options:
        bootstrap_options = Options.create(
            env=env,
            config=config,
            known_scope_infos=[GlobalOptions.get_scope_info()],
            args=args,
        )

        for options_info in collect_options_info(BootstrapOptions):
            # Only use of Options.register?
            bootstrap_options.register(GLOBAL_SCOPE, *options_info.flag_names,
                                       **options_info.flag_options)

        return bootstrap_options
Esempio n. 23
0
 def test_no_recursive_subsystem_options(self):
   options = Options.create(env={},
                            config=self._create_config({}),
                            known_scope_infos=[subsystem('foo')],
                            args='./pants',
                            option_tracker=OptionTracker())
   # All subsystem options are implicitly recursive (a subscope of subsystem scope represents
   # a separate instance of the subsystem, so it needs all the options).
   # We disallow explicit specification of recursive (even if set to True), to avoid confusion.
   with self.assertRaises(RecursiveSubsystemOption):
     options.register('foo', '--bar', recursive=False)
     options.for_scope('foo')
   with self.assertRaises(RecursiveSubsystemOption):
     options.register('foo', '--baz', recursive=True)
     options.for_scope('foo')
Esempio n. 24
0
 def test_no_recursive_subsystem_options(self):
     options = Options.create(env={},
                              config=self._create_config({}),
                              known_scope_infos=[subsystem('foo')],
                              args='./pants',
                              option_tracker=OptionTracker())
     # All subsystem options are implicitly recursive (a subscope of subsystem scope represents
     # a separate instance of the subsystem, so it needs all the options).
     # We disallow explicit specification of recursive (even if set to True), to avoid confusion.
     with self.assertRaises(RecursiveSubsystemOption):
         options.register('foo', '--bar', recursive=False)
         options.for_scope('foo')
     with self.assertRaises(RecursiveSubsystemOption):
         options.register('foo', '--baz', recursive=True)
         options.for_scope('foo')
Esempio n. 25
0
  def _full_options(self, known_scope_infos):
    bootstrap_option_values = self.get_bootstrap_options().for_global_scope()
    options = Options.create(self.env,
                             self.config,
                             known_scope_infos,
                             args=self.args,
                             bootstrap_option_values=bootstrap_option_values)

    distinct_optionable_classes = set()
    for ksi in sorted(known_scope_infos, key=lambda si: si.scope):
      if not ksi.optionable_cls or ksi.optionable_cls in distinct_optionable_classes:
        continue
      distinct_optionable_classes.add(ksi.optionable_cls)
      ksi.optionable_cls.register_options_on_scope(options)

    return options
Esempio n. 26
0
  def _full_options(self, known_scope_infos):
    bootstrap_option_values = self.get_bootstrap_options().for_global_scope()
    options = Options.create(self.env,
                             self.config,
                             known_scope_infos,
                             args=self.args,
                             bootstrap_option_values=bootstrap_option_values)

    distinct_optionable_classes = set()
    for ksi in sorted(known_scope_infos, key=lambda si: si.scope):
      if not ksi.optionable_cls or ksi.optionable_cls in distinct_optionable_classes:
        continue
      distinct_optionable_classes.add(ksi.optionable_cls)
      ksi.optionable_cls.register_options_on_scope(options)

    return options
Esempio n. 27
0
    def parse_bootstrap_options(env: Mapping[str, str], args: Sequence[str],
                                config: Config) -> Options:
        bootstrap_options = Options.create(
            env=env,
            config=config,
            known_scope_infos=[GlobalOptions.get_scope_info()],
            args=args,
        )

        def register_global(*args, **kwargs):
            ## Only use of Options.register?
            bootstrap_options.register(GLOBAL_SCOPE, *args, **kwargs)

        GlobalOptions.register_bootstrap_options(register_global)
        opts = bootstrap_options.for_global_scope()
        if opts.v2 and not opts.v1 and opts.backend_packages == []:
            is_v2_exclusive.set()
        return bootstrap_options
Esempio n. 28
0
    def _full_options(self, known_scope_infos: FrozenOrderedSet[ScopeInfo]) -> Options:
        bootstrap_option_values = self.get_bootstrap_options().for_global_scope()
        options = Options.create(
            self.env,
            self.config,
            known_scope_infos,
            args=self.args,
            bootstrap_option_values=bootstrap_option_values,
        )

        distinct_optionable_classes: Set[Type[Optionable]] = set()
        for ksi in known_scope_infos:
            if not ksi.optionable_cls or ksi.optionable_cls in distinct_optionable_classes:
                continue
            distinct_optionable_classes.add(ksi.optionable_cls)
            ksi.optionable_cls.register_options_on_scope(options)

        return options
Esempio n. 29
0
 def test_shadowing(self):
   options = Options.create(env={},
                            config=self._create_config({}),
                            known_scope_infos=[task('bar'), intermediate('foo'), task('foo.bar')],
                            args='./pants',
                            option_tracker=OptionTracker())
   options.register('', '--opt1')
   options.register('foo', '-o', '--opt2')
   with self.assertRaises(Shadowing):
     options.register('bar', '--opt1')
   with self.assertRaises(Shadowing):
     options.register('foo.bar', '--opt1')
   with self.assertRaises(Shadowing):
     options.register('foo.bar', '--opt2')
   with self.assertRaises(Shadowing):
     options.register('foo.bar', '--opt1', '--opt3')
   with self.assertRaises(Shadowing):
     options.register('foo.bar', '--opt3', '--opt2')
Esempio n. 30
0
 def test_shadowing(self):
   options = Options.create(env={},
                            config=self._create_config({}),
                            known_scope_infos=[task('bar'), intermediate('foo'), task('foo.bar')],
                            args='./pants',
                            option_tracker=OptionTracker())
   options.register('', '--opt1')
   options.register('foo', '-o', '--opt2')
   with self.assertRaises(Shadowing):
     options.register('bar', '--opt1')
   with self.assertRaises(Shadowing):
     options.register('foo.bar', '--opt1')
   with self.assertRaises(Shadowing):
     options.register('foo.bar', '--opt2')
   with self.assertRaises(Shadowing):
     options.register('foo.bar', '--opt1', '--opt3')
   with self.assertRaises(Shadowing):
     options.register('foo.bar', '--opt3', '--opt2')
Esempio n. 31
0
  def get_full_options(self, known_scope_infos):
    """Get the full Options instance bootstrapped by this object for the given known scopes.

    :param known_scope_infos: ScopeInfos for all scopes that may be encountered.
    :returns: A bootrapped Options instance that also carries options for all the supplied known
              scopes.
    :rtype: :class:`Options`
    """
    key = frozenset(sorted(known_scope_infos))
    if key not in self._full_options:
      # Note: Don't inline this into the Options() call, as this populates
      # self._post_bootstrap_config, which is another argument to that call.
      bootstrap_option_values = self.get_bootstrap_options().for_global_scope()
      self._full_options[key] = Options.create(self._env,
                                               self._post_bootstrap_config,
                                               known_scope_infos,
                                               args=self._args,
                                               bootstrap_option_values=bootstrap_option_values)
    return self._full_options[key]
Esempio n. 32
0
  def get_full_options(self, known_scope_infos):
    """Get the full Options instance bootstrapped by this object for the given known scopes.

    :param known_scope_infos: ScopeInfos for all scopes that may be encountered.
    :returns: A bootrapped Options instance that also carries options for all the supplied known
              scopes.
    :rtype: :class:`Options`
    """
    key = frozenset(sorted(known_scope_infos))
    if key not in self._full_options:
      # Note: Don't inline this into the Options() call, as this populates
      # self._post_bootstrap_config, which is another argument to that call.
      bootstrap_option_values = self.get_bootstrap_options().for_global_scope()
      self._full_options[key] = Options.create(self._env,
                                               self._post_bootstrap_config,
                                               known_scope_infos,
                                               args=self._args,
                                               bootstrap_option_values=bootstrap_option_values)
    return self._full_options[key]
Esempio n. 33
0
    def _full_options(
        self, known_scope_infos: FrozenOrderedSet[ScopeInfo], allow_unknown_options: bool = False
    ) -> Options:
        bootstrap_option_values = self.get_bootstrap_options().for_global_scope()
        options = Options.create(
            self.env,
            self.config,
            known_scope_infos,
            args=self.args,
            bootstrap_option_values=bootstrap_option_values,
            allow_unknown_options=allow_unknown_options,
        )

        distinct_subsystem_classes: set[type[Subsystem]] = set()
        for ksi in known_scope_infos:
            if not ksi.subsystem_cls or ksi.subsystem_cls in distinct_subsystem_classes:
                continue
            distinct_subsystem_classes.add(ksi.subsystem_cls)
            ksi.subsystem_cls.register_options_on_scope(options)

        return options
Esempio n. 34
0
 def test_option_tracker_required(self):
   with self.assertRaises(Options.OptionTrackerRequiredError):
     Options.create(None, None, [])
Esempio n. 35
0
 def test_frozen_registration(self):
   options = Options.create(args=[], env={}, config=self._create_config({}),
                            known_scope_infos=[task('foo')], option_tracker=OptionTracker())
   options.register('foo', '--arg1')
   with self.assertRaises(FrozenRegistration):
     options.register(GLOBAL_SCOPE, '--arg2')
Esempio n. 36
0
 def assertError(expected_error, *args, **kwargs):
   with self.assertRaises(expected_error):
     options = Options.create(args=[], env={}, config=self._create_config({}),
                              known_scope_infos=[], option_tracker=OptionTracker())
     options.register(GLOBAL_SCOPE, *args, **kwargs)
     options.for_global_scope()
Esempio n. 37
0
def test_get_all_help_info():
    class Global(Subsystem):
        options_scope = GLOBAL_SCOPE
        help = "Global options."

        opt1 = IntOption("--opt1", default=42, help="Option 1")
        # This is special in having a short option `-l`. Make sure it works.
        level = LogLevelOption()

    class Foo(Subsystem):
        options_scope = "foo"
        help = "A foo."

        opt2 = BoolOption("--opt2",
                          default=True,
                          advanced=True,
                          help="Option 2")

    class Bar(GoalSubsystem):
        name = "bar"
        help = "The bar goal."
        deprecated_options_scope = "bar-old"
        deprecated_options_scope_removal_version = "9.9.999"

    class QuxField(StringField):
        alias = "qux"
        default = "blahblah"
        help = "A qux string."

    class QuuxField(IntField):
        alias = "quux"
        required = True
        help = "A quux int.\n\nMust be non-zero. Or zero. Whatever you like really."

    class BazLibrary(Target):
        alias = "baz_library"
        help = "A library of baz-es.\n\nUse it however you like."

        core_fields = [QuxField, QuuxField]

    options = Options.create(
        env={},
        config=Config.load([]),
        known_scope_infos=[
            Global.get_scope_info(),
            Foo.get_scope_info(),
            Bar.get_scope_info()
        ],
        args=["./pants"],
        bootstrap_option_values=None,
    )
    Global.register_options_on_scope(options)
    Foo.register_options_on_scope(options)
    Bar.register_options_on_scope(options)

    @rule
    def rule_info_test(foo: Foo) -> Target:
        """This rule is for testing info extraction only."""

    def fake_consumed_scopes_mapper(scope: str) -> Tuple[str, ...]:
        return ("somescope", f"used_by_{scope or 'GLOBAL_SCOPE'}")

    bc_builder = BuildConfiguration.Builder()
    bc_builder.register_subsystems("help_info_extracter_test", (Foo, Bar))
    bc_builder.register_target_types("help_info_extracter_test",
                                     (BazLibrary, ))
    bc_builder.register_rules("help_info_extracter_test",
                              collect_rules(locals()))

    all_help_info = HelpInfoExtracter.get_all_help_info(
        options,
        UnionMembership({}),
        fake_consumed_scopes_mapper,
        RegisteredTargetTypes({BazLibrary.alias: BazLibrary}),
        bc_builder.create(),
    )

    all_help_info_dict = all_help_info.asdict()
    expected_all_help_info_dict = {
        "scope_to_help_info": {
            GLOBAL_SCOPE: {
                "scope":
                GLOBAL_SCOPE,
                "description":
                "Global options.",
                "provider":
                "",
                "is_goal":
                False,
                "deprecated_scope":
                None,
                "basic": (
                    {
                        "display_args": ("--opt1=<int>", ),
                        "comma_separated_display_args": "--opt1=<int>",
                        "scoped_cmd_line_args": ("--opt1", ),
                        "unscoped_cmd_line_args": ("--opt1", ),
                        "config_key": "opt1",
                        "env_var": "PANTS_OPT1",
                        "value_history": {
                            "ranked_values": (
                                {
                                    "rank": Rank.NONE,
                                    "value": None,
                                    "details": None
                                },
                                {
                                    "rank": Rank.HARDCODED,
                                    "value": 42,
                                    "details": None
                                },
                            ),
                        },
                        "typ": int,
                        "default": 42,
                        "help": "Option 1",
                        "deprecation_active": False,
                        "deprecated_message": None,
                        "removal_version": None,
                        "removal_hint": None,
                        "choices": None,
                        "comma_separated_choices": None,
                    },
                    {
                        "display_args":
                        ("-l=<LogLevel>", "--level=<LogLevel>"),
                        "comma_separated_display_args":
                        "-l=<LogLevel>, --level=<LogLevel>",
                        "scoped_cmd_line_args": ("-l", "--level"),
                        "unscoped_cmd_line_args": ("-l", "--level"),
                        "config_key":
                        "level",
                        "env_var":
                        "PANTS_LEVEL",
                        "value_history": {
                            "ranked_values": (
                                {
                                    "rank": Rank.NONE,
                                    "value": None,
                                    "details": None
                                },
                                {
                                    "rank": Rank.HARDCODED,
                                    "value": LogLevel.INFO,
                                    "details": None
                                },
                            ),
                        },
                        "typ":
                        LogLevel,
                        "default":
                        LogLevel.INFO,
                        "help":
                        "Set the logging level.",
                        "deprecation_active":
                        False,
                        "deprecated_message":
                        None,
                        "removal_version":
                        None,
                        "removal_hint":
                        None,
                        "choices": ("trace", "debug", "info", "warn", "error"),
                        "comma_separated_choices":
                        "trace, debug, info, warn, error",
                    },
                ),
                "advanced":
                tuple(),
                "deprecated":
                tuple(),
            },
            "foo": {
                "scope":
                "foo",
                "provider":
                "help_info_extracter_test",
                "description":
                "A foo.",
                "is_goal":
                False,
                "deprecated_scope":
                None,
                "basic": (),
                "advanced": ({
                    "display_args": ("--[no-]foo-opt2", ),
                    "comma_separated_display_args":
                    "--[no-]foo-opt2",
                    "scoped_cmd_line_args": ("--foo-opt2", "--no-foo-opt2"),
                    "unscoped_cmd_line_args": ("--opt2", "--no-opt2"),
                    "config_key":
                    "opt2",
                    "env_var":
                    "PANTS_FOO_OPT2",
                    "value_history": {
                        "ranked_values": (
                            {
                                "rank": Rank.NONE,
                                "value": None,
                                "details": None
                            },
                            {
                                "rank": Rank.HARDCODED,
                                "value": True,
                                "details": None
                            },
                        ),
                    },
                    "typ":
                    bool,
                    "default":
                    True,
                    "help":
                    "Option 2",
                    "deprecation_active":
                    False,
                    "deprecated_message":
                    None,
                    "removal_version":
                    None,
                    "removal_hint":
                    None,
                    "choices":
                    None,
                    "comma_separated_choices":
                    None,
                }, ),
                "deprecated":
                tuple(),
            },
            "bar": {
                "scope": "bar",
                "provider": "help_info_extracter_test",
                "description": "The bar goal.",
                "is_goal": True,
                "deprecated_scope": "bar-old",
                "basic": tuple(),
                "advanced": tuple(),
                "deprecated": tuple(),
            },
            "bar-old": {
                "scope": "bar-old",
                "provider": "help_info_extracter_test",
                "description": "The bar goal.",
                "is_goal": True,
                "deprecated_scope": "bar-old",
                "basic": tuple(),
                "advanced": tuple(),
                "deprecated": tuple(),
            },
        },
        "name_to_goal_info": {
            "bar": {
                "name": "bar",
                "provider": "help_info_extracter_test",
                "description": "The bar goal.",
                "consumed_scopes": ("somescope", "used_by_bar"),
                "is_implemented": True,
            },
            "bar-old": {
                "name": "bar",
                "provider": "help_info_extracter_test",
                "description": "The bar goal.",
                "consumed_scopes": ("somescope", "used_by_bar-old"),
                "is_implemented": True,
            },
        },
        "name_to_target_type_info": {
            "baz_library": {
                "alias":
                "baz_library",
                "provider":
                "help_info_extracter_test",
                "summary":
                "A library of baz-es.",
                "description":
                "A library of baz-es.\n\nUse it however you like.",
                "fields": (
                    {
                        "alias": "qux",
                        "provider": "",
                        "default": "'blahblah'",
                        "description": "A qux string.",
                        "required": False,
                        "type_hint": "str | None",
                    },
                    {
                        "alias":
                        "quux",
                        "provider":
                        "",
                        "default":
                        None,
                        "description":
                        "A quux int.\n\nMust be non-zero. Or zero. "
                        "Whatever you like really.",
                        "required":
                        True,
                        "type_hint":
                        "int",
                    },
                ),
            }
        },
        "name_to_rule_info": {
            "construct_scope_foo": {
                "description": None,
                "documentation": "A foo.",
                "input_gets": ("Get(ScopedOptions, Scope, ..)", ),
                "input_types": (),
                "name": "construct_scope_foo",
                "output_type": "Foo",
                "provider": "help_info_extracter_test",
            },
            "pants.help.help_info_extracter_test.test_get_all_help_info.rule_info_test":
            {
                "description": None,
                "documentation":
                "This rule is for testing info extraction only.",
                "input_gets": (),
                "input_types": ("Foo", ),
                "name":
                "pants.help.help_info_extracter_test.test_get_all_help_info.rule_info_test",
                "output_type": "Target",
                "provider": "help_info_extracter_test",
            },
        },
        "name_to_api_type_info": {
            "pants.help.help_info_extracter_test.Foo": {
                "consumed_by_rules":
                ("pants.help.help_info_extracter_test.test_get_all_help_info.rule_info_test",
                 ),
                "dependees": ("help_info_extracter_test", ),
                "dependencies": ("pants.option.scope", ),
                "documentation":
                None,
                "is_union":
                False,
                "module":
                "pants.help.help_info_extracter_test",
                "name":
                "Foo",
                "provider":
                "help_info_extracter_test",
                "returned_by_rules": ("construct_scope_foo", ),
                "union_members": (),
                "union_type":
                None,
                "used_in_rules": (),
            },
            "pants.engine.target.Target": {
                "consumed_by_rules": (),
                "dependees": (),
                "dependencies": (),
                "documentation":
                ("A Target represents an addressable set of metadata.\n\n    Set the `help` "
                 "class property with a description, which will be used in `./pants help`. For "
                 "the\n    best rendering, use soft wrapping (e.g. implicit string concatenation"
                 ") within paragraphs, but\n    hard wrapping (`\n`) to separate distinct "
                 "paragraphs and/or lists.\n    "),
                "is_union":
                False,
                "module":
                "pants.engine.target",
                "name":
                "Target",
                "provider":
                "help_info_extracter_test",
                "returned_by_rules":
                ("pants.help.help_info_extracter_test.test_get_all_help_info.rule_info_test",
                 ),
                "union_members": (),
                "union_type":
                None,
                "used_in_rules": (),
            },
            "pants.option.scope.Scope": {
                "consumed_by_rules": (),
                "dependees": (),
                "dependencies": (),
                "documentation": "An options scope.",
                "is_union": False,
                "module": "pants.option.scope",
                "name": "Scope",
                "provider": "pants.option.scope",
                "returned_by_rules": (),
                "union_members": (),
                "union_type": None,
                "used_in_rules": ("construct_scope_foo", ),
            },
        },
    }

    # Break down this colossal structure into pieces so it is easier to spot where the issue is.
    # Check keys equality first, then contents
    assert set(expected_all_help_info_dict) == set(all_help_info_dict)
    for key in all_help_info_dict:
        actual = all_help_info_dict[key]
        expected = expected_all_help_info_dict[key]
        assert expected == actual
def test_get_all_help_info():
    class Global(Subsystem):
        options_scope = GLOBAL_SCOPE
        help = "Global options."

        opt1 = IntOption("-o", "--opt1", default=42, help="Option 1")

    class Foo(Subsystem):
        options_scope = "foo"
        help = "A foo."

        opt2 = BoolOption("--opt2",
                          default=True,
                          advanced=True,
                          help="Option 2")

    class Bar(GoalSubsystem):
        name = "bar"
        help = "The bar goal."
        deprecated_options_scope = "bar-old"
        deprecated_options_scope_removal_version = "9.9.999"

    class QuxField(StringField):
        alias = "qux"
        default = "blahblah"
        help = "A qux string."

    class QuuxField(IntField):
        alias = "quux"
        required = True
        help = "A quux int.\n\nMust be non-zero. Or zero. Whatever you like really."

    class BazLibrary(Target):
        alias = "baz_library"
        help = "A library of baz-es.\n\nUse it however you like."

        core_fields = [QuxField, QuuxField]

    options = Options.create(
        env={},
        config=Config.load([]),
        known_scope_infos=[
            Global.get_scope_info(),
            Foo.get_scope_info(),
            Bar.get_scope_info()
        ],
        args=["./pants"],
        bootstrap_option_values=None,
    )
    Global.register_options_on_scope(options)
    Foo.register_options_on_scope(options)
    Bar.register_options_on_scope(options)

    @rule
    def rule_info_test(foo: Foo) -> Target:
        """This rule is for testing info extraction only."""

    def fake_consumed_scopes_mapper(scope: str) -> Tuple[str, ...]:
        return ("somescope", f"used_by_{scope or 'GLOBAL_SCOPE'}")

    bc_builder = BuildConfiguration.Builder()
    bc_builder.register_subsystems("help_info_extracter_test", (Foo, Bar))
    bc_builder.register_target_types("help_info_extracter_test",
                                     (BazLibrary, ))
    bc_builder.register_rules("help_info_extracter_test",
                              collect_rules(locals()))

    all_help_info = HelpInfoExtracter.get_all_help_info(
        options,
        UnionMembership({}),
        fake_consumed_scopes_mapper,
        RegisteredTargetTypes({BazLibrary.alias: BazLibrary}),
        bc_builder.create(),
    )

    all_help_info_dict = all_help_info.asdict()
    expected_all_help_info_dict = {
        "scope_to_help_info": {
            GLOBAL_SCOPE: {
                "scope":
                GLOBAL_SCOPE,
                "description":
                "Global options.",
                "provider":
                "",
                "is_goal":
                False,
                "deprecated_scope":
                None,
                "basic": ({
                    "display_args": ("-o=<int>", "--opt1=<int>"),
                    "comma_separated_display_args": "-o=<int>, --opt1=<int>",
                    "scoped_cmd_line_args": ("-o", "--opt1"),
                    "unscoped_cmd_line_args": ("-o", "--opt1"),
                    "config_key": "opt1",
                    "env_var": "PANTS_OPT1",
                    "value_history": {
                        "ranked_values": (
                            {
                                "rank": Rank.NONE,
                                "value": None,
                                "details": None
                            },
                            {
                                "rank": Rank.HARDCODED,
                                "value": 42,
                                "details": None
                            },
                        ),
                    },
                    "typ": int,
                    "default": 42,
                    "help": "Option 1",
                    "deprecation_active": False,
                    "deprecated_message": None,
                    "removal_version": None,
                    "removal_hint": None,
                    "choices": None,
                    "comma_separated_choices": None,
                }, ),
                "advanced":
                tuple(),
                "deprecated":
                tuple(),
            },
            "foo": {
                "scope":
                "foo",
                "provider":
                "help_info_extracter_test",
                "description":
                "A foo.",
                "is_goal":
                False,
                "deprecated_scope":
                None,
                "basic": (),
                "advanced": ({
                    "display_args": ("--[no-]foo-opt2", ),
                    "comma_separated_display_args":
                    "--[no-]foo-opt2",
                    "scoped_cmd_line_args": ("--foo-opt2", "--no-foo-opt2"),
                    "unscoped_cmd_line_args": ("--opt2", "--no-opt2"),
                    "config_key":
                    "opt2",
                    "env_var":
                    "PANTS_FOO_OPT2",
                    "value_history": {
                        "ranked_values": (
                            {
                                "rank": Rank.NONE,
                                "value": None,
                                "details": None
                            },
                            {
                                "rank": Rank.HARDCODED,
                                "value": True,
                                "details": None
                            },
                        ),
                    },
                    "typ":
                    bool,
                    "default":
                    True,
                    "help":
                    "Option 2",
                    "deprecation_active":
                    False,
                    "deprecated_message":
                    None,
                    "removal_version":
                    None,
                    "removal_hint":
                    None,
                    "choices":
                    None,
                    "comma_separated_choices":
                    None,
                }, ),
                "deprecated":
                tuple(),
            },
            "bar": {
                "scope": "bar",
                "provider": "help_info_extracter_test",
                "description": "The bar goal.",
                "is_goal": True,
                "deprecated_scope": "bar-old",
                "basic": tuple(),
                "advanced": tuple(),
                "deprecated": tuple(),
            },
            "bar-old": {
                "scope": "bar-old",
                "provider": "help_info_extracter_test",
                "description": "The bar goal.",
                "is_goal": True,
                "deprecated_scope": "bar-old",
                "basic": tuple(),
                "advanced": tuple(),
                "deprecated": tuple(),
            },
        },
        "rule_output_type_to_rule_infos": {
            "Foo": ({
                "description": None,
                "help": "A foo.",
                "input_gets": ("Get(ScopedOptions, Scope, ..)", ),
                "input_types": (),
                "name": "construct_scope_foo",
                "output_desc": None,
                "output_type": "Foo",
                "provider": "help_info_extracter_test",
            }, ),
            "Target": ({
                "description":
                None,
                "help":
                "This rule is for testing info extraction only.",
                "input_gets": (),
                "input_types": ("Foo", ),
                "name":
                "pants.help.help_info_extracter_test.rule_info_test",
                "output_desc":
                ("A Target represents an addressable set of metadata.\n\n    Set the "
                 "`help` class property with a description, which will be used in "
                 "`./pants help`. For the\n    best rendering, use soft wrapping (e.g. "
                 "implicit string concatenation) within paragraphs, but\n    hard wrapping "
                 "(`\n`) to separate distinct paragraphs and/or lists.\n    "),
                "output_type":
                "Target",
                "provider":
                "help_info_extracter_test",
            }, ),
        },
        "name_to_goal_info": {
            "bar": {
                "name": "bar",
                "provider": "help_info_extracter_test",
                "description": "The bar goal.",
                "consumed_scopes": ("somescope", "used_by_bar"),
                "is_implemented": True,
            },
            "bar-old": {
                "name": "bar",
                "provider": "help_info_extracter_test",
                "description": "The bar goal.",
                "consumed_scopes": ("somescope", "used_by_bar-old"),
                "is_implemented": True,
            },
        },
        "name_to_target_type_info": {
            "baz_library": {
                "alias":
                "baz_library",
                "provider":
                "help_info_extracter_test",
                "summary":
                "A library of baz-es.",
                "description":
                "A library of baz-es.\n\nUse it however you like.",
                "fields": (
                    {
                        "alias": "qux",
                        "provider": "",
                        "default": "'blahblah'",
                        "description": "A qux string.",
                        "required": False,
                        "type_hint": "str | None",
                    },
                    {
                        "alias":
                        "quux",
                        "provider":
                        "",
                        "default":
                        None,
                        "description":
                        "A quux int.\n\nMust be non-zero. Or zero. "
                        "Whatever you like really.",
                        "required":
                        True,
                        "type_hint":
                        "int",
                    },
                ),
            }
        },
    }
    assert expected_all_help_info_dict == all_help_info_dict
Esempio n. 39
0
def test_get_all_help_info():
    class Global(Subsystem):
        options_scope = GLOBAL_SCOPE
        help = "Global options."

        @classmethod
        def register_options(cls, register):
            register("-o", "--opt1", type=int, default=42, help="Option 1")

    class Foo(Subsystem):
        options_scope = "foo"
        help = "A foo."

        @classmethod
        def register_options(cls, register):
            register("--opt2", type=bool, default=True, help="Option 2")
            register("--opt3", advanced=True, choices=["a", "b", "c"])

    class Bar(GoalSubsystem):
        name = "bar"
        help = "The bar goal."

    class QuxField(StringField):
        alias = "qux"
        default = "blahblah"
        help = "A qux string."

    class QuuxField(IntField):
        alias = "quux"
        required = True
        help = "A quux int.\n\nMust be non-zero. Or zero. Whatever you like really."

    class BazLibrary(Target):
        alias = "baz_library"
        help = "A library of baz-es.\n\nUse it however you like."

        core_fields = [QuxField, QuuxField]

    options = Options.create(
        env={},
        config=Config.load_file_contents(""),
        known_scope_infos=[
            Global.get_scope_info(),
            Foo.get_scope_info(),
            Bar.get_scope_info()
        ],
        args=["./pants"],
        bootstrap_option_values=None,
    )
    Global.register_options_on_scope(options)
    Foo.register_options_on_scope(options)
    Bar.register_options_on_scope(options)

    def fake_consumed_scopes_mapper(scope: str) -> Tuple[str, ...]:
        return ("somescope", f"used_by_{scope or 'GLOBAL_SCOPE'}")

    all_help_info = HelpInfoExtracter.get_all_help_info(
        options,
        UnionMembership({}),
        fake_consumed_scopes_mapper,
        RegisteredTargetTypes({BazLibrary.alias: BazLibrary}),
    )
    all_help_info_dict = dataclasses.asdict(all_help_info)
    expected_all_help_info_dict = {
        "scope_to_help_info": {
            GLOBAL_SCOPE: {
                "scope":
                GLOBAL_SCOPE,
                "description":
                "Global options.",
                "is_goal":
                False,
                "basic": ({
                    "display_args": ("-o=<int>", "--opt1=<int>"),
                    "comma_separated_display_args": "-o=<int>, --opt1=<int>",
                    "scoped_cmd_line_args": ("-o", "--opt1"),
                    "unscoped_cmd_line_args": ("-o", "--opt1"),
                    "config_key": "opt1",
                    "env_var": "PANTS_OPT1",
                    "value_history": {
                        "ranked_values": (
                            {
                                "rank": Rank.NONE,
                                "value": None,
                                "details": None
                            },
                            {
                                "rank": Rank.HARDCODED,
                                "value": 42,
                                "details": None
                            },
                        ),
                    },
                    "typ": int,
                    "default": 42,
                    "help": "Option 1",
                    "deprecation_active": False,
                    "deprecated_message": None,
                    "removal_version": None,
                    "removal_hint": None,
                    "choices": None,
                    "comma_separated_choices": None,
                }, ),
                "advanced":
                tuple(),
                "deprecated":
                tuple(),
            },
            "foo": {
                "scope":
                "foo",
                "description":
                "A foo.",
                "is_goal":
                False,
                "basic": ({
                    "display_args": ("--[no-]foo-opt2", ),
                    "comma_separated_display_args":
                    "--[no-]foo-opt2",
                    "scoped_cmd_line_args": ("--foo-opt2", "--no-foo-opt2"),
                    "unscoped_cmd_line_args": ("--opt2", "--no-opt2"),
                    "config_key":
                    "opt2",
                    "env_var":
                    "PANTS_FOO_OPT2",
                    "value_history": {
                        "ranked_values": (
                            {
                                "rank": Rank.NONE,
                                "value": None,
                                "details": None
                            },
                            {
                                "rank": Rank.HARDCODED,
                                "value": True,
                                "details": None
                            },
                        ),
                    },
                    "typ":
                    bool,
                    "default":
                    True,
                    "help":
                    "Option 2",
                    "deprecation_active":
                    False,
                    "deprecated_message":
                    None,
                    "removal_version":
                    None,
                    "removal_hint":
                    None,
                    "choices":
                    None,
                    "comma_separated_choices":
                    None,
                }, ),
                "advanced": ({
                    "display_args": ("--foo-opt3=<str>", ),
                    "comma_separated_display_args": "--foo-opt3=<str>",
                    "scoped_cmd_line_args": ("--foo-opt3", ),
                    "unscoped_cmd_line_args": ("--opt3", ),
                    "config_key": "opt3",
                    "env_var": "PANTS_FOO_OPT3",
                    "value_history": {
                        "ranked_values": ({
                            "rank": Rank.NONE,
                            "value": None,
                            "details": None
                        }, ),
                    },
                    "typ": str,
                    "default": None,
                    "help": "No help available.",
                    "deprecation_active": False,
                    "deprecated_message": None,
                    "removal_version": None,
                    "removal_hint": None,
                    "choices": ("a", "b", "c"),
                    "comma_separated_choices": "a, b, c",
                }, ),
                "deprecated":
                tuple(),
            },
            "bar": {
                "scope": "bar",
                "description": "The bar goal.",
                "is_goal": True,
                "basic": tuple(),
                "advanced": tuple(),
                "deprecated": tuple(),
            },
        },
        "name_to_goal_info": {
            "bar": {
                "name": "bar",
                "description": "The bar goal.",
                "consumed_scopes": ("somescope", "used_by_bar"),
                "is_implemented": True,
            }
        },
        "name_to_target_type_info": {
            "baz_library": {
                "alias":
                "baz_library",
                "summary":
                "A library of baz-es.",
                "description":
                "A library of baz-es.\n\nUse it however you like.",
                "fields": (
                    {
                        "alias": "qux",
                        "default": "'blahblah'",
                        "description": "A qux string.",
                        "required": False,
                        "type_hint": "str | None",
                    },
                    {
                        "alias":
                        "quux",
                        "default":
                        None,
                        "description":
                        "A quux int.\n\nMust be non-zero. Or zero. "
                        "Whatever you like really.",
                        "required":
                        True,
                        "type_hint":
                        "int",
                    },
                ),
            }
        },
    }
    assert expected_all_help_info_dict == all_help_info_dict
Esempio n. 40
0
 def test_option_tracker_required(self):
     with self.assertRaises(Options.OptionTrackerRequiredError):
         Options.create(None, None, [])
Esempio n. 41
0
def test_get_all_help_info():
    class Global(Subsystem):
        """Global options."""

        options_scope = GLOBAL_SCOPE

        @classmethod
        def register_options(cls, register):
            register("-o", "--opt1", type=int, default=42, help="Option 1")

    class Foo(Subsystem):
        """A foo."""

        options_scope = "foo"

        @classmethod
        def register_options(cls, register):
            register("--opt2", type=bool, default=True, help="Option 2")
            register("--opt3", advanced=True, choices=["a", "b", "c"])

    class Bar(GoalSubsystem):
        """The bar goal."""

        name = "bar"

    options = Options.create(
        env={},
        config=Config.load_file_contents(""),
        known_scope_infos=[
            Global.get_scope_info(),
            Foo.get_scope_info(),
            Bar.get_scope_info()
        ],
        args=["./pants"],
        bootstrap_option_values=None,
    )
    Global.register_options_on_scope(options)
    Foo.register_options_on_scope(options)
    Bar.register_options_on_scope(options)

    def fake_consumed_scopes_mapper(scope: str) -> Tuple[str, ...]:
        return ("somescope", f"used_by_{scope or 'GLOBAL_SCOPE'}")

    all_help_info = HelpInfoExtracter.get_all_help_info(
        options, UnionMembership({}), fake_consumed_scopes_mapper)
    all_help_info_dict = dataclasses.asdict(all_help_info)
    expected_all_help_info_dict = {
        "scope_to_help_info": {
            GLOBAL_SCOPE: {
                "scope":
                GLOBAL_SCOPE,
                "description":
                "Global options.",
                "is_goal":
                False,
                "basic": ({
                    "display_args": ("-o=<int>", "--opt1=<int>"),
                    "comma_separated_display_args": "-o=<int>, --opt1=<int>",
                    "scoped_cmd_line_args": ("-o", "--opt1"),
                    "unscoped_cmd_line_args": ("-o", "--opt1"),
                    "config_key": "opt1",
                    "env_var": "PANTS_OPT1",
                    "value_history": {
                        "ranked_values": (
                            {
                                "rank": Rank.NONE,
                                "value": None,
                                "details": None
                            },
                            {
                                "rank": Rank.HARDCODED,
                                "value": 42,
                                "details": None
                            },
                        ),
                    },
                    "typ": int,
                    "default": 42,
                    "help": "Option 1",
                    "deprecated_message": None,
                    "removal_version": None,
                    "removal_hint": None,
                    "choices": None,
                    "comma_separated_choices": None,
                }, ),
                "advanced":
                tuple(),
                "deprecated":
                tuple(),
            },
            "foo": {
                "scope":
                "foo",
                "description":
                "A foo.",
                "is_goal":
                False,
                "basic": ({
                    "display_args": ("--[no-]foo-opt2", ),
                    "comma_separated_display_args":
                    "--[no-]foo-opt2",
                    "scoped_cmd_line_args": ("--foo-opt2", "--no-foo-opt2"),
                    "unscoped_cmd_line_args": ("--opt2", "--no-opt2"),
                    "config_key":
                    "opt2",
                    "env_var":
                    "PANTS_FOO_OPT2",
                    "value_history": {
                        "ranked_values": (
                            {
                                "rank": Rank.NONE,
                                "value": None,
                                "details": None
                            },
                            {
                                "rank": Rank.HARDCODED,
                                "value": True,
                                "details": None
                            },
                        ),
                    },
                    "typ":
                    bool,
                    "default":
                    True,
                    "help":
                    "Option 2",
                    "deprecated_message":
                    None,
                    "removal_version":
                    None,
                    "removal_hint":
                    None,
                    "choices":
                    None,
                    "comma_separated_choices":
                    None,
                }, ),
                "advanced": ({
                    "display_args": ("--foo-opt3=<str>", ),
                    "comma_separated_display_args": "--foo-opt3=<str>",
                    "scoped_cmd_line_args": ("--foo-opt3", ),
                    "unscoped_cmd_line_args": ("--opt3", ),
                    "config_key": "opt3",
                    "env_var": "PANTS_FOO_OPT3",
                    "value_history": {
                        "ranked_values": ({
                            "rank": Rank.NONE,
                            "value": None,
                            "details": None
                        }, ),
                    },
                    "typ": str,
                    "default": None,
                    "help": "No help available.",
                    "deprecated_message": None,
                    "removal_version": None,
                    "removal_hint": None,
                    "choices": ("a", "b", "c"),
                    "comma_separated_choices": "a, b, c",
                }, ),
                "deprecated":
                tuple(),
            },
            "bar": {
                "scope": "bar",
                "description": "The bar goal.",
                "is_goal": True,
                "basic": tuple(),
                "advanced": tuple(),
                "deprecated": tuple(),
            },
        },
        "name_to_goal_info": {
            "bar": {
                "name": "bar",
                "description": "The bar goal.",
                "consumed_scopes": ("somescope", "used_by_bar"),
                "is_implemented": True,
            }
        },
    }
    assert expected_all_help_info_dict == all_help_info_dict
Esempio n. 42
0
  def test_scope_deprecation(self):
    # Note: This test demonstrates that two different new scopes can deprecate the same
    # old scope. I.e., it's possible to split an old scope's options among multiple new scopes.
    class DummyOptionable1(Optionable):
      options_scope = 'new-scope1'
      options_scope_category = ScopeInfo.SUBSYSTEM
      deprecated_options_scope = 'deprecated-scope'
      deprecated_options_scope_removal_version = '9999.9.9'

    class DummyOptionable2(Optionable):
      options_scope = 'new-scope2'
      options_scope_category = ScopeInfo.SUBSYSTEM
      deprecated_options_scope = 'deprecated-scope'
      deprecated_options_scope_removal_version = '9999.9.9'

    options = Options.create(env={},
                             config=self._create_config({
                               DummyOptionable1.options_scope: {
                                 'foo': 'xx'
                               },
                               DummyOptionable1.deprecated_options_scope: {
                                 'foo': 'yy',
                                 'bar': 'zz',
                                 'baz': 'ww',
                                 'qux': 'uu'
                               },
                             }),
                             known_scope_infos=[
                               DummyOptionable1.get_scope_info(),
                               DummyOptionable2.get_scope_info()
                             ],
                             args=shlex.split('./pants --new-scope1-baz=vv'),
                             option_tracker=OptionTracker())

    options.register(DummyOptionable1.options_scope, '--foo')
    options.register(DummyOptionable1.options_scope, '--bar')
    options.register(DummyOptionable1.options_scope, '--baz')
    options.register(DummyOptionable2.options_scope, '--qux')

    with self.warnings_catcher() as w:
      vals1 = options.for_scope(DummyOptionable1.options_scope)

    # Check that we got a warning.
    self.assertEquals(1, len(w))
    self.assertTrue(isinstance(w[0].message, DeprecationWarning))

    # Check values.
    # Deprecated scope takes precedence at equal rank.
    self.assertEquals('yy', vals1.foo)
    self.assertEquals('zz', vals1.bar)
    # New scope takes precedence at higher rank.
    self.assertEquals('vv', vals1.baz)

    with self.warnings_catcher() as w:
      vals2 = options.for_scope(DummyOptionable2.options_scope)

    # Check that we got a warning.
    self.assertEquals(1, len(w))
    self.assertTrue(isinstance(w[0].message, DeprecationWarning))

    # Check values.
    self.assertEquals('uu', vals2.qux)