|
1 # Copyright (C) 2003-2007 John Goerzen |
|
2 # <jgoerzen@complete.org> |
|
3 # |
|
4 # This program is free software; you can redistribute it and/or modify |
|
5 # it under the terms of the GNU General Public License as published by |
|
6 # the Free Software Foundation; either version 2 of the License, or |
|
7 # (at your option) any later version. |
|
8 # |
|
9 # This program is distributed in the hope that it will be useful, |
|
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 # GNU General Public License for more details. |
|
13 # |
|
14 # You should have received a copy of the GNU General Public License |
|
15 # along with this program; if not, write to the Free Software |
|
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
17 |
|
18 import util |
|
19 import os.path |
|
20 from commandver import cmd, isdarcs, issvk, isgit, ishg, vcscmd |
|
21 |
|
22 class wc: |
|
23 """Object for a working copy.""" |
|
24 |
|
25 def __init__(self, wcpath, verbose = 0, fsonly = 0): |
|
26 self.wcpath = os.path.abspath(wcpath) |
|
27 self.verb = verbose |
|
28 self.fsonly = fsonly |
|
29 if not self.wcverify(): |
|
30 raise Exception, "%s is not a tla working copy" % self.wcpath |
|
31 |
|
32 def gettreeversion(self): |
|
33 if isdarcs(): |
|
34 #util.chdircmd(self.wcpath, util.getstdoutsafeexec, "darcs", |
|
35 # ['check']) |
|
36 return "Darcs repository" |
|
37 elif ishg(): |
|
38 return "Mercurial repository" |
|
39 elif issvk(): |
|
40 return "Svk repository" |
|
41 elif isgit(): |
|
42 return "Git repository" |
|
43 else: |
|
44 return util.chdircmd(self.wcpath, util.getstdoutsafeexec, vcscmd, |
|
45 ['tree-version'])[0].strip() |
|
46 |
|
47 def wcverify(self): |
|
48 try: |
|
49 self.gettreeversion() |
|
50 except util.ExecProblem: |
|
51 return 0 |
|
52 return 1 |
|
53 |
|
54 def gettaggingmethod(self): |
|
55 if isdarcs() or isgit() or ishg(): |
|
56 return 'explicit' |
|
57 else: |
|
58 return util.chdircmd(self.wcpath, util.getstdoutsafeexec, vcscmd, |
|
59 [cmd().tagging_method])[0].strip() |
|
60 |
|
61 def gettree(self): |
|
62 return util.maketree(self.wcpath, |
|
63 ignore = [r'(^(\{arch\}$|,,|\.hg|\.hgtags|\.hgignore|\.git|_darcs|\.arch-ids$|\.arch-inventory$|\+\+)|/\.arch-ids/)']) |
|
64 |
|
65 def addtag(self, file): |
|
66 if self.verb: |
|
67 print "Adding %s" % file |
|
68 if (file[-1] == '/') and \ |
|
69 (not os.path.exists(os.path.join(self.wcpath, |
|
70 file[:-1]))): |
|
71 try: |
|
72 print "addtag: making dir %s" % file[:-1] |
|
73 os.makedirs(os.path.join(self.wcpath, file[:-1])) |
|
74 except: |
|
75 raise |
|
76 file = self.slashstrip(file) |
|
77 isdir = os.path.isdir(os.path.join(self.wcpath, file)) |
|
78 if (not self.fsonly) and \ |
|
79 (not ishg()) and ((not isdarcs()) or isdir): |
|
80 # Darcs will see adds later, but we need to add dirs |
|
81 # now so darcs mv will work. |
|
82 # |
|
83 # Mercurial will see adds later, and doesn't track directories, |
|
84 # so we don't do anything with it. |
|
85 util.chdircmd(self.wcpath, util.safeexec, vcscmd, |
|
86 cmd().add + [file]) |
|
87 |
|
88 def movetag(self, src, dest): |
|
89 if self.verb: |
|
90 print "Moving %s to %s" % (src, dest) |
|
91 if src[-1] == '/' \ |
|
92 and dest[-1] == '/' \ |
|
93 and ((not isdarcs()) and (not isgit()) and (not ishg())): |
|
94 # Dir to dir -- darcs mv will catch it already. |
|
95 # Git doesn't do rename recording, so don't worry about it? |
|
96 return |
|
97 src, dest = self.slashstrip(src, dest) |
|
98 if not self.fsonly: |
|
99 util.chdircmd(self.wcpath, util.safeexec, vcscmd, |
|
100 [cmd().move, src, dest]) |
|
101 |
|
102 def movefile(self, src, dest): |
|
103 if self.verb: |
|
104 print "Moving file %s to %s" % (src, dest) |
|
105 src, dest = self.slashstrip(src, dest) |
|
106 |
|
107 def doit(): |
|
108 destdir = os.path.dirname(dest) |
|
109 if (not os.path.exists(destdir)) and destdir != '': |
|
110 self.makedirs(destdir) |
|
111 if self.fsonly or \ |
|
112 (not isdarcs() and (not isgit()) and (not ishg())): |
|
113 # Darcs, hg, and git actually do this when they move the tag |
|
114 os.rename(src, dest) |
|
115 |
|
116 util.chdircmd(self.wcpath, doit) |
|
117 |
|
118 def delfile(self, file): |
|
119 if self.verb: |
|
120 print "Deleting file %s" % file |
|
121 fullfile = os.path.join(self.wcpath, file) |
|
122 if os.path.isfile(fullfile): |
|
123 os.unlink(fullfile) |
|
124 else: |
|
125 util.safeexec("rm", ['-rf', fullfile]) |
|
126 |
|
127 def deltag(self, file): |
|
128 if (not self.fsonly) and \ |
|
129 ((not isdarcs()) and (not ishg())): |
|
130 if self.verb: |
|
131 print "Deleting %s" % file |
|
132 if os.path.islink(os.path.join(self.wcpath,file)) or os.path.exists(os.path.join(self.wcpath, file)): |
|
133 util.chdircmd(self.wcpath, util.safeexec, vcscmd, |
|
134 cmd().delete + [file]) |
|
135 |
|
136 def makelog(self, summary, logtext): |
|
137 self.summary = summary |
|
138 self.logtext = logtext |
|
139 if ishg() or isgit() or isdarcs(): |
|
140 logfn = self.wcpath + "/../,,vcslog" |
|
141 else: |
|
142 logfn = util.chdircmd(self.wcpath, util.getstdoutsafeexec, vcscmd, |
|
143 ['make-log'])[0].strip() |
|
144 |
|
145 self.logfn = os.path.abspath(logfn) |
|
146 |
|
147 fd = open(self.logfn, "w") |
|
148 if isgit(): |
|
149 fd.write("%s\n\n" % summary) |
|
150 if ishg(): |
|
151 fd.write("%s\n" % summary) |
|
152 elif not (isdarcs() or ishg()): |
|
153 fd.write("Summary: %s\n" % summary) |
|
154 fd.write("Keywords: \n\n") |
|
155 fd.write(logtext) |
|
156 print "LOGTEXT", logtext |
|
157 fd.close() |
|
158 |
|
159 |
|
160 def commit(self): |
|
161 if self.verb: |
|
162 print "Committing changes" |
|
163 if isdarcs(): |
|
164 util.chdircmd(self.wcpath, util.safeexec, vcscmd, |
|
165 [cmd().commit, "-l", "-a", "-m", self.summary, |
|
166 "--logfile", self.logfn, |
|
167 "--delete-logfile"]) |
|
168 elif isgit(): |
|
169 util.chdircmd(self.wcpath, util.safeexec, vcscmd, |
|
170 [cmd().commit, "-a", "-F", self.logfn]) |
|
171 os.unlink(self.logfn) |
|
172 elif ishg(): |
|
173 util.chdircmd(self.wcpath, util.safeexec, vcscmd, |
|
174 [cmd().commit, "-A", "-l", self.logfn]) |
|
175 os.unlink(self.logfn) |
|
176 else: |
|
177 if len(util.chdircmd(self.wcpath, util.getstdoutsafeexec, vcscmd, ['logs']))==0: |
|
178 util.chdircmd(self.wcpath, util.safeexec, vcscmd, [cmd().importcmd]) |
|
179 else: |
|
180 util.chdircmd(self.wcpath, util.safeexec, vcscmd, [cmd().commit]) |
|
181 |
|
182 def slashstrip(self, *args): |
|
183 retval = [] |
|
184 for item in args: |
|
185 if not len(item): |
|
186 retval.append(item) |
|
187 if item[-1] == '/': |
|
188 item = item[:-1] |
|
189 retval.append(item) |
|
190 if len(args) == 1: |
|
191 return retval[0] |
|
192 return retval |
|
193 |
|
194 |
|
195 def makedirs(self, name, mode=0777): |
|
196 """makedirs(path [, mode=0777]) |
|
197 |
|
198 Super-mkdir; create a leaf directory and all intermediate ones. |
|
199 Works like mkdir, except that any intermediate path segment (not |
|
200 just the rightmost) will be created if it does not exist. This is |
|
201 recursive. |
|
202 |
|
203 (Modified from Python source) |
|
204 |
|
205 """ |
|
206 head, tail = os.path.split(name) |
|
207 if not tail: |
|
208 head, tail = os.path.split(head) |
|
209 if head and tail and not os.path.exists(head): |
|
210 self.makedirs(head, mode) |
|
211 if self.verb: |
|
212 print "Created directory", name |
|
213 os.mkdir(name, mode) |
|
214 self.addtag(name) |
|
215 |