#
# old_revision [9f3769cf9cfad6e230a05bf69effb900571c4572]
#
# patch "ChangeLog"
# from [475065e0075fea72070c1b9e3df9d6156a2d23d2]
# to [3c78ab706bc27dfb612042684426b16377300c1c]
#
# patch "commands.cc"
# from [33b8690ab922b91ac0218b9412ba6a84d024094d]
# to [4cfb88859a1a856ecf9d5340e26d558fecc9a6e1]
#
# patch "lua.cc"
# from [c8c228b16b396eaf8cbc1b41ca6363593e9abfee]
# to [6b9dd32e7d083192b2996adf831d32a013e23fd8]
#
# patch "lua.hh"
# from [71e2943fa623254b4e3e1340e1f8c4b442271a6c]
# to [1c16c56eee90a8c7ab87d5e0bca28da928f3c248]
#
# patch "std_hooks.lua"
# from [a5e3529e680469a911323f45286466780088f35d]
# to [aee63195ac081781e08738050eb7e169dcef83b3]
#
============================================================
--- ChangeLog 475065e0075fea72070c1b9e3df9d6156a2d23d2
+++ ChangeLog 3c78ab706bc27dfb612042684426b16377300c1c
@@ -1,3 +1,12 @@
+2006-01-25 Blake Kaplan
+
+ * commands.cc CMD(commit): Call a new lua hook to validate the commit
+ message. Don't ignore -m "" when it's passed on the command line.
+ * lua.cc, lua.hh: Add a new hook that validates a given commit message
+ and passes in the added files, deleted files, and modified files.
+ * std_hooks.lua: Give a default hook to validate commit messages. This
+ currently disallows empty messages, as monotone currently does.
+
2006-01-20 Richard Levitte
* po/sv.po: Added a \n at the end of a msgstr that was missing
============================================================
--- commands.cc 33b8690ab922b91ac0218b9412ba6a84d024094d
+++ commands.cc 4cfb88859a1a856ecf9d5340e26d558fecc9a6e1
@@ -1,4 +1,5 @@
// -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*-
+// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
// copyright (C) 2002, 2003 graydon hoare
// all rights reserved.
// licensed to the public under the terms of the GNU GPL (>= 2)
@@ -2258,12 +2259,12 @@
N(app.message().length() == 0 || app.message_file().length() == 0,
F("--message and --message-file are mutually exclusive"));
- if (app.message().length() > 0)
+ if (app.is_explicit_option(OPT_MESSAGE))
{
log_message = app.message();
given = true;
}
- else if (app.message_file().length() > 0)
+ else if (app.is_explicit_option(OPT_MSGFILE))
{
data dat;
read_data_for_command_line(app.message_file(), dat);
@@ -2274,7 +2275,56 @@
given = false;
}
+static void
+revision_set_to_vectors(revision_set const & rs,
+ vector & additions,
+ vector & deletions,
+ vector & modifications)
+{
+ // Iterate over the edges, extracting the useful information out of each
+ // one. XXX We might be able to assume only 1 or 2 edges here.
+ for (edge_map::const_iterator beg = rs.edges.begin(), end = rs.edges.end();
+ beg != end; ++beg)
+ {
+ cset const & changes = edge_changes(beg);
+ // Grab the deletions.
+ for (path_set::const_iterator change = changes.nodes_deleted.begin(),
+ lastchange = changes.nodes_deleted.end();
+ change != lastchange; ++change)
+ {
+ file_path current(*change);
+ ostringstream os;
+ os << current;
+ deletions.push_back(os.str());
+ }
+
+ // Grab the additions.
+ for (std::map::const_iterator change = changes.files_added.begin(),
+ lastchange = changes.files_added.end(); change != lastchange; ++change)
+ {
+ file_path current(change->first);
+ ostringstream os;
+ os << current;
+ additions.push_back(os.str());
+ }
+
+ // Grab the modifications.
+ typedef std::map >::const_iterator
+ delta_iterator;
+ for (delta_iterator change = changes.deltas_applied.begin(),
+ lastchange = changes.deltas_applied.end();
+ change != lastchange; ++change)
+ {
+ file_path current(change->first);
+ ostringstream os;
+ os << current;
+ modifications.push_back(os.str());
+ }
+ }
+}
+
CMD(commit, N_("working copy"), N_("[PATH]..."),
N_("commit working copy to database"),
OPT_BRANCH_NAME % OPT_MESSAGE % OPT_MSGFILE % OPT_DATE %
@@ -2340,6 +2390,18 @@
write_user_log(data(log_message));
}
+ // If the hook doesn't exist, allow the message to be used.
+ bool message_validated;
+ string reason;
+
+ vector deletions, additions, modifications;
+ revision_set_to_vectors(rs, additions, deletions, modifications);
+
+ app.lua.hook_validate_commit_message(log_message, additions, deletions,
+ modifications, message_validated,
+ reason);
+ N(message_validated, F("log message rejected: %s\n") % reason);
+
{
transaction_guard guard(app.db);
packet_db_writer dbw(app);
============================================================
--- lua.cc c8c228b16b396eaf8cbc1b41ca6363593e9abfee
+++ lua.cc 6b9dd32e7d083192b2996adf831d32a013e23fd8
@@ -1,4 +1,5 @@
// -*- mode: C++; c-file-style: "gnu"; indent-tabs-mode: nil -*-
+// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
// copyright (C) 2002, 2003 graydon hoare
// all rights reserved.
// licensed to the public under the terms of the GNU GPL (>= 2)
@@ -1382,6 +1383,50 @@
return ll.ok();
}
+static bool
+push_vector_as_table(Lua & ll, std::vector const & source)
+{
+ typedef std::vector::const_iterator iterator_t;
+ int k = 1;
+
+ ll.push_table();
+
+ for (iterator_t beg = source.begin(), end = source.end(); beg != end; ++beg, ++k)
+ {
+ ll.push_int(k);
+ ll.push_str(*beg);
+ ll.set_table();
+ }
+
+ return ll.ok();
+}
+
+bool
+lua_hooks::hook_validate_commit_message(std::string const & message,
+ std::vector const & added,
+ std::vector const & deleted,
+ std::vector const & modified,
+ bool & validated,
+ std::string & reason)
+{
+ Lua ll(st);
+ ll
+ .func("validate_commit_message")
+ .push_str(message);
+
+ push_vector_as_table(ll, added);
+ push_vector_as_table(ll, deleted);
+ push_vector_as_table(ll, modified);
+
+ return ll
+ .call(4, 2)
+ .extract_str(reason)
+ // XXX When validated, the extra returned string is superfluous.
+ .pop()
+ .extract_bool(validated)
+ .ok();
+}
+
bool
lua_hooks::hook_note_commit(revision_id const & new_id,
revision_data const & rdat,
============================================================
--- lua.hh 71e2943fa623254b4e3e1340e1f8c4b442271a6c
+++ lua.hh 1c16c56eee90a8c7ab87d5e0bca28da928f3c248
@@ -106,6 +106,14 @@
bool hook_get_linesep_conv(file_path const & p,
std::string & db, std::string & ext);
+ // validation hooks
+ bool hook_validate_commit_message(std::string const & message,
+ std::vector const & added,
+ std::vector const & deleted,
+ std::vector const & modified,
+ bool & validated,
+ std::string & reason);
+
// notification hooks
bool hook_note_commit(revision_id const & new_id,
revision_data const & rdat,
============================================================
--- std_hooks.lua a5e3529e680469a911323f45286466780088f35d
+++ std_hooks.lua aee63195ac081781e08738050eb7e169dcef83b3
@@ -705,3 +705,10 @@
io.close(permfile)
return matches
end
+
+function validate_commit_message(message, additions, deletions, modifications)
+ if (message == "") then
+ return false, "empty messages aren't allowed"
+ end
+ return true, ""
+end