# # # delete "editable_policy.cc" # # delete "editable_policy.hh" # # delete "policy.cc" # # delete "policy.hh" # # add_dir "policies" # # add_file "policies/base_policy.cc" # content [121eef2b7addf65e07a3a9989c7195c07c9cf189] # # add_file "policies/base_policy.hh" # content [a9592aaaa4ad3b119a0634336524c99db99545d7] # # add_file "policies/branch.cc" # content [3bd0cffe26cab385a546c33bcf07eab8ae5737c9] # # add_file "policies/branch.hh" # content [c25aa6d7e6c48211fcefd83213ebe419725bbf83] # # add_file "policies/delegation.cc" # content [4a7c89808693be8687cb1b20a3e1b0b4ea9e39dc] # # add_file "policies/delegation.hh" # content [ee273aa1e5304644dcbaa25cb8ddf365f4a2c056] # # add_file "policies/policy.cc" # content [7551a8648e7c09d1434d5c0730a4061b6fd92955] # # add_file "policies/policy.hh" # content [56615716634a51255294bfc1a939352429f2f289] # # patch "Makefile.am" # from [5d06fbc9c44cda097cf6f3d13aa24340ea7b254e] # to [9912bff17334d7e7eaf2830cdcd32c66f21f32ac] # # patch "origin_type.hh" # from [0e329b2b10d081f52a8346044a6522a9fdc68552] # to [73b6558e4547e45be124ba982988fc4aeb2a7894] # # patch "project.cc" # from [f92b771b4502161354efc473ffc528e2899b28c7] # to [4d4ca05c7f5fe69502fe88cf537c4eabf4d755db] # # patch "project.hh" # from [42168aabd3451e426e4d676ae468ca2ec6e793ef] # to [624981224ba71fd8332156bb49378e7dd96d3ee0] # # patch "sanity.cc" # from [981b8ecbcf2ecc2b4d617f94bbbe303f95c4b57a] # to [5393cfd075d9e203095d3aea44eb86cc090e338d] # # patch "sanity.hh" # from [9b631056da3997a94b2310e7f10d65c219fa5312] # to [3d2e1905e34223a55c977ba92f50ac0952778fc7] # # patch "transforms.hh" # from [301029c9284881c127a16fc610a8c22eb670cdde] # to [855daf66c85a6b955766d5323a61ab0b76dc5915] # ============================================================ --- policies/base_policy.cc 121eef2b7addf65e07a3a9989c7195c07c9cf189 +++ policies/base_policy.cc 121eef2b7addf65e07a3a9989c7195c07c9cf189 @@ -0,0 +1,68 @@ +// Copyright (C) 2008 and later by various people +// see monotone commit logs for details and authors +// +// This program is made available under the GNU GPL version 2.0 or +// greater. See the accompanying file COPYING for details. +// +// This program is distributed WITHOUT ANY WARRANTY; without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. + +#include "base.hh" +#include "policies/base_policy.hh" + +#include "transforms.hh" + +#include + +using std::make_pair; +using std::map; + +class database; +class lua_hooks; +class options; + +namespace policies { + base_policy::base_policy(database & db, options const & opts, lua_hooks & lua): + _empty(true) + { + load(db, opts, lua); + } + bool base_policy::empty() const + { + return _empty; + } + void base_policy::load(database & db, options const & opts, lua_hooks & lua) + { + typedef map > override_map; + for (override_map::const_iterator i = opts.policy_revisions.begin(); + i != opts.policy_revisions.end(); ++i) + { + id r = decode_hexenc(i->second); + delegations.insert(make_pair(i->first(), delegation(revision_id(r)))); + _empty = false; + } + + typedef map hook_map; + hook_map hm; + lua.hook_get_projects(hm); + for (hm::const_iterator i = hm.begin(); i != hm.end(); ++i) + { + if (delegations.find(i->first) == delegations.end()) + { + del_map::iterator d = delegations.insert(make_pair(i->first, delegation())); + d->second.deserialize(i->second()); + _empty = false; + } + } + } +} + +#endif +// Local Variables: +// mode: C++ +// fill-column: 76 +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: ============================================================ --- policies/base_policy.hh a9592aaaa4ad3b119a0634336524c99db99545d7 +++ policies/base_policy.hh a9592aaaa4ad3b119a0634336524c99db99545d7 @@ -0,0 +1,39 @@ +// Copyright (C) 2008 and later by various people +// see monotone commit logs for details and authors +// +// This program is made available under the GNU GPL version 2.0 or +// greater. See the accompanying file COPYING for details. +// +// This program is distributed WITHOUT ANY WARRANTY; without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. + +#ifndef __POLICIES_BASE_POLICY_HH__ +#define __POLICIES_BASE_POLICY_HH__ + +#include "policies/policy.hh" + +class database; +class lua_hooks; +class options; + +namespace policies { + // The top-level policy, defined by command-line options and lua hooks. + class base_policy : public policy + { + bool _empty; + void load(database & db, options const & opts, lua_hooks & lua); + public: + base_policy(database & db, options const & opts, lua_hooks & lua); + bool empty() const; + }; +} + +#endif +// Local Variables: +// mode: C++ +// fill-column: 76 +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: ============================================================ --- policies/branch.cc 3bd0cffe26cab385a546c33bcf07eab8ae5737c9 +++ policies/branch.cc 3bd0cffe26cab385a546c33bcf07eab8ae5737c9 @@ -0,0 +1,28 @@ +// Copyright (C) 2008 and later by various people +// see monotone commit logs for details and authors +// +// This program is made available under the GNU GPL version 2.0 or +// greater. See the accompanying file COPYING for details. +// +// This program is distributed WITHOUT ANY WARRANTY; without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. + +#include "base.hh" +#include "policies/branch.hh" + +namespace policies { + branch::branch() { } + branch_uid const & branch::get_uid() const + { + return uid; + } +} + +// Local Variables: +// mode: C++ +// fill-column: 76 +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: ============================================================ --- policies/branch.hh c25aa6d7e6c48211fcefd83213ebe419725bbf83 +++ policies/branch.hh c25aa6d7e6c48211fcefd83213ebe419725bbf83 @@ -0,0 +1,42 @@ +// Copyright (C) 2008 and later by various people +// see monotone commit logs for details and authors +// +// This program is made available under the GNU GPL version 2.0 or +// greater. See the accompanying file COPYING for details. +// +// This program is distributed WITHOUT ANY WARRANTY; without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. + +#ifndef __POLICIES_BRANCH_HH__ +#define __POLICIES_BRANCH_HH__ + +#include +#include + +#include "vocab.hh" + +namespace policies { + + class branch + { + branch_uid uid; + std::set signers; + public: + branch(); + branch_uid const & get_uid() const; + std::set const & get_signers() const; + void serialize(std::string & out) const; + void deserialize(std::string const & in); + }; +} + +#endif + +// Local Variables: +// mode: C++ +// fill-column: 76 +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: ============================================================ --- policies/delegation.cc 4a7c89808693be8687cb1b20a3e1b0b4ea9e39dc +++ policies/delegation.cc 4a7c89808693be8687cb1b20a3e1b0b4ea9e39dc @@ -0,0 +1,20 @@ +// Copyright (C) 2008 and later by various people +// see monotone commit logs for details and authors +// +// This program is made available under the GNU GPL version 2.0 or +// greater. See the accompanying file COPYING for details. +// +// This program is distributed WITHOUT ANY WARRANTY; without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. + +#include "base.hh" +#include "policies/delegation.hh" + +// Local Variables: +// mode: C++ +// fill-column: 76 +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: ============================================================ --- policies/delegation.hh ee273aa1e5304644dcbaa25cb8ddf365f4a2c056 +++ policies/delegation.hh ee273aa1e5304644dcbaa25cb8ddf365f4a2c056 @@ -0,0 +1,48 @@ +// Copyright (C) 2008 and later by various people +// see monotone commit logs for details and authors +// +// This program is made available under the GNU GPL version 2.0 or +// greater. See the accompanying file COPYING for details. +// +// This program is distributed WITHOUT ANY WARRANTY; without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. + +#ifndef __POLICIES_DELEGATION_HH__ +#define __POLICIES_DELEGATION_HH__ + +#include +#include + +#include "vocab.hh" + +#include "policies/branch.hh" + +namespace policies { + class policy; + + class delegation + { + enum delegation_type { revision_type, branch_type }; + delegation_type type; + revision_id revid; + branch branch_desc; + public: + delegation(); + explicit delegation(revision_id const & r); + void serialize(std::string & out) const; + void deserialize(std::string const & in); + + boost::shared_ptr resolve(boost::shared_ptr parent) const; + }; +} + +#endif + +// Local Variables: +// mode: C++ +// fill-column: 76 +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: ============================================================ --- policies/policy.cc 7551a8648e7c09d1434d5c0730a4061b6fd92955 +++ policies/policy.cc 7551a8648e7c09d1434d5c0730a4061b6fd92955 @@ -0,0 +1,66 @@ +// Copyright (C) 2008 and later by various people +// see monotone commit logs for details and authors +// +// This program is made available under the GNU GPL version 2.0 or +// greater. See the accompanying file COPYING for details. +// +// This program is distributed WITHOUT ANY WARRANTY; without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. + +#include "base.hh" +#include "policies/policy.hh" + +#include "keys.hh" + +namespace policies { + policy::policy() + { + } + policy::~policy() + { + } + + key_name policy::get_key_name(key_id const & ident) const + { + } + + key_id policy::get_key_id(key_name const & ident) const + { + key_map::const_iterator k = keys.find(ident()); + if (k != keys.end()) + { + key_id out; + key_hash_code(k->second.first, k->second.second, out); + return out; + } + boost::shared_ptr p = parent.lock(); + if (p) + return p->get_key_id(ident); + else + return key_id(); + } + + policy::del_map const & policy::list_delegations() const + { + return delegations; + } + + map const & policy::list_branches() const + { + return branches; + } + + map const & policy::list_tags() const + { + return tags; + } +} + +// Local Variables: +// mode: C++ +// fill-column: 76 +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: ============================================================ --- policies/policy.hh 56615716634a51255294bfc1a939352429f2f289 +++ policies/policy.hh 56615716634a51255294bfc1a939352429f2f289 @@ -0,0 +1,65 @@ +// Copyright (C) 2008 and later by various people +// see monotone commit logs for details and authors +// +// This program is made available under the GNU GPL version 2.0 or +// greater. See the accompanying file COPYING for details. +// +// This program is distributed WITHOUT ANY WARRANTY; without even the +// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. + +#ifndef __POLICIES_POLICY_HH__ +#define __POLICIES_POLICY_HH__ + +#include +#include + +#include "vocab.hh" + +#include "policies/branch.hh" +#include "policies/delegation.hh" + +namespace policies { + class policy + { + public: + typedef std::map del_map; + typedef std::map > key_map; + protected: + std::map branches; + del_map delegations; + + key_map keys; + std::map tags; + + boost::weak_ptr parent; + + policy(); + + public: + virtual ~policy(); + + // keys + key_name get_key_name(key_id const & ident) const; + key_id get_key_id(key_name const & ident) const; + + // delegations + del_map const & list_delegations() const; + + // branches + std::map const & list_branches() const; + + // tags + std::map const & list_tags() const; + }; +} + +#endif + +// Local Variables: +// mode: C++ +// fill-column: 76 +// c-file-style: "gnu" +// indent-tabs-mode: nil +// End: +// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: ============================================================ --- Makefile.am 5d06fbc9c44cda097cf6f3d13aa24340ea7b254e +++ Makefile.am 9912bff17334d7e7eaf2830cdcd32c66f21f32ac @@ -50,8 +50,6 @@ MOST_SOURCES = \ update.cc update.hh \ work.cc migrate_work.cc work.hh \ cert.cc cert.hh \ - policy.cc policy.hh \ - editable_policy.cc editable_policy.hh \ project.cc project.hh \ outdated_indicator.cc outdated_indicator.hh \ database.cc database.hh \ @@ -78,6 +76,10 @@ MOST_SOURCES = \ network/wrapped_session.hh network/wrapped_session.cc \ netxx_pipe.cc netxx_pipe.hh \ netcmd.cc netcmd.hh \ + policies/base_policy.hh policies/base_policy.cc \ + policies/branch.hh policies/branch.cc \ + policies/delegation.hh policies/delegation.cc \ + policies/policy.hh policies/policy.cc \ merkle_tree.cc merkle_tree.hh \ lcs.cc lcs.hh \ rcs_import.cc rcs_import.hh \ ============================================================ --- origin_type.hh 0e329b2b10d081f52a8346044a6522a9fdc68552 +++ origin_type.hh 73b6558e4547e45be124ba982988fc4aeb2a7894 @@ -19,7 +19,8 @@ namespace origin { workspace, system, user, - no_fault + no_fault, + try_xform // failed checks will throw try_xform_failed and not log }; } ============================================================ --- project.cc f92b771b4502161354efc473ffc528e2899b28c7 +++ project.cc 4d4ca05c7f5fe69502fe88cf537c4eabf4d755db @@ -11,12 +11,15 @@ #include "vector.hh" #include #include +#include #include "cert.hh" #include "database.hh" #include "file_io.hh" #include "globish.hh" -#include "policy.hh" +//#include "policy.hh" +#include "policies/base_policy.hh" +//#include "policies/policy.hh" #include "project.hh" #include "revision.hh" #include "transforms.hh" @@ -36,21 +39,226 @@ using boost::shared_ptr; using std::vector; using std::map; using boost::shared_ptr; +using boost::weak_ptr; +using policies::branch; +using policies::policy; + +struct policy_key +{ + weak_ptr parent; + string delegation_name; + string serialized_delegation; +}; + +bool operator<(policy_key const & l, policy_key const & r) +{ + if (l.parent < r.parent) + return true; + else if (r.parent < l.parent) + return false; + + if (l.delegation_name < r.delegation_name) + return true; + else if (r.delegation_name < l.delegation_name) + return false; + + return l.serialized_delegation < r.serialized_delegation; +} + +typedef map > child_policy_map; + +// walk the tree of policies, resolving children if needed +void walk_policies(shared_ptr root, + child_policy_map & children, + boost::function, string)> fn, + string current_prefix = "") +{ + fn(root, current_prefix); + + policy::del_map const & d(root->list_delegations()); + for (policy::del_map::const_iterator i = d.begin(); i != d.end(); ++i) + { + string child_prefix = current_prefix; + if (!i->first.empty()) + child_prefix += string(".") + i->first; + + policy_key child_key; + child_key.parent = root; + child_key.delegation_name = i->first; + i->second.serialize(child_key.serialized_delegation); + + child_policy_map::iterator c = children.find(child_key); + if (c == children.end()) + { + pair x = + children.insert(make_pair(child_key, i->second.resolve(root))); + c = x.first; + } + + walk_policies(c->second, children, fn, child_prefix); + } +} + +struct branch_info +{ + branch self; + shared_ptr owner; + branch_info(branch const & b, shared_ptr o) + : self(b), owner(o) + { } +}; +class branch_lister +{ + map & branches; +public: + branch_lister(map & b) : branches(b) { } + void operator()(shared_ptr pol, string prefix) + { + map const & x = pol->list_branches(); + for (map::const_iterator i = x.begin(); i != x.end(); ++i) + { + if (prefix.empty()) + branches.insert(make_pair(branch_name(prefix, origin::internal), + branch_info(i->second, pol))); + else if (i->first.empty()) + branches.insert(make_pair(branch_name(i->first, origin::internal), + branch_info(i->second, pol))); + else + branches.insert(make_pair(branch_name(prefix + "." + i->first, + origin::internal), + branch_info(i->second, pol))); + } + } +}; + +class tag_lister +{ + set & tags; +public: + tag_lister(set & t) : tags(t) { } + void operator()(shared_ptr pol, string prefix) + { + map const & x = pol->list_tags(); + for (map::const_iterator i = x.begin(); + i != x.end(); ++i) + { + string name = prefix; + if (!name.empty() && !i->first.empty()) + name += "."; + name += i->first; + tags.insert(tag_t(i->second, + utf8(name, origin::internal), + key_id())); + } + } +}; + class policy_info { + shared_ptr policy; + child_policy_map child_policies; public: - shared_ptr policy; bool passthru; explicit policy_info(database & db) - : policy(policy_branch::empty_policy(db)), + : policy(), passthru(true) { } - policy_info(shared_ptr const & ep, database & db) - : policy(policy_branch::create(ep, db)), passthru(false) + policy_info(shared_ptr const & ep, database & db) + : policy(ep), passthru(false) { } + + void all_branches(set & branches) + { + branches.clear(); + if (!policy) + return; + + map branch_map; + walk_policies(policy, child_policies, branch_lister(branch_map)); + for (map::iterator i = branch_map.begin(); + i != branch_map.end(); ++i) + { + branches.insert(i->first); + } + } + void all_branches(set & branches) + { + branches.clear(); + if (!policy) + return; + + map branch_map; + walk_policies(policy, child_policies, branch_lister(branch_map)); + for (map::iterator i = branch_map.begin(); + i != branch_map.end(); ++i) + { + branches.insert(i->second.self.get_uid()); + } + } + + void all_tags(set & tags) + { + tags.clear(); + if (!policy) + return; + + walk_policies(policy, child_policies, tag_lister(tags)); + } + + branch_uid translate_branch(branch_name const & name) + { + map branch_map; + walk_policies(policy, child_policies, branch_lister(branch_map)); + map::const_iterator i = branch_map.find(name); + if (i != branch_map.end()) + { + return i->second.self.get_uid(); + } + I(false); + } + + branch_name translate_branch(branch_uid const & uid) + { + map branch_map; + walk_policies(policy, child_policies, branch_lister(branch_map)); + for (map::iterator i = branch_map.begin(); + i != branch_map.end(); ++i) + { + if (i->second.self.get_uid() == uid) + return i->first; + } + I(false); + } + + void lookup_branch(branch_name const & name, + branch_uid & uid, set & signers) + { + map branch_map; + walk_policies(policy, child_policies, branch_lister(branch_map)); + map::const_iterator i = branch_map.find(name); + if (i != branch_map.end()) + { + uid = i->second.self.get_uid(); + set raw_signers = i->second.self.get_signers(); + for (set::iterator k = raw_signers.begin(); + k != raw_signers.end(); ++k) + { + key_id id; + if (try_decode_hexenc((*k)(), id)) + signers.insert(id); + else + { + key_name kn = typecast_vocab(*k); + signers.insert(i->second.owner->get_key_id(kn)); + } + } + return ; + } + I(false); + } }; bool @@ -87,41 +295,11 @@ project_t::project_t(database & db, lua_ project_t::project_t(database & db, lua_hooks & lua, options & opts) : db(db) { - shared_ptr ep(new editable_policy(db, set())); - // Empty editable_policy's start with (at least) a self-referencing - // __policy__ branch. We don't want that. - while (!ep->get_all_branches().empty()) - { - ep->remove_branch(ep->get_all_branches().begin()->first); - } - - bool have_delegation(false); - - for (map >::const_iterator - i = opts.policy_revisions.begin(); - i != opts.policy_revisions.end(); ++i) - { - data dat("revision_id ["+i->second()+"]\n", origin::internal); - ep->get_delegation(i->first(), true)->read(dat); - have_delegation = true; - } - - std::map defs; - lua.hook_get_projects(defs); - for (map::const_iterator i = defs.begin(); - i != defs.end(); ++i) - { - // Don't overwrite something that was overridden - // from the command line (above). - if (ep->get_delegation(i->first)) - continue; - ep->get_delegation(i->first, true)->read(i->second); - have_delegation = true; - } - if (have_delegation) - project_policy.reset(new policy_info(ep, db)); + shared_ptr bp(new policies::base_policy(db, opts, lua)); + if (bp->empty()) + project_policy.reset(new policy_info(db)); else - project_policy.reset(new policy_info(db)); + project_policy.reset(new policy_info(bp, db)); } project_t @@ -129,7 +307,7 @@ project_t::empty_project(database & db) { return project_t(db); } - +/* bool project_t::get_policy_branch_policy_of(branch_name const & name, editable_policy & policy_branch_policy, @@ -176,6 +354,7 @@ project_t::get_subpolicies(branch_name c } } } +*/ void project_t::get_branch_list(set & names, @@ -183,12 +362,7 @@ project_t::get_branch_list(setpassthru) { - policy_branch::branchmap branches = project_policy->policy->branches(); - for (policy_branch::branchmap::const_iterator i = branches.begin(); - i != branches.end(); ++i) - { - names.insert(i->first); - } + project_policy->all_branches(names); return; } if (indicator.outdated()) @@ -223,12 +397,14 @@ project_t::get_branch_list(globish const { if (!project_policy->passthru) { - policy_branch::branchmap branches = project_policy->policy->branches(); - for (policy_branch::branchmap::const_iterator i = branches.begin(); - i != branches.end(); ++i) + set all_names; + project_policy->all_branches(all_names); + + for (set::const_iterator i = all_names.begin(); + i != all_names.end(); ++i) { - if (glob.matches(i->first())) - names.insert(i->first); + if (glob.matches((*i)())) + names.insert(*i); } return; } @@ -268,12 +444,7 @@ project_t::get_branch_list(std::setpolicy->branches(); - for (policy_branch::branchmap::const_iterator i = branches.begin(); - i != branches.end(); ++i) - { - branch_ids.insert(i->second.uid); - } + project_policy->all_branches(branch_ids); } branch_uid @@ -281,10 +452,8 @@ project_t::translate_branch(branch_name { if (project_policy->passthru) return typecast_vocab(name); - policy_branch::branchmap branches = project_policy->policy->branches(); - policy_branch::branchmap::iterator i = branches.find(name); - I(i != branches.end()); - return i->second.uid; + else + return project_policy->translate_branch(name); } branch_name @@ -292,14 +461,8 @@ project_t::translate_branch(branch_uid c { if (project_policy->passthru) return typecast_vocab(uid); - policy_branch::branchmap branches = project_policy->policy->branches(); - for (policy_branch::branchmap::const_iterator i = branches.begin(); - i != branches.end(); ++i) - { - if (i->second.uid == uid) - return i->first; - } - I(false); + else + return project_policy->translate_branch(uid); } namespace @@ -307,11 +470,37 @@ namespace struct not_in_branch : public is_failure { project_t & project; - branch_name const & branch; + branch_uid const & branch; + bool is_managed; + set trusted_signers; not_in_branch(project_t & project, - branch_name const & branch) - : project(project), branch(branch) + branch_uid const & branch) + : project(project), + branch(branch), + is_managed(false) {} + not_in_branch(project_t & project, + branch_uid const & branch, + set const & signers) + : project(project), + branch(branch), + is_managed(true), + trusted_signers(signers) + {} + bool is_trusted(set const & signers, + id const & rid, + cert_name const & name, + cert_value const & value) + { + for (set::const_iterator i = signers.begin(); + i != signers.end(); ++i) + { + set::const_iterator t = trusted_signers.find(*i); + if (t != trusted_signers.end()) + return true; + } + return false; + } virtual bool operator()(revision_id const & rid) { vector certs; @@ -319,7 +508,12 @@ namespace cert_name(branch_cert_name), typecast_vocab(branch), certs); - project.db.erase_bogus_certs(project, certs); + if (is_managed) + project.db.erase_bogus_certs(certs, + bind(¬_in_branch::is_trusted, + this, _1, _2, _3, _4)); + else + project.db.erase_bogus_certs(project, certs); return certs.empty(); } }; @@ -327,11 +521,35 @@ namespace struct suspended_in_branch : public is_failure { project_t & project; - branch_name const & branch; + branch_uid const & branch; + bool is_managed; + set trusted_signers; suspended_in_branch(project_t & project, - branch_name const & branch) - : project(project), branch(branch) + branch_uid const & branch) + : project(project), branch(branch), is_managed(false) {} + suspended_in_branch(project_t & project, + branch_uid const & branch, + set const & signers) + : project(project), + branch(branch), + is_managed(true), + trusted_signers(signers) + {} + bool is_trusted(set const & signers, + id const & rid, + cert_name const & name, + cert_value const & value) + { + for (set::const_iterator i = signers.begin(); + i != signers.end(); ++i) + { + set::const_iterator t = trusted_signers.find(*i); + if (t != trusted_signers.end()) + return true; + } + return false; + } virtual bool operator()(revision_id const & rid) { vector certs; @@ -339,7 +557,12 @@ namespace cert_name(suspend_cert_name), typecast_vocab(branch), certs); - project.db.erase_bogus_certs(project, certs); + if (is_managed) + project.db.erase_bogus_certs(certs, + bind(&suspended_in_branch::is_trusted, + this, _1, _2, _3, _4)); + else + project.db.erase_bogus_certs(project, certs); return !certs.empty(); } }; @@ -360,44 +583,47 @@ project_t::get_branch_heads(branch_name { L(FL("getting heads of branch %s") % name); + branch_uid uid; + set signers; if (project_policy->passthru) + uid = typecast_vocab(name); + else { + project_policy->lookup_branch(name, uid, signers); + } - branch.first = db.get_revisions_with_cert(cert_name(branch_cert_name), - typecast_vocab(name), + branch.first = db.get_revisions_with_cert(cert_name(branch_cert_name), + typecast_vocab(uid), branch.second); - not_in_branch p(*this, name); - erase_ancestors_and_failures(db, branch.second, p, - inverse_graph_cache_ptr); + shared_ptr p; + if (project_policy->passthru) + p.reset(new not_in_branch(*this, uid)); + else + p.reset(new not_in_branch(*this, uid, signers)); - if (!ignore_suspend_certs) + erase_ancestors_and_failures(db, branch.second, *p, + inverse_graph_cache_ptr); + + if (!ignore_suspend_certs) + { + shared_ptr s; + if (project_policy->passthru) + s.reset(new suspended_in_branch(*this, uid)); + else + s.reset(new suspended_in_branch(*this, uid, signers)); + set::iterator it = branch.second.begin(); + while (it != branch.second.end()) { - suspended_in_branch s(*this, name); - set::iterator it = branch.second.begin(); - while (it != branch.second.end()) - { - if (s(*it)) - branch.second.erase(it++); - else - it++; - } + if ((*s)(*it)) + branch.second.erase(it++); + else + it++; } } - else - { - shared_ptr bp; - bp = project_policy->policy->maybe_get_branch_policy(name); - E(bp, name.made_from, - F("Cannot find policy for branch %s.") % name); - branch.first = ::get_branch_heads(*bp, ignore_suspend_certs, db, - branch.second, - inverse_graph_cache_ptr); - } - L(FL("found heads of branch %s (%s heads)") % name % branch.second.size()); } @@ -412,12 +638,12 @@ project_t::revision_is_in_branch(revisio { branch_uid bid = typecast_vocab(branch); vector certs; - db.get_revision_certs(id, branch_cert_name, - typecast_vocab(bid), certs); + db.get_revision_certs(id, branch_cert_name, + typecast_vocab(bid), certs); int num = certs.size(); - db.erase_bogus_certs(*this, certs); + db.erase_bogus_certs(*this, certs); L(FL("found %d (%d valid) %s branch certs on revision %s") % num @@ -429,11 +655,12 @@ project_t::revision_is_in_branch(revisio } else { - shared_ptr bp; - bp = project_policy->policy->maybe_get_branch_policy(branch); - E(bp, branch.made_from, - F("Cannot find policy for branch %s.") % branch); - return ::revision_is_in_branch(*bp, id, db); + branch_uid uid; + set signers; + project_policy->lookup_branch(branch, uid, signers); + + not_in_branch p(*this, uid, signers); + return !p(id); } } @@ -584,7 +811,7 @@ project_t::get_tags(set & tags) { std::vector certs; outdated_indicator i = db.get_revision_certs(tag_cert_name, certs); - db.erase_bogus_certs(*this, certs); + db.erase_bogus_certs(*this, certs); tags.clear(); for (std::vector::const_iterator i = certs.begin(); i != certs.end(); ++i) @@ -596,14 +823,7 @@ project_t::get_tags(set & tags) } else { - policy_branch::tagmap got = project_policy->policy->tags(); - for (policy_branch::tagmap::const_iterator i = got.begin(); - i != got.end(); ++i) - { - tags.insert(tag_t(i->second.rev, - typecast_vocab(i->first), - key_id())); - } + project_policy->all_tags(tags); return outdated_indicator(); } } ============================================================ --- project.hh 42168aabd3451e426e4d676ae468ca2ec6e793ef +++ project.hh 624981224ba71fd8332156bb49378e7dd96d3ee0 @@ -15,7 +15,7 @@ #include "branch_name.hh" #include "cert.hh" -#include "editable_policy.hh" +//#include "editable_policy.hh" #include "outdated_indicator.hh" #include "vocab.hh" @@ -99,12 +99,12 @@ public: // Used by migration code. static project_t empty_project(database & db); - bool get_policy_branch_policy_of(branch_name const & name, - editable_policy & policy_branch_policy, - branch_name & policy_prefix); - bool policy_exists(branch_name const & name) const; - void get_subpolicies(branch_name const & name, - std::set & names) const; + //bool get_policy_branch_policy_of(branch_name const & name, + // editable_policy & policy_branch_policy, + // branch_name & policy_prefix); + //bool policy_exists(branch_name const & name) const; + //void get_subpolicies(branch_name const & name, + // std::set & names) const; void get_branch_list(std::set & names, bool check_heads = false); ============================================================ --- sanity.cc 981b8ecbcf2ecc2b4d617f94bbbe303f95c4b57a +++ sanity.cc 5393cfd075d9e203095d3aea44eb86cc090e338d @@ -322,6 +322,9 @@ sanity::generic_failure(char const * exp throw std::logic_error("sanity::generic_failure occured " "before sanity::initialize"); + if (caused_by == origin::try_xform) + throw try_xform_failed(); + log(FL("Encountered an error while musing upon the following:"), file, line); gasp(); ============================================================ --- sanity.hh 9b631056da3997a94b2310e7f10d65c219fa5312 +++ sanity.hh 3d2e1905e34223a55c977ba92f50ac0952778fc7 @@ -52,6 +52,11 @@ public: virtual ~unrecoverable_failure() throw() {} }; +class try_xform_failed : public std::exception { +public: + char const * what() const throw() { return "could not xform data"; } +}; + class MusingI; class format_base; ============================================================ --- transforms.hh 301029c9284881c127a16fc610a8c22eb670cdde +++ transforms.hh 855daf66c85a6b955766d5323a61ab0b76dc5915 @@ -102,7 +102,22 @@ template T decode_hexenc_as( origin::type made_from) { return T(decode_hexenc(in, made_from), made_from); } +template +bool try_decode_hexenc(std::string in, T & out) +{ + try + { + out = decode_hexenc_as(in, origin::try_xform); + out.made_from = origin::internal; + return true; + } + catch (try_xform_failed) + { + return false; + } +} + // gzip template