]> git.ipfire.org Git - people/jschlag/pbs.git/blob - src/buildservice/sources.py
e028478a3e864b254edac357e374f8c6be4bdde2
[people/jschlag/pbs.git] / src / buildservice / sources.py
1 #!/usr/bin/python
2
3 import datetime
4 import logging
5 import os
6 import subprocess
7
8 from . import base
9 from . import database
10 from . import git
11
12 from .decorators import *
13
14 class Sources(base.Object):
15 def _get_source(self, query, *args):
16 res = self.db.get(query, *args)
17
18 if res:
19 return Source(self.backend, res.id, data=res)
20
21 def _get_sources(self, query, *args):
22 res = self.db.query(query, *args)
23
24 for row in res:
25 yield Source(self.backend, row.id, data=row)
26
27 def _get_commit(self, query, *args):
28 res = self.db.get(query, *args)
29
30 if res:
31 return Commit(self.backend, res.id, data=res)
32
33 def _get_commits(self, query, *args):
34 res = self.db.query(query, *args)
35
36 for row in res:
37 yield Commit(self.backend, row.id, data=row)
38
39 def __iter__(self):
40 return self._get_sources("SELECT * FROM sources")
41
42 def get_by_id(self, id):
43 return self._get_source("SELECT * FROM sources \
44 WHERE id = %s", id)
45
46 def get_by_distro(self, distro):
47 return self._get_sources("SELECT * FROM sources \
48 WHERE distro_id = %s", distro.id)
49
50 def update_revision(self, source_id, revision):
51 query = "UPDATE sources SET revision = %s WHERE id = %s"
52
53 return self.db.execute(query, revision, source_id)
54
55 def get_pending_commits(self, limit=None):
56 query = "SELECT id FROM sources_commits WHERE state = 'pending' ORDER BY id ASC"
57 args = []
58
59 if limit:
60 query += " LIMIT %s"
61 args.append(limit)
62
63 rows = self.db.query(query, *args)
64
65 commits = []
66 for row in rows:
67 commit = Commit(self.pakfire, row.id)
68 commits.append(commit)
69
70 return commits
71
72 def get_commit_by_id(self, commit_id):
73 commit = self.db.get("SELECT id FROM sources_commits WHERE id = %s", commit_id)
74
75 if commit:
76 return Commit(self.pakfire, commit.id)
77
78 def pull(self):
79 for source in self:
80 repo = git.Repo(self.backend, source, mode="mirror")
81
82 # If the repository is not yet cloned, we need to make a local
83 # clone to work with.
84 if not repo.cloned:
85 repo.clone()
86
87 # Otherwise we just fetch updates.
88 else:
89 repo.fetch()
90
91 # Import all new revisions.
92 repo.import_revisions()
93
94
95 class Commit(base.DataObject):
96 table = "sources_commits"
97
98 @property
99 def revision(self):
100 return self.data.revision
101
102 @lazy_property
103 def source(self):
104 return self.backend.sources.get_by_id(self.data.source_id)
105
106 @property
107 def distro(self):
108 """
109 A shortcut to the distribution this commit
110 belongs to.
111 """
112 return self.source.distro
113
114 def set_state(self, state):
115 self._set_attribute("state", state)
116
117 state = property(lambda s: s.data.state, set_state)
118
119 @property
120 def author(self):
121 return self.data.author
122
123 @property
124 def committer(self):
125 return self.data.committer
126
127 @property
128 def subject(self):
129 return self.data.subject.strip()
130
131 @property
132 def message(self):
133 return self.data.body.strip()
134
135 @property
136 def message_full(self):
137 msg = [self.subject, ""] + self.message.splitlines()
138
139 return "\n".join(msg)
140
141 @property
142 def date(self):
143 return self.data.date
144
145 @lazy_property
146 def packages(self):
147 return self.backend.packages._get_packages("SELECT * FROM packages \
148 WHERE commit_id = %s", self.id)
149
150 def reset(self):
151 """
152 Removes all packages that have been created by this commit and
153 resets the state so it will be processed again.
154 """
155 # Remove all packages and corresponding builds.
156 for pkg in self.packages:
157 # Check if there is a build associated with the package.
158 # If so, the whole build will be deleted.
159 if pkg.build:
160 pkg.build.delete()
161
162 else:
163 # Delete the package.
164 pkg.delete()
165
166 # Clear the cache.
167 del self.packages
168
169 # Reset the state to 'pending'.
170 self.state = "pending"
171
172
173 class Source(base.DataObject):
174 table = "sources"
175
176 def __eq__(self, other):
177 return self.id == other.id
178
179 def __len__(self):
180 ret = self.db.get("SELECT COUNT(*) AS len FROM sources_commits \
181 WHERE source_id = %s", self.id)
182
183 return ret.len
184
185 def create_commit(self, revision, author, committer, subject, body, date):
186 commit = self.backend.sources._get_commit("INSERT INTO sources_commits(source_id, \
187 revision, author, committer, subject, body, date) VALUES(%s, %s, %s, %s, %s, %s, %s)",
188 self.id, revision, author, committer, subject, body, date)
189
190 # Commit
191 commit.source = self
192
193 return commit
194
195 @property
196 def info(self):
197 return {
198 "id" : self.id,
199 "name" : self.name,
200 "url" : self.url,
201 "path" : self.path,
202 "targetpath" : self.targetpath,
203 "revision" : self.revision,
204 "branch" : self.branch,
205 }
206
207 @property
208 def name(self):
209 return self.data.name
210
211 @property
212 def identifier(self):
213 return self.data.identifier
214
215 @property
216 def url(self):
217 return self.data.url
218
219 @property
220 def gitweb(self):
221 return self.data.gitweb
222
223 @property
224 def revision(self):
225 return self.data.revision
226
227 @property
228 def branch(self):
229 return self.data.branch
230
231 @property
232 def builds(self):
233 return self.pakfire.builds.get_by_source(self.id)
234
235 @lazy_property
236 def distro(self):
237 return self.pakfire.distros.get_by_id(self.data.distro_id)
238
239 @property
240 def start_revision(self):
241 return self.data.revision
242
243 @lazy_property
244 def head_revision(self):
245 return self.backend.sources._get_commit("SELECT * FROM sources_commits \
246 WHERE source_id = %s ORDER BY id DESC LIMIT 1", self.id)
247
248 def get_commits(self, limit=None, offset=None):
249 return self.backend.sources._get_commits("SELECT * FROM sources_commits \
250 WHERE source_id = %s ORDER BY id DESC LIMIT %s OFFSET %s", limit, offset)
251
252 def get_commit(self, revision):
253 commit = self.backend.sources._get_commit("SELECT * FROM sources_commits \
254 WHERE source_id = %s AND revision = %s", self.id, revision)
255
256 if commit:
257 commit.source = self
258 return commit