# # # patch "cmd.cc" # from [a7d3e349b9b0c4ca20d77df537c999320984d441] # to [cccdf8eb731992378caa5b1b6e571871a6c4f860] # # patch "cmd_automate.cc" # from [906e9fb69e5c187eff0e0c02a058dfb41300434f] # to [500220a163b7270354d416076438587ce598e1b1] # # patch "commands.hh" # from [a8a38db021714abcdbbe8dea95f345eab1c5b557] # to [8b4b67bd3366d9ecab8c17851c6007edecac5c03] # ============================================================ --- cmd.cc a7d3e349b9b0c4ca20d77df537c999320984d441 +++ cmd.cc cccdf8eb731992378caa5b1b6e571871a6c4f860 @@ -82,12 +82,19 @@ CMD_GROUP(user, "user", "", CMD_REF(__ro N_("Commands defined by the user"), ""); +template<> void dump(size_t const & in, std::string & out) +{ + out = boost::lexical_cast(in); +} namespace commands { void remove_command_name_from_args(command_id const & ident, args_vector & args, size_t invisible_length) { + MM(ident); + MM(args); + MM(invisible_length); I(ident.empty() || args.size() >= ident.size() - invisible_length); for (args_vector::size_type i = invisible_length; i < ident.size(); i++) { @@ -102,7 +109,8 @@ namespace commands { command const * subcmd, command_id const & subcmd_full_ident, size_t subcmd_invisible_length, - args_vector const & subcmd_cmdline) + args_vector const & subcmd_cmdline, + vector > const * const separate_params) { I(cmd); options::opts::all_options().instantiate(&app.opts).reset(); @@ -136,10 +144,19 @@ namespace commands { if (subcmd) { app.opts.args.clear(); - (options::opts::globals() | subcmd->opts()) - .instantiate(&app.opts) - /* the first argument here is only ever modified if the second is 'true' */ - .from_command_line(const_cast(subcmd_cmdline), false); + option::concrete_option_set subcmd_optset + = (options::opts::globals() | subcmd->opts()) + .instantiate(&app.opts); + if (!separate_params) + { + /* the first argument here is only ever modified if the second is 'true' */ + subcmd_optset.from_command_line(const_cast(subcmd_cmdline), false); + } + else + { + subcmd_optset.from_key_value_pairs(*separate_params); + app.opts.args = subcmd_cmdline; + } remove_command_name_from_args(subcmd_full_ident, app.opts.args, subcmd_invisible_length); } ============================================================ --- cmd_automate.cc 906e9fb69e5c187eff0e0c02a058dfb41300434f +++ cmd_automate.cc 500220a163b7270354d416076438587ce598e1b1 @@ -236,7 +236,6 @@ CMD_AUTOMATE_NO_STDIO(stdio, "", { automate const * acmd = 0; command_id id; - args_vector args; // FIXME: what follows is largely duplicated // in network/automate_session.cc::do_work() @@ -248,6 +247,7 @@ CMD_AUTOMATE_NO_STDIO(stdio, "", if (!ar.get_command(params, cmdline)) break; + args_vector args; vector::iterator i = cmdline.begin(); for (; i != cmdline.end(); ++i) { @@ -271,10 +271,6 @@ CMD_AUTOMATE_NO_STDIO(stdio, "", id = *matches.begin(); - I(args.size() >= id.size()); - for (command_id::size_type i = 0; i < id.size(); i++) - args.erase(args.begin()); - command const * cmd = CMD_REF(automate)->find_command(id); I(cmd != NULL); @@ -284,19 +280,22 @@ CMD_AUTOMATE_NO_STDIO(stdio, "", E(acmd->can_run_from_stdio(), origin::network, F("sorry, that can't be run remotely or over stdio")); - if (cmd->use_workspace_options()) - { - // Re-read the ws options file, rather than just copying - // the options from the previous apts.opts object, because - // the file may have changed due to user activity. - workspace::check_format(); - workspace::get_options(app.opts); - } - options::options_type opts; - opts = options::opts::globals() | cmd->opts(); - opts.instantiate(&app.opts).from_key_value_pairs(params); + commands::command_id my_id_for_hook = id; + my_id_for_hook.insert(my_id_for_hook.begin(), utf8("automate", origin::internal)); + // group name + my_id_for_hook.insert(my_id_for_hook.begin(), utf8("automation", origin::internal)); + commands::reapply_options(app, + app.reset_info.cmd, + commands::command_id() /* doesn't matter */, + cmd, my_id_for_hook, 2, + args, + ¶ms); + // disable user prompts, f.e. for password decryption + app.opts.non_interactive = true; + + // set a fixed ticker type regardless what the user wants to // see, because anything else would screw the stdio-encoded output ui.set_tick_write_stdio(); @@ -323,7 +322,7 @@ CMD_AUTOMATE_NO_STDIO(stdio, "", // as soon as a command requires a workspace, this is set to true workspace::used = false; - acmd->exec_from_automate(app, id, args, os); + acmd->exec_from_automate(app, id, app.opts.args, os); os.end_cmd(0); // usually, if a command succeeds, any of its workspace-relevant ============================================================ --- commands.hh a8a38db021714abcdbbe8dea95f345eab1c5b557 +++ commands.hh 8b4b67bd3366d9ecab8c17851c6007edecac5c03 @@ -35,7 +35,9 @@ namespace commands { command const * subcmd = 0, command_id const & subcmd_full_ident = command_id(), size_t subcmd_invisible_length = 1, - args_vector const & subcmd_cmdline = args_vector()); + args_vector const & subcmd_cmdline = args_vector(), + std::vector > + const * const separate_params = 0); void process(app_state & app, command_id const & ident, args_vector const & args); options::options_type command_options(command_id const & ident);