Returns all available packages. Optionally, package names (and name globs)
    can be passed and the results will be filtered to packages matching those
    names.

    This function can be helpful in discovering the version or repo to specify
    in a :mod:`pkg.installed <salt.states.pkg.installed>` state.

    The return data will be a dictionary mapping package names to a list of
    version numbers, ordered from newest to oldest. If ``byrepo`` is set to
    ``True``, then the return dictionary will contain repository names at the
    top level, and each repository will map packages to lists of version
    numbers. For example:

    .. code-block:: python

        # With byrepo=False (default)
        {
            'bash': ['4.4.005-2'],
            'nginx': ['1.10.2-2']
        }
        # With byrepo=True
        {
            'core': {
                'bash': ['4.4.005-2']
            },
            'extra': {
                'nginx': ['1.10.2-2']
            }
        }

    fromrepo : None
        Only include results from the specified repo(s). Multiple repos can be
        specified, comma-separated.

    byrepo : False
        When ``True``, the return data for each package will be organized by
        repository.

    refresh : False
        When ``True``, the package database will be refreshed (i.e. ``pacman
        -Sy``) before checking for available versions.

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.list_repo_pkgs
        salt '*' pkg.list_repo_pkgs foo bar baz
        salt '*' pkg.list_repo_pkgs 'samba4*' fromrepo=base,updates
        salt '*' pkg.list_repo_pkgs 'python2-*' byrepo=True

def list_repo_pkgs(*args, **kwargs):
    '''
    Returns all available packages. Optionally, package names (and name globs)
    can be passed and the results will be filtered to packages matching those
    names.

    This function can be helpful in discovering the version or repo to specify
    in a :mod:`pkg.installed <salt.states.pkg.installed>` state.

    The return data will be a dictionary mapping package names to a list of
    version numbers, ordered from newest to oldest. If ``byrepo`` is set to
    ``True``, then the return dictionary will contain repository names at the
    top level, and each repository will map packages to lists of version
    numbers. For example:

    .. code-block:: python

        # With byrepo=False (default)
        {
            'bash': ['4.4.005-2'],
            'nginx': ['1.10.2-2']
        }
        # With byrepo=True
        {
            'core': {
                'bash': ['4.4.005-2']
            },
            'extra': {
                'nginx': ['1.10.2-2']
            }
        }

    fromrepo : None
        Only include results from the specified repo(s). Multiple repos can be
        specified, comma-separated.

    byrepo : False
        When ``True``, the return data for each package will be organized by
        repository.

    refresh : False
        When ``True``, the package database will be refreshed (i.e. ``pacman
        -Sy``) before checking for available versions.

    CLI Examples:

    .. code-block:: bash

        salt '*' pkg.list_repo_pkgs
        salt '*' pkg.list_repo_pkgs foo bar baz
        salt '*' pkg.list_repo_pkgs 'samba4*' fromrepo=base,updates
        salt '*' pkg.list_repo_pkgs 'python2-*' byrepo=True
    '''
    kwargs = salt.utils.args.clean_kwargs(**kwargs)
    fromrepo = kwargs.pop('fromrepo', '') or ''
    byrepo = kwargs.pop('byrepo', False)
    refresh = kwargs.pop('refresh', False)
    if kwargs:
        salt.utils.args.invalid_kwargs(kwargs)

    if fromrepo:
        try:
            repos = [x.strip() for x in fromrepo.split(',')]
        except AttributeError:
            repos = [x.strip() for x in six.text_type(fromrepo).split(',')]
    else:
        repos = []

    if refresh:
        refresh_db()

    out = __salt__['cmd.run_all'](
        ['pacman', '-Sl'],
        output_loglevel='trace',
        ignore_retcode=True,
        python_shell=False
    )

    ret = {}
    for line in salt.utils.itertools.split(out['stdout'], '\n'):
        try:
            repo, pkg_name, pkg_ver = line.strip().split()[:3]
        except ValueError:
            continue

        if repos and repo not in repos:
            continue

        if args:
            for arg in args:
                if fnmatch.fnmatch(pkg_name, arg):
                    skip_pkg = False
                    break
            else:
                # Package doesn't match any of the passed args, skip it
                continue

        ret.setdefault(repo, {}).setdefault(pkg_name, []).append(pkg_ver)

    if byrepo:
        for reponame in ret:
            # Sort versions newest to oldest
            for pkgname in ret[reponame]:
                sorted_versions = sorted(
                    [_LooseVersion(x) for x in ret[reponame][pkgname]],
                    reverse=True
                )
                ret[reponame][pkgname] = [x.vstring for x in sorted_versions]
        return ret
    else:
        byrepo_ret = {}
        for reponame in ret:
            for pkgname in ret[reponame]:
                byrepo_ret.setdefault(pkgname, []).extend(ret[reponame][pkgname])
        for pkgname in byrepo_ret:
            sorted_versions = sorted(
                [_LooseVersion(x) for x in byrepo_ret[pkgname]],
                reverse=True
            )
            byrepo_ret[pkgname] = [x.vstring for x in sorted_versions]
        return byrepo_ret