]> git.ipfire.org Git - pbs.git/blame - src/buildservice/sources.py
Move main.py to __init__.py
[pbs.git] / src / buildservice / sources.py
CommitLineData
9137135a
MT
1#!/usr/bin/python
2
3import datetime
4import logging
5import os
6import subprocess
7
8import base
f6e6ff79 9import builds
1ceb1b33 10import database
f6e6ff79 11import packages
9137135a
MT
12
13class Sources(base.Object):
14 def get_all(self):
15 sources = self.db.query("SELECT id FROM sources ORDER BY id")
16
17 return [Source(self.pakfire, s.id) for s in sources]
18
19 def get_by_id(self, id):
f6e6ff79 20 return Source(self.pakfire, id)
9137135a
MT
21
22 def get_by_distro(self, distro):
23 sources = self.db.query("SELECT id FROM sources WHERE distro_id = %s", distro.id)
24
25 return [Source(self.pakfire, s.id) for s in sources]
26
27 def update_revision(self, source_id, revision):
28 query = "UPDATE sources SET revision = %s WHERE id = %s"
29
30 return self.db.execute(query, revision, source_id)
31
f6e6ff79
MT
32 def get_pending_commits(self, limit=None):
33 query = "SELECT id FROM sources_commits WHERE state = 'pending' ORDER BY id ASC"
34 args = []
9137135a 35
f6e6ff79
MT
36 if limit:
37 query += " LIMIT %s"
38 args.append(limit)
39
40 rows = self.db.query(query, *args)
41
42 commits = []
43 for row in rows:
44 commit = Commit(self.pakfire, row.id)
45 commits.append(commit)
46
47 return commits
48
49 def get_commit_by_id(self, commit_id):
50 commit = self.db.get("SELECT id FROM sources_commits WHERE id = %s", commit_id)
51
52 if commit:
53 return Commit(self.pakfire, commit.id)
54
55
56class Commit(base.Object):
9137135a
MT
57 def __init__(self, pakfire, id):
58 base.Object.__init__(self, pakfire)
59
60 self.id = id
61
f6e6ff79
MT
62 # Cache.
63 self._data = None
64 self._source = None
65 self._packages = None
66
67 @classmethod
68 def create(cls, pakfire, source, revision, author, committer, subject, body, date):
69 try:
70 id = pakfire.db.execute("INSERT INTO sources_commits(source_id, revision, \
71 author, committer, subject, body, date) VALUES(%s, %s, %s, %s, %s, %s, %s)",
72 source.id, revision, author, committer, subject, body, date)
1ceb1b33 73 except database.IntegrityError:
f6e6ff79
MT
74 # If the commit (apperently) already existed, we return nothing.
75 return
9137135a 76
f6e6ff79 77 return cls(pakfire, id)
9137135a
MT
78
79 @property
f6e6ff79
MT
80 def data(self):
81 if self._data is None:
82 data = self.db.get("SELECT * FROM sources_commits WHERE id = %s", self.id)
9137135a 83
f6e6ff79
MT
84 self._data = data
85 assert self._data
9137135a 86
f6e6ff79 87 return self._data
9137135a 88
f6e6ff79
MT
89 @property
90 def revision(self):
91 return self.data.revision
92
93 @property
94 def source_id(self):
95 return self.data.source_id
96
97 @property
98 def source(self):
99 if self._source is None:
100 self._source = Source(self.pakfire, self.source_id)
101
102 return self._source
103
104 @property
105 def distro(self):
106 """
107 A shortcut to the distribution this commit
108 belongs to.
109 """
110 return self.source.distro
9137135a 111
f6e6ff79
MT
112 def get_state(self):
113 return self.data.state
9137135a 114
f6e6ff79
MT
115 def set_state(self, state):
116 self.db.execute("UPDATE sources_commits SET state = %s WHERE id = %s",
117 state, self.id)
9137135a 118
f6e6ff79
MT
119 if self._data:
120 self._data["state"] = state
9137135a 121
f6e6ff79 122 state = property(get_state, set_state)
9137135a 123
f6e6ff79
MT
124 @property
125 def author(self):
126 return self.data.author
127
128 @property
129 def committer(self):
130 return self.data.committer
131
132 @property
133 def subject(self):
b9d096e0 134 return self.data.subject.strip()
f6e6ff79
MT
135
136 @property
137 def message(self):
138 return self.data.body.strip()
139
4b1e87c4
MT
140 @property
141 def message_full(self):
142 msg = [self.subject, ""] + self.message.splitlines()
143
144 return "\n".join(msg)
145
f6e6ff79
MT
146 @property
147 def date(self):
148 return self.data.date
149
150 @property
151 def packages(self):
152 if self._packages is None:
153 self._packages = []
9137135a 154
f6e6ff79
MT
155 for pkg in self.db.query("SELECT id FROM packages WHERE commit_id = %s", self.id):
156 pkg = packages.Package(self.pakfire, pkg.id)
157 self._packages.append(pkg)
9137135a 158
f6e6ff79 159 self._packages.sort()
9137135a 160
f6e6ff79
MT
161 return self._packages
162
163 def reset(self):
9137135a 164 """
f6e6ff79
MT
165 Removes all packages that have been created by this commit and
166 resets the state so it will be processed again.
9137135a 167 """
f6e6ff79
MT
168 # Remove all packages and corresponding builds.
169 for pkg in self.packages:
170 # Check if there is a build associated with the package.
171 # If so, the whole build will be deleted.
172 if pkg.build:
173 pkg.build.delete()
9137135a 174
f6e6ff79
MT
175 else:
176 # Delete the package.
177 pkg.delete()
178
179 # Clear the cache.
180 self._packages = None
9137135a 181
f6e6ff79
MT
182 # Reset the state to 'pending'.
183 self.state = "pending"
9137135a 184
9137135a 185
f6e6ff79
MT
186class Source(base.Object):
187 def __init__(self, pakfire, id):
188 base.Object.__init__(self, pakfire)
189
190 self.id = id
191
192 self._data = None
193 self._head_revision = None
194
195 @property
196 def data(self):
197 if self._data is None:
198 data = self.db.get("SELECT * FROM sources WHERE id = %s", self.id)
9137135a 199
f6e6ff79
MT
200 self._data = data
201 assert self._data
9137135a 202
f6e6ff79 203 return self._data
9137135a 204
f6e6ff79
MT
205 def __cmp__(self, other):
206 return cmp(self.id, other.id)
9137135a 207
f6e6ff79
MT
208 @property
209 def info(self):
210 return {
211 "id" : self.id,
212 "name" : self.name,
213 "url" : self.url,
214 "path" : self.path,
215 "targetpath" : self.targetpath,
216 "revision" : self.revision,
217 "branch" : self.branch,
218 }
9137135a
MT
219
220 def _import_revision(self, revision):
221 logging.debug("Going to import revision: %s" % revision)
222
223 rev_author = self._git("log -1 --format=\"%%an <%%ae>\" %s" % revision)
224 rev_committer = self._git("log -1 --format=\"%%cn <%%ce>\" %s" % revision)
225 rev_subject = self._git("log -1 --format=\"%%s\" %s" % revision)
226 rev_body = self._git("log -1 --format=\"%%b\" %s" % revision)
227 rev_date = self._git("log -1 --format=\"%%at\" %s" % revision)
228 rev_date = datetime.datetime.utcfromtimestamp(float(rev_date))
229
230 # Convert strings properly. No idea why I have to do that.
231 rev_author = rev_author.decode("latin-1").strip()
232 rev_committer = rev_committer.decode("latin-1").strip()
233 rev_subject = rev_subject.decode("latin-1").strip()
234 rev_body = rev_body.decode("latin-1").rstrip()
235
236 # Create a new source build object.
237 build.SourceBuild.new(self.pakfire, self.id, revision, rev_author,
238 rev_committer, rev_subject, rev_body, rev_date)
239
240 @property
241 def name(self):
f6e6ff79 242 return self.data.name
9137135a
MT
243
244 @property
f6e6ff79
MT
245 def identifier(self):
246 return self.data.identifier
9137135a
MT
247
248 @property
f6e6ff79
MT
249 def url(self):
250 return self.data.url
9137135a
MT
251
252 @property
f6e6ff79
MT
253 def gitweb(self):
254 return self.data.gitweb
9137135a
MT
255
256 @property
257 def revision(self):
f6e6ff79 258 return self.data.revision
9137135a
MT
259
260 @property
261 def branch(self):
f6e6ff79 262 return self.data.branch
9137135a
MT
263
264 @property
265 def builds(self):
266 return self.pakfire.builds.get_by_source(self.id)
267
268 @property
269 def distro(self):
f6e6ff79
MT
270 return self.pakfire.distros.get_by_id(self.data.distro_id)
271
272 @property
273 def start_revision(self):
274 return self.data.revision
275
276 @property
277 def head_revision(self):
278 if self._head_revision is None:
279 commit = self.db.get("SELECT id FROM sources_commits \
280 WHERE source_id = %s ORDER BY id DESC LIMIT 1", self.id)
281
282 if commit:
283 self._head_revision = Commit(self.pakfire, commit.id)
284
285 return self._head_revision
286
287 @property
288 def num_commits(self):
289 ret = self.db.get("SELECT COUNT(*) AS num FROM sources_commits \
290 WHERE source_id = %s", self.id)
291
292 return ret.num
293
294 def get_commits(self, limit=None, offset=None):
295 query = "SELECT id FROM sources_commits WHERE source_id = %s \
296 ORDER BY id DESC"
297 args = [self.id,]
298
299 if limit:
300 if offset:
301 query += " LIMIT %s,%s"
302 args += [offset, limit]
303 else:
304 query += " LIMIT %s"
305 args += [limit,]
306
307 commits = []
308 for commit in self.db.query(query, *args):
309 commit = Commit(self.pakfire, commit.id)
310 commits.append(commit)
311
312 return commits
313
314 def get_commit(self, revision):
315 commit = self.db.get("SELECT id FROM sources_commits WHERE source_id = %s \
316 AND revision = %s LIMIT 1", self.id, revision)
317
318 if not commit:
319 return
320
321 commit = Commit(self.pakfire, commit.id)
322 commit._source = self
323
324 return commit