# # # patch "automate.cc" # from [4b4356adc040a901c42bcb8f0e2c6421e3c7272d] # to [2e526be3d7d5e6f5ff820704444e7151dc0ee10a] # # patch "cmd.hh" # from [8c23440201398c17660da8dd43dcc93052be1496] # to [8f5e1e444560beb1ada3df3442c312af2a88938d] # # patch "cmd_automate.cc" # from [70adf70cff51acf0add835845ce5f98f367d7fad] # to [819bd0e40ed4c53d4963feffb631d8255e535599] # # patch "cmd_diff_log.cc" # from [b7b33c8f4ec36c21d8be3117a113138d703c30ee] # to [c036a48598bb628d28e9a5cb15a6ae13b13c4786] # # patch "cmd_files.cc" # from [1d35ebb8c6fafe6f4c263533d1724bf0d53fa216] # to [7db4cf9b2f5be53b92f60ee75f31fe550cf23c46] # # patch "cmd_list.cc" # from [b32f6e0c1875dc0832ed3fdb9bf4c10c40d58523] # to [5d77b7cc9409c98ac2a68152eef6d436cc42db74] # # patch "cmd_ws_commit.cc" # from [873d518fd5f0d334e3f55fbfdb625ac0b974e130] # to [c6a531365009a13693131695a94734af29688ef6] # ============================================================ --- automate.cc 4b4356adc040a901c42bcb8f0e2c6421e3c7272d +++ automate.cc 2e526be3d7d5e6f5ff820704444e7151dc0ee10a @@ -61,7 +61,7 @@ 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.) -CMD_AUTOMATE_WITH_DATABASE(heads, N_("[BRANCH]"), +CMD_AUTOMATE(heads, N_("[BRANCH]"), N_("Prints the heads of the given branch"), N_(""), options::opts::none) @@ -69,6 +69,8 @@ CMD_AUTOMATE_WITH_DATABASE(heads, N_("[B N(args.size() < 2, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + if (args.size() ==1 ) { // branchname was explicitly given, use that db.set_opt_branchname(branch_name(idx(args, 0)())); @@ -88,7 +90,7 @@ CMD_AUTOMATE_WITH_DATABASE(heads, N_("[B // 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. -CMD_AUTOMATE_WITH_DATABASE(ancestors, N_("REV1 [REV2 [REV3 [...]]]"), +CMD_AUTOMATE(ancestors, N_("REV1 [REV2 [REV3 [...]]]"), N_("Prints the ancestors of the given revisions"), N_(""), options::opts::none) @@ -96,6 +98,8 @@ CMD_AUTOMATE_WITH_DATABASE(ancestors, N_ N(args.size() > 0, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + set ancestors; vector frontier; for (args_vector::const_iterator i = args.begin(); i != args.end(); ++i) @@ -138,7 +142,7 @@ CMD_AUTOMATE_WITH_DATABASE(ancestors, N_ // 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. -CMD_AUTOMATE_WITH_DATABASE(descendents, N_("REV1 [REV2 [REV3 [...]]]"), +CMD_AUTOMATE(descendents, N_("REV1 [REV2 [REV3 [...]]]"), N_("Prints the descendents of the given revisions"), N_(""), options::opts::none) @@ -146,6 +150,8 @@ CMD_AUTOMATE_WITH_DATABASE(descendents, N(args.size() > 0, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + set descendents; vector frontier; for (args_vector::const_iterator i = args.begin(); i != args.end(); ++i) @@ -189,11 +195,13 @@ CMD_AUTOMATE_WITH_DATABASE(descendents, // 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. -CMD_AUTOMATE_WITH_DATABASE(erase_ancestors, N_("[REV1 [REV2 [REV3 [...]]]]"), +CMD_AUTOMATE(erase_ancestors, N_("[REV1 [REV2 [REV3 [...]]]]"), N_("Erases the ancestors in a list of revisions"), N_(""), options::opts::none) { + CMD_REQUIRES_DATABASE(app); + set revs; for (args_vector::const_iterator i = args.begin(); i != args.end(); ++i) { @@ -216,11 +224,13 @@ CMD_AUTOMATE_WITH_DATABASE(erase_ancesto // 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. -CMD_AUTOMATE_WITH_DATABASE(toposort, N_("[REV1 [REV2 [REV3 [...]]]]"), +CMD_AUTOMATE(toposort, N_("[REV1 [REV2 [REV3 [...]]]]"), N_("Topologically sorts a list of revisions"), N_(""), options::opts::none) { + CMD_REQUIRES_DATABASE(app); + set revs; for (args_vector::const_iterator i = args.begin(); i != args.end(); ++i) { @@ -251,7 +261,7 @@ CMD_AUTOMATE_WITH_DATABASE(toposort, N_( // 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. -CMD_AUTOMATE_WITH_DATABASE(ancestry_difference, N_("NEW_REV [OLD_REV1 [OLD_REV2 [...]]]"), +CMD_AUTOMATE(ancestry_difference, N_("NEW_REV [OLD_REV1 [OLD_REV2 [...]]]"), N_("Lists the ancestors of the first revision given, not in " "the others"), N_(""), @@ -260,6 +270,8 @@ CMD_AUTOMATE_WITH_DATABASE(ancestry_diff N(args.size() > 0, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + revision_id a; set bs; args_vector::const_iterator i = args.begin(); @@ -294,7 +306,7 @@ CMD_AUTOMATE_WITH_DATABASE(ancestry_diff // 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. -CMD_AUTOMATE_WITH_DATABASE(leaves, "", +CMD_AUTOMATE(leaves, "", N_("Lists the leaves of the revision graph"), N_(""), options::opts::none) @@ -302,6 +314,8 @@ CMD_AUTOMATE_WITH_DATABASE(leaves, "", N(args.size() == 0, F("no arguments needed")); + CMD_REQUIRES_DATABASE(app); + // this might be more efficient in SQL, but for now who cares. set leaves; db.get_revision_ids(leaves); @@ -324,7 +338,7 @@ CMD_AUTOMATE_WITH_DATABASE(leaves, "", // 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. -CMD_AUTOMATE_WITH_EVERYTHING(roots, "", +CMD_AUTOMATE(roots, "", N_("Lists the roots of the revision graph"), N_(""), options::opts::none) @@ -332,11 +346,13 @@ CMD_AUTOMATE_WITH_EVERYTHING(roots, "", N(args.size() == 0, F("no arguments needed")); + CMD_REQUIRES_DATABASE(app); + // the real root revisions are the children of one single imaginary root // with an empty revision id set roots; revision_id nullid; - app.db.get_revision_children(nullid, roots); + db.get_revision_children(nullid, roots); for (set::const_iterator i = roots.begin(); i != roots.end(); ++i) output << i->inner()() << '\n'; @@ -352,14 +368,16 @@ CMD_AUTOMATE_WITH_EVERYTHING(roots, "", // 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. -CMD_AUTOMATE_WITH_DATABASE(parents, N_("REV"), +CMD_AUTOMATE(parents, N_("REV"), N_("Prints the parents of a revision"), N_(""), options::opts::none) { N(args.size() == 1, F("wrong argument count")); - + + CMD_REQUIRES_DATABASE(app); + revision_id rid(idx(args, 0)()); N(db.revision_exists(rid), F("No such revision %s") % rid); set parents; @@ -380,14 +398,16 @@ CMD_AUTOMATE_WITH_DATABASE(parents, N_(" // 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. -CMD_AUTOMATE_WITH_DATABASE(children, N_("REV"), +CMD_AUTOMATE(children, N_("REV"), N_("Prints the children of a revision"), N_(""), options::opts::none) { N(args.size() == 1, F("wrong argument count")); - + + CMD_REQUIRES_DATABASE(app); + revision_id rid(idx(args, 0)()); N(db.revision_exists(rid), F("No such revision %s") % rid); set children; @@ -418,7 +438,7 @@ CMD_AUTOMATE_WITH_DATABASE(children, N_( // The output as a whole is alphabetically sorted; additionally, the parents // within each line are alphabetically sorted. // Error conditions: None. -CMD_AUTOMATE_WITH_DATABASE(graph, "", +CMD_AUTOMATE(graph, "", N_("Prints the complete ancestry graph"), N_(""), options::opts::none) @@ -426,6 +446,8 @@ CMD_AUTOMATE_WITH_DATABASE(graph, "", N(args.size() == 0, F("no arguments needed")); + CMD_REQUIRES_DATABASE(app); + multimap edges_mmap; map > child_to_parents; @@ -464,7 +486,7 @@ CMD_AUTOMATE_WITH_DATABASE(graph, "", // 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. -CMD_AUTOMATE_WITH_DATABASE(select, N_("SELECTOR"), +CMD_AUTOMATE(select, N_("SELECTOR"), N_("Lists the revisions that match a selector"), N_(""), options::opts::none) @@ -472,6 +494,8 @@ CMD_AUTOMATE_WITH_DATABASE(select, N_("S N(args.size() == 1, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + vector > sels(selectors::parse_selector(args[0](), db)); @@ -649,7 +673,7 @@ 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. -CMD_AUTOMATE_WITH_EVERYTHING(inventory, "", +CMD_AUTOMATE(inventory, "", N_("Prints a summary of files found in the workspace"), N_(""), options::opts::none) @@ -657,7 +681,8 @@ CMD_AUTOMATE_WITH_EVERYTHING(inventory, N(args.size() == 0, F("no arguments needed")); - app.require_workspace(); + CMD_REQUIRES_DATABASE(app); + CMD_REQUIRES_WORKSPACE(app); temp_node_id_source nis; roster_t curr, base; @@ -666,13 +691,13 @@ CMD_AUTOMATE_WITH_EVERYTHING(inventory, cset cs; MM(cs); path_set unchanged, changed, missing, unknown, ignored; - app.work.get_current_roster_shape(curr, nis); - app.work.get_work_rev(rev); + work.get_current_roster_shape(curr, nis); + work.get_work_rev(rev); N(rev.edges.size() == 1, F("this command can only be used in a single-parent workspace")); cs = edge_changes(rev.edges.begin()); - app.db.get_roster(edge_old_revision(rev.edges.begin()), base); + db.get_roster(edge_old_revision(rev.edges.begin()), base); // The current roster (curr) has the complete set of registered nodes // conveniently with unchanged sha1 hash values. @@ -697,8 +722,8 @@ CMD_AUTOMATE_WITH_EVERYTHING(inventory, vector roots; roots.push_back(file_path()); - app.work.classify_roster_paths(curr, unchanged, changed, missing); - app.work.find_unknown_and_ignored(mask, roots, unknown, ignored); + work.classify_roster_paths(curr, unchanged, changed, missing); + work.find_unknown_and_ignored(mask, roots, unknown, ignored); inventory_node_state(inventory, unchanged, inventory_item::UNCHANGED_NODE); @@ -852,7 +877,7 @@ CMD_AUTOMATE_WITH_EVERYTHING(inventory, // 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. -CMD_AUTOMATE_WITH_EVERYTHING(get_revision, N_("[REVID]"), +CMD_AUTOMATE(get_revision, N_("[REVID]"), N_("Shows change information for a revision"), N_(""), options::opts::none) @@ -860,20 +885,23 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_revisio N(args.size() < 2, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + temp_node_id_source nis; revision_data dat; revision_id ident; if (args.size() == 0) { + CMD_REQUIRES_WORKSPACE(app); + roster_t new_roster; parent_map old_rosters; revision_t rev; - app.require_workspace(); - app.work.get_parent_rosters(old_rosters); - app.work.get_current_roster_shape(new_roster, nis); - app.work.update_current_roster_from_filesystem(new_roster); + work.get_parent_rosters(old_rosters); + work.get_current_roster_shape(new_roster, nis); + work.update_current_roster_from_filesystem(new_roster); make_revision(old_rosters, new_roster, rev); calculate_ident(rev, ident); @@ -882,9 +910,9 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_revisio else { ident = revision_id(idx(args, 0)()); - N(app.db.revision_exists(ident), + N(db.revision_exists(ident), F("no revision %s found in database") % ident); - app.db.get_revision(ident, dat); + db.get_revision(ident, dat); } L(FL("dumping revision %s") % ident); @@ -898,7 +926,7 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_revisio // 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. -CMD_AUTOMATE_WITH_EVERYTHING(get_base_revision_id, "", +CMD_AUTOMATE(get_base_revision_id, "", N_("Shows the revision on which the workspace is based"), N_(""), options::opts::none) @@ -906,10 +934,10 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_base_re N(args.size() == 0, F("no arguments needed")); - app.require_workspace(); + CMD_REQUIRES_WORKSPACE(app); parent_map parents; - app.work.get_parent_rosters(parents); + work.get_parent_rosters(parents); N(parents.size() == 1, F("this command can only be used in a single-parent workspace")); @@ -925,7 +953,7 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_base_re // 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. -CMD_AUTOMATE_WITH_EVERYTHING(get_current_revision_id, "", +CMD_AUTOMATE(get_current_revision_id, "", N_("Shows the revision of the current workspace"), N_(""), options::opts::none) @@ -933,7 +961,7 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_current N(args.size() == 0, F("no arguments needed")); - app.require_workspace(); + CMD_REQUIRES_WORKSPACE(app); parent_map parents; roster_t new_roster; @@ -941,11 +969,10 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_current revision_t rev; temp_node_id_source nis; - app.require_workspace(); - app.work.get_current_roster_shape(new_roster, nis); - app.work.update_current_roster_from_filesystem(new_roster); + work.get_current_roster_shape(new_roster, nis); + work.update_current_roster_from_filesystem(new_roster); - app.work.get_parent_rosters(parents); + work.get_parent_rosters(parents); make_revision(parents, new_roster, rev); calculate_ident(rev, new_revision_id); @@ -994,7 +1021,7 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_current // // Error conditions: If the revision ID specified is unknown or // invalid prints an error message to stderr and exits with status 1. -CMD_AUTOMATE_WITH_EVERYTHING(get_manifest_of, N_("[REVID]"), +CMD_AUTOMATE(get_manifest_of, N_("[REVID]"), N_("Shows the manifest associated with a revision"), N_(""), options::opts::none) @@ -1008,18 +1035,21 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_manifes if (args.size() == 0) { + CMD_REQUIRES_WORKSPACE(app); + temp_node_id_source nis; - app.require_workspace(); - app.work.get_current_roster_shape(new_roster, nis); - app.work.update_current_roster_from_filesystem(new_roster); + work.get_current_roster_shape(new_roster, nis); + work.update_current_roster_from_filesystem(new_roster); } else { + CMD_REQUIRES_DATABASE(app); + revision_id rid = revision_id(idx(args, 0)()); - N(app.db.revision_exists(rid), + N(db.revision_exists(rid), F("no revision %s found in database") % rid); - app.db.get_roster(rid, new_roster); + db.get_roster(rid, new_roster); } calculate_ident(new_roster, mid); @@ -1040,7 +1070,7 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_manifes // // Error conditions: If the revision id specified is unknown or // invalid prints an error message to stderr and exits with status 1. -CMD_AUTOMATE_WITH_DATABASE(packet_for_rdata, N_("REVID"), +CMD_AUTOMATE(packet_for_rdata, N_("REVID"), N_("Prints the revision data in packet format"), N_(""), options::opts::none) @@ -1048,6 +1078,8 @@ CMD_AUTOMATE_WITH_DATABASE(packet_for_rd N(args.size() == 1, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + packet_writer pw(output); revision_id r_id(idx(args, 0)()); @@ -1069,7 +1101,7 @@ CMD_AUTOMATE_WITH_DATABASE(packet_for_rd // // Error conditions: If the revision id specified is unknown or // invalid prints an error message to stderr and exits with status 1. -CMD_AUTOMATE_WITH_DATABASE(packets_for_certs, N_("REVID"), +CMD_AUTOMATE(packets_for_certs, N_("REVID"), N_("Prints the certs associated with a revision in " "packet format"), N_(""), @@ -1078,6 +1110,8 @@ CMD_AUTOMATE_WITH_DATABASE(packets_for_c N(args.size() == 1, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + packet_writer pw(output); revision_id r_id(idx(args, 0)()); @@ -1100,7 +1134,7 @@ CMD_AUTOMATE_WITH_DATABASE(packets_for_c // // Error conditions: If the file id specified is unknown or invalid // prints an error message to stderr and exits with status 1. -CMD_AUTOMATE_WITH_DATABASE(packet_for_fdata, N_("FILEID"), +CMD_AUTOMATE(packet_for_fdata, N_("FILEID"), N_("Prints the file data in packet format"), N_(""), options::opts::none) @@ -1108,6 +1142,8 @@ CMD_AUTOMATE_WITH_DATABASE(packet_for_fd N(args.size() == 1, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + packet_writer pw(output); file_id f_id(idx(args, 0)()); @@ -1130,7 +1166,7 @@ CMD_AUTOMATE_WITH_DATABASE(packet_for_fd // // Error conditions: If any of the file ids specified are unknown or // invalid prints an error message to stderr and exits with status 1. -CMD_AUTOMATE_WITH_DATABASE(packet_for_fdelta, N_("OLD_FILE NEW_FILE"), +CMD_AUTOMATE(packet_for_fdelta, N_("OLD_FILE NEW_FILE"), N_("Prints the file delta in packet format"), N_(""), options::opts::none) @@ -1138,6 +1174,8 @@ CMD_AUTOMATE_WITH_DATABASE(packet_for_fd N(args.size() == 2, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + packet_writer pw(output); file_id f_old_id(idx(args, 0)()); @@ -1167,7 +1205,7 @@ CMD_AUTOMATE_WITH_DATABASE(packet_for_fd // 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. -CMD_AUTOMATE_WITH_DATABASE(common_ancestors, N_("REV1 [REV2 [REV3 [...]]]"), +CMD_AUTOMATE(common_ancestors, N_("REV1 [REV2 [REV3 [...]]]"), N_("Prints revisions that are common ancestors of a list " "of revisions"), N_(""), @@ -1176,6 +1214,8 @@ CMD_AUTOMATE_WITH_DATABASE(common_ancest N(args.size() > 0, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + set ancestors, common_ancestors; vector frontier; for (args_vector::const_iterator i = args.begin(); i != args.end(); ++i) @@ -1234,7 +1274,7 @@ CMD_AUTOMATE_WITH_DATABASE(common_ancest // in alphabetically sorted order. // Error conditions: // None. -CMD_AUTOMATE_WITH_EVERYTHING(branches, "", +CMD_AUTOMATE(branches, "", N_("Prints all branch certs in the revision graph"), N_(""), options::opts::none) @@ -1242,13 +1282,16 @@ CMD_AUTOMATE_WITH_EVERYTHING(branches, " N(args.size() == 0, F("no arguments needed")); + CMD_REQUIRES_DATABASE(app); + set names; - app.db.get_project().get_branch_list(names); + db.get_project().get_branch_list(names); for (set::const_iterator i = names.begin(); i != names.end(); ++i) { + // FIXME: should this lua hook be in the database context? if (!app.lua.hook_ignore_branch(*i)) output << (*i) << '\n'; } @@ -1286,7 +1329,7 @@ CMD_AUTOMATE_WITH_EVERYTHING(branches, " // Stanzas are printed in arbitrary order. // Error conditions: // A run-time exception is thrown for illegal patterns. -CMD_AUTOMATE_WITH_EVERYTHING(tags, N_("[BRANCH_PATTERN]"), +CMD_AUTOMATE(tags, N_("[BRANCH_PATTERN]"), N_("Prints all tags attached to a set of branches"), N_(""), options::opts::none) @@ -1294,6 +1337,8 @@ CMD_AUTOMATE_WITH_EVERYTHING(tags, N_("[ N(args.size() < 2, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + globish incl("*"); bool filtering(false); @@ -1309,13 +1354,13 @@ CMD_AUTOMATE_WITH_EVERYTHING(tags, N_("[ prt.print_stanza(stz); set tags; - app.db.get_project().get_tags(tags); + db.get_project().get_tags(tags); for (set::const_iterator tag = tags.begin(); tag != tags.end(); ++tag) { set branches; - app.db.get_project().get_revision_branches(tag->ident, branches); + db.get_project().get_revision_branches(tag->ident, branches); bool show(!filtering); vector branch_names; @@ -1323,6 +1368,8 @@ CMD_AUTOMATE_WITH_EVERYTHING(tags, N_("[ for (set::const_iterator branch = branches.begin(); branch != branches.end(); ++branch) { + // FIXME: again, hook_ignore_branch should probably be in the + // database context... if (app.lua.hook_ignore_branch(*branch)) continue; @@ -1379,7 +1426,7 @@ namespace // // Error conditions: If the passphrase is empty or the key already exists, // prints an error message to stderr and exits with status 1. -CMD_AUTOMATE_WITH_DATABASE(genkey, N_("KEYID PASSPHRASE"), +CMD_AUTOMATE(genkey, N_("KEYID PASSPHRASE"), N_("Generates a key"), N_(""), options::opts::none) @@ -1387,6 +1434,8 @@ CMD_AUTOMATE_WITH_DATABASE(genkey, N_("K N(args.size() == 2, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + rsa_keypair_id ident; internalize_rsa_keypair_id(idx(args, 0), ident); @@ -1442,7 +1491,7 @@ CMD_AUTOMATE_WITH_DATABASE(genkey, N_("K // Sample output (for 'mtn automate get_option branch: // net.venge.monotone // -CMD_AUTOMATE_WITH_EVERYTHING(get_option, N_("OPTION"), +CMD_AUTOMATE(get_option, N_("OPTION"), N_("Shows the value of an option"), N_(""), options::opts::none) @@ -1450,15 +1499,14 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_option, N(args.size() == 1, F("wrong argument count")); - // this command requires a workspace to be run on - app.require_workspace(); + CMD_REQUIRES_WORKSPACE(app); system_path database_option; branch_name branch_option; rsa_keypair_id key_option; system_path keydir_option; - app.work.get_ws_options(database_option, branch_option, - key_option, keydir_option); + work.get_ws_options(database_option, branch_option, + key_option, keydir_option); string opt = args[0](); @@ -1494,7 +1542,7 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_option, // Sample output (for 'mtn automate get_content_changed 3bccff99d08421df72519b61a4dded16d1139c33 ChangeLog): // content_mark [276264b0b3f1e70fc1835a700e6e61bdbe4c3f2f] // -CMD_AUTOMATE_WITH_DATABASE(get_content_changed, N_("REV FILE"), +CMD_AUTOMATE(get_content_changed, N_("REV FILE"), N_("Lists the revisions that changed the content relative " "to another revision"), N_(""), @@ -1503,6 +1551,8 @@ CMD_AUTOMATE_WITH_DATABASE(get_content_c N(args.size() == 2, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + roster_t new_roster; revision_id ident; marking_map mm; @@ -1557,7 +1607,7 @@ CMD_AUTOMATE_WITH_DATABASE(get_content_c // // Sample output (for automate get_corresponding_path 91f25c8ee830b11b52dd356c925161848d4274d0 foo2 dae0d8e3f944c82a9688bcd6af99f5b837b41968; see automate_get_corresponding_path test) // file "foo" -CMD_AUTOMATE_WITH_DATABASE(get_corresponding_path, N_("REV1 FILE REV2"), +CMD_AUTOMATE(get_corresponding_path, N_("REV1 FILE REV2"), N_("Prints the name of a file in a target revision relative " "to a given revision"), N_(""), @@ -1566,6 +1616,8 @@ CMD_AUTOMATE_WITH_DATABASE(get_correspon N(args.size() == 3, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + roster_t new_roster, old_roster; revision_id ident, old_ident; @@ -1610,7 +1662,7 @@ CMD_AUTOMATE_WITH_DATABASE(get_correspon // The ID of the new file (40 digit hex string) // Error conditions: // a runtime exception is thrown if base revision is not available -CMD_AUTOMATE_WITH_DATABASE(put_file, N_("[FILEID] CONTENTS"), +CMD_AUTOMATE(put_file, N_("[FILEID] CONTENTS"), N_("Stores a file in the database"), N_(""), options::opts::none) @@ -1618,6 +1670,8 @@ CMD_AUTOMATE_WITH_DATABASE(put_file, N_( N(args.size() == 1 || args.size() == 2, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + file_id sha1sum; transaction_guard tr(db); if (args.size() == 1) @@ -1663,7 +1717,7 @@ CMD_AUTOMATE_WITH_DATABASE(put_file, N_( // The ID of the new revision // Error conditions: // none -CMD_AUTOMATE_WITH_DATABASE(put_revision, N_("REVISION-DATA"), +CMD_AUTOMATE(put_revision, N_("REVISION-DATA"), N_("Stores a revision into the database"), N_(""), options::opts::none) @@ -1671,6 +1725,8 @@ CMD_AUTOMATE_WITH_DATABASE(put_revision, N(args.size() == 1, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + revision_t rev; read_revision(revision_data(idx(args, 0)()), rev); @@ -1720,7 +1776,7 @@ CMD_AUTOMATE_WITH_DATABASE(put_revision, // nothing // Error conditions: // none -CMD_AUTOMATE_WITH_DATABASE(cert, N_("REVISION-ID NAME VALUE"), +CMD_AUTOMATE(cert, N_("REVISION-ID NAME VALUE"), N_("Adds a revision certificate"), N_(""), options::opts::none) @@ -1728,6 +1784,8 @@ CMD_AUTOMATE_WITH_DATABASE(cert, N_("REV N(args.size() == 3, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + cert c; revision_id rid(idx(args, 0)()); @@ -1753,14 +1811,16 @@ CMD_AUTOMATE_WITH_DATABASE(cert, N_("REV // nothing // Error conditions: // none -CMD_AUTOMATE_WITH_DATABASE(db_set, N_("DOMAIN NAME VALUE"), +CMD_AUTOMATE(db_set, N_("DOMAIN NAME VALUE"), N_("Sets a database variable"), N_(""), options::opts::none) { N(args.size() == 3, F("wrong argument count")); - + + CMD_REQUIRES_DATABASE(app); + var_domain domain = var_domain(idx(args, 0)()); utf8 name = idx(args, 1); utf8 value = idx(args, 2); @@ -1779,7 +1839,7 @@ CMD_AUTOMATE_WITH_DATABASE(db_set, N_("D // variable value // Error conditions: // a runtime exception is thrown if the variable is not set -CMD_AUTOMATE_WITH_DATABASE(db_get, N_("DOMAIN NAME"), +CMD_AUTOMATE(db_get, N_("DOMAIN NAME"), N_("Gets a database variable"), N_(""), options::opts::none) @@ -1787,6 +1847,8 @@ CMD_AUTOMATE_WITH_DATABASE(db_get, N_("D N(args.size() == 2, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + var_domain domain = var_domain(idx(args, 0)()); utf8 name = idx(args, 1); var_key key(domain, var_name(name())); ============================================================ --- cmd.hh 8c23440201398c17660da8dd43dcc93052be1496 +++ cmd.hh 8f5e1e444560beb1ada3df3442c312af2a88938d @@ -246,7 +246,7 @@ void commands::cmd_ ## C::exec(app_state // command definition allows the description of input/output format, // error conditions, version when added, etc. 'desc' can later be // automatically built from these. -#define CMD_AUTOMATE_WITH_EVERYTHING(C, params, abstract, desc, opts)\ +#define CMD_AUTOMATE(C, params, abstract, desc, opts) \ namespace commands { \ class automate_ ## C : public automate \ { \ @@ -267,69 +267,12 @@ void commands::automate_ ## C :: exec_fr app_state & app, \ std::ostream & output) const -#define CMD_AUTOMATE_WITH_DATABASE(C, params, abstract, desc, opts) \ -namespace commands { \ - class automate_ ## C : public automate \ - { \ - void exec_from_automate(args_vector args, \ - command_id const & execid, \ - app_state & app, \ - std::ostream & output) const; \ - \ - void exec_from_automate(args_vector args, \ - command_id const & execid, \ - database & db, \ - std::ostream & output) const; \ - public: \ - automate_ ## C() : automate(#C, params, abstract, desc, \ - options::options_type() | opts) \ - {} \ - }; \ - automate_ ## C C ## _automate; \ -} \ -void commands::automate_ ## C :: exec_from_automate \ - (args_vector args, \ - command_id const & execid, \ - app_state & app, \ - std::ostream & output) const \ - { exec_from_automate(args, execid, app.db, output); } \ - \ -void commands::automate_ ## C :: exec_from_automate \ - (args_vector args, \ - command_id const & execid, \ - database & db, \ - std::ostream & output) const +#define CMD_REQUIRES_DATABASE(app) \ +database & db = app.db -#define CMD_AUTOMATE_WITH_NOTHING(C, params, abstract, desc, opts) \ -namespace commands { \ - class automate_ ## C : public automate \ - { \ - void exec_from_automate(args_vector args, \ - command_id const & execid, \ - app_state & app, \ - std::ostream & output) const; \ - \ - void exec_from_automate(args_vector args, \ - command_id const & execid, \ - std::ostream & output) const; \ - public: \ - automate_ ## C() : automate(#C, params, abstract, desc, \ - options::options_type() | opts) \ - {} \ - }; \ - automate_ ## C C ## _automate; \ -} \ -void commands::automate_ ## C :: exec_from_automate \ - (args_vector args, \ - command_id const & execid, \ - app_state & app, \ - std::ostream & output) const \ - { exec_from_automate(args, execid, output); } \ - \ -void commands::automate_ ## C :: exec_from_automate \ - (args_vector args, \ - command_id const & execid, \ - std::ostream & output) const +#define CMD_REQUIRES_WORKSPACE(app) \ +workspace & work = app.work; \ +app.require_workspace() CMD_FWD_DECL(__root__); CMD_FWD_DECL(automation); ============================================================ --- cmd_automate.cc 70adf70cff51acf0add835845ce5f98f367d7fad +++ cmd_automate.cc 819bd0e40ed4c53d4963feffb631d8255e535599 @@ -58,7 +58,7 @@ static string const interface_version = // Output format: ".\n". Always matches // "[0-9]+\.[0-9]+\n". // Error conditions: None. -CMD_AUTOMATE_WITH_NOTHING(interface_version, "", +CMD_AUTOMATE(interface_version, "", N_("Prints the automation interface's version"), N_(""), options::opts::none) @@ -315,7 +315,7 @@ struct automate_ostream : public std::os }; -CMD_AUTOMATE_WITH_EVERYTHING(stdio, "", +CMD_AUTOMATE(stdio, "", N_("Automates several commands in one run"), N_(""), options::opts::automate_stdio_size) @@ -323,9 +323,12 @@ CMD_AUTOMATE_WITH_EVERYTHING(stdio, "", N(args.size() == 0, F("no arguments needed")); + CMD_REQUIRES_DATABASE(app); + // FIXME: additionally requires some app.opts... + // initialize the database early so any calling process is notified // immediately if a version discrepancy exists - app.db.ensure_open(); + db.ensure_open(); automate_ostream os(output, app.opts.automate_stdio_size); automate_reader ar(std::cin); ============================================================ --- cmd_diff_log.cc b7b33c8f4ec36c21d8be3117a113138d703c30ee +++ cmd_diff_log.cc c036a48598bb628d28e9a5cb15a6ae13b13c4786 @@ -526,12 +526,14 @@ CMD(diff, "diff", "", CMD_REF(informativ // 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. -CMD_AUTOMATE_WITH_EVERYTHING(content_diff, N_("[FILE [...]]"), +CMD_AUTOMATE(content_diff, N_("[FILE [...]]"), N_("Calculates diffs of files"), N_(""), options::opts::revision | options::opts::depth | options::opts::exclude) { + // FIXME: prepare_diff and dump_diffs should not take 'app' argument. + cset included; std::string dummy_header; bool new_is_archived; ============================================================ --- cmd_files.cc 1d35ebb8c6fafe6f4c263533d1724bf0d53fa216 +++ cmd_files.cc 7db4cf9b2f5be53b92f60ee75f31fe550cf23c46 @@ -224,7 +224,7 @@ CMD(identify, "identify", "", CMD_REF(de // // Error conditions: If the file path doesn't point to a valid file prints // an error message to stderr and exits with status 1. -CMD_AUTOMATE_WITH_EVERYTHING(identify, N_("PATH"), +CMD_AUTOMATE(identify, N_("PATH"), N_("Prints the file identifier of a file"), N_(""), options::opts::none) @@ -322,7 +322,7 @@ CMD(cat, "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. -CMD_AUTOMATE_WITH_EVERYTHING(get_file, N_("FILEID"), +CMD_AUTOMATE(get_file, N_("FILEID"), N_("Prints the contents of a file (given an identifier)"), N_(""), options::opts::none) @@ -330,6 +330,8 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_file, N N(args.size() == 1, F("wrong argument count")); + // FIXME: dump_file should not take app arg + file_id ident(idx(args, 0)()); dump_file(output, app, ident); } @@ -348,7 +350,7 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_file, N // // Error conditions: If the file id specified is unknown or invalid prints // an error message to stderr and exits with status 1. -CMD_AUTOMATE_WITH_EVERYTHING(get_file_of, N_("FILENAME"), +CMD_AUTOMATE(get_file_of, N_("FILENAME"), N_("Prints the contents of a file (given a name)"), N_(""), options::opts::revision) @@ -359,17 +361,23 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_file_of revision_id rid; if (app.opts.revision_selectors.size() == 0) { - app.require_workspace(); + CMD_REQUIRES_WORKSPACE(app); parent_map parents; - app.work.get_parent_rosters(parents); + work.get_parent_rosters(parents); N(parents.size() == 1, F("this command can only be used in a single-parent workspace")); rid = parent_id(parents.begin()); } else - complete(app.db, idx(app.opts.revision_selectors, 0)(), rid); + { + CMD_REQUIRES_DATABASE(app); + // FIXME: what about app.opts.revision_selectors? + complete(db, idx(app.opts.revision_selectors, 0)(), rid); + } + + // FIXME: again, dump_file should not take app arg dump_file(output, app, rid, idx(args, 0)); } ============================================================ --- cmd_list.cc b32f6e0c1875dc0832ed3fdb9bf4c10c40d58523 +++ cmd_list.cc 5d77b7cc9409c98ac2a68152eef6d436cc42db74 @@ -557,14 +557,16 @@ namespace // private_location "keystore" // // Error conditions: None. -CMD_AUTOMATE_WITH_DATABASE(keys, "", +CMD_AUTOMATE(keys, "", N_("Lists all keys in the keystore"), N_(""), options::opts::none) { N(args.size() == 0, F("no arguments needed")); - + + CMD_REQUIRES_DATABASE(app); + vector dbkeys; vector kskeys; // public_hash, private_hash, public_location, private_location @@ -653,7 +655,7 @@ CMD_AUTOMATE_WITH_DATABASE(keys, "", // 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. -CMD_AUTOMATE_WITH_DATABASE(certs, N_("REV"), +CMD_AUTOMATE(certs, N_("REV"), N_("Prints all certificates attached to a revision"), N_(""), options::opts::none) @@ -661,6 +663,8 @@ CMD_AUTOMATE_WITH_DATABASE(certs, N_("RE N(args.size() == 1, F("wrong argument count")); + CMD_REQUIRES_DATABASE(app); + vector certs; transaction_guard guard(db, false); ============================================================ --- cmd_ws_commit.cc 873d518fd5f0d334e3f55fbfdb625ac0b974e130 +++ cmd_ws_commit.cc c6a531365009a13693131695a94734af29688ef6 @@ -776,7 +776,7 @@ CMD(attr_set, "set", "", CMD_REF(attr), // // Error conditions: If the path has no attributes, prints only the // format version, if the file is unknown, escalates -CMD_AUTOMATE_WITH_EVERYTHING(get_attributes, N_("PATH"), +CMD_AUTOMATE(get_attributes, N_("PATH"), N_("Prints all attributes for the specified path"), N_(""), options::opts::none) @@ -784,8 +784,7 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_attribu N(args.size() > 0, F("wrong argument count")); - // this command requires a workspace to be run on - app.require_workspace(); + CMD_REQUIRES_WORKSPACE(app); // retrieve the path split_path path; @@ -796,8 +795,8 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_attribu temp_node_id_source nis; // get the base and the current roster of this workspace - app.work.get_current_roster_shape(current, nis); - app.work.get_parent_rosters(parents); + work.get_current_roster_shape(current, nis); + work.get_parent_rosters(parents); N(parents.size() == 1, F("this command can only be used in a single-parent workspace")); base = parent_roster(parents.begin()); @@ -891,7 +890,7 @@ CMD_AUTOMATE_WITH_EVERYTHING(get_attribu // // Error conditions: If PATH is unknown in the new roster, prints an error and // exits with status 1. -CMD_AUTOMATE_WITH_EVERYTHING(set_attribute, N_("PATH KEY VALUE"), +CMD_AUTOMATE(set_attribute, N_("PATH KEY VALUE"), N_("Sets an attribute on a certain path"), N_(""), options::opts::none) @@ -899,11 +898,12 @@ CMD_AUTOMATE_WITH_EVERYTHING(set_attribu N(args.size() == 3, F("wrong argument count")); + CMD_REQUIRES_WORKSPACE(app); + roster_t new_roster; temp_node_id_source nis; - app.require_workspace(); - app.work.get_current_roster_shape(new_roster, nis); + work.get_current_roster_shape(new_roster, nis); file_path path = file_path_external(idx(args,0)); split_path sp; @@ -918,12 +918,12 @@ CMD_AUTOMATE_WITH_EVERYTHING(set_attribu node->attrs[a_key] = make_pair(true, a_value); parent_map parents; - app.work.get_parent_rosters(parents); + work.get_parent_rosters(parents); revision_t new_work; make_revision_for_workspace(parents, new_roster, new_work); - app.work.put_work_rev(new_work); - app.work.update_any_attrs(); + work.put_work_rev(new_work); + work.update_any_attrs(); } // Name: drop_attribute @@ -937,7 +937,7 @@ CMD_AUTOMATE_WITH_EVERYTHING(set_attribu // Error conditions: If PATH is unknown in the new roster or the specified // attribute key is unknown, prints an error and exits with // status 1. -CMD_AUTOMATE_WITH_EVERYTHING(drop_attribute, N_("PATH [KEY]"), +CMD_AUTOMATE(drop_attribute, N_("PATH [KEY]"), N_("Drops an attribute or all of them from a certain path"), N_(""), options::opts::none) @@ -945,11 +945,12 @@ CMD_AUTOMATE_WITH_EVERYTHING(drop_attrib N(args.size() ==1 || args.size() == 2, F("wrong argument count")); + CMD_REQUIRES_WORKSPACE(app); + roster_t new_roster; temp_node_id_source nis; - app.require_workspace(); - app.work.get_current_roster_shape(new_roster, nis); + work.get_current_roster_shape(new_roster, nis); file_path path = file_path_external(idx(args,0)); split_path sp; @@ -975,12 +976,12 @@ CMD_AUTOMATE_WITH_EVERYTHING(drop_attrib } parent_map parents; - app.work.get_parent_rosters(parents); + work.get_parent_rosters(parents); revision_t new_work; make_revision_for_workspace(parents, new_roster, new_work); - app.work.put_work_rev(new_work); - app.work.update_any_attrs(); + work.put_work_rev(new_work); + work.update_any_attrs(); } CMD(commit, "commit", "ci", CMD_REF(workspace), N_("[PATH]..."),