monotone

monotone Mtn Source Tree

Root/project.cc

1// 2007 Timothy Brownawell <tbrownaw@gmail.com>
2// GNU GPL V2 or later
3
4#include "base.hh"
5#include "vector.hh"
6
7#include "cert.hh"
8#include "database.hh"
9#include "project.hh"
10#include "revision.hh"
11#include "transforms.hh"
12#include "lua_hooks.hh"
13#include "keys.hh"
14#include "options.hh"
15
16using std::string;
17using std::set;
18using std::vector;
19using std::multimap;
20using std::make_pair;
21
22project_t::project_t(database & db)
23 : db(db)
24{}
25
26void
27project_t::get_branch_list(std::set<branch_name> & names,
28 bool check_heads)
29{
30 if (indicator.outdated())
31 {
32 std::vector<std::string> got;
33 indicator = db.get_branches(got);
34 branches.clear();
35 multimap<revision_id, revision_id> inverse_graph_cache;
36
37 for (std::vector<std::string>::iterator i = got.begin();
38 i != got.end(); ++i)
39 {
40 // check that the branch has at least one non-suspended head
41 const branch_name branch(*i);
42 std::set<revision_id> heads;
43
44 if (check_heads)
45 get_branch_heads(branch, heads, false, &inverse_graph_cache);
46
47 if (!check_heads || !heads.empty())
48 branches.insert(branch);
49 }
50 }
51
52 names = branches;
53}
54
55void
56project_t::get_branch_list(globish const & glob,
57 std::set<branch_name> & names,
58 bool check_heads)
59{
60 std::vector<std::string> got;
61 db.get_branches(glob, got);
62 names.clear();
63 multimap<revision_id, revision_id> inverse_graph_cache;
64
65 for (std::vector<std::string>::iterator i = got.begin();
66 i != got.end(); ++i)
67 {
68 // check that the branch has at least one non-suspended head
69 const branch_name branch(*i);
70 std::set<revision_id> heads;
71
72 if (check_heads)
73 get_branch_heads(branch, heads, false, &inverse_graph_cache);
74
75 if (!check_heads || !heads.empty())
76 names.insert(branch);
77 }
78}
79
80namespace
81{
82 struct not_in_branch : public is_failure
83 {
84 database & db;
85 branch_name const & branch;
86 not_in_branch(database & db,
87 branch_name const & branch)
88 : db(db), branch(branch)
89 {}
90 virtual bool operator()(revision_id const & rid)
91 {
92 vector< revision<cert> > certs;
93 db.get_revision_certs(rid,
94 cert_name(branch_cert_name),
95 cert_value(branch()),
96 certs);
97 erase_bogus_certs(db, certs);
98 return certs.empty();
99 }
100 };
101
102 struct suspended_in_branch : public is_failure
103 {
104 database & db;
105 branch_name const & branch;
106 suspended_in_branch(database & db,
107 branch_name const & branch)
108 : db(db), branch(branch)
109 {}
110 virtual bool operator()(revision_id const & rid)
111 {
112 vector< revision<cert> > certs;
113 db.get_revision_certs(rid,
114 cert_name(suspend_cert_name),
115 cert_value(branch()),
116 certs);
117 erase_bogus_certs(db, certs);
118 return !certs.empty();
119 }
120 };
121}
122
123void
124project_t::get_branch_heads(branch_name const & name,
125 std::set<revision_id> & heads,
126 bool ignore_suspend_certs,
127 multimap<revision_id, revision_id> * inverse_graph_cache_ptr)
128{
129 std::pair<branch_name, suspended_indicator>
130 cache_index(name, ignore_suspend_certs);
131 std::pair<outdated_indicator, std::set<revision_id> > &
132 branch = branch_heads[cache_index];
133 if (branch.first.outdated())
134 {
135 L(FL("getting heads of branch %s") % name);
136
137 branch.first = db.get_revisions_with_cert(cert_name(branch_cert_name),
138 cert_value(name()),
139 branch.second);
140
141 not_in_branch p(db, name);
142 erase_ancestors_and_failures(db, branch.second, p,
143 inverse_graph_cache_ptr);
144
145 if (!ignore_suspend_certs)
146 {
147 suspended_in_branch s(db, name);
148 std::set<revision_id>::iterator it = branch.second.begin();
149 while (it != branch.second.end())
150 if (s(*it))
151 branch.second.erase(it++);
152 else
153 it++;
154 }
155
156 L(FL("found heads of branch %s (%s heads)")
157 % name % branch.second.size());
158 }
159 heads = branch.second;
160}
161
162bool
163project_t::revision_is_in_branch(revision_id const & id,
164 branch_name const & branch)
165{
166 vector<revision<cert> > certs;
167 db.get_revision_certs(id, branch_cert_name, cert_value(branch()), certs);
168
169 int num = certs.size();
170
171 erase_bogus_certs(db, certs);
172
173 L(FL("found %d (%d valid) %s branch certs on revision %s")
174 % num
175 % certs.size()
176 % branch
177 % id);
178
179 return !certs.empty();
180}
181
182void
183project_t::put_revision_in_branch(key_store & keys,
184 revision_id const & id,
185 branch_name const & branch)
186{
187 cert_revision_in_branch(db, keys, id, branch);
188}
189
190bool
191project_t::revision_is_suspended_in_branch(revision_id const & id,
192 branch_name const & branch)
193{
194 vector<revision<cert> > certs;
195 db.get_revision_certs(id, suspend_cert_name, cert_value(branch()), certs);
196
197 int num = certs.size();
198
199 erase_bogus_certs(db, certs);
200
201 L(FL("found %d (%d valid) %s suspend certs on revision %s")
202 % num
203 % certs.size()
204 % branch
205 % id);
206
207 return !certs.empty();
208}
209
210void
211project_t::suspend_revision_in_branch(key_store & keys,
212 revision_id const & id,
213 branch_name const & branch)
214{
215 cert_revision_suspended_in_branch(db, keys, id, branch);
216}
217
218
219outdated_indicator
220project_t::get_revision_cert_hashes(revision_id const & rid,
221 std::vector<id> & hashes)
222{
223 return db.get_revision_certs(rid, hashes);
224}
225
226outdated_indicator
227project_t::get_revision_certs(revision_id const & id,
228 std::vector<revision<cert> > & certs)
229{
230 return db.get_revision_certs(id, certs);
231}
232
233outdated_indicator
234project_t::get_revision_certs_by_name(revision_id const & id,
235 cert_name const & name,
236 std::vector<revision<cert> > & certs)
237{
238 outdated_indicator i = db.get_revision_certs(id, name, certs);
239 erase_bogus_certs(db, certs);
240 return i;
241}
242
243outdated_indicator
244project_t::get_revision_branches(revision_id const & id,
245 std::set<branch_name> & branches)
246{
247 std::vector<revision<cert> > certs;
248 outdated_indicator i = get_revision_certs_by_name(id, branch_cert_name, certs);
249 branches.clear();
250 for (std::vector<revision<cert> >::const_iterator i = certs.begin();
251 i != certs.end(); ++i)
252 branches.insert(branch_name(i->inner().value()));
253
254 return i;
255}
256
257outdated_indicator
258project_t::get_branch_certs(branch_name const & branch,
259 std::vector<revision<cert> > & certs)
260{
261 return db.get_revision_certs(branch_cert_name, cert_value(branch()), certs);
262}
263
264tag_t::tag_t(revision_id const & ident,
265 utf8 const & name,
266 rsa_keypair_id const & key)
267 : ident(ident), name(name), key(key)
268{}
269
270bool
271operator < (tag_t const & a, tag_t const & b)
272{
273 if (a.name < b.name)
274 return true;
275 else if (a.name == b.name)
276 {
277 if (a.ident < b.ident)
278 return true;
279 else if (a.ident == b.ident)
280 {
281 if (a.key < b.key)
282 return true;
283 }
284 }
285 return false;
286}
287
288outdated_indicator
289project_t::get_tags(set<tag_t> & tags)
290{
291 std::vector<revision<cert> > certs;
292 outdated_indicator i = db.get_revision_certs(tag_cert_name, certs);
293 erase_bogus_certs(db, certs);
294 tags.clear();
295 for (std::vector<revision<cert> >::const_iterator i = certs.begin();
296 i != certs.end(); ++i)
297 tags.insert(tag_t(revision_id(i->inner().ident),
298 utf8(i->inner().value()), i->inner().key));
299
300 return i;
301}
302
303void
304project_t::put_tag(key_store & keys,
305 revision_id const & id,
306 string const & name)
307{
308 cert_revision_tag(db, keys, id, name);
309}
310
311
312void
313project_t::put_standard_certs(key_store & keys,
314 revision_id const & id,
315 branch_name const & branch,
316 utf8 const & changelog,
317 date_t const & time,
318 string const & author)
319{
320 I(!branch().empty());
321 I(!changelog().empty());
322 I(time.valid());
323 I(!author.empty());
324
325 cert_revision_in_branch(db, keys, id, branch);
326 cert_revision_changelog(db, keys, id, changelog);
327 cert_revision_date_time(db, keys, id, time);
328 cert_revision_author(db, keys, id, author);
329}
330
331void
332project_t::put_standard_certs_from_options(options const & opts,
333 lua_hooks & lua,
334 key_store & keys,
335 revision_id const & id,
336 branch_name const & branch,
337 utf8 const & changelog)
338{
339 date_t date;
340 if (opts.date_given)
341 date = opts.date;
342 else
343 date = date_t::now();
344
345 string author = opts.author();
346 if (author.empty())
347 {
348 rsa_keypair_id key;
349 get_user_key(opts, lua, db, keys, key);
350
351 if (!lua.hook_get_author(branch, key, author))
352 author = key();
353 }
354
355 put_standard_certs(keys, id, branch, changelog, date, author);
356}
357
358void
359project_t::put_cert(key_store & keys,
360 revision_id const & id,
361 cert_name const & name,
362 cert_value const & value)
363{
364 put_simple_revision_cert(db, keys, id, name, value);
365}
366
367
368// Local Variables:
369// mode: C++
370// fill-column: 76
371// c-file-style: "gnu"
372// indent-tabs-mode: nil
373// End:
374// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
375

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status