Get absolute path to asset in package.

    ``path`` can be just a package name like 'package' or it can be
    a package name and a relative file system path like 'package:util'.

    If ``path`` ends with a slash, it will be stripped unless
    ``keep_slash`` is set (for use with ``rsync``, for example).

    >>> file_path = os.path.normpath(__file__)
    >>> dir_name = os.path.dirname(file_path)
    >>> file_name = os.path.basename(file_path)
    >>> os.chdir(dir_name)
    >>>
    >>> asset_path('runcommands.util') == dir_name
    True
    >>> asset_path('runcommands.util:path.py') == file_path
    True
    >>> asset_path('runcommands.util:{name}.py', format_kwargs={'name': 'path'}) == file_path
    True
    >>> asset_path('runcommands.util:dir/') == (dir_name + '/dir')
    True
    >>> asset_path('runcommands.util:dir/', keep_slash=True) == (dir_name + '/dir/')
    True

def asset_path(path, format_kwargs={}, keep_slash=False):
    """Get absolute path to asset in package.

    ``path`` can be just a package name like 'package' or it can be
    a package name and a relative file system path like 'package:util'.

    If ``path`` ends with a slash, it will be stripped unless
    ``keep_slash`` is set (for use with ``rsync``, for example).

    >>> file_path = os.path.normpath(__file__)
    >>> dir_name = os.path.dirname(file_path)
    >>> file_name = os.path.basename(file_path)
    >>> os.chdir(dir_name)
    >>>
    >>> asset_path('runcommands.util') == dir_name
    True
    >>> asset_path('runcommands.util:path.py') == file_path
    True
    >>> asset_path('runcommands.util:{name}.py', format_kwargs={'name': 'path'}) == file_path
    True
    >>> asset_path('runcommands.util:dir/') == (dir_name + '/dir')
    True
    >>> asset_path('runcommands.util:dir/', keep_slash=True) == (dir_name + '/dir/')
    True

    """
    if format_kwargs:
        path = path.format_map(format_kwargs)

    has_slash = path.endswith(os.sep)

    if ':' in path:
        package_name, *rel_path = path.split(':', 1)
    else:
        package_name, rel_path = path, ()

    try:
        package = importlib.import_module(package_name)
    except ImportError:
        raise ValueError(
            'Could not get asset path for {path}; could not import package: {package_name}'
            .format_map(locals()))

    if not hasattr(package, '__file__'):
        raise ValueError("Can't compute path relative to namespace package")

    package_path = os.path.dirname(package.__file__)
    path = os.path.join(package_path, *rel_path)
    path = os.path.normpath(path)

    if has_slash and keep_slash:
        path = '{path}{slash}'.format(path=path, slash=os.sep)

    return path