# # # add_file "option_reset_info.hh" # content [4a2fb29c93c1332bcfac55a34e79158b35f6ab02] # # patch "Makefile.am" # from [2a42de1455a8d6a5b635bebab2f0965da83a95b4] # to [c22791893a2e339375c609fe99533f01904f1234] # # patch "app_state.hh" # from [a2fa81c489cb7299b2a24b3401ec4e0c35875353] # to [2cce720315529c3baa30faa03db94fbdb88285f6] # # patch "cmd.cc" # from [65a03fdde15e23c0918118c2330553fdf8e4935d] # to [5c36b7cff092295b30e91930ffb401fc6a4510a1] # # patch "cmd_ws_commit.cc" # from [c7d6e3540bce1c1d5896a198376a4553c4df8654] # to [950ec8b23cc87441c3de37a0f8f743e992542f6c] # # patch "commands.hh" # from [17323d9bc503702bd9a24c927f4200a99a6625ef] # to [cd142f8a073ac9e2af690f05d18fb765274cf413] # # patch "key_store.cc" # from [6baa5ed8d6427745a64effcfd20e1c7f25bd1d7d] # to [e8b7b7329a0833c2b6b649ab1ca7dd538563068e] # # patch "monotone.cc" # from [b63cf8becab066c6d890c8edf63e90ed73115106] # to [18c066704f5ac41ee05a1cdd4373d1f8ce2cbd94] # # patch "work.cc" # from [49ef124c843675a8a4b13ffcbd0441887414af3f] # to [e3ffe9910135852f5108ec14e22376b85238d41a] # ============================================================ --- option_reset_info.hh 4a2fb29c93c1332bcfac55a34e79158b35f6ab02 +++ option_reset_info.hh 4a2fb29c93c1332bcfac55a34e79158b35f6ab02 @@ -0,0 +1,34 @@ +// 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 __OPTION_RESET_INFO_HH__ +#define __OPTION_RESET_INFO_HH__ + +#include "option.hh" + +typedef std::vector< utf8 > command_id; + +struct option_reset_info +{ + args_vector default_args; + args_vector cmdline_args; + command_id cmd; +}; + +#endif // __OPTION_RESET_INFO_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: ============================================================ --- Makefile.am 2a42de1455a8d6a5b635bebab2f0965da83a95b4 +++ Makefile.am c22791893a2e339375c609fe99533f01904f1234 @@ -115,6 +115,7 @@ MOST_SOURCES = \ netio.hh gettext.h \ package_revision.cc package_full_revision.cc \ option.cc option.hh options.cc options.hh options_list.hh \ + option_reset_info.hh \ specialized_lexical_cast.cc lexical_cast.hh \ parallel_iter.hh safe_map.hh pch.hh current_exception.hh ============================================================ --- app_state.hh a2fa81c489cb7299b2a24b3401ec4e0c35875353 +++ app_state.hh 2cce720315529c3baa30faa03db94fbdb88285f6 @@ -13,6 +13,7 @@ #include #include "options.hh" +#include "option_reset_info.hh" #include "lua_hooks.hh" // This class holds any state that needs to be persistent across multiple @@ -26,6 +27,7 @@ public: ~app_state(); options opts; + option_reset_info reset_info; lua_hooks lua; bool mtn_automate_allowed; }; ============================================================ --- cmd.cc 65a03fdde15e23c0918118c2330553fdf8e4935d +++ cmd.cc 5c36b7cff092295b30e91930ffb401fc6a4510a1 @@ -84,6 +84,17 @@ namespace commands { namespace commands { + void remove_command_name_from_args(command_id const & ident, + args_vector & args) + { + I(ident.empty() || args.size() >= ident.size() - 1); + for (args_vector::size_type i = 1; i < ident.size(); i++) + { + I(ident[i]().find(args[0]()) == 0); + args.erase(args.begin()); + } + } + // monotone.cc calls this function after option processing. void process(app_state & app, command_id const & ident, args_vector const & args) @@ -98,15 +109,30 @@ namespace commands { origin::user, F("command '%s' is invalid; it is a group") % join_words(ident)); - E(!(!cmd->is_leaf() && args.empty()), origin::user, - F("no subcommand specified for '%s'") % visibleid); + if (!cmd->is_leaf()) + { + // args used in the command name have not been stripped yet + remove_command_name_from_args(app.reset_info.cmd, app.opts.args); - E(!(!cmd->is_leaf() && !args.empty()), origin::user, - F("could not match '%s' to a subcommand of '%s'") % - join_words(args) % visibleid); + E(!args.empty(), origin::user, + F("no subcommand specified for '%s'") % visibleid); + E(false, origin::user, + F("could not match '%s' to a subcommand of '%s'") % + join_words(args) % visibleid); + } + L(FL("executing command '%s'") % visibleid); + options::opts::all_options().instantiate(&app.opts).reset(); + + option::concrete_option_set optset + = (options::opts::globals() + | commands::command_options(app.reset_info.cmd)) + .instantiate(&app.opts); + + optset.from_command_line(app.reset_info.default_args, false); + // at this point we process the data from _MTN/options if // the command needs it. if (cmd->use_workspace_options()) @@ -115,6 +141,9 @@ namespace commands { workspace::get_options(app.opts); } + optset.from_command_line(app.reset_info.cmdline_args, false); + remove_command_name_from_args(app.reset_info.cmd, app.opts.args); + cmd->exec(app, ident, args); } ============================================================ --- cmd_ws_commit.cc c7d6e3540bce1c1d5896a198376a4553c4df8654 +++ cmd_ws_commit.cc 950ec8b23cc87441c3de37a0f8f743e992542f6c @@ -694,20 +694,11 @@ CMD(mkdir, "mkdir", "", CMD_REF(workspac work.perform_additions(db, paths, false, !app.opts.no_ignore); } -CMD(add, "add", "", CMD_REF(workspace), N_("[PATH]..."), - N_("Adds files to the workspace"), - "", - options::opts::unknown | options::opts::no_ignore | - options::opts::recursive) +void perform_add(app_state & app, + database & db, + workspace & work, + vector roots) { - if (!app.opts.unknown && (args.size() < 1)) - throw usage(execid); - - database db(app); - workspace work(app); - - vector roots = args_to_paths(args); - set paths; bool add_recursive = app.opts.recursive; if (app.opts.unknown) @@ -731,24 +722,35 @@ CMD(add, "add", "", CMD_REF(workspace), work.perform_additions(db, paths, add_recursive, !app.opts.no_ignore); } -CMD(drop, "drop", "rm", CMD_REF(workspace), N_("[PATH]..."), - N_("Drops files from the workspace"), +CMD(add, "add", "", CMD_REF(workspace), N_("[PATH]..."), + N_("Adds files to the workspace"), "", - options::opts::bookkeep_only | options::opts::missing | options::opts::recursive) + options::opts::unknown | options::opts::no_ignore | + options::opts::recursive) { - if (!app.opts.missing && (args.size() < 1)) + if (!app.opts.unknown && (args.size() < 1)) throw usage(execid); database db(app); workspace work(app); + vector roots = args_to_paths(args); + + perform_add(app, db, work, roots); +} + +void perform_drop(app_state & app, + database & db, + workspace & work, + vector roots) +{ set paths; if (app.opts.missing) { temp_node_id_source nis; roster_t current_roster_shape; work.get_current_roster_shape(db, nis, current_roster_shape); - node_restriction mask(args_to_paths(args), + node_restriction mask(roots, args_to_paths(app.opts.exclude_patterns), app.opts.depth, current_roster_shape, ignored_file(work)); @@ -756,15 +758,27 @@ CMD(drop, "drop", "rm", CMD_REF(workspac } else { - vector roots = args_to_paths(args); paths = set(roots.begin(), roots.end()); } work.perform_deletions(db, paths, app.opts.recursive, app.opts.bookkeep_only); } +CMD(drop, "drop", "rm", CMD_REF(workspace), N_("[PATH]..."), + N_("Drops files from the workspace"), + "", + options::opts::bookkeep_only | options::opts::missing | options::opts::recursive) +{ + if (!app.opts.missing && (args.size() < 1)) + throw usage(execid); + database db(app); + workspace work(app); + perform_drop(app, db, work, args_to_paths(args)); +} + + CMD(rename, "rename", "mv", CMD_REF(workspace), N_("SRC DEST\n" "SRC1 [SRC2 [...]] DEST_DIR"), @@ -1400,18 +1414,14 @@ CMD_AUTOMATE(drop_attribute, N_("PATH [K drop_attr(app, args); } - -CMD(commit, "commit", "ci", CMD_REF(workspace), N_("[PATH]..."), - N_("Commits workspace changes to the database"), - "", - options::opts::branch | options::opts::message | options::opts::msgfile | - options::opts::date | options::opts::author | options::opts::depth | - options::opts::exclude) +void perform_commit(app_state & app, + database & db, + workspace & work, + project_t & project, + command_id const & execid, + vector const & paths) { - database db(app); key_store keys(app); - workspace work(app); - project_t project(db); utf8 log_message(""); bool log_message_given; @@ -1433,7 +1443,7 @@ CMD(commit, "commit", "ci", CMD_REF(work work.get_parent_rosters(db, old_rosters); work.get_current_roster_shape(db, nis, new_roster); - node_restriction mask(args_to_paths(args), + node_restriction mask(paths, args_to_paths(app.opts.exclude_patterns), app.opts.depth, old_rosters, new_roster, ignored_file(work)); @@ -1715,6 +1725,19 @@ CMD(commit, "commit", "ci", CMD_REF(work } } +CMD(commit, "commit", "ci", CMD_REF(workspace), N_("[PATH]..."), + N_("Commits workspace changes to the database"), + "", + options::opts::branch | options::opts::message | options::opts::msgfile | + options::opts::date | options::opts::author | options::opts::depth | + options::opts::exclude) +{ + database db(app); + workspace work(app); + project_t project(db); + perform_commit(app, db, work, project, execid, args_to_paths(args)); +} + CMD_NO_WORKSPACE(setup, "setup", "", CMD_REF(tree), N_("[DIRECTORY]"), N_("Sets up a new workspace directory"), N_("If no directory is specified, uses the current directory."), @@ -1832,14 +1855,13 @@ CMD_NO_WORKSPACE(import, "import", "", C work.put_work_rev(rev); // prepare stuff for 'add' and so on. - args_vector empty_args; options save_opts; // add --unknown save_opts.exclude_patterns = app.opts.exclude_patterns; app.opts.exclude_patterns = args_vector(); app.opts.unknown = true; app.opts.recursive = true; - process(app, make_command_id("workspace add"), empty_args); + perform_add(app, db, work, vector()); app.opts.recursive = false; app.opts.unknown = false; app.opts.exclude_patterns = save_opts.exclude_patterns; @@ -1847,13 +1869,15 @@ CMD_NO_WORKSPACE(import, "import", "", C // drop --missing save_opts.no_ignore = app.opts.no_ignore; app.opts.missing = true; - process(app, make_command_id("workspace drop"), empty_args); + perform_drop(app, db, work, vector()); app.opts.missing = false; app.opts.no_ignore = save_opts.no_ignore; // commit if (!app.opts.dryrun) - process(app, make_command_id("workspace commit"), empty_args); + perform_commit(app, db, work, project, + make_command_id("workspace commit"), + vector()); } catch (...) { ============================================================ --- commands.hh 17323d9bc503702bd9a24c927f4200a99a6625ef +++ commands.hh cd142f8a073ac9e2af690f05d18fb765274cf413 @@ -25,6 +25,8 @@ namespace commands { command_id make_command_id(std::string const & path); void explain_usage(command_id const & cmd, bool show_hidden, std::ostream & out); command_id complete_command(args_vector const & args); + void remove_command_name_from_args(command_id const & ident, + args_vector & args); void process(app_state & app, command_id const & ident, args_vector const & args); options::options_type command_options(command_id const & ident); ============================================================ --- key_store.cc 6baa5ed8d6427745a64effcfd20e1c7f25bd1d7d +++ key_store.cc e8b7b7329a0833c2b6b649ab1ca7dd538563068e @@ -83,6 +83,7 @@ struct key_store_state have_read(false), lua(app.lua) { E(app.opts.key_dir_given + || app.opts.key_dir != system_path(get_default_keydir(), origin::user) || app.opts.conf_dir_given || !app.opts.no_default_confdir, origin::user, ============================================================ --- monotone.cc b63cf8becab066c6d890c8edf63e90ed73115106 +++ monotone.cc 18c066704f5ac41ee05a1cdd4373d1f8ce2cbd94 @@ -182,11 +182,10 @@ cpp_main(int argc, char ** argv) { // read global options first // command specific options will be read below - args_vector opt_args(args); + app.reset_info.cmdline_args = args; - option::concrete_option_set optset - = options::opts::all_options().instantiate(&app.opts); - optset.from_command_line(opt_args); + options::opts::all_options().instantiate(&app.opts) + .from_command_line(app.reset_info.cmdline_args); if (app.opts.version_given) { @@ -215,39 +214,17 @@ cpp_main(int argc, char ** argv) // this needs to be after the hooks are loaded, because new // command names may have been added with the alias_command() // lua extension function - commands::command_id cmd; if (!app.opts.args.empty()) { - cmd = commands::complete_command(app.opts.args); - I(!cmd.empty()); + app.reset_info.cmd = commands::complete_command(app.opts.args); + I(!app.reset_info.cmd.empty()); } - // reset the options, and apply defaults from the lua hooks - optset.reset(); - { - // check if the user specified default arguments for this command - args_vector default_args; - if (!cmd.empty() - && app.lua.hook_get_default_command_options(cmd, default_args)) - { - optset.from_command_line(default_args, false); - } - } + // check if the user specified default arguments for this command + if (!app.reset_info.cmd.empty()) + app.lua.hook_get_default_command_options(app.reset_info.cmd, + app.reset_info.default_args); - // re-parse the command-line options now that we know - // what the command is - optset = (options::opts::globals() | commands::command_options(cmd)) - .instantiate(&app.opts); - optset.from_command_line(opt_args, false); - // trim the command itself from the positionals - I(cmd.empty() || app.opts.args.size() >= cmd.size() - 1); - for (args_vector::size_type i = 1; i < cmd.size(); i++) - { - I(cmd[i]().find(app.opts.args[0]()) == 0); - app.opts.args.erase(app.opts.args.begin()); - } - - if (workspace::found) { bookkeeping_path dump_path; @@ -267,18 +244,18 @@ cpp_main(int argc, char ** argv) // stop here if they asked for help if (app.opts.help) - throw usage(cmd); + throw usage(app.reset_info.cmd); // main options processed, now invoke the // sub-command w/ remaining args - if (cmd.empty()) + if (app.reset_info.cmd.empty()) throw usage(commands::command_id()); // as soon as a command requires a workspace, this is set to true workspace::used = false; - commands::process(app, cmd, app.opts.args); + commands::process(app, app.reset_info.cmd, app.opts.args); workspace::maybe_set_options(app.opts, app.lua); ============================================================ --- work.cc 49ef124c843675a8a4b13ffcbd0441887414af3f +++ work.cc e3ffe9910135852f5108ec14e22376b85238d41a @@ -584,7 +584,7 @@ workspace::get_options(options & opts) if (!opts.key_dir_given && !opts.conf_dir_given && cur_opts.key_dir_given) { // if empty/missing, we want to keep the default opts.key_dir = cur_opts.key_dir; - opts.key_dir_given = true; + //opts.key_dir_given = true; } if (opts.branch().empty() && cur_opts.branch_given)