# # # patch "automate.cc" # from [7fe1988316269eb34d1ca1e2a08f99df2a1ceb92] # to [ae5795ae2ee9abf213cde05ab0ae22f8850979dc] # # patch "cert.cc" # from [998ff85450d2c9459428f159da44f88d0de1524d] # to [ee0f832e3b34cbb3fd6f701e09501a28bdc3643d] # # patch "cert.hh" # from [e19095fd325166c38bcfcfb378f84f6dbbdf60e3] # to [f5f5492ce2552c357e75c70f206e7a5c690901cb] # # patch "cmd_key_cert.cc" # from [ad6d77c2c604e15b31c69d0bd82e1efbc360a167] # to [67d6c867196333e7d7c0b4d97ab89a72c86472ea] # # patch "database.cc" # from [99517814a88a6b21aabc07958c328af6a69e9aea] # to [92b6154a2180f68fd7681607eea565934b9ee518] # # patch "database_check.cc" # from [748c15e077685e9ab0783151323ee94150cabaa4] # to [ac24fbc342afb2b6d3b9f69bc3da2d3ce054c56e] # # patch "migrate_ancestry.cc" # from [1d8b2629b8e66f43b01088a868f64390f6a7f4bb] # to [ec057d749d84ef486c42b3cced77cd74e5f12034] # # patch "project.cc" # from [86618b33d4154fb81225a6fb34480ebf63c1d220] # to [660e86dc61bb01e617617cfced6e2e8ee04af276] # # patch "project.hh" # from [2ae5e78f9d9aaa989ff53b50565960a39cb9f1b2] # to [78364423054750c92f48bee022e134a8d3abe640] # ============================================================ --- automate.cc 7fe1988316269eb34d1ca1e2a08f99df2a1ceb92 +++ automate.cc ae5795ae2ee9abf213cde05ab0ae22f8850979dc @@ -2114,9 +2114,11 @@ CMD_AUTOMATE(cert, N_("REVISION-ID NAME F("no such revision '%s'") % hrid); cache_user_key(app.opts, app.lua, db, keys); - put_simple_revision_cert(db, keys, rid, - typecast_vocab(idx(args, 1)), - typecast_vocab(idx(args, 2))); + + project_t project(db); + project.put_cert(keys, rid, + typecast_vocab(idx(args, 1)), + typecast_vocab(idx(args, 2))); } // Name: get_db_variables ============================================================ --- cert.cc 998ff85450d2c9459428f159da44f88d0de1524d +++ cert.cc ee0f832e3b34cbb3fd6f701e09501a28bdc3643d @@ -20,17 +20,13 @@ #include "cert.hh" #include "constants.hh" #include "database.hh" -#include "interner.hh" #include "keys.hh" #include "key_store.hh" #include "netio.hh" -#include "options.hh" -#include "project.hh" #include "revision.hh" #include "sanity.hh" #include "simplestring_xform.hh" #include "transforms.hh" -#include "ui.hh" #include "vocab_cast.hh" using std::make_pair; @@ -364,170 +360,6 @@ check_cert(database & db, cert const & t return db.check_signature(t.key, signed_text, t.sig); } -bool -put_simple_revision_cert(database & db, - key_store & keys, - revision_id const & id, - cert_name const & nm, - cert_value const & val) -{ - I(!keys.signing_key().empty()); - - cert t(id, nm, val, keys.signing_key); - string signed_text; - cert_signable_text(t, signed_text); - load_key_pair(keys, t.key); - keys.make_signature(db, t.key, signed_text, t.sig); - - revision cc(t); - return db.put_revision_cert(cc); -} - -// "special certs" - -// Guess which branch is appropriate for a commit below IDENT. -// OPTS may override. Branch name is returned in BRANCHNAME. -// Does not modify branch state in OPTS. -void -guess_branch(options & opts, project_t & project, - revision_id const & ident, branch_name & branchname) -{ - if (opts.branch_given && !opts.branch().empty()) - branchname = opts.branch; - else - { - E(!ident.inner()().empty(), origin::user, - F("no branch found for empty revision, " - "please provide a branch name")); - - set branches; - project.get_revision_branches(ident, branches); - - E(!branches.empty(), origin::user, - F("no branch certs found for revision %s, " - "please provide a branch name") % ident); - - E(branches.size() == 1, origin::user, - F("multiple branch certs found for revision %s, " - "please provide a branch name") % ident); - - set::iterator i = branches.begin(); - I(i != branches.end()); - branchname = *i; - } -} - -// As above, but set the branch name in the options -// if it wasn't already set. -void -guess_branch(options & opts, project_t & project, revision_id const & ident) -{ - branch_name branchname; - guess_branch(opts, project, ident, branchname); - opts.branch = branchname; -} - -void -cert_revision_in_branch(database & db, - key_store & keys, - revision_id const & rev, - branch_name const & branch) -{ - put_simple_revision_cert(db, keys, rev, branch_cert_name, - typecast_vocab(branch)); -} - -void -cert_revision_suspended_in_branch(database & db, - key_store & keys, - revision_id const & rev, - branch_name const & branch) -{ - put_simple_revision_cert(db, keys, rev, suspend_cert_name, - typecast_vocab(branch)); -} - - -// "standard certs" - -void -cert_revision_date_time(database & db, - key_store & keys, - revision_id const & rev, - date_t const & t) -{ - cert_value val = cert_value(t.as_iso_8601_extended(), origin::internal); - put_simple_revision_cert(db, keys, rev, date_cert_name, val); -} - -void -cert_revision_author(database & db, - key_store & keys, - revision_id const & rev, - string const & author) -{ - put_simple_revision_cert(db, keys, rev, author_cert_name, - cert_value(author, origin::user)); -} - -void -cert_revision_tag(database & db, - key_store & keys, - revision_id const & rev, - string const & tagname) -{ - put_simple_revision_cert(db, keys, rev, tag_cert_name, - cert_value(tagname, origin::user)); -} - -void -cert_revision_changelog(database & db, - key_store & keys, - revision_id const & rev, - utf8 const & log) -{ - put_simple_revision_cert(db, keys, rev, changelog_cert_name, - typecast_vocab(log)); -} - -void -cert_revision_comment(database & db, - key_store & keys, - revision_id const & rev, - utf8 const & comment) -{ - put_simple_revision_cert(db, keys, rev, comment_cert_name, - typecast_vocab(comment)); -} - -void -cert_revision_testresult(database & db, - key_store & keys, - revision_id const & rev, - string const & results) -{ - bool passed = false; - if (lowercase(results) == "true" || - lowercase(results) == "yes" || - lowercase(results) == "pass" || - results == "1") - passed = true; - else if (lowercase(results) == "false" || - lowercase(results) == "no" || - lowercase(results) == "fail" || - results == "0") - passed = false; - else - throw recoverable_failure(origin::user, - "could not interpret test results, " - "tried '0/1' 'yes/no', 'true/false', " - "'pass/fail'"); - - put_simple_revision_cert(db, keys, rev, testresult_cert_name, - cert_value(lexical_cast(passed), - origin::internal)); -} - // Local Variables: // mode: C++ // fill-column: 76 ============================================================ --- cert.hh e19095fd325166c38bcfcfb378f84f6dbbdf60e3 +++ cert.hh f5f5492ce2552c357e75c70f206e7a5c690901cb @@ -84,69 +84,6 @@ void erase_bogus_certs(database & db, st void erase_bogus_certs(database & db, std::vector< revision > & certs); void erase_bogus_certs(database & db, std::vector< manifest > & certs); -// Special certs -- system won't work without them. - -#define branch_cert_name cert_name("branch") - -void -cert_revision_in_branch(database & db, key_store & keys, - revision_id const & rev, - branch_name const & branchname); - - -// We also define some common cert types, to help establish useful -// conventions. you should use these unless you have a compelling -// reason not to. - -void -guess_branch(options & opts, project_t & project, revision_id const & rev, - branch_name & branchname); -void -guess_branch(options & opts, project_t & project, revision_id const & rev); - -#define date_cert_name cert_name("date") -#define author_cert_name cert_name("author") -#define tag_cert_name cert_name("tag") -#define changelog_cert_name cert_name("changelog") -#define comment_cert_name cert_name("comment") -#define testresult_cert_name cert_name("testresult") -#define suspend_cert_name cert_name("suspend") - -void -cert_revision_suspended_in_branch(database & db, key_store & keys, - revision_id const & rev, - branch_name const & branchname); - -void -cert_revision_date_time(database & db, key_store & keys, - revision_id const & rev, - date_t const & t); - -void -cert_revision_author(database & db, key_store & keys, - revision_id const & m, - std::string const & author); - -void -cert_revision_tag(database & db, key_store & keys, - revision_id const & rev, - std::string const & tagname); - -void -cert_revision_changelog(database & db, key_store & keys, - revision_id const & rev, - utf8 const & changelog); - -void -cert_revision_comment(database & db, key_store & keys, - revision_id const & m, - utf8 const & comment); - -void -cert_revision_testresult(database & db, key_store & keys, - revision_id const & m, - std::string const & results); - #endif // __CERT_HH__ // Local Variables: ============================================================ --- cmd_key_cert.cc ad6d77c2c604e15b31c69d0bd82e1efbc360a167 +++ cmd_key_cert.cc 67d6c867196333e7d7c0b4d97ab89a72c86472ea @@ -280,7 +280,7 @@ CMD(testresult, "testresult", "", CMD_RE complete(app.opts, app.lua, project, idx(args, 0)(), r); cache_user_key(app.opts, app.lua, db, keys); - cert_revision_testresult(db, keys, r, idx(args, 1)()); + project.put_revision_testresult(keys, r, idx(args, 1)()); } @@ -360,7 +360,7 @@ CMD(comment, "comment", "", CMD_REF(revi complete(app.opts, app.lua, project, idx(args, 0)(), r); cache_user_key(app.opts, app.lua, db, keys); - cert_revision_comment(db, keys, r, comment); + project.put_revision_comment(keys, r, comment); } // Local Variables: ============================================================ --- database.cc 99517814a88a6b21aabc07958c328af6a69e9aea +++ database.cc 92b6154a2180f68fd7681607eea565934b9ee518 @@ -34,6 +34,7 @@ #include "app_state.hh" #include "cert.hh" +#include "project.hh" #include "cleanup.hh" #include "constants.hh" #include "dates.hh" ============================================================ --- database_check.cc 748c15e077685e9ab0783151323ee94150cabaa4 +++ database_check.cc ac24fbc342afb2b6d3b9f69bc3da2d3ce054c56e @@ -18,6 +18,7 @@ #include "vocab.hh" #include "transforms.hh" #include "cert.hh" +#include "project.hh" #include "rev_height.hh" #include "roster.hh" #include "outdated_indicator.hh" ============================================================ --- migrate_ancestry.cc 1d8b2629b8e66f43b01088a868f64390f6a7f4bb +++ migrate_ancestry.cc ec057d749d84ef486c42b3cced77cd74e5f12034 @@ -11,7 +11,7 @@ #include "migration.hh" #include "revision.hh" #include "roster.hh" - +#include "project.hh" #include "constants.hh" #include "database.hh" #include "graph.hh" @@ -212,6 +212,7 @@ void anc_graph::write_certs() typedef multimap >::const_iterator ci; + project_t project(db); for (map::const_iterator i = node_to_new_rev.begin(); i != node_to_new_rev.end(); ++i) @@ -225,7 +226,7 @@ void anc_graph::write_certs() cert_name name(j->second.first); cert_value val(j->second.second); - if (put_simple_revision_cert(db, keys, rev, name, val)) + if (project.put_cert(keys, rev, name, val)) ++n_certs_out; } } ============================================================ --- project.cc 86618b33d4154fb81225a6fb34480ebf63c1d220 +++ project.cc 660e86dc61bb01e617617cfced6e2e8ee04af276 @@ -16,16 +16,19 @@ #include "revision.hh" #include "transforms.hh" #include "lua_hooks.hh" +#include "key_store.hh" #include "keys.hh" #include "options.hh" #include "vocab_cast.hh" #include "simplestring_xform.hh" +#include "lexical_cast.hh" using std::string; using std::set; using std::vector; using std::multimap; using std::make_pair; +using boost::lexical_cast; project_t::project_t(database & db) : db(db) @@ -193,7 +196,7 @@ project_t::put_revision_in_branch(key_st revision_id const & id, branch_name const & branch) { - cert_revision_in_branch(db, keys, id, branch); + put_cert(keys, id, branch_cert_name, typecast_vocab(branch)); } bool @@ -222,7 +225,7 @@ project_t::suspend_revision_in_branch(ke revision_id const & id, branch_name const & branch) { - cert_revision_suspended_in_branch(db, keys, id, branch); + put_cert(keys, id, suspend_cert_name, typecast_vocab(branch)); } @@ -317,10 +320,11 @@ project_t::put_tag(key_store & keys, revision_id const & id, string const & name) { - cert_revision_tag(db, keys, id, name); + put_cert(keys, id, tag_cert_name, cert_value(name, origin::user)); } + void project_t::put_standard_certs(key_store & keys, revision_id const & id, @@ -334,10 +338,14 @@ project_t::put_standard_certs(key_store I(time.valid()); I(!author.empty()); - cert_revision_in_branch(db, keys, id, branch); - cert_revision_changelog(db, keys, id, changelog); - cert_revision_date_time(db, keys, id, time); - cert_revision_author(db, keys, id, author); + put_cert(keys, id, branch_cert_name, + typecast_vocab(branch)); + put_cert(keys, id, changelog_cert_name, + typecast_vocab(changelog)); + put_cert(keys, id, date_cert_name, + cert_value(time.as_iso_8601_extended(), origin::internal)); + put_cert(keys, id, author_cert_name, + cert_value(author, origin::user)); } void @@ -367,15 +375,58 @@ project_t::put_standard_certs_from_optio put_standard_certs(keys, id, branch, changelog, date, author); } -void +bool project_t::put_cert(key_store & keys, revision_id const & id, cert_name const & name, cert_value const & value) { - put_simple_revision_cert(db, keys, id, name, value); + I(!keys.signing_key().empty()); + + cert t(id, name, value, keys.signing_key); + string signed_text; + cert_signable_text(t, signed_text); + load_key_pair(keys, t.key); + keys.make_signature(db, t.key, signed_text, t.sig); + + revision cc(t); + return db.put_revision_cert(cc); } +void +project_t::put_revision_comment(key_store & keys, + revision_id const & id, + utf8 const & comment) +{ + put_cert(keys, id, comment_cert_name, typecast_vocab(comment)); +} + +void +project_t::put_revision_testresult(key_store & keys, + revision_id const & id, + string const & results) +{ + bool passed; + if (lowercase(results) == "true" || + lowercase(results) == "yes" || + lowercase(results) == "pass" || + results == "1") + passed = true; + else if (lowercase(results) == "false" || + lowercase(results) == "no" || + lowercase(results) == "fail" || + results == "0") + passed = false; + else + E(false, origin::user, + F("could not interpret test result string '%s'; " + "valid strings are: 1, 0, yes, no, true, false, pass, fail") + % results); + + put_cert(keys, id, testresult_cert_name, + cert_value(lexical_cast(passed), origin::internal)); +} + // These should maybe be converted to member functions. string @@ -425,7 +476,48 @@ notify_if_multiple_heads(project_t & pro } } +// Guess which branch is appropriate for a commit below IDENT. +// OPTS may override. Branch name is returned in BRANCHNAME. +// Does not modify branch state in OPTS. +void +guess_branch(options & opts, project_t & project, + revision_id const & ident, branch_name & branchname) +{ + if (opts.branch_given && !opts.branch().empty()) + branchname = opts.branch; + else + { + E(!ident.inner()().empty(), origin::user, + F("no branch found for empty revision, " + "please provide a branch name")); + set branches; + project.get_revision_branches(ident, branches); + + E(!branches.empty(), origin::user, + F("no branch certs found for revision %s, " + "please provide a branch name") % ident); + + E(branches.size() == 1, origin::user, + F("multiple branch certs found for revision %s, " + "please provide a branch name") % ident); + + set::iterator i = branches.begin(); + I(i != branches.end()); + branchname = *i; + } +} + +// As above, but set the branch name in the options +// if it wasn't already set. +void +guess_branch(options & opts, project_t & project, revision_id const & ident) +{ + branch_name branchname; + guess_branch(opts, project, ident, branchname); + opts.branch = branchname; +} + // Local Variables: // mode: C++ // fill-column: 76 ============================================================ --- project.hh 2ae5e78f9d9aaa989ff53b50565960a39cb9f1b2 +++ project.hh 78364423054750c92f48bee022e134a8d3abe640 @@ -21,7 +21,26 @@ class lua_hooks; class key_store; class options; class lua_hooks; +struct globish; +// "Special" certs have syntax and semantics essential to correct operation. +// They add structure to the ancestry graph. + +#define branch_cert_name cert_name("branch") +#define suspend_cert_name cert_name("suspend") +#define tag_cert_name cert_name("tag") + +// "Standard" certs are largely for user information, but their values have +// conventional syntax and semantics defined by the system, and the +// revision-trust hook can use them to impose further structure on the +// ancestry graph. + +#define date_cert_name cert_name("date") +#define author_cert_name cert_name("author") +#define changelog_cert_name cert_name("changelog") +#define comment_cert_name cert_name("comment") +#define testresult_cert_name cert_name("testresult") + class tag_t { public: @@ -101,10 +120,18 @@ public: branch_name const & branch, utf8 const & changelog); - void put_cert(key_store & keys, + bool put_cert(key_store & keys, revision_id const & id, cert_name const & name, cert_value const & value); + + // "standard certs" + void put_revision_testresult(key_store & keys, + revision_id const & id, + std::string const & results); + void put_revision_comment(key_store & keys, + revision_id const & id, + utf8 const & comment); }; std::string @@ -114,6 +141,12 @@ notify_if_multiple_heads(project_t & pro notify_if_multiple_heads(project_t & project, branch_name const & branchname, bool ignore_suspend_certs); +void +guess_branch(options & opts, project_t & project, revision_id const & rev, + branch_name & branchname); +void +guess_branch(options & opts, project_t & project, revision_id const & rev); + #endif // Local Variables: