]>
Commit | Line | Data |
---|---|---|
9137135a MT |
1 | #!/usr/bin/python |
2 | ||
3 | import datetime | |
4 | import logging | |
5 | import os | |
6 | import subprocess | |
7 | ||
2c909128 MT |
8 | from . import base |
9 | from . import database | |
9137135a MT |
10 | |
11 | class 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 | ||
54 | class 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 |
184 | class 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 |