Collector

The collector object is responsible for collecting configuration and setting up converters

For example:

class JsonCollector(Collector):
    def start_configuration(self):
        return MergedOptions()

    def find_missing_config(self, configuration):
        assert "important_option" in configuration

    def extra_prepare(self, configuration, args_dict):
        configuration.update(
              {"some_option": args_dict["some_option"]}
            , source=<extra_prepare>
            )

    def read_file(self, location):
        return json.loads(location)

    def add_configuration(self, configuration, collect_another_source, done, result, src):
        configuration.update(result, source=src)
        for loc in result.get("others", []):
            collect_another_source(
                  os.path.join(os.path.dirname(src), loc)
                , prefix=os.path.splitext(loc)[1]
                )

    def extra_configuration_collection(self, configuration):
        def convert(p, v):
            return v * 2
        configuration.add_converter(
              Converter(
                  convert=convert
                , convert_path=["some", "contrived", "example"]
                )
            )

collector = JsonCollector()
collector.prepare(
      "/path/to/first_config_file.json"
    , {"some_option": "stuff"}
    )

#### /path/to/first_config_file.json
# { "hello": "there"
# , "others": ["some.json"]
# }

#### /path/to/some.json
# { "some":
#   { "contrived":
#     { "example": 2
#     }
#   }
# }

collector.configuration["some_option"] == "stuff"
collector.configuration["some.contrived.example"] == 4

Hooks

class delfick_project.option_merge.collector.Collector

When using the Collector, it is expected that you implement a number of hooks to make this class useful.

exception BadConfigurationErrorKls(_errors)
exception BadFileErrorKls(message)
add_configuration(configuration, collect_another_source, done, result, src)

Hook to add to the configuration the loaded result from src into configuration

The collect_another_source function can be used to collect another source

And done is a dictionary of configuration we have already added

alter_clone_args_dict(new_collector, new_args_dict, *args, **kwargs)

Hook for altering args_dict given to a clone collector it must return a dictionary

This dictionary will be used in the prepare call for the new collector

extra_configuration_collection(configuration)

Hook to do any extra configuration collection or converter registration

extra_prepare(configuration, args_dict)

Hook for any extra preparation before the converters are activated

extra_prepare_after_activation(configuration, args_dict)

Hook for any extra preparation after the converters are activated

find_missing_config(configuration)

Hook to raise errors about missing configuration

home_dir_configuration_location()

Hook to return the location of the configuration in the user’s home directory

read_file(location)

Hook to read in a file and return a dictionary

setup()

Called at __init__ time

start_configuration()

Hook for starting the base of the configuration

Usage

Collector.prepare(configuration_file, args_dict, extra_files=None)

Prepare the collector!

  • Collect all the configuration

  • find missing configuration

  • do self.extra_prepare

  • Activate the converters

  • Do self.extra_prepare_after_activation

Collector.clone(*args, **kwargs)

Create a new collector that is a clone of this one

Collector.register_converters(specs, configuration=None, announce_converters=True)

Register converters

specs

a Dictionary of {key: spec}

Where key is either a string or a tuple of strings

You would use a tuple of strings if you want to have a nested key, which is useful if any part of the key has dots in it.

For example ("images", "ubuntu.16.04")

configuration

The configuration to add the converter to.

This defaults to self.configuration

announce_converters

If True (default) then we log when we convert these keys

For example:

collector.register_converters({
    "one": sb.string_spec(),
    ("two", "three"): sb.integer_spec()
})