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

Archive Download this file

Branches

Tags

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