# # # patch "cmd_netsync.cc" # from [08012b1b75787b9ee18f0f60f10140d6e74aa06f] # to [7e90119a925aa6ea1e0e70230eb126ecc087f826] # # patch "network/connection_info.hh" # from [181811d9adbba91506779f28461d29a46a40f2a1] # to [fac7aea0ae5a634aa7d07ef9c2cd58c1126fb463] # # patch "network/netsync_session.cc" # from [e3b98a67f8eba6168d692d6a29ffa66d4db2f796] # to [af33fae1c6aa4a71cc9a5797a1632f0cd93ce0fc] # # patch "network/netsync_session.hh" # from [e5483827d8db0964dabed6565fddf1713f701a7d] # to [2aab016afb94688dbeeaec9c4526445cd9ee368b] # ============================================================ --- cmd_netsync.cc 08012b1b75787b9ee18f0f60f10140d6e74aa06f +++ cmd_netsync.cc 7e90119a925aa6ea1e0e70230eb126ecc087f826 @@ -1,5 +1,6 @@ // Copyright (C) 2002 Graydon Hoare // 2006 Timothy Brownawell +// 2010 Stephen Leake // // This program is made available under the GNU GPL version 2.0 or // greater. See the accompanying file COPYING for details. @@ -12,6 +13,7 @@ #include "cmd.hh" #include "automate_ostream_demuxed.hh" +#include "basic_io.hh" #include "merge_content.hh" #include "netsync.hh" #include "network/connection_info.hh" @@ -272,10 +274,12 @@ CMD_AUTOMATE_NO_STDIO(remote, F("received remote error code %d") % os.get_error()); } -void print_dryrun_info(protocol_role role, - shared_conn_info info, - project_t & project) +static void +print_dryrun_info_cmd(protocol_role role, + shared_conn_info info, + project_t & project) { + // print dryrun info for command line if (role != source_role) { if (info->client.dryrun_incoming_keys_is_estimate) @@ -299,10 +303,10 @@ void print_dryrun_info(protocol_role rol % info->client.dryrun_outgoing_certs % info->client.dryrun_outgoing_keys); P(F("would send %d revisions:") - % info->client.dryrun_outgoing_revs.size()); + % info->client.outgoing_revs.size()); map branch_counts; - for (set::const_iterator i = info->client.dryrun_outgoing_revs.begin(); - i != info->client.dryrun_outgoing_revs.end(); ++i) + for (vector::const_iterator i = info->client.outgoing_revs.begin(); + i != info->client.outgoing_revs.end(); ++i) { set my_branches; project.get_revision_branches(*i, my_branches); @@ -320,6 +324,169 @@ void print_dryrun_info(protocol_role rol } } +namespace +{ + namespace syms + { + symbol const branch("branch"); + symbol const cert("cert"); + symbol const dryrun("dryrun"); + symbol const estimate("estimate"); + symbol const key("key"); + symbol const name("name"); + symbol const receive("receive"); + symbol const revision("revision"); + symbol const send("send"); + symbol const value("value"); + } +} + +static void +print_dryrun_info_auto(protocol_role role, + shared_conn_info info, + project_t & project, + std::ostream & output) +{ + // print dry run info for automate session + basic_io::printer pr; + basic_io::stanza st; + + st.push_symbol(syms::dryrun); + + if (role != source_role) + { + // sink or sink_and_source; print sink info + st.push_symbol(syms::receive); + + if (info->client.dryrun_incoming_keys_is_estimate) + { + st.push_symbol(syms::estimate); + } + + st.push_str_pair(syms::revision, + boost::lexical_cast(info->client.dryrun_incoming_revs)); + st.push_str_pair(syms::cert, + boost::lexical_cast(info->client.dryrun_incoming_certs)); + st.push_str_pair(syms::key, + boost::lexical_cast(info->client.dryrun_incoming_keys)); + } + if (role != sink_role) + { + // source or sink_and_source; print source info + st.push_symbol(syms::send); + + st.push_str_pair(syms::revision, + boost::lexical_cast(info->client.outgoing_revs.size())); + st.push_str_pair(syms::cert, + boost::lexical_cast(info->client.dryrun_outgoing_certs)); + st.push_str_pair(syms::key, + boost::lexical_cast(info->client.dryrun_outgoing_keys)); + map branch_counts; + for (vector::const_iterator i = info->client.outgoing_revs.begin(); + i != info->client.outgoing_revs.end(); ++i) + { + set my_branches; + project.get_revision_branches(*i, my_branches); + for(set::iterator b = my_branches.begin(); + b != my_branches.end(); ++b) + { + ++branch_counts[*b]; + } + } + for (map::iterator i = branch_counts.begin(); + i != branch_counts.end(); ++i) + { + st.push_str_triple(syms::branch, i->first(), boost::lexical_cast(i->second)); + } + } + pr.print_stanza(st); + output.write(pr.buf.data(), pr.buf.size()); +} + +static void +print_cert(cert const & item, + basic_io::printer & pr, + std::ostream & output) +{ + basic_io::stanza st; + st.push_symbol(syms::cert); + st.push_binary_pair(syms::revision, item.ident.inner()); + st.push_str_pair(syms::name, item.name()); + st.push_str_pair(syms::value, item.value()); + st.push_binary_pair(syms::key, item.key.inner()); + pr.print_stanza(st); + output.write(pr.buf.data(), pr.buf.size()); +} + +static void +print_info_auto(protocol_role role, + shared_conn_info info, + project_t & project, + std::ostream & output) +{ + // print info for automate session + basic_io::printer pr; + basic_io::stanza st; + + if (role != source_role) + { + // sink or sink_and_source; print sink info + st.push_symbol(syms::receive); + pr.print_stanza(st); + output.write(pr.buf.data(), pr.buf.size()); + + for (vector::const_iterator i = info->client.incoming_revs.begin(); + i != info->client.incoming_revs.end(); ++i) + { + st.push_binary_pair(syms::revision, i->inner()); + } + pr.print_stanza(st); + output.write(pr.buf.data(), pr.buf.size()); + + for (vector::const_iterator i = info->client.incoming_certs.begin(); + i != info->client.incoming_certs.end(); ++i) + { + print_cert(*i, pr, output); + } + for (vector::const_iterator i = info->client.incoming_keys.begin(); + i != info->client.incoming_keys.end(); ++i) + { + st.push_binary_pair(syms::key, i->inner()); + } + pr.print_stanza(st); + output.write(pr.buf.data(), pr.buf.size()); + } + if (role != sink_role) + { + // source or sink_and_source; print source info + st.push_symbol(syms::send); + pr.print_stanza(st); + output.write(pr.buf.data(), pr.buf.size()); + + for (vector::const_iterator i = info->client.outgoing_revs.begin(); + i != info->client.outgoing_revs.end(); ++i) + { + st.push_binary_pair(syms::revision, i->inner()); + } + pr.print_stanza(st); + output.write(pr.buf.data(), pr.buf.size()); + + for (vector::const_iterator i = info->client.outgoing_certs.begin(); + i != info->client.outgoing_certs.end(); ++i) + { + print_cert(*i, pr, output); + } + + for (vector::const_iterator i = info->client.outgoing_keys.begin(); + i != info->client.outgoing_keys.end(); ++i) + { + st.push_binary_pair(syms::key, i->inner()); + } + pr.print_stanza(st); + output.write(pr.buf.data(), pr.buf.size()); + } +} + CMD(push, "push", "", CMD_REF(network), N_("[URL]\n[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), N_("Pushes branches to a netsync server"), @@ -340,7 +507,7 @@ CMD(push, "push", "", CMD_REF(network), run_netsync_protocol(app, app.opts, app.lua, project, keys, client_voice, source_role, info); if (app.opts.dryrun) - print_dryrun_info(source_role, info, project); + print_dryrun_info_cmd(source_role, info, project); } CMD_AUTOMATE(push, N_("[URL]\n[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), @@ -362,7 +529,9 @@ CMD_AUTOMATE(push, N_("[URL]\n[ADDRESS[: run_netsync_protocol(app, app.opts, app.lua, project, keys, client_voice, source_role, info); if (app.opts.dryrun) - print_dryrun_info(source_role, info, project); + print_dryrun_info_auto(source_role, info, project, output); + else + print_info_auto(source_role, info, project, output); } CMD(pull, "pull", "", CMD_REF(network), @@ -392,7 +561,7 @@ CMD(pull, "pull", "", CMD_REF(network), updater.maybe_do_update(); if (app.opts.dryrun) - print_dryrun_info(sink_role, info, project); + print_dryrun_info_cmd(sink_role, info, project); } CMD_AUTOMATE(pull, N_("[URL]\n[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), @@ -414,7 +583,9 @@ CMD_AUTOMATE(pull, N_("[URL]\n[ADDRESS[: run_netsync_protocol(app, app.opts, app.lua, project, keys, client_voice, sink_role, info); if (app.opts.dryrun) - print_dryrun_info(sink_role, info, project); + print_dryrun_info_auto(sink_role, info, project, output); + else + print_info_auto(sink_role, info, project, output); } CMD(sync, "sync", "", CMD_REF(network), @@ -449,7 +620,7 @@ CMD(sync, "sync", "", CMD_REF(network), updater.maybe_do_update(); if (app.opts.dryrun) - print_dryrun_info(source_and_sink_role, info, project); + print_dryrun_info_cmd(source_and_sink_role, info, project); } CMD_AUTOMATE(sync, N_("[URL]\n[ADDRESS[:PORTNUMBER] [PATTERN ...]]"), @@ -477,7 +648,9 @@ CMD_AUTOMATE(sync, N_("[URL]\n[ADDRESS[: run_netsync_protocol(app, app.opts, app.lua, project, keys, client_voice, source_and_sink_role, info); if (app.opts.dryrun) - print_dryrun_info(source_and_sink_role, info, project); + print_dryrun_info_auto(source_and_sink_role, info, project, output); + else + print_info_auto(source_and_sink_role, info, project, output); } CMD_NO_WORKSPACE(clone, "clone", "", CMD_REF(network), ============================================================ --- network/netsync_session.cc e3b98a67f8eba6168d692d6a29ffa66d4db2f796 +++ network/netsync_session.cc af33fae1c6aa4a71cc9a5797a1632f0cd93ce0fc @@ -138,6 +138,18 @@ void netsync_session::on_end(size_t iden keys_in || keys_out)) error_code = error_codes::partial_transfer; + if (is_automate) + { + // Save data for automate output + conn_info->client.outgoing_revs = sent_revisions; + conn_info->client.outgoing_certs = sent_certs; + conn_info->client.outgoing_keys = sent_keys; + conn_info->client.incoming_revs = written_revisions; + conn_info->client.incoming_certs = written_certs; + conn_info->client.incoming_keys = written_keys; + } + + // Call Lua hooks vector unattached_written_certs; map > rev_written_certs; for (vector::iterator i = written_revisions.begin(); @@ -456,7 +468,7 @@ netsync_session::dry_run_finished() cons for (set::const_iterator i = rev_refiner.items_to_send.begin(); i != rev_refiner.items_to_send.end(); ++i) { - conn_info->client.dryrun_outgoing_revs.insert(revision_id(*i)); + conn_info->client.outgoing_revs.push_back(revision_id(*i)); } conn_info->client.dryrun_outgoing_certs = cert_refiner.items_to_send.size(); conn_info->client.dryrun_outgoing_keys = key_refiner.items_to_send.size(); ============================================================ --- network/netsync_session.hh e5483827d8db0964dabed6565fddf1713f701a7d +++ network/netsync_session.hh 2aab016afb94688dbeeaec9c4526445cd9ee368b @@ -73,8 +73,9 @@ netsync_session: refiner cert_refiner; refiner rev_refiner; - // dry-run info + // dry-run & automate info bool is_dry_run; + bool is_automate; bool dry_run_keys_refined; shared_conn_info conn_info; bool dry_run_finished() const; ============================================================ --- network/connection_info.hh 181811d9adbba91506779f28461d29a46a40f2a1 +++ network/connection_info.hh fac7aea0ae5a634aa7d07ef9c2cd58c1126fb463 @@ -1,4 +1,4 @@ -// Copyright (C) 2005 and later by various people +// Copyright (C) 2005, 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 @@ -77,13 +77,23 @@ struct netsync_connection_info void set_connection_successful(); + // dryrun output data size_t dryrun_incoming_revs; size_t dryrun_incoming_certs; size_t dryrun_incoming_keys; bool dryrun_incoming_keys_is_estimate; - std::set dryrun_outgoing_revs; size_t dryrun_outgoing_certs; size_t dryrun_outgoing_keys; + + // automate and dryrun output data + std::vector outgoing_revs; + + // automate output data + std::vector outgoing_certs; + std::vector outgoing_keys; + std::vector incoming_revs; + std::vector incoming_certs; + std::vector incoming_keys; } client; static void