1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 import os
17
18 from twisted.python import log
19 from twisted.internet import defer
20
21 from buildslave.commands.base import SourceBaseCommand
22 from buildslave import runprocess
23
24
26 """Error class for this module."""
27
28
30 """Monotone specific VC operation. In addition to the arguments
31 handled by SourceBaseCommand, this command reads the following keys:
32
33 ['repourl'] (required): the Monotone repository string
34 ['branch'] (required): which branch to retrieve.
35
36 ['revision'] (optional): which revision (revision selector)
37 to retrieve.
38 ['progress'] (optional): have mtn output progress markers,
39 avoiding timeouts for long fetches;
40 """
41
42 header = "monotone operation"
43
60
65
66 d = self._checkDb();
67 d.addCallback(cont)
68 return d
69
71 return self._dovccmd(self._update, True)
72
74 return self._dovccmd(self._checkout, True)
75
78
80 return os.path.isdir(os.path.join(self._fullSrcdir(), "_MTN"))
81
82 - def _dovccmd(self, fn, dopull, cb=None, **kwargs):
83 if dopull:
84 command = [self.mtn, 'pull', self.sourcedata,
85 '--db', self.database]
86 if self.progress:
87 command.extend(['--ticker=dot'])
88 else:
89 command.extend(['--ticker=none'])
90 c = runprocess.RunProcess(self.builder, command,
91 self.builder.basedir,
92 environ=self.env, sendRC=False,
93 timeout=self.timeout,
94 maxTime=self.maxTime,
95 keepStdout=True, usePTY=False,
96 logEnviron=self.logEnviron)
97 self.sendStatus({"header": "pulling %s from %s\n"
98 % (self.branch, self.sourcedata)})
99 self.command = c
100 d = c.start()
101 d.addCallback(self._abandonOnFailure)
102 d.addCallback(fn)
103 else:
104 d = fn(None)
105 if cb:
106 d.addCallback(cb)
107 return d
108
110 command = [self.mtn, 'update',
111 '--db', self.database]
112 if self.revision:
113 command.extend(['--revision', self.revision])
114 else:
115 command.extend(["-r", "h:" + self.branch])
116 command.extend(["-b", self.branch])
117 c = runprocess.RunProcess(self.builder, command, self._fullSrcdir(),
118 environ=self.env, sendRC=False,
119 timeout=self.timeout, maxTime=self.maxTime,
120 keepStdout=True, usePTY=False,
121 logEnviron=self.logEnviron)
122 d = c.start()
123 return d
124
126 command = [self.mtn, 'checkout', self._fullSrcdir(),
127 '--db', self.database]
128 if self.revision:
129 command.extend(['--revision', self.revision])
130 command.extend(['--branch', self.branch])
131 c = runprocess.RunProcess(self.builder, command, self.builder.basedir,
132 environ=self.env, sendRC=False,
133 timeout=self.timeout, maxTime=self.maxTime,
134 keepStdout=True, usePTY=False,
135 logEnviron=self.logEnviron)
136 d = c.start()
137 return d
138
140
141
142
143 c = runprocess.RunProcess(self.builder, [self.mtn, 'db', 'info',
144 '--db', self.database],
145 self.builder.basedir,
146 environ=self.env, sendRC=False,
147 keepStdout=True, sendStderr=False,
148 usePTY=False, logEnviron=self.logEnviron)
149 d = c.start()
150 def afterCheckRepo(res, cdi):
151 if type(res) is int and res != 0:
152 log.msg("No database found, creating it")
153
154
155
156 self._pull_timeout = max(self._pull_timeout, 3 * 60 * 60)
157 c = runprocess.RunProcess(self.builder, [self.mtn, 'db', 'init',
158 '--db', self.database],
159 self.builder.basedir,
160 environ=self.env,
161 sendRC=False, usePTY=False,
162 logEnviron=self.logEnviron)
163 self.command = c
164 return c.start()
165 elif cdi.stdout.find("(migration needed)") > 0:
166 log.msg("Older format database found, migrating it")
167
168 c = runprocess.RunProcess(self.builder, [self.mtn,
169 'db', 'migrate',
170 '--db', self.database],
171 self.builder.basedir,
172 environ=self.env,
173 sendRC=False, usePTY=False,
174 logEnviron=self.logEnviron)
175 self.command = c
176 return c.start()
177 elif cdi.stdout.find("(too new, cannot use)") > 0:
178 raise MonotoneError, "The database is of a newer format than mtn can handle... Abort!"
179 else:
180 return defer.succeed(res)
181 d.addCallback(afterCheckRepo, c)
182 return d
183
185 def _parse(res):
186 hash = self.command.stdout.strip()
187 if len(hash) != 40:
188 return None
189 return hash
190 return self._dovccmd(self._get_base_revision, False, _parse)
191
193 c = runprocess.RunProcess(self.builder,
194 [self.mtn, 'automate', 'select', 'w:'],
195 self._fullSrcdir(),
196 sendRC=False,
197 timeout=self.timeout, maxTime=self.maxTime,
198 keepStdout=True, usePTY=False,
199 logEnviron=self.logEnviron)
200 d = c.start()
201 d.addCallback(self._abandonOnFailure)
202 return d
203