Execute a specific top file instead of the default. This is useful to apply
    configurations from a different environment (for example, dev or prod), without
    modifying the default top file.

    queue : False
        Instead of failing immediately when another state run is in progress,
        queue the new state run to begin running once the other has finished.

        This option starts a new thread for each queued state run, so use this
        option sparingly.

    saltenv
        Specify a salt fileserver environment to be used when applying states

    pillarenv
        Specify a Pillar environment to be used when applying states. This
        can also be set in the minion config file using the
        :conf_minion:`pillarenv` option. When neither the
        :conf_minion:`pillarenv` minion config option nor this CLI argument is
        used, all Pillar environments will be merged together.

        .. versionadded:: 2017.7.0

    CLI Example:

    .. code-block:: bash

        salt '*' state.top reverse_top.sls
        salt '*' state.top prod_top.sls exclude=sls_to_exclude
        salt '*' state.top dev_top.sls exclude="[{'id': 'id_to_exclude'}, {'sls': 'sls_to_exclude'}]"

def top(topfn, test=None, queue=False, **kwargs):
    '''
    Execute a specific top file instead of the default. This is useful to apply
    configurations from a different environment (for example, dev or prod), without
    modifying the default top file.

    queue : False
        Instead of failing immediately when another state run is in progress,
        queue the new state run to begin running once the other has finished.

        This option starts a new thread for each queued state run, so use this
        option sparingly.

    saltenv
        Specify a salt fileserver environment to be used when applying states

    pillarenv
        Specify a Pillar environment to be used when applying states. This
        can also be set in the minion config file using the
        :conf_minion:`pillarenv` option. When neither the
        :conf_minion:`pillarenv` minion config option nor this CLI argument is
        used, all Pillar environments will be merged together.

        .. versionadded:: 2017.7.0

    CLI Example:

    .. code-block:: bash

        salt '*' state.top reverse_top.sls
        salt '*' state.top prod_top.sls exclude=sls_to_exclude
        salt '*' state.top dev_top.sls exclude="[{'id': 'id_to_exclude'}, {'sls': 'sls_to_exclude'}]"
    '''
    conflict = _check_queue(queue, kwargs)
    if conflict is not None:
        return conflict
    orig_test = __opts__.get('test', None)
    opts = salt.utils.state.get_sls_opts(__opts__, **kwargs)
    opts['test'] = _get_test_value(test, **kwargs)

    pillar_override = kwargs.get('pillar')
    pillar_enc = kwargs.get('pillar_enc')
    if pillar_enc is None \
            and pillar_override is not None \
            and not isinstance(pillar_override, dict):
        raise SaltInvocationError(
            'Pillar data must be formatted as a dictionary, unless pillar_enc '
            'is specified.'
        )
    try:
        st_ = salt.state.HighState(opts,
                                   pillar_override,
                                   pillar_enc=pillar_enc,
                                   context=__context__,
                                   proxy=__proxy__,
                                   initial_pillar=_get_initial_pillar(opts))
    except NameError:
        st_ = salt.state.HighState(opts,
                                   pillar_override,
                                   pillar_enc=pillar_enc,
                                   context=__context__,
                                   initial_pillar=_get_initial_pillar(opts))
    errors = _get_pillar_errors(kwargs, pillar=st_.opts['pillar'])
    if errors:
        __context__['retcode'] = salt.defaults.exitcodes.EX_PILLAR_FAILURE
        return ['Pillar failed to render with the following messages:'] + errors

    st_.push_active()
    st_.opts['state_top'] = salt.utils.url.create(topfn)
    ret = {}
    orchestration_jid = kwargs.get('orchestration_jid')
    if 'saltenv' in kwargs:
        st_.opts['state_top_saltenv'] = kwargs['saltenv']
    try:
        snapper_pre = _snapper_pre(opts, kwargs.get('__pub_jid', 'called localy'))
        ret = st_.call_highstate(
                exclude=kwargs.get('exclude', []),
                cache=kwargs.get('cache', None),
                cache_name=kwargs.get('cache_name', 'highstate'),
                orchestration_jid=orchestration_jid)
    finally:
        st_.pop_active()

    _set_retcode(ret, highstate=st_.building_highstate)
    # Work around Windows multiprocessing bug, set __opts__['test'] back to
    # value from before this function was run.
    _snapper_post(opts, kwargs.get('__pub_jid', 'called localy'), snapper_pre)
    __opts__['test'] = orig_test
    return ret