~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: John Arbash Meinel
  • Date: 2006-08-16 22:00:19 UTC
  • mto: This revision was merged to the branch mainline in revision 1942.
  • Revision ID: john@arbash-meinel.com-20060816220019-541cb90093258ac3
Using real utf8 and cache_utf8 has similar performance, 272ms, and 363ms

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Bazaar-NG -- distributed version control
 
1
# Bazaar -- distributed version control
2
2
#
3
3
# Copyright (C) 2005 by Canonical Ltd
4
4
#
53
53
from bzrlib.trace import mutter
54
54
 
55
55
 
 
56
# On win32, O_BINARY is used to indicate the file should
 
57
# be opened in binary mode, rather than text mode.
 
58
# On other platforms, O_BINARY doesn't exist, because
 
59
# they always open in binary mode, so it is okay to
 
60
# OR with 0 on those platforms
 
61
O_BINARY = getattr(os, 'O_BINARY', 0)
 
62
 
 
63
 
56
64
def make_readonly(filename):
57
65
    """Make a filename read-only."""
58
66
    mod = os.stat(filename).st_mode
118
126
        raise
119
127
 
120
128
 
 
129
def get_umask():
 
130
    """Return the current umask"""
 
131
    # Assume that people aren't messing with the umask while running
 
132
    # XXX: This is not thread safe, but there is no way to get the
 
133
    #      umask without setting it
 
134
    umask = os.umask(0)
 
135
    os.umask(umask)
 
136
    return umask
 
137
 
 
138
 
121
139
def kind_marker(kind):
122
140
    if kind == 'file':
123
141
        return ''
875
893
    to exclude some directories, they are then not descended into.
876
894
    
877
895
    The data yielded is of the form:
878
 
    [(relpath, basename, kind, lstat, path_from_top), ...]
 
896
    ((directory-relpath, directory-path-from-top),
 
897
    [(relpath, basename, kind, lstat), ...]),
 
898
     - directory-relpath is the relative path of the directory being returned
 
899
       with respect to top. prefix is prepended to this.
 
900
     - directory-path-from-root is the path including top for this directory. 
 
901
       It is suitable for use with os functions.
 
902
     - relpath is the relative path within the subtree being walked.
 
903
     - basename is the basename of the path
 
904
     - kind is the kind of the file now. If unknown then the file is not
 
905
       present within the tree - but it may be recorded as versioned. See
 
906
       versioned_kind.
 
907
     - lstat is the stat data *if* the file was statted.
 
908
     - planned, not implemented: 
 
909
       path_from_tree_root is the path from the root of the tree.
879
910
 
880
911
    :param prefix: Prefix the relpaths that are yielded with 'prefix'. This 
881
912
        allows one to walk a subtree but get paths that are relative to a tree
882
913
        rooted higher up.
883
914
    :return: an iterator over the dirs.
884
915
    """
 
916
    #TODO there is a bit of a smell where the results of the directory-
 
917
    # summary in this, and the path from the root, may not agree 
 
918
    # depending on top and prefix - i.e. ./foo and foo as a pair leads to
 
919
    # potentially confusing output. We should make this more robust - but
 
920
    # not at a speed cost. RBC 20060731
885
921
    lstat = os.lstat
886
922
    pending = []
887
923
    _directory = _directory_kind
899
935
        for name in sorted(_listdir(top)):
900
936
            abspath = top + '/' + name
901
937
            statvalue = lstat(abspath)
902
 
            dirblock.append ((relroot + name, name, file_kind_from_stat_mode(statvalue.st_mode), statvalue, abspath))
903
 
        yield dirblock
 
938
            dirblock.append((relroot + name, name,
 
939
                file_kind_from_stat_mode(statvalue.st_mode),
 
940
                statvalue, abspath))
 
941
        yield (currentdir[0], top), dirblock
904
942
        # push the user specified dirs from dirblock
905
943
        for dir in reversed(dirblock):
906
944
            if dir[2] == _directory:
907
945
                pending.append(dir)
908
946
 
909
947
 
 
948
def copy_tree(from_path, to_path, handlers={}):
 
949
    """Copy all of the entries in from_path into to_path.
 
950
 
 
951
    :param from_path: The base directory to copy. 
 
952
    :param to_path: The target directory. If it does not exist, it will
 
953
        be created.
 
954
    :param handlers: A dictionary of functions, which takes a source and
 
955
        destinations for files, directories, etc.
 
956
        It is keyed on the file kind, such as 'directory', 'symlink', or 'file'
 
957
        'file', 'directory', and 'symlink' should always exist.
 
958
        If they are missing, they will be replaced with 'os.mkdir()',
 
959
        'os.readlink() + os.symlink()', and 'shutil.copy2()', respectively.
 
960
    """
 
961
    # Now, just copy the existing cached tree to the new location
 
962
    # We use a cheap trick here.
 
963
    # Absolute paths are prefixed with the first parameter
 
964
    # relative paths are prefixed with the second.
 
965
    # So we can get both the source and target returned
 
966
    # without any extra work.
 
967
 
 
968
    def copy_dir(source, dest):
 
969
        os.mkdir(dest)
 
970
 
 
971
    def copy_link(source, dest):
 
972
        """Copy the contents of a symlink"""
 
973
        link_to = os.readlink(source)
 
974
        os.symlink(link_to, dest)
 
975
 
 
976
    real_handlers = {'file':shutil.copy2,
 
977
                     'symlink':copy_link,
 
978
                     'directory':copy_dir,
 
979
                    }
 
980
    real_handlers.update(handlers)
 
981
 
 
982
    if not os.path.exists(to_path):
 
983
        real_handlers['directory'](from_path, to_path)
 
984
 
 
985
    for dir_info, entries in walkdirs(from_path, prefix=to_path):
 
986
        for relpath, name, kind, st, abspath in entries:
 
987
            real_handlers[kind](abspath, relpath)
 
988
 
 
989
 
910
990
def path_prefix_key(path):
911
991
    """Generate a prefix-order path key for path.
912
992