calculate-relative
author Simon MacMullen <simon@rabbitmq.com>
Fri Feb 03 15:59:12 2012 +0000 (3 months ago)
changeset 8922 4f87837a40be
parent 1426 fd671216482b
permissions -rwxr-xr-x
Merge bug24702
dpw@1539
     1
#!/usr/bin/env python
paulj@1426
     2
#
paulj@1426
     3
# relpath.py
paulj@1426
     4
# R.Barran 30/08/2004
paulj@1426
     5
# Retrieved from http://code.activestate.com/recipes/302594/
paulj@1426
     6
paulj@1426
     7
import os
paulj@1426
     8
import sys
paulj@1426
     9
paulj@1426
    10
def relpath(target, base=os.curdir):
paulj@1426
    11
    """
paulj@1426
    12
    Return a relative path to the target from either the current dir or an optional base dir.
paulj@1426
    13
    Base can be a directory specified either as absolute or relative to current dir.
paulj@1426
    14
    """
paulj@1426
    15
paulj@1426
    16
    if not os.path.exists(target):
paulj@1426
    17
        raise OSError, 'Target does not exist: '+target
paulj@1426
    18
paulj@1426
    19
    if not os.path.isdir(base):
paulj@1426
    20
        raise OSError, 'Base is not a directory or does not exist: '+base
paulj@1426
    21
paulj@1426
    22
    base_list = (os.path.abspath(base)).split(os.sep)
paulj@1426
    23
    target_list = (os.path.abspath(target)).split(os.sep)
paulj@1426
    24
paulj@1426
    25
    # On the windows platform the target may be on a completely different drive from the base.
paulj@1426
    26
    if os.name in ['nt','dos','os2'] and base_list[0] <> target_list[0]:
paulj@1426
    27
        raise OSError, 'Target is on a different drive to base. Target: '+target_list[0].upper()+', base: '+base_list[0].upper()
paulj@1426
    28
paulj@1426
    29
    # Starting from the filepath root, work out how much of the filepath is
paulj@1426
    30
    # shared by base and target.
paulj@1426
    31
    for i in range(min(len(base_list), len(target_list))):
paulj@1426
    32
        if base_list[i] <> target_list[i]: break
paulj@1426
    33
    else:
paulj@1426
    34
        # If we broke out of the loop, i is pointing to the first differing path elements.
paulj@1426
    35
        # If we didn't break out of the loop, i is pointing to identical path elements.
paulj@1426
    36
        # Increment i so that in all cases it points to the first differing path elements.
paulj@1426
    37
        i+=1
paulj@1426
    38
paulj@1426
    39
    rel_list = [os.pardir] * (len(base_list)-i) + target_list[i:]
paulj@1426
    40
    if (len(rel_list) == 0):
paulj@1426
    41
        return "."
paulj@1426
    42
    return os.path.join(*rel_list)
paulj@1426
    43
paulj@1426
    44
if __name__ == "__main__":
paulj@1426
    45
    print(relpath(sys.argv[1], sys.argv[2]))