Migrates a configuration file.

        This is used to help you update your configurations throughout the
        lifetime of your application. It is probably best explained through
        example.

        Examples:
            Assume we have a JSON config file ('/path/to/config.json')
            like the following:
            ``{"db_name": "test_db_name", "db_host": "1.2.3.4"}``

            >>> spec = YapconfSpec({
            ...    'db_name': {
            ...        'type': 'str',
            ...        'default': 'new_default',
            ...        'previous_defaults': ['test_db_name']
            ...    },
            ...    'db_host': {
            ...        'type': 'str',
            ...        'previous_defaults': ['localhost']
            ...    }
            ... })

            We can migrate that file quite easily with the spec object:

            >>> spec.migrate_config_file('/path/to/config.json')

            Will result in /path/to/config.json being overwritten:
            ``{"db_name": "new_default", "db_host": "1.2.3.4"}``

        Args:
            config_file_path (str): The path to your current config
            always_update (bool): Always update values (even to None)
            current_file_type (str): Defaults to self._file_type
            output_file_name (str): Defaults to the current_file_path
            output_file_type (str): Defaults to self._file_type
            create (bool): Create the file if it doesn't exist (otherwise
                error if the file does not exist).
            update_defaults (bool): Update values that have a value set to
                something listed in the previous_defaults
            dump_kwargs (dict): A key-value pair that will be passed to dump
            include_bootstrap (bool): Include bootstrap items in the output

        Returns:
            box.Box: The newly migrated configuration.

def migrate_config_file(
        self,
        config_file_path,
        always_update=False,
        current_file_type=None,
        output_file_name=None,
        output_file_type=None,
        create=True,
        update_defaults=True,
        dump_kwargs=None,
        include_bootstrap=True,
    ):
        """Migrates a configuration file.

        This is used to help you update your configurations throughout the
        lifetime of your application. It is probably best explained through
        example.

        Examples:
            Assume we have a JSON config file ('/path/to/config.json')
            like the following:
            ``{"db_name": "test_db_name", "db_host": "1.2.3.4"}``

            >>> spec = YapconfSpec({
            ...    'db_name': {
            ...        'type': 'str',
            ...        'default': 'new_default',
            ...        'previous_defaults': ['test_db_name']
            ...    },
            ...    'db_host': {
            ...        'type': 'str',
            ...        'previous_defaults': ['localhost']
            ...    }
            ... })

            We can migrate that file quite easily with the spec object:

            >>> spec.migrate_config_file('/path/to/config.json')

            Will result in /path/to/config.json being overwritten:
            ``{"db_name": "new_default", "db_host": "1.2.3.4"}``

        Args:
            config_file_path (str): The path to your current config
            always_update (bool): Always update values (even to None)
            current_file_type (str): Defaults to self._file_type
            output_file_name (str): Defaults to the current_file_path
            output_file_type (str): Defaults to self._file_type
            create (bool): Create the file if it doesn't exist (otherwise
                error if the file does not exist).
            update_defaults (bool): Update values that have a value set to
                something listed in the previous_defaults
            dump_kwargs (dict): A key-value pair that will be passed to dump
            include_bootstrap (bool): Include bootstrap items in the output

        Returns:
            box.Box: The newly migrated configuration.
        """

        current_file_type = current_file_type or self._file_type
        output_file_type = output_file_type or self._file_type
        output_file_name = output_file_name or config_file_path

        current_config = self._get_config_if_exists(config_file_path,
                                                    create,
                                                    current_file_type)

        migrated_config = {}

        if include_bootstrap:
            items = self._yapconf_items.values()
        else:
            items = [
                item for item in self._yapconf_items.values()
                if not item.bootstrap
            ]
        for item in items:
            item.migrate_config(current_config, migrated_config,
                                always_update, update_defaults)

        if create:
            yapconf.dump_data(migrated_config,
                              filename=output_file_name,
                              file_type=output_file_type,
                              klazz=YapconfLoadError,
                              dump_kwargs=dump_kwargs)

        return Box(migrated_config)