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