allura
修訂 | f712b011404d8ff8953557e632bb80505c24172f (tree) |
---|---|
時間 | 2011-10-06 02:14:56 |
作者 | Rick Copeland <rcopeland@geek...> |
Commiter | Rick Copeland |
[#2020] Add tests for new git objects
Signed-off-by: Rick Copeland <rcopeland@geek.net>
@@ -10,6 +10,7 @@ from pylons import g | ||
10 | 10 | |
11 | 11 | from ming import Field, Index, collection |
12 | 12 | from ming import schema as S |
13 | +from ming.base import Object | |
13 | 14 | from ming.utils import LazyProperty |
14 | 15 | from ming.orm import mapper |
15 | 16 |
@@ -22,8 +23,11 @@ from .session import repository_orm_session | ||
22 | 23 | |
23 | 24 | log = logging.getLogger(__name__) |
24 | 25 | |
26 | +# Some schema types | |
25 | 27 | SUser = dict(name=str, email=str, date=datetime) |
26 | 28 | SObjType=S.OneOf('blob', 'tree', 'submodule') |
29 | + | |
30 | +# Used for when we're going to batch queries using $in | |
27 | 31 | QSIZE = 100 |
28 | 32 | README_RE = re.compile('^README(\.[^.]*)?$', re.IGNORECASE) |
29 | 33 |
@@ -88,7 +92,7 @@ CommitRunDoc = collection( | ||
88 | 92 | |
89 | 93 | class RepoObject(object): |
90 | 94 | |
91 | - def __repr__(self): | |
95 | + def __repr__(self): # pragma no cover | |
92 | 96 | return '<%s %s>' % ( |
93 | 97 | self.__class__.__name__, self._id) |
94 | 98 |
@@ -105,10 +109,17 @@ class RepoObject(object): | ||
105 | 109 | self._id) |
106 | 110 | return id.replace('.', '/') |
107 | 111 | |
112 | + @LazyProperty | |
113 | + def legacy(self): | |
114 | + return Object(object_id=self._id) | |
115 | + | |
108 | 116 | class Commit(RepoObject): |
109 | 117 | # Ephemeral attrs |
110 | 118 | repo=None |
111 | 119 | |
120 | + def set_context(self, repo): | |
121 | + self.repo = repo | |
122 | + | |
112 | 123 | @LazyProperty |
113 | 124 | def author_url(self): |
114 | 125 | u = User.by_email_address(self.authored.email) |
@@ -125,10 +136,10 @@ class Commit(RepoObject): | ||
125 | 136 | self.tree_id = self.repo.compute_tree(self) |
126 | 137 | if self.tree_id is None: |
127 | 138 | return None |
128 | - t = Tree.query.get(object_id=self.tree_id) | |
139 | + t = Tree.query.get(_id=self.tree_id) | |
129 | 140 | if t is None: |
130 | 141 | self.tree_id = self.repo.compute_tree(self) |
131 | - t = Tree.query.get(object_id=self.tree_id) | |
142 | + t = Tree.query.get(_id=self.tree_id) | |
132 | 143 | if t is not None: t.set_context(self) |
133 | 144 | return t |
134 | 145 |
@@ -138,21 +149,15 @@ class Commit(RepoObject): | ||
138 | 149 | first_line = message.split('\n')[0] |
139 | 150 | return h.text.truncate(first_line, 50) |
140 | 151 | |
141 | - def get_path(self, path): | |
142 | - '''Return the blob on the given path''' | |
143 | - if path.startswith('/'): path = path[1:] | |
144 | - path_parts = path.split('/') | |
145 | - return self.tree.get_blob(path_parts[-1], path_parts[:-1]) | |
146 | - | |
147 | 152 | def shorthand_id(self): |
148 | - return self.repo.shorthand_for_commit(self) | |
153 | + return self.repo.shorthand_for_commit(self._id) | |
149 | 154 | |
150 | 155 | @LazyProperty |
151 | 156 | def symbolic_ids(self): |
152 | - return self.repo.symbolics_for_commit(self) | |
157 | + return self.repo.symbolics_for_commit(self.legacy) | |
153 | 158 | |
154 | 159 | def url(self): |
155 | - return self.repo.url_for_commit(self) | |
160 | + return self.repo.url_for_commit(self.legacy) | |
156 | 161 | |
157 | 162 | def log_iter(self, skip, count): |
158 | 163 | for oids in utils.chunked_iter(commitlog(self._id), QSIZE): |
@@ -161,16 +166,23 @@ class Commit(RepoObject): | ||
161 | 166 | (ci._id, ci) for ci in self.query.find(dict( |
162 | 167 | _id={'$in': oids}))) |
163 | 168 | for oid in oids: |
164 | - ci = commits[oid] | |
165 | - ci.set_context(self.repo) | |
166 | - yield ci | |
169 | + if skip: | |
170 | + skip -= 1 | |
171 | + continue | |
172 | + if count: | |
173 | + count -= 1 | |
174 | + ci = commits[oid] | |
175 | + ci.set_context(self.repo) | |
176 | + yield ci | |
177 | + else: | |
178 | + break | |
167 | 179 | |
168 | 180 | def log(self, skip, count): |
169 | 181 | return list(self.log_iter(skip, count)) |
170 | 182 | |
171 | 183 | def count_revisions(self): |
172 | 184 | result = 0 |
173 | - for oid in commitlog(self): result += 1 | |
185 | + for oid in commitlog(self._id): result += 1 | |
174 | 186 | return result |
175 | 187 | |
176 | 188 | def context(self): |
@@ -217,7 +229,8 @@ class Tree(RepoObject): | ||
217 | 229 | for x in self.blob_ids: |
218 | 230 | if README_RE.match(x.name): |
219 | 231 | name = x.name |
220 | - text = h.really_unicode(self.repo.blob_text(x.id)) | |
232 | + text = self.repo.open_blob(Object(object_id=x.id)).read() | |
233 | + text = h.really_unicode(text) | |
221 | 234 | break |
222 | 235 | if text == '': |
223 | 236 | text = '<p><em>Empty File</em></p>' |
@@ -231,9 +244,9 @@ class Tree(RepoObject): | ||
231 | 244 | |
232 | 245 | def ls(self): |
233 | 246 | # Load last commit info |
234 | - oids = [ x.id for x in chain(self.tree_ids, self.object_ids, self.other_ids) ] | |
247 | + oids = [ x.id for x in chain(self.tree_ids, self.blob_ids, self.other_ids) ] | |
235 | 248 | lc_index = dict( |
236 | - (lc.object_id, lc.commit) | |
249 | + (lc.object_id, lc.commit_info) | |
237 | 250 | for lc in LastCommitDoc.m.find(dict( |
238 | 251 | repo_id=self.repo._id, |
239 | 252 | object_id={'$in': oids}))) |
@@ -293,7 +306,7 @@ class Tree(RepoObject): | ||
293 | 306 | return d |
294 | 307 | |
295 | 308 | def is_blob(self, name): |
296 | - return self.by_name[name].type == 'blob' | |
309 | + return self.by_name[name]['type'] == 'blob' | |
297 | 310 | |
298 | 311 | mapper(Commit, CommitDoc, repository_orm_session) |
299 | 312 | mapper(Tree, TreeDoc, repository_orm_session) |
@@ -3,7 +3,6 @@ from itertools import chain | ||
3 | 3 | from cPickle import dumps |
4 | 4 | |
5 | 5 | import bson |
6 | -from tg import config | |
7 | 6 | |
8 | 7 | from ming.base import Object |
9 | 8 |
@@ -63,7 +62,7 @@ def refresh_repo(repo, all_commits=False, notify=True): | ||
63 | 62 | |
64 | 63 | # Send notifications |
65 | 64 | if notify: |
66 | - send_notifications(commit_ids) | |
65 | + send_notifications(repo, commit_ids) | |
67 | 66 | |
68 | 67 | def refresh_commit_trees(ci, cache): |
69 | 68 | '''Refresh the list of trees included withn a commit''' |
@@ -221,7 +220,8 @@ def unknown_commit_ids(all_commit_ids): | ||
221 | 220 | '''filter out all commit ids that have already been cached''' |
222 | 221 | result = [] |
223 | 222 | for chunk in utils.chunked_iter(all_commit_ids, QSIZE): |
224 | - q = CommitDoc.m.find(_id={'$in':chunk}) | |
223 | + chunk = list(chunk) | |
224 | + q = CommitDoc.m.find(dict(_id={'$in':chunk})) | |
225 | 225 | known_commit_ids = set(ci._id for ci in q) |
226 | 226 | result += [ oid for oid in chunk if oid not in known_commit_ids ] |
227 | 227 | return result |
@@ -280,12 +280,13 @@ def compute_diffs(repo_id, tree_cache, rhs_ci): | ||
280 | 280 | def send_notifications(repo, commit_ids): |
281 | 281 | '''Create appropriate notification and feed objects for a refresh''' |
282 | 282 | from allura.model import Feed, Notification |
283 | + from allura.model.repository import config | |
283 | 284 | commit_msgs = [] |
284 | 285 | for oids in utils.chunked_iter(commit_ids, QSIZE): |
285 | 286 | chunk = list(oids) |
286 | 287 | index = dict( |
287 | 288 | (doc._id, doc) |
288 | - for doc in CommitDoc.m.find(dict(_id={'$in':chunk}))) | |
289 | + for doc in Commit.query.find(dict(_id={'$in':chunk}))) | |
289 | 290 | for oid in chunk: |
290 | 291 | ci = index[oid] |
291 | 292 | href = '%s%sci/%s/' % ( |
@@ -303,9 +303,9 @@ class Repository(Artifact): | ||
303 | 303 | |
304 | 304 | def refresh(self, all_commits=False, notify=True): |
305 | 305 | '''Find any new commits in the repository and update''' |
306 | + self._impl.refresh_heads() | |
306 | 307 | if asbool(tg.config.get('scm.new_refresh')): |
307 | 308 | refresh_repo(self, all_commits, notify) |
308 | - self._impl.refresh_heads() | |
309 | 309 | self.status = 'analyzing' |
310 | 310 | session(self).flush() |
311 | 311 | sess = session(Commit) |
@@ -52,6 +52,8 @@ ew.url_base = /nf/_ew_/ | ||
52 | 52 | static.script_name = /nf/_static_/ |
53 | 53 | static.url_base = /nf/_static_/ |
54 | 54 | |
55 | +scm.new_refresh = true | |
56 | + | |
55 | 57 | scm.host.ro.git = git://git.localhost$path |
56 | 58 | scm.host.rw.git = ssh://$username@localhost:8022/scm-repo$path |
57 | 59 | scm.host.https.git = https://$username@localhost:8022/scm-repo$path |
@@ -7,8 +7,59 @@ from ming.orm import ThreadLocalORMSession | ||
7 | 7 | |
8 | 8 | from alluratest.controller import setup_basic_test, setup_global_objects |
9 | 9 | from allura.lib import helpers as h |
10 | +from allura import model as M | |
10 | 11 | from forgegit import model as GM |
11 | 12 | |
13 | +class TestNewGit(unittest.TestCase): | |
14 | + | |
15 | + def setUp(self): | |
16 | + setup_basic_test() | |
17 | + setup_global_objects() | |
18 | + h.set_context('test', 'src') | |
19 | + repo_dir = pkg_resources.resource_filename( | |
20 | + 'forgegit', 'tests/data') | |
21 | + self.repo = GM.Repository( | |
22 | + name='testgit.git', | |
23 | + fs_path=repo_dir, | |
24 | + url_path = '/test/', | |
25 | + tool = 'git', | |
26 | + status = 'creating') | |
27 | + self.repo.refresh() | |
28 | + self.rev = M.repo.Commit.query.get(_id=self.repo.heads[0]['object_id']) | |
29 | + self.rev.repo = self.repo | |
30 | + ThreadLocalORMSession.flush_all() | |
31 | + ThreadLocalORMSession.close_all() | |
32 | + | |
33 | + def test_commit(self): | |
34 | + assert self.rev.primary() is self.rev | |
35 | + assert self.rev.index_id().startswith('allura/model/repo/Commit#') | |
36 | + self.rev.author_url | |
37 | + self.rev.committer_url | |
38 | + assert self.rev.tree._id == self.rev.tree_id | |
39 | + assert self.rev.summary == self.rev.message.splitlines()[0] | |
40 | + assert self.rev.shorthand_id() == '[1e146e]' | |
41 | + assert self.rev.symbolic_ids == (['master'], []) | |
42 | + assert self.rev.url() == ( | |
43 | + '/p/test/src/ci/' | |
44 | + '1e146e67985dcd71c74de79613719bef7bddca4a/') | |
45 | + all_cis = self.rev.log(0, 1000) | |
46 | + assert len(all_cis) == 4 | |
47 | + assert self.rev.log(1,1000) == all_cis[1:] | |
48 | + assert self.rev.log(0,3) == all_cis[:3] | |
49 | + assert self.rev.log(1,2) == all_cis[1:3] | |
50 | + for ci in all_cis: | |
51 | + ci.count_revisions() | |
52 | + ci.context() | |
53 | + self.rev.tree.ls() | |
54 | + print self.rev.tree.readme() | |
55 | + assert self.rev.tree.path() == '/' | |
56 | + assert self.rev.tree.url() == ( | |
57 | + '/p/test/src/ci/' | |
58 | + '1e146e67985dcd71c74de79613719bef7bddca4a/' | |
59 | + 'tree/') | |
60 | + self.rev.tree.by_name['README'] | |
61 | + assert self.rev.tree.is_blob('README') == True | |
62 | + | |
12 | 63 | class TestGitRepo(unittest.TestCase): |
13 | 64 | |
14 | 65 | def setUp(self): |