# # # add_file "policies/editable_policy.cc" # content [06796791844f610c07db45ed0418890b40f76337] # # add_file "policies/editable_policy.hh" # content [aaa986ebda3403ab4a87c4bb7b9764ea95cd44d8] # # add_file "policies/policy_branch.cc" # content [06796791844f610c07db45ed0418890b40f76337] # # add_file "policies/policy_branch.hh" # content [3fdcc5c21b9d9f72d001d4241d86b5f176b4fcce] # # patch "Makefile.am" # from [9912bff17334d7e7eaf2830cdcd32c66f21f32ac] # to [2a947bd84511fbaf16d49ddbcaab67f29da0b69e] # # patch "cmd_policy.cc" # from [84fa781d5de27e04bcbbe6231f220af8d4c2052e] # to [5962413a38906b1c862afa55dd1059ae2f43106a] # # patch "policies/base_policy.hh" # from [a9592aaaa4ad3b119a0634336524c99db99545d7] # to [a39d323843f43fa9f449d4af360e3bd1afed9944] # # patch "policies/delegation.hh" # from [ee273aa1e5304644dcbaa25cb8ddf365f4a2c056] # to [2e25046f2100fed7cbb1479a0b7cc6c4d2974292] # # patch "policies/policy.hh" # from [56615716634a51255294bfc1a939352429f2f289] # to [7cd5e6122758b0b1daf9cd2470154d87ae4ccf8b] # # patch "project.cc" # from [4d4ca05c7f5fe69502fe88cf537c4eabf4d755db] # to [f9eb9aba664b6fd0cc2c26060b6cdd57cb20305f] # # patch "project.hh" # from [624981224ba71fd8332156bb49378e7dd96d3ee0] # to [f18835d5a0bc939f48558bc121af77288aff4a5e] # ============================================================ --- policies/editable_policy.cc 06796791844f610c07db45ed0418890b40f76337 +++ policies/editable_policy.cc 06796791844f610c07db45ed0418890b40f76337 @@ -0,0 +1,21 @@ +// 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" + + + +// 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/editable_policy.hh aaa986ebda3403ab4a87c4bb7b9764ea95cd44d8 +++ policies/editable_policy.hh aaa986ebda3403ab4a87c4bb7b9764ea95cd44d8 @@ -0,0 +1,46 @@ +// Copyright (C) 2010 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_EDITABLE_POLICY_HH__ +#define __POLICIES_EDITABLE_POLICY_HH__ + +#include "policies/policy.hh" + +namespace policies { + class editable_policy : public policy + { + public: + explicit editable_policy(policy const & p); + + void set_key_name(key_id const & ident, key_name const & name); + void remove_key(key_id const & ident); + + void set_branch(std::string const & name, branch const & value); + void remove_branch(std::string const & name); + + void set_tag(std::string const & name, revision_id const & value); + void remove_tag(std::string const & name); + + void set_delegation(std::string const & name, delegation const & value); + void remove_delegation(std::string const & name); + + virtual bool outdated() const { return 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/policy_branch.cc 06796791844f610c07db45ed0418890b40f76337 +++ policies/policy_branch.cc 06796791844f610c07db45ed0418890b40f76337 @@ -0,0 +1,21 @@ +// 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" + + + +// 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_branch.hh 3fdcc5c21b9d9f72d001d4241d86b5f176b4fcce +++ policies/policy_branch.hh 3fdcc5c21b9d9f72d001d4241d86b5f176b4fcce @@ -0,0 +1,63 @@ +// Copyright (C) 2010 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_BRANCH_HH__ +#define __POLICIES_POLICY_BRANCH_HH__ + +#include + +#include "policies/branch.hh" +#include "policies/policy.hh" + +namespace policies { + class policy_branch + { + public: + typedef std::set > policy_set; + private: + branch spec; + policy_set policies; + void reload(); + public: + typedef policy_set::const_iterator iterator; + + policy_branch(branch const & b); + static policy_branch new_branch(std::set const & signers); + + branch const & get_spec() const; + + policy create_initial_revision() const; + + iterator begin() const; + iterator end() const; + + void commit(policy const & p, utf8 const & changelog, + iterator parent_1, iterator parent_2); + inline void commit(policy const & p, utf8 const & changelog, + iterator parent) + { + commit(p, changelog, parent, end()); + } + inline void commit(policy const & p, utf8 const & changelog) + { + commit(p, changelog, end()); + } + }; +} + +#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 9912bff17334d7e7eaf2830cdcd32c66f21f32ac +++ Makefile.am 2a947bd84511fbaf16d49ddbcaab67f29da0b69e @@ -79,7 +79,9 @@ MOST_SOURCES = \ policies/base_policy.hh policies/base_policy.cc \ policies/branch.hh policies/branch.cc \ policies/delegation.hh policies/delegation.cc \ + policies/editable_policy.hh policies/editable_policy.cc \ policies/policy.hh policies/policy.cc \ + policies/policy_branch.hh policies/policy_branch.cc \ merkle_tree.cc merkle_tree.hh \ lcs.cc lcs.hh \ rcs_import.cc rcs_import.hh \ ============================================================ --- cmd_policy.cc 84fa781d5de27e04bcbbe6231f220af8d4c2052e +++ cmd_policy.cc 5962413a38906b1c862afa55dd1059ae2f43106a @@ -10,12 +10,16 @@ #include "basic_io.hh" #include "botan/botan.h" #include "cmd.hh" +#include "database.hh" #include "dates.hh" -#include "editable_policy.hh" +//#include "editable_policy.hh" #include "file_io.hh" #include "keys.hh" #include "key_store.hh" -#include "policy.hh" +//#include "policy.hh" +#include "policies/base_policy.hh" +#include "policies/editable_policy.hh" +#include "policies/policy_branch.hh" #include "project.hh" #include "revision.hh" #include "roster.hh" @@ -29,6 +33,14 @@ using std::string; using boost::shared_ptr; using std::string; +inline static external_key_name +key_id_to_external_name(key_id const & ident) +{ + return external_key_name(encode_hexenc(ident.inner()(), + origin::internal), + origin::internal); +} + CMD(create_project, "create_project", "", CMD_REF(policy), N_("NAME"), N_("Bootstrap creation of a new project."), @@ -54,18 +66,19 @@ CMD(create_project, "create_project", "" mkdir_p(project_dir); cache_user_key(app.opts, app.lua, db, keys, project); - std::set admin_keys; - admin_keys.insert(keys.signing_key); - std::string policy_uid; - data policy_spec; - editable_policy ep(db, admin_keys); - ep.get_branch("__policy__")->write(policy_spec); - project_t p = project_t::empty_project(db); - ep.commit(p, keys, utf8(N_("Create new policy branch"))); - write_data(project_file, policy_spec, project_dir); - P(F("Wrote project spec to %s") % project_file); + std::set signers; + signers.insert(key_id_to_external_name(keys.signing_key)); + policies::policy_branch br = policies::policy_branch::new_branch(signers); + policies::editable_policy ep(br.create_initial_revision()); + br.commit(ep, utf8(N_("Create new policy branch"))); + + policies::editable_policy bp(project.get_base_policy()); + + bp.set_delegation(project_name, policies::delegation(br.get_spec())); + + policies::base_policy::write(bp); } CMD(create_subpolicy, "create_subpolicy", "", CMD_REF(policy), ============================================================ --- policies/base_policy.hh a9592aaaa4ad3b119a0634336524c99db99545d7 +++ policies/base_policy.hh a39d323843f43fa9f449d4af360e3bd1afed9944 @@ -26,6 +26,10 @@ namespace policies { public: base_policy(database & db, options const & opts, lua_hooks & lua); bool empty() const; + inline bool outdated() const { return false; } + + // Use lua hooks to write out the given policy. + static void write(policy const & pol); }; } ============================================================ --- policies/delegation.hh ee273aa1e5304644dcbaa25cb8ddf365f4a2c056 +++ policies/delegation.hh 2e25046f2100fed7cbb1479a0b7cc6c4d2974292 @@ -30,6 +30,7 @@ namespace policies { public: delegation(); explicit delegation(revision_id const & r); + explicit delegation(branch const & b); void serialize(std::string & out) const; void deserialize(std::string const & in); ============================================================ --- policies/policy.hh 56615716634a51255294bfc1a939352429f2f289 +++ policies/policy.hh 7cd5e6122758b0b1daf9cd2470154d87ae4ccf8b @@ -12,6 +12,7 @@ #define __POLICIES_POLICY_HH__ #include +#include #include #include "vocab.hh" @@ -40,17 +41,26 @@ namespace policies { virtual ~policy(); // keys + // a key could have several names, should + // there be an invariant against that? 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; + delegation const & get_delegation(std::string const & name) const; // branches std::map const & list_branches() const; + branch const & get_branch(std::string const & name) const; // tags std::map const & list_tags() const; + revision_id const & get_tag(std::string const & name) const; + + virtual bool outdated() const { return false; } + + boost::shared_ptr get_parent() const; }; } ============================================================ --- project.cc 4d4ca05c7f5fe69502fe88cf537c4eabf4d755db +++ project.cc f9eb9aba664b6fd0cc2c26060b6cdd57cb20305f @@ -19,6 +19,8 @@ #include "globish.hh" //#include "policy.hh" #include "policies/base_policy.hh" +#include "policies/editable_policy.hh" +#include "policies/policy_branch.hh" //#include "policies/policy.hh" #include "project.hh" #include "revision.hh" @@ -154,6 +156,44 @@ public: } }; + +struct governing_policy_info +{ + shared_ptr governing_policy; + std::string governing_policy_name; + + shared_ptr governing_policy_parent; + std::string delegation_to_governing_policy; +}; +// find the policy governing a particular name +class policy_finder +{ + string target; + governing_policy_info & info; +public: + policy_finder(string const & target, governing_policy_info & info) + : target(target), info(info) + { + info.governing_policy_name.clear(); + info.delegation_to_governing_policy.clear(); + info.governing_policy.reset(); + info.governing_policy_parent.reset(); + } + + void operator()(shared_ptr pol, string prefix) + { + if (prefix.empty()) + { + return; + } + if (target.find(prefix) == 0 && prefix.size() > info.governing_policy_name.size()) + { + info.governing_policy_name = prefix; + info.governing_policy = pol; + } + } +}; + class policy_info { shared_ptr policy; @@ -246,9 +286,9 @@ public: for (set::iterator k = raw_signers.begin(); k != raw_signers.end(); ++k) { - key_id id; + id id; if (try_decode_hexenc((*k)(), id)) - signers.insert(id); + signers.insert(key_id(id)); else { key_name kn = typecast_vocab(*k); @@ -259,6 +299,23 @@ public: } I(false); } + + void find_governing_policy(std::string const & of_what, + governing_policy_info & info) + { + walk_policies(policy, child_policies, + policy_finder(of_what, info)); + if (info.governing_policy) + { + // also return the parent, if it's a 'real' database policy rather + // than the synthesized root policy + info.governing_policy_parent = info.governing_policy->get_parent(); + if (info.governing_policy_parent == policy) + { + info.governing_policy_parent.reset(); + } + } + } }; bool @@ -837,18 +894,18 @@ project_t::put_tag(key_store & keys, put_cert(keys, id, tag_cert_name, cert_value(name, origin::user)); else { - shared_ptr policy_br; - branch_name tag_name(name, origin::internal); - branch_name policy_name; - policy_br = project_policy->policy->walk(tag_name, policy_name); - E(policy_br && policy_br != project_policy->policy, - origin::internal, - F("Cannot find a parent policy for tag %s") % tag_name); - tag_name.strip_prefix(policy_name); - editable_policy ep(*policy_br->get_policy()); - ep.get_tag(tag_name(), true)->rev = id; - ep.commit(*this, keys, utf8((F("Set tag %s to %s") % tag_name % id).str(), - tag_name.made_from)); + governing_policy_info info; + project_policy->find_governing_policy(name, info); + policies::branch pol_spec = info.governing_policy->get_branch("__policy__"); + + policies::policy_branch br(pol_spec); + I(br.begin() != br.end()); + policies::editable_policy ep(**br.begin()); + + ep.set_tag(name.substr(info.governing_policy_name.size() + 1), id); + + br.commit(ep, utf8((F("Set tag %s") % name).str(), + origin::internal)); } } ============================================================ --- project.hh 624981224ba71fd8332156bb49378e7dd96d3ee0 +++ project.hh f18835d5a0bc939f48558bc121af77288aff4a5e @@ -74,6 +74,10 @@ class policy_info; class policy_info; +namespace policies { + class policy; +} + class project_t { // In the hypothetical future situation where one monotone process is @@ -99,6 +103,8 @@ public: // Used by migration code. static project_t empty_project(database & db); + policies::policy & get_base_policy() const; + //bool get_policy_branch_policy_of(branch_name const & name, // editable_policy & policy_branch_policy, // branch_name & policy_prefix);