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