Get abs. path for ``path``.

    ``path`` may be a relative or absolute file system path or an asset
    path. If ``path`` is already an abs. path, it will be returned as
    is. Otherwise, it will be converted into a normalized abs. path.

    If ``relative_to`` is passed *and* ``path`` is not absolute, the
    path will be joined to the specified prefix before it's made
    absolute.

    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)
    >>>
    >>> abs_path(file_name) == file_path
    True
    >>> abs_path('runcommands.util:') == dir_name
    True
    >>> abs_path('runcommands.util:path.py') == file_path
    True
    >>> abs_path('/{xyz}', format_kwargs={'xyz': 'abc'})
    '/abc'
    >>> abs_path('banana', relative_to='/usr')
    '/usr/banana'
    >>> abs_path('/usr/banana/')
    '/usr/banana'
    >>> abs_path('banana/', relative_to='/usr', keep_slash=True)
    '/usr/banana/'
    >>> abs_path('runcommands.util:banana/', keep_slash=True) == (dir_name + '/banana/')
    True

def abs_path(path, format_kwargs={}, relative_to=None, keep_slash=False):
    """Get abs. path for ``path``.

    ``path`` may be a relative or absolute file system path or an asset
    path. If ``path`` is already an abs. path, it will be returned as
    is. Otherwise, it will be converted into a normalized abs. path.

    If ``relative_to`` is passed *and* ``path`` is not absolute, the
    path will be joined to the specified prefix before it's made
    absolute.

    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)
    >>>
    >>> abs_path(file_name) == file_path
    True
    >>> abs_path('runcommands.util:') == dir_name
    True
    >>> abs_path('runcommands.util:path.py') == file_path
    True
    >>> abs_path('/{xyz}', format_kwargs={'xyz': 'abc'})
    '/abc'
    >>> abs_path('banana', relative_to='/usr')
    '/usr/banana'
    >>> abs_path('/usr/banana/')
    '/usr/banana'
    >>> abs_path('banana/', relative_to='/usr', keep_slash=True)
    '/usr/banana/'
    >>> abs_path('runcommands.util:banana/', keep_slash=True) == (dir_name + '/banana/')
    True

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

    has_slash = path.endswith(os.sep)

    if os.path.isabs(path):
        path = os.path.normpath(path)
    elif ':' in path:
        path = asset_path(path, keep_slash=False)
    else:
        path = os.path.expanduser(path)
        if relative_to:
            path = os.path.join(relative_to, path)
        path = os.path.abspath(path)
        path = os.path.normpath(path)

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

    return path