Mercurial > cpython-lru_cache-weakref
view Tools/scripts/treesync.py @ 49955:878d40468c4e legacy-trunk
Issue #4384: Added logging integration with warnings module using captureWarnings(). This change includes a NullHandler which does nothing; it will be of use to library developers who want to avoid the "No handlers could be found for logger XXX" message which can appear if the library user doesn't configure logging.
| author | Vinay Sajip <vinay_sajip@yahoo.co.uk> |
|---|---|
| date | Wed, 03 Dec 2008 23:22:58 +0000 |
| parents | 981fff7363b9 |
| children | 081b4f0e81b7 |
line wrap: on
line source
#! /usr/bin/env python """Script to synchronize two source trees. Invoke with two arguments: python treesync.py slave master The assumption is that "master" contains CVS administration while slave doesn't. All files in the slave tree that have a CVS/Entries entry in the master tree are synchronized. This means: If the files differ: if the slave file is newer: normalize the slave file if the files still differ: copy the slave to the master else (the master is newer): copy the master to the slave normalizing the slave means replacing CRLF with LF when the master doesn't use CRLF """ import os, sys, stat, getopt # Interactivity options default_answer = "ask" create_files = "yes" create_directories = "no" write_slave = "ask" write_master = "ask" def main(): global always_no, always_yes global create_directories, write_master, write_slave opts, args = getopt.getopt(sys.argv[1:], "nym:s:d:f:a:") for o, a in opts: if o == '-y': default_answer = "yes" if o == '-n': default_answer = "no" if o == '-s': write_slave = a if o == '-m': write_master = a if o == '-d': create_directories = a if o == '-f': create_files = a if o == '-a': create_files = create_directories = write_slave = write_master = a try: [slave, master] = args except ValueError: print "usage: python", sys.argv[0] or "treesync.py", print "[-n] [-y] [-m y|n|a] [-s y|n|a] [-d y|n|a] [-f n|y|a]", print "slavedir masterdir" return process(slave, master) def process(slave, master): cvsdir = os.path.join(master, "CVS") if not os.path.isdir(cvsdir): print "skipping master subdirectory", master print "-- not under CVS" return print "-"*40 print "slave ", slave print "master", master if not os.path.isdir(slave): if not okay("create slave directory %s?" % slave, answer=create_directories): print "skipping master subdirectory", master print "-- no corresponding slave", slave return print "creating slave directory", slave try: os.mkdir(slave) except os.error, msg: print "can't make slave directory", slave, ":", msg return else: print "made slave directory", slave cvsdir = None subdirs = [] names = os.listdir(master) for name in names: mastername = os.path.join(master, name) slavename = os.path.join(slave, name) if name == "CVS": cvsdir = mastername else: if os.path.isdir(mastername) and not os.path.islink(mastername): subdirs.append((slavename, mastername)) if cvsdir: entries = os.path.join(cvsdir, "Entries") for e in open(entries).readlines(): words = e.split('/') if words[0] == '' and words[1:]: name = words[1] s = os.path.join(slave, name) m = os.path.join(master, name) compare(s, m) for (s, m) in subdirs: process(s, m) def compare(slave, master): try: sf = open(slave, 'r') except IOError: sf = None try: mf = open(master, 'rb') except IOError: mf = None if not sf: if not mf: print "Neither master nor slave exists", master return print "Creating missing slave", slave copy(master, slave, answer=create_files) return if not mf: print "Not updating missing master", master return if sf and mf: if identical(sf, mf): return sft = mtime(sf) mft = mtime(mf) if mft > sft: # Master is newer -- copy master to slave sf.close() mf.close() print "Master ", master print "is newer than slave", slave copy(master, slave, answer=write_slave) return # Slave is newer -- copy slave to master print "Slave is", sft-mft, "seconds newer than master" # But first check what to do about CRLF mf.seek(0) fun = funnychars(mf) mf.close() sf.close() if fun: print "***UPDATING MASTER (BINARY COPY)***" copy(slave, master, "rb", answer=write_master) else: print "***UPDATING MASTER***" copy(slave, master, "r", answer=write_master) BUFSIZE = 16*1024 def identical(sf, mf): while 1: sd = sf.read(BUFSIZE) md = mf.read(BUFSIZE) if sd != md: return 0 if not sd: break return 1 def mtime(f): st = os.fstat(f.fileno()) return st[stat.ST_MTIME] def funnychars(f): while 1: buf = f.read(BUFSIZE) if not buf: break if '\r' in buf or '\0' in buf: return 1 return 0 def copy(src, dst, rmode="rb", wmode="wb", answer='ask'): print "copying", src print " to", dst if not okay("okay to copy? ", answer): return f = open(src, rmode) g = open(dst, wmode) while 1: buf = f.read(BUFSIZE) if not buf: break g.write(buf) f.close() g.close() def okay(prompt, answer='ask'): answer = answer.strip().lower() if not answer or answer[0] not in 'ny': answer = raw_input(prompt) answer = answer.strip().lower() if not answer: answer = default_answer if answer[:1] == 'y': return 1 if answer[:1] == 'n': return 0 print "Yes or No please -- try again:" return okay(prompt) if __name__ == '__main__': main()
