History

add hg and python

cinap_lenrek committed 15 years ago

Commit 4bb9e221 parent 987265c3706 files · +1228772 −-233Browse files

Showing the changes to sys/src/cmd/python/Tools/scripts/treesync.py (1 of 3706 files). Show all

Unified · Split

sys/src/cmd/python/Tools/scripts/treesync.py+205−0
@@ -0,0 +1,205 @@
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()