# # # add_file "tests/t_commit_validate.at" # content [2d6e25f801aa61c96d7c063bd1c7e7d1224b55c3] # # patch "AUTHORS" # from [be2883d201fdd61b63582334f52312a640e012a1] # to [66d90072b355ef6e2b66f56c0dfa00de1565dc98] # # patch "ChangeLog" # from [bf1a29e94427360f9b7bc7979bdb0cd391271cf7] # to [e9d45791d5a39f5ba1be493c45c2fea09844090c] # # patch "commands.cc" # from [2f64f75b9afb4a86bac84bcc6cacaba86866be2b] # to [78e7bbd22db960aa549baac02fa8e5b67d548d36] # # patch "lua.cc" # from [78722201fdc513bfee248ce6b30b1b1ae593250e] # to [73e300a804cd3040e47d4d017e3d51f398548255] # # patch "lua.hh" # from [0d1c63ed6c7b36665ad92780ed88afa1edff3194] # to [a682ec35ee70ef30fd080616f8f21d8ef2a1a6ea] # # patch "std_hooks.lua" # from [1740ad529749fadac6c115b8373ca26e9f932ad6] # to [259f2956124c69bd0f616943ad64663f67213cd6] # # patch "testsuite.at" # from [9e39ba6a09e3b23919675a2ae8adf1275eac5e08] # to [e5ebd77d485969726da4a4702dcae6fa31c09a2d] # ============================================================ --- tests/t_commit_validate.at 2d6e25f801aa61c96d7c063bd1c7e7d1224b55c3 +++ tests/t_commit_validate.at 2d6e25f801aa61c96d7c063bd1c7e7d1224b55c3 @@ -0,0 +1,31 @@ +# -*- Autoconf -*- +# vim: tw=0 + +AT_SETUP([commit validation lua hook]) + +MONOTONE_SETUP + +AT_DATA(commit_validate.lua, [ +function validate_commit_message(message, info) + if (not string.find(info, "input.txt")) then + return false, "Wrong info message" + end + if (message == "denyme") then + return false, "input.txt" + end + + return true, "" +end +]) + +AT_DATA(input.txt, [version 0 of the file +]) + +AT_CHECK(MONOTONE add input.txt, [], [ignore], [ignore]) + +AT_CHECK(MONOTONE --branch=testbranch --rcfile=commit_validate.lua commit -m "denyme", 1, [ignore], [monotone: beginning commit on branch 'testbranch' +monotone: misuse: log message rejected: input.txt +]) +AT_CHECK(MONOTONE --branch=testbranch --rcfile=commit_validate.lua commit -m "allowme", 0, ignore, ignore) + +AT_CLEANUP ============================================================ --- AUTHORS be2883d201fdd61b63582334f52312a640e012a1 +++ AUTHORS 66d90072b355ef6e2b66f56c0dfa00de1565dc98 @@ -72,6 +72,7 @@ Roland McGrath Daniel Carosone Vinzenz Feenstra + Blake Kaplan Several people have also contributed to the translation of monotone into non-English languages; their work is available in the po/ ============================================================ --- ChangeLog bf1a29e94427360f9b7bc7979bdb0cd391271cf7 +++ ChangeLog e9d45791d5a39f5ba1be493c45c2fea09844090c @@ -1,3 +1,12 @@ +2006-02-06 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-02-05 Benoît Dejean * ui.cc (tick_write_count::write_ticks): Reverted lexical_cast, ============================================================ --- commands.cc 2f64f75b9afb4a86bac84bcc6cacaba86866be2b +++ commands.cc 78e7bbd22db960aa549baac02fa8e5b67d548d36 @@ -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,6 @@ given = false; } - CMD(commit, N_("workspace"), N_("[PATH]..."), N_("commit workspace to database"), OPT_BRANCH_NAME % OPT_MESSAGE % OPT_MSGFILE % OPT_DATE % @@ -2340,6 +2340,16 @@ write_user_log(data(log_message)); } + // If the hook doesn't exist, allow the message to be used. + bool message_validated; + string reason, new_manifest_text; + + dump(rs, new_manifest_text); + + app.lua.hook_validate_commit_message(log_message, new_manifest_text, + 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 78722201fdc513bfee248ce6b30b1b1ae593250e +++ lua.cc 73e300a804cd3040e47d4d017e3d51f398548255 @@ -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,24 @@ return ll.ok(); } +bool +lua_hooks::hook_validate_commit_message(std::string const & message, + std::string const & new_manifest_text, + bool & validated, + std::string & reason) +{ + return Lua(st) + .func("validate_commit_message") + .push_str(message) + .push_str(new_manifest_text) + .call(2, 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 0d1c63ed6c7b36665ad92780ed88afa1edff3194 +++ lua.hh a682ec35ee70ef30fd080616f8f21d8ef2a1a6ea @@ -106,6 +106,12 @@ 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::string const & new_manifest_text, + bool & validated, + std::string & reason); + // notification hooks bool hook_note_commit(revision_id const & new_id, revision_data const & rdat, ============================================================ --- std_hooks.lua 1740ad529749fadac6c115b8373ca26e9f932ad6 +++ std_hooks.lua 259f2956124c69bd0f616943ad64663f67213cd6 @@ -705,3 +705,10 @@ io.close(permfile) return matches end + +function validate_commit_message(message, new_manifest_id) + if (message == "") then + return false, "empty messages aren't allowed" + end + return true, "" +end ============================================================ --- testsuite.at 9e39ba6a09e3b23919675a2ae8adf1275eac5e08 +++ testsuite.at e5ebd77d485969726da4a4702dcae6fa31c09a2d @@ -615,6 +615,7 @@ m4_include(tests/t_checkout_creates_log.at) m4_include(tests/t_commit_log_1.at) m4_include(tests/t_commit_log_2.at) +m4_include(tests/t_commit_validate.at) m4_include(tests/t_dropkey_1.at) m4_include(tests/t_dropkey_2.at) m4_include(tests/t_rename_attr.at)