# # # patch "automate.cc" # from [eafada922c297d508bb1e327a56c40d539d65e81] # to [ea36f8c7509de57e71698d2931089010a24ab554] # # patch "cmd.hh" # from [562e34f7eab6eba5cdc5556886358371049a3204] # to [073acef739548c6ac77a2b5a87d3e6b344d9825c] # # patch "cmd_automate.cc" # from [a24d742ae4e84d50beaa4a13d0bdb2fcf58de131] # to [4a97e715a71d967aaf7b99f1112b87a9864f69bd] # # patch "cmd_diff_log.cc" # from [7bf15437720c86dc06d0312ded49c48c29120531] # to [44b7952434f2b0e44f35b958291a2fa8af79c03f] # # patch "cmd_files.cc" # from [9c5f3cfc27283b7f749093e4ac47bff1b0ff22e2] # to [b563f395a431c1471363c93099b44ede69bcc65b] # # patch "cmd_list.cc" # from [097180da9a25f0ce457ee38808fa21e4dc9c367e] # to [b65a77480398df56c35f64b4a01a386f1f3422d0] # # patch "commands.cc" # from [0c6893af4d16629b742caa05f541bc5c71977895] # to [4cdd6c02ce00454a314bf17f2a35dd7c5e3b570b] # ============================================================ --- automate.cc eafada922c297d508bb1e327a56c40d539d65e81 +++ automate.cc ea36f8c7509de57e71698d2931089010a24ab554 @@ -61,7 +61,10 @@ using std::vector; // newline. Revision ids are printed in alphabetically sorted order. // Error conditions: If the branch does not exist, prints nothing. (There are // no heads.) -AUTOMATE(heads, N_("[BRANCH]"), options::opts::none) +CMD_AUTOMATE(heads, N_("[BRANCH]"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() < 2, F("wrong argument count")); @@ -85,7 +88,10 @@ AUTOMATE(heads, N_("[BRANCH]"), options: // newline. Revision ids are printed in alphabetically sorted order. // Error conditions: If any of the revisions do not exist, prints nothing to // stdout, prints an error message to stderr, and exits with status 1. -AUTOMATE(ancestors, N_("REV1 [REV2 [REV3 [...]]]"), options::opts::none) +CMD_AUTOMATE(ancestors, N_("REV1 [REV2 [REV3 [...]]]"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() > 0, F("wrong argument count")); @@ -132,7 +138,10 @@ AUTOMATE(ancestors, N_("REV1 [REV2 [REV3 // newline. Revision ids are printed in alphabetically sorted order. // Error conditions: If any of the revisions do not exist, prints nothing to // stdout, prints an error message to stderr, and exits with status 1. -AUTOMATE(descendents, N_("REV1 [REV2 [REV3 [...]]]"), options::opts::none) +CMD_AUTOMATE(descendents, N_("REV1 [REV2 [REV3 [...]]]"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() > 0, F("wrong argument count")); @@ -180,7 +189,10 @@ AUTOMATE(descendents, N_("REV1 [REV2 [RE // newline. Revision ids are printed in alphabetically sorted order. // Error conditions: If any of the revisions do not exist, prints nothing to // stdout, prints an error message to stderr, and exits with status 1. -AUTOMATE(erase_ancestors, N_("[REV1 [REV2 [REV3 [...]]]]"), options::opts::none) +CMD_AUTOMATE(erase_ancestors, N_("[REV1 [REV2 [REV3 [...]]]]"), + N_("TODO"), + N_(""), + options::opts::none) { set revs; for (args_vector::const_iterator i = args.begin(); i != args.end(); ++i) @@ -212,7 +224,10 @@ AUTOMATE(erase_ancestors, N_("[REV1 [REV // // Error conditions: If the file name has no attributes, prints only the // format version, if the file is unknown, escalates -AUTOMATE(attributes, N_("FILE"), options::opts::none) +CMD_AUTOMATE(attributes, N_("FILE"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() > 0, F("wrong argument count")); @@ -326,7 +341,10 @@ AUTOMATE(attributes, N_("FILE"), options // newline. Revisions are printed in topologically sorted order. // Error conditions: If any of the revisions do not exist, prints nothing to // stdout, prints an error message to stderr, and exits with status 1. -AUTOMATE(toposort, N_("[REV1 [REV2 [REV3 [...]]]]"), options::opts::none) +CMD_AUTOMATE(toposort, N_("[REV1 [REV2 [REV3 [...]]]]"), + N_("TODO"), + N_(""), + options::opts::none) { set revs; for (args_vector::const_iterator i = args.begin(); i != args.end(); ++i) @@ -358,7 +376,10 @@ AUTOMATE(toposort, N_("[REV1 [REV2 [REV3 // newline. Revisions are printed in topologically sorted order. // Error conditions: If any of the revisions do not exist, prints nothing to // stdout, prints an error message to stderr, and exits with status 1. -AUTOMATE(ancestry_difference, N_("NEW_REV [OLD_REV1 [OLD_REV2 [...]]]"), options::opts::none) +CMD_AUTOMATE(ancestry_difference, N_("NEW_REV [OLD_REV1 [OLD_REV2 [...]]]"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() > 0, F("wrong argument count")); @@ -397,7 +418,10 @@ AUTOMATE(ancestry_difference, N_("NEW_RE // Output format: A list of revision ids, in hexadecimal, each followed by a // newline. Revision ids are printed in alphabetically sorted order. // Error conditions: None. -AUTOMATE(leaves, "", options::opts::none) +CMD_AUTOMATE(leaves, "", + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 0, F("no arguments needed")); @@ -425,7 +449,10 @@ AUTOMATE(leaves, "", options::opts::none // newline. Revision ids are printed in alphabetically sorted order. // Error conditions: If the revision does not exist, prints nothing to stdout, // prints an error message to stderr, and exits with status 1. -AUTOMATE(parents, N_("REV"), options::opts::none) +CMD_AUTOMATE(parents, N_("REV"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 1, F("wrong argument count")); @@ -450,7 +477,10 @@ AUTOMATE(parents, N_("REV"), options::op // newline. Revision ids are printed in alphabetically sorted order. // Error conditions: If the revision does not exist, prints nothing to stdout, // prints an error message to stderr, and exits with status 1. -AUTOMATE(children, N_("REV"), options::opts::none) +CMD_AUTOMATE(children, N_("REV"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 1, F("wrong argument count")); @@ -485,7 +515,10 @@ AUTOMATE(children, N_("REV"), options::o // The output as a whole is alphabetically sorted; additionally, the parents // within each line are alphabetically sorted. // Error conditions: None. -AUTOMATE(graph, "", options::opts::none) +CMD_AUTOMATE(graph, "", + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 0, F("no arguments needed")); @@ -528,7 +561,10 @@ AUTOMATE(graph, "", options::opts::none) // Output format: A list of revision ids, in hexadecimal, each followed by a // newline. Revision ids are printed in alphabetically sorted order. // Error conditions: None. -AUTOMATE(select, N_("SELECTOR"), options::opts::none) +CMD_AUTOMATE(select, N_("SELECTOR"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 1, F("wrong argument count")); @@ -710,7 +746,10 @@ extract_added_file_paths(addition_map co // Error conditions: If no workspace book keeping _MTN directory is found, // prints an error message to stderr, and exits with status 1. -AUTOMATE(inventory, "", options::opts::none) +CMD_AUTOMATE(inventory, "", + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 0, F("no arguments needed")); @@ -910,7 +949,10 @@ AUTOMATE(inventory, "", options::opts::n // the same type will be sorted by the filename they refer to. // Error conditions: If the revision specified is unknown or invalid // prints an error message to stderr and exits with status 1. -AUTOMATE(get_revision, N_("[REVID]"), options::opts::none) +CMD_AUTOMATE(get_revision, N_("[REVID]"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() < 2, F("wrong argument count")); @@ -953,7 +995,10 @@ AUTOMATE(get_revision, N_("[REVID]"), op // on. This is the value stored in _MTN/revision // Error conditions: If no workspace book keeping _MTN directory is found, // prints an error message to stderr, and exits with status 1. -AUTOMATE(get_base_revision_id, "", options::opts::none) +CMD_AUTOMATE(get_base_revision_id, "", + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 0, F("no arguments needed")); @@ -977,7 +1022,10 @@ AUTOMATE(get_base_revision_id, "", optio // files in the workspace. // Error conditions: If no workspace book keeping _MTN directory is found, // prints an error message to stderr, and exits with status 1. -AUTOMATE(get_current_revision_id, "", options::opts::none) +CMD_AUTOMATE(get_current_revision_id, "", + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 0, F("no arguments needed")); @@ -1043,7 +1091,10 @@ AUTOMATE(get_current_revision_id, "", op // // Error conditions: If the revision ID specified is unknown or // invalid prints an error message to stderr and exits with status 1. -AUTOMATE(get_manifest_of, N_("[REVID]"), options::opts::none) +CMD_AUTOMATE(get_manifest_of, N_("[REVID]"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() < 2, F("wrong argument count")); @@ -1086,7 +1137,10 @@ AUTOMATE(get_manifest_of, N_("[REVID]"), // // Error conditions: If the revision id specified is unknown or // invalid prints an error message to stderr and exits with status 1. -AUTOMATE(packet_for_rdata, N_("REVID"), options::opts::none) +CMD_AUTOMATE(packet_for_rdata, N_("REVID"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 1, F("wrong argument count")); @@ -1112,7 +1166,10 @@ AUTOMATE(packet_for_rdata, N_("REVID"), // // Error conditions: If the revision id specified is unknown or // invalid prints an error message to stderr and exits with status 1. -AUTOMATE(packets_for_certs, N_("REVID"), options::opts::none) +CMD_AUTOMATE(packets_for_certs, N_("REVID"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 1, F("wrong argument count")); @@ -1139,7 +1196,10 @@ AUTOMATE(packets_for_certs, N_("REVID"), // // Error conditions: If the file id specified is unknown or invalid // prints an error message to stderr and exits with status 1. -AUTOMATE(packet_for_fdata, N_("FILEID"), options::opts::none) +CMD_AUTOMATE(packet_for_fdata, N_("FILEID"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 1, F("wrong argument count")); @@ -1166,7 +1226,10 @@ AUTOMATE(packet_for_fdata, N_("FILEID"), // // Error conditions: If any of the file ids specified are unknown or // invalid prints an error message to stderr and exits with status 1. -AUTOMATE(packet_for_fdelta, N_("OLD_FILE NEW_FILE"), options::opts::none) +CMD_AUTOMATE(packet_for_fdelta, N_("OLD_FILE NEW_FILE"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 2, F("wrong argument count")); @@ -1200,7 +1263,10 @@ AUTOMATE(packet_for_fdelta, N_("OLD_FILE // Error conditions: If any of the revisions do not exist, prints // nothing to stdout, prints an error message to stderr, and exits // with status 1. -AUTOMATE(common_ancestors, N_("REV1 [REV2 [REV3 [...]]]"), options::opts::none) +CMD_AUTOMATE(common_ancestors, N_("REV1 [REV2 [REV3 [...]]]"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() > 0, F("wrong argument count")); @@ -1263,7 +1329,10 @@ AUTOMATE(common_ancestors, N_("REV1 [REV // in alphabetically sorted order. // Error conditions: // None. -AUTOMATE(branches, "", options::opts::none) +CMD_AUTOMATE(branches, "", + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 0, F("no arguments needed")); @@ -1312,7 +1381,10 @@ AUTOMATE(branches, "", options::opts::no // Stanzas are printed in arbitrary order. // Error conditions: // A run-time exception is thrown for illegal patterns. -AUTOMATE(tags, N_("[BRANCH_PATTERN]"), options::opts::none) +CMD_AUTOMATE(tags, N_("[BRANCH_PATTERN]"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() < 2, F("wrong argument count")); @@ -1402,7 +1474,10 @@ namespace // // Error conditions: If the passphrase is empty or the key already exists, // prints an error message to stderr and exits with status 1. -AUTOMATE(genkey, N_("KEYID PASSPHRASE"), options::opts::none) +CMD_AUTOMATE(genkey, N_("KEYID PASSPHRASE"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 2, F("wrong argument count")); @@ -1461,7 +1536,10 @@ AUTOMATE(genkey, N_("KEYID PASSPHRASE"), // Sample output (for 'mtn automate get_option branch: // net.venge.monotone // -AUTOMATE(get_option, N_("OPTION"), options::opts::none) +CMD_AUTOMATE(get_option, N_("OPTION"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 1, F("wrong argument count")); @@ -1510,7 +1588,10 @@ AUTOMATE(get_option, N_("OPTION"), optio // Sample output (for 'mtn automate get_content_changed 3bccff99d08421df72519b61a4dded16d1139c33 ChangeLog): // content_mark [276264b0b3f1e70fc1835a700e6e61bdbe4c3f2f] // -AUTOMATE(get_content_changed, N_("REV FILE"), options::opts::none) +CMD_AUTOMATE(get_content_changed, N_("REV FILE"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 2, F("wrong argument count")); @@ -1569,7 +1650,10 @@ AUTOMATE(get_content_changed, N_("REV FI // // Sample output (for automate get_corresponding_path 91f25c8ee830b11b52dd356c925161848d4274d0 foo2 dae0d8e3f944c82a9688bcd6af99f5b837b41968; see automate_get_corresponding_path test) // file "foo" -AUTOMATE(get_corresponding_path, N_("REV1 FILE REV2"), options::opts::none) +CMD_AUTOMATE(get_corresponding_path, N_("REV1 FILE REV2"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 3, F("wrong argument count")); @@ -1618,7 +1702,10 @@ AUTOMATE(get_corresponding_path, N_("REV // The ID of the new file (40 digit hex string) // Error conditions: // a runtime exception is thrown if base revision is not available -AUTOMATE(put_file, N_("[FILEID] CONTENTS"), options::opts::none) +CMD_AUTOMATE(put_file, N_("[FILEID] CONTENTS"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 1 || args.size() == 2, F("wrong argument count")); @@ -1668,7 +1755,10 @@ AUTOMATE(put_file, N_("[FILEID] CONTENTS // The ID of the new revision // Error conditions: // none -AUTOMATE(put_revision, N_("REVISION-DATA"), options::opts::none) +CMD_AUTOMATE(put_revision, N_("REVISION-DATA"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 1, F("wrong argument count")); @@ -1722,7 +1812,10 @@ AUTOMATE(put_revision, N_("REVISION-DATA // nothing // Error conditions: // none -AUTOMATE(cert, N_("REVISION-ID NAME VALUE"), options::opts::none) +CMD_AUTOMATE(cert, N_("REVISION-ID NAME VALUE"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 3, F("wrong argument count")); @@ -1752,7 +1845,10 @@ AUTOMATE(cert, N_("REVISION-ID NAME VALU // nothing // Error conditions: // none -AUTOMATE(db_set, N_("DOMAIN NAME VALUE"), options::opts::none) +CMD_AUTOMATE(db_set, N_("DOMAIN NAME VALUE"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 3, F("wrong argument count")); @@ -1775,7 +1871,10 @@ AUTOMATE(db_set, N_("DOMAIN NAME VALUE") // variable value // Error conditions: // a runtime exception is thrown if the variable is not set -AUTOMATE(db_get, N_("DOMAIN NAME"), options::opts::none) +CMD_AUTOMATE(db_get, N_("DOMAIN NAME"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 2, F("wrong argument count")); ============================================================ --- cmd.hh 562e34f7eab6eba5cdc5556886358371049a3204 +++ cmd.hh 073acef739548c6ac77a2b5a87d3e6b344d9825c @@ -87,6 +87,24 @@ namespace commands complete_command(command_id const & id, command_id completed = command_id()); }; + + class automate : public command + { + public: + automate(std::string const & name, + std::string const & params, + std::string const & abstract, + std::string const & desc, + options::options_type const & opts); + + virtual void exec(app_state & app, + command_id const & execid, + args_vector const & args); + virtual void run(args_vector args, + command_id const & execid, + app_state & app, + std::ostream & output) const = 0; + }; }; inline std::vector @@ -168,30 +186,6 @@ void commands::cmd_ ## C::exec(app_state #define CMD_HIDDEN(C, aliases, parent, params, abstract, desc, opts) \ _CMD2(C, aliases, parent, true, params, abstract, desc, opts) -// Use this for commands that want to define a params() function -// instead of having a static description. (Good for "automate" -// and possibly "list".) -#define CMD_WITH_SUBCMDS(C, aliases, parent, abstract, desc, opts) \ -namespace commands { \ - class cmd_ ## C : public command \ - { \ - public: \ - cmd_ ## C() : command(#C, aliases, parent, false, "", abstract, \ - desc, true, \ - options::options_type() | opts) \ - {} \ - virtual void exec(app_state & app, \ - command_id const & execid, \ - args_vector const & args); \ - std::string params(); \ - options::options_type get_options(args_vector const & args); \ - }; \ - cmd_ ## C C ## _cmd; \ -} \ -void commands::cmd_ ## C::exec(app_state & app, \ - command_id const & execid, \ - args_vector const & args) - // XXX Should the 'opts' parameter go away? #define CMD_GROUP(C, aliases, parent, abstract, desc, opts) \ namespace commands { \ @@ -248,6 +242,25 @@ void commands::cmd_ ## C::exec(app_state command_id const & execid, \ args_vector const & args) \ +#define CMD_AUTOMATE(C, params, abstract, desc, opts) \ +namespace commands { \ + struct automate_ ## C : public automate \ + { \ + automate_ ## C() : automate(#C, params, abstract, desc, \ + options::options_type() | opts) \ + {} \ + void run(args_vector args, \ + command_id const & execid, \ + app_state & app, \ + std::ostream & output) const; \ + }; \ + automate_ ## C C ## _automate; \ +} \ +void commands::automate_ ## C :: run(args_vector args, \ + command_id const & execid, \ + app_state & app, \ + std::ostream & output) const + CMD_FWD_DECL(__root__); CMD_FWD_DECL(automation); @@ -263,43 +276,6 @@ CMD_FWD_DECL(workspace); CMD_FWD_DECL(variables); CMD_FWD_DECL(workspace); -namespace automation { - struct automate - { - std::string name; - std::string params; - options::options_type opts; - automate(std::string const & n, std::string const & p, - options::options_type const & o); - virtual void run(args_vector args, - std::string const & help_name, - app_state & app, - std::ostream & output) const = 0; - virtual ~automate(); - }; -} - -#define AUTOMATE(NAME, PARAMS, OPTIONS) \ -namespace automation { \ - struct auto_ ## NAME : public automate \ - { \ - auto_ ## NAME () \ - : automate(#NAME, PARAMS, options::options_type() | OPTIONS) \ - {} \ - void run(args_vector args, std::string const & help_name, \ - app_state & app, std::ostream & output) const; \ - virtual ~auto_ ## NAME() {} \ - }; \ - static auto_ ## NAME NAME ## _auto; \ -} \ -void automation::auto_ ## NAME :: run(args_vector args, \ - std::string const & help_name,\ - app_state & app, \ - std::ostream & output) const - - - - // Local Variables: // mode: C++ // fill-column: 76 ============================================================ --- cmd_automate.cc a24d742ae4e84d50beaa4a13d0bdb2fcf58de131 +++ cmd_automate.cc 4a97e715a71d967aaf7b99f1112b87a9864f69bd @@ -18,50 +18,36 @@ using std::pair; using std::map; using std::ostream; using std::pair; +using std::set; using std::string; using std::vector; -namespace automation { - // When this is split into multiple files, there will not be any - // guarantees about initialization order. So, use something we can - // initialize ourselves. - static map * automations; - automate::automate(string const &n, string const &p, - options::options_type const & o) - : name(n), params(p), opts(o) +CMD_GROUP(automate, "", CMD_REF(__root__), + N_("Interface for scripted execution"), + N_(""), + options::opts::none); + +namespace commands { + automate::automate(string const & name, + string const & params, + string const & abstract, + string const & desc, + options::options_type const & opts) : + command(name, "", CMD_REF(automate), false, params, abstract, + desc, false, opts) { - static bool first(true); - if (first) - { - first = false; - automations = new map; - } - automations->insert(make_pair(name, this)); } - automate::~automate() {} -} -automation::automate & -find_automation(arg_type const & name, string const & root_cmd_name) -{ - map::const_iterator - i = automation::automations->find(name()); - if (i == automation::automations->end()) - throw usage(commands::command_id()); // XXX root_cmd_name - else - return *(i->second); + void + automate::exec(app_state & app, + command_id const & execid, + args_vector const & args) + { + make_io_binary(); + run(args, execid, app, std::cout); + } } -void -automate_command(arg_type cmd, args_vector args, - commands::command_id const & root_cmd_name, - app_state & app, - ostream & output) -{ - string const & leaf = root_cmd_name[root_cmd_name.size() - 1](); - find_automation(cmd, leaf).run(args, leaf, app, output); -} - static string const interface_version = "4.2"; // Name: interface_version @@ -73,7 +59,10 @@ static string const interface_version = // Output format: ".\n". Always matches // "[0-9]+\.[0-9]+\n". // Error conditions: None. -AUTOMATE(interface_version, "", options::opts::none) +CMD_AUTOMATE(interface_version, "", + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 0, F("no arguments needed")); @@ -327,7 +316,10 @@ struct automate_ostream : public std::os }; -AUTOMATE(stdio, "", options::opts::automate_stdio_size) +CMD_AUTOMATE(stdio, "", + N_("TODO"), + N_(""), + options::opts::automate_stdio_size) { N(args.size() == 0, F("no arguments needed")); @@ -342,13 +334,11 @@ AUTOMATE(stdio, "", options::opts::autom vector cmdline; while(ar.get_command(params, cmdline))//while(!EOF) { - arg_type cmd; args_vector args; vector::iterator i = cmdline.begin(); E(i != cmdline.end(), F("Bad input to automate stdio: command name is missing")); - cmd = arg_type(*i); - for (++i; i != cmdline.end(); ++i) + for (; i != cmdline.end(); ++i) { args.push_back(arg_type(*i)); } @@ -358,11 +348,35 @@ AUTOMATE(stdio, "", options::opts::autom opts = options::opts::all_options() - options::opts::globals(); opts.instantiate(&app.opts).reset(); - opts = options::opts::globals(); - opts = opts | find_automation(cmd, help_name).opts; - opts.instantiate(&app.opts).from_key_value_pairs(params); - commands::command_id help_name; // XXX - automate_command(cmd, args, help_name, app, os); + command_id id; + for (args_vector::const_iterator iter = args.begin(); + iter != args.end(); iter++) + id.push_back(utf8((*iter)())); + + if (!id.empty()) + { + I(!args.empty()); + + set< command_id > matches = + CMD_REF(automate)->complete_command(id); + N(matches.size() == 1, + F("invalid automation specified")); + id = *matches.begin(); + id.erase(id.begin()); // Remove 'automate' from the beginning. + + for (command_id::size_type i = 0; i < id.size(); i++) + args.erase(args.begin()); + + command * cmd = CMD_REF(automate)->find_command(id); + I(cmd != NULL); + automate * acmd = reinterpret_cast< automate * >(cmd); + + opts = options::opts::globals() | acmd->opts(); + opts.instantiate(&app.opts).from_key_value_pairs(params); + acmd->run(args, id, app, os); + } + else + opts.instantiate(&app.opts).from_key_value_pairs(params); } catch(informative_failure & f) { @@ -375,51 +389,6 @@ AUTOMATE(stdio, "", options::opts::autom } } - -CMD_WITH_SUBCMDS(automate, "", CMD_REF(automation), - N_("Interface for scripted execution"), - N_("This set of commands provides a stable interface to run " - "monotone from other, external tools and interact with it " - "by means of a text protocol over standard file " - "descriptors."), - options::opts::none) -{ - if (args.size() == 0) - throw usage(execid); - - args_vector::const_iterator i = args.begin(); - arg_type cmd = *i; - ++i; - args_vector cmd_args(i, args.end()); - - make_io_binary(); - - automate_command(cmd, cmd_args, execid, app, std::cout); -} - -std::string commands::cmd_automate::params() -{ - std::string out; - map::const_iterator i; - for (i = automation::automations->begin(); - i != automation::automations->end(); ++i) - { - out += i->second->name + " " + i->second->params; - if (out[out.size()-1] != '\n') - out += "\n"; - } - return out; -} - -options::options_type -commands::cmd_automate::get_options(args_vector const & args) -{ - if (args.size() < 2) - return options::options_type(); - return find_automation(idx(args,1), idx(args,0)()).opts; -} - - // Local Variables: // mode: C++ // fill-column: 76 ============================================================ --- cmd_diff_log.cc 7bf15437720c86dc06d0312ded49c48c29120531 +++ cmd_diff_log.cc 44b7952434f2b0e44f35b958291a2fa8af79c03f @@ -526,8 +526,11 @@ CMD(diff, "", CMD_REF(informative), N_(" // doubles the output of automate get_revision). If no content changes happened, // the output is empty. All file operations beside mtn add are omitted, // as they don't change the content of the file. -AUTOMATE(content_diff, N_("[FILE [...]]"), - options::opts::revision | options::opts::depth | options::opts::exclude) +CMD_AUTOMATE(content_diff, N_("[FILE [...]]"), + N_("TODO"), + N_(""), + options::opts::revision | options::opts::depth | + options::opts::exclude) { cset included; std::string dummy_header; ============================================================ --- cmd_files.cc 9c5f3cfc27283b7f749093e4ac47bff1b0ff22e2 +++ cmd_files.cc b563f395a431c1471363c93099b44ede69bcc65b @@ -224,7 +224,10 @@ CMD(identify, "", CMD_REF(debug), N_("[P // // Error conditions: If the file path doesn't point to a valid file prints // an error message to stderr and exits with status 1. -AUTOMATE(identify, N_("PATH"), options::opts::none) +CMD_AUTOMATE(identify, N_("PATH"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 1, F("wrong argument count")); @@ -319,7 +322,10 @@ CMD(cat, "", CMD_REF(informative), // // Error conditions: If the file id specified is unknown or invalid prints // an error message to stderr and exits with status 1. -AUTOMATE(get_file, N_("FILEID"), options::opts::none) +CMD_AUTOMATE(get_file, N_("FILEID"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 1, F("wrong argument count")); @@ -342,7 +348,10 @@ AUTOMATE(get_file, N_("FILEID"), options // // Error conditions: If the file id specified is unknown or invalid prints // an error message to stderr and exits with status 1. -AUTOMATE(get_file_of, N_("FILENAME"), options::opts::revision) +CMD_AUTOMATE(get_file_of, N_("FILENAME"), + N_("TODO"), + N_(""), + options::opts::revision) { N(args.size() == 1, F("wrong argument count")); ============================================================ --- cmd_list.cc 097180da9a25f0ce457ee38808fa21e4dc9c367e +++ cmd_list.cc b65a77480398df56c35f64b4a01a386f1f3422d0 @@ -558,7 +558,10 @@ namespace // private_location "keystore" // // Error conditions: None. -AUTOMATE(keys, "", options::opts::none) +CMD_AUTOMATE(keys, "", + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 0, F("no arguments needed")); @@ -650,7 +653,10 @@ AUTOMATE(keys, "", options::opts::none) // key, a warning message is printed to stderr. If the revision // specified is unknown or invalid prints an error message to stderr // and exits with status 1. -AUTOMATE(certs, N_("REV"), options::opts::none) +CMD_AUTOMATE(certs, N_("REV"), + N_("TODO"), + N_(""), + options::opts::none) { N(args.size() == 1, F("wrong argument count")); ============================================================ --- commands.cc 0c6893af4d16629b742caa05f541bc5c71977895 +++ commands.cc 4cdd6c02ce00454a314bf17f2a35dd7c5e3b570b @@ -418,6 +418,9 @@ namespace std }; }; +// XXX +CMD_FWD_DECL(automate); + namespace commands { command_id @@ -437,6 +440,10 @@ namespace commands for (command::children_set::const_iterator iter = cs.begin(); iter != cs.end(); iter++) { + // XXX Ugly hack to avoid completion collisions... + if (*iter == CMD_REF(automate)) + continue; + set< command_id > m2 = (*iter)->complete_command(id); matches.insert(m2.begin(), m2.end()); }