symbian-qemu-0.9.1-12/python-2.6.1/Tools/scripts/treesync.py
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 #! /usr/bin/env python
       
     2 
       
     3 """Script to synchronize two source trees.
       
     4 
       
     5 Invoke with two arguments:
       
     6 
       
     7 python treesync.py slave master
       
     8 
       
     9 The assumption is that "master" contains CVS administration while
       
    10 slave doesn't.  All files in the slave tree that have a CVS/Entries
       
    11 entry in the master tree are synchronized.  This means:
       
    12 
       
    13     If the files differ:
       
    14         if the slave file is newer:
       
    15             normalize the slave file
       
    16             if the files still differ:
       
    17                 copy the slave to the master
       
    18         else (the master is newer):
       
    19             copy the master to the slave
       
    20 
       
    21     normalizing the slave means replacing CRLF with LF when the master
       
    22     doesn't use CRLF
       
    23 
       
    24 """
       
    25 
       
    26 import os, sys, stat, getopt
       
    27 
       
    28 # Interactivity options
       
    29 default_answer = "ask"
       
    30 create_files = "yes"
       
    31 create_directories = "no"
       
    32 write_slave = "ask"
       
    33 write_master = "ask"
       
    34 
       
    35 def main():
       
    36     global always_no, always_yes
       
    37     global create_directories, write_master, write_slave
       
    38     opts, args = getopt.getopt(sys.argv[1:], "nym:s:d:f:a:")
       
    39     for o, a in opts:
       
    40         if o == '-y':
       
    41             default_answer = "yes"
       
    42         if o == '-n':
       
    43             default_answer = "no"
       
    44         if o == '-s':
       
    45             write_slave = a
       
    46         if o == '-m':
       
    47             write_master = a
       
    48         if o == '-d':
       
    49             create_directories = a
       
    50         if o == '-f':
       
    51             create_files = a
       
    52         if o == '-a':
       
    53             create_files = create_directories = write_slave = write_master = a
       
    54     try:
       
    55         [slave, master] = args
       
    56     except ValueError:
       
    57         print "usage: python", sys.argv[0] or "treesync.py",
       
    58         print "[-n] [-y] [-m y|n|a] [-s y|n|a] [-d y|n|a] [-f n|y|a]",
       
    59         print "slavedir masterdir"
       
    60         return
       
    61     process(slave, master)
       
    62 
       
    63 def process(slave, master):
       
    64     cvsdir = os.path.join(master, "CVS")
       
    65     if not os.path.isdir(cvsdir):
       
    66         print "skipping master subdirectory", master
       
    67         print "-- not under CVS"
       
    68         return
       
    69     print "-"*40
       
    70     print "slave ", slave
       
    71     print "master", master
       
    72     if not os.path.isdir(slave):
       
    73         if not okay("create slave directory %s?" % slave,
       
    74                     answer=create_directories):
       
    75             print "skipping master subdirectory", master
       
    76             print "-- no corresponding slave", slave
       
    77             return
       
    78         print "creating slave directory", slave
       
    79         try:
       
    80             os.mkdir(slave)
       
    81         except os.error, msg:
       
    82             print "can't make slave directory", slave, ":", msg
       
    83             return
       
    84         else:
       
    85             print "made slave directory", slave
       
    86     cvsdir = None
       
    87     subdirs = []
       
    88     names = os.listdir(master)
       
    89     for name in names:
       
    90         mastername = os.path.join(master, name)
       
    91         slavename = os.path.join(slave, name)
       
    92         if name == "CVS":
       
    93             cvsdir = mastername
       
    94         else:
       
    95             if os.path.isdir(mastername) and not os.path.islink(mastername):
       
    96                 subdirs.append((slavename, mastername))
       
    97     if cvsdir:
       
    98         entries = os.path.join(cvsdir, "Entries")
       
    99         for e in open(entries).readlines():
       
   100             words = e.split('/')
       
   101             if words[0] == '' and words[1:]:
       
   102                 name = words[1]
       
   103                 s = os.path.join(slave, name)
       
   104                 m = os.path.join(master, name)
       
   105                 compare(s, m)
       
   106     for (s, m) in subdirs:
       
   107         process(s, m)
       
   108 
       
   109 def compare(slave, master):
       
   110     try:
       
   111         sf = open(slave, 'r')
       
   112     except IOError:
       
   113         sf = None
       
   114     try:
       
   115         mf = open(master, 'rb')
       
   116     except IOError:
       
   117         mf = None
       
   118     if not sf:
       
   119         if not mf:
       
   120             print "Neither master nor slave exists", master
       
   121             return
       
   122         print "Creating missing slave", slave
       
   123         copy(master, slave, answer=create_files)
       
   124         return
       
   125     if not mf:
       
   126         print "Not updating missing master", master
       
   127         return
       
   128     if sf and mf:
       
   129         if identical(sf, mf):
       
   130             return
       
   131     sft = mtime(sf)
       
   132     mft = mtime(mf)
       
   133     if mft > sft:
       
   134         # Master is newer -- copy master to slave
       
   135         sf.close()
       
   136         mf.close()
       
   137         print "Master             ", master
       
   138         print "is newer than slave", slave
       
   139         copy(master, slave, answer=write_slave)
       
   140         return
       
   141     # Slave is newer -- copy slave to master
       
   142     print "Slave is", sft-mft, "seconds newer than master"
       
   143     # But first check what to do about CRLF
       
   144     mf.seek(0)
       
   145     fun = funnychars(mf)
       
   146     mf.close()
       
   147     sf.close()
       
   148     if fun:
       
   149         print "***UPDATING MASTER (BINARY COPY)***"
       
   150         copy(slave, master, "rb", answer=write_master)
       
   151     else:
       
   152         print "***UPDATING MASTER***"
       
   153         copy(slave, master, "r", answer=write_master)
       
   154 
       
   155 BUFSIZE = 16*1024
       
   156 
       
   157 def identical(sf, mf):
       
   158     while 1:
       
   159         sd = sf.read(BUFSIZE)
       
   160         md = mf.read(BUFSIZE)
       
   161         if sd != md: return 0
       
   162         if not sd: break
       
   163     return 1
       
   164 
       
   165 def mtime(f):
       
   166     st = os.fstat(f.fileno())
       
   167     return st[stat.ST_MTIME]
       
   168 
       
   169 def funnychars(f):
       
   170     while 1:
       
   171         buf = f.read(BUFSIZE)
       
   172         if not buf: break
       
   173         if '\r' in buf or '\0' in buf: return 1
       
   174     return 0
       
   175 
       
   176 def copy(src, dst, rmode="rb", wmode="wb", answer='ask'):
       
   177     print "copying", src
       
   178     print "     to", dst
       
   179     if not okay("okay to copy? ", answer):
       
   180         return
       
   181     f = open(src, rmode)
       
   182     g = open(dst, wmode)
       
   183     while 1:
       
   184         buf = f.read(BUFSIZE)
       
   185         if not buf: break
       
   186         g.write(buf)
       
   187     f.close()
       
   188     g.close()
       
   189 
       
   190 def okay(prompt, answer='ask'):
       
   191     answer = answer.strip().lower()
       
   192     if not answer or answer[0] not in 'ny':
       
   193         answer = raw_input(prompt)
       
   194         answer = answer.strip().lower()
       
   195         if not answer:
       
   196             answer = default_answer
       
   197     if answer[:1] == 'y':
       
   198         return 1
       
   199     if answer[:1] == 'n':
       
   200         return 0
       
   201     print "Yes or No please -- try again:"
       
   202     return okay(prompt)
       
   203 
       
   204 if __name__ == '__main__':
       
   205     main()