// // aegis - project change supervisor // Copyright (C) 2014 Walter Franzini // Copyright (C) 2014 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or (at // your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License along // with this program. If not, see . // #include #include #include #include #include change_functor_export::~change_functor_export() { } change_functor_export::change_functor_export( bool arg1, output::pointer arg2, nstring arg3 ) : change_functor(arg1), ofp(arg2), ref(arg3) { } void change_functor_export::one_more_file(const change::pointer &cp, fstate_src_ty *src) { switch (src->action) { case file_action_remove: if (src->move) return; ofp->fprintf("D %s\n", src->file_name->str_text); break; case file_action_create: if (src->move) { ofp->fprintf("C %s %s\n", src->move->str_text, src->file_name->str_text); ofp->fprintf("D %s\n", src->move->str_text); } // FALLTHROUGH case file_action_modify: { ofp->fprintf("M %s inline %s\n", src->executable ? "100755" : "100644", src->file_name->str_text); bool need_to_unlink = false; string_ty *file_path = cp->file_version_path(src, need_to_unlink); trace(("file_path = \"%s\";\n", file_path->str_text)); trace(("need_to_unlink = %d;\n", need_to_unlink)); os_become_orig(); ofp->fprintf("data %ld\n", os_file_size(file_path)); input::pointer ifp = input_file::open(nstring(file_path), false); ofp << ifp; ofp->fputs("\n"); if (need_to_unlink) os_unlink(file_path); os_become_undo(); break; } case file_action_transparent: case file_action_insulate: break; } } void change_functor_export::operator()(const change::pointer &cp) { ofp->fprintf("# change: %s\n", cp->version_get().c_str()); // todo: map outstanding changes to stash. if (!cp->is_completed()) return; cstate_ty *cstate_src = cp->cstate_get(); ofp->fprintf("commit %s\n", ref.c_str()); user_ty::pointer author; user_ty::pointer committer; time_t when_develop_end; time_t when_completed; for (size_t i = 0; i < cstate_src->history->length; ++i) { cstate_history_ty *event = cstate_src->history->list[i]; switch (event->what) { case cstate_history_what_develop_end: case cstate_history_what_develop_end_2ar: case cstate_history_what_develop_end_2ai: author = user_ty::create(nstring(event->who)); when_develop_end = event->when; break; case cstate_history_what_integrate_pass: committer = user_ty::create(nstring(event->who)); when_completed = event->when; break; case cstate_history_what_new_change: case cstate_history_what_develop_begin: case cstate_history_what_develop_begin_undo: case cstate_history_what_develop_end_undo: case cstate_history_what_review_begin: case cstate_history_what_review_begin_undo: case cstate_history_what_review_pass: case cstate_history_what_review_pass_2ar: case cstate_history_what_review_pass_2br: case cstate_history_what_review_pass_undo: case cstate_history_what_review_pass_undo_2ar: case cstate_history_what_review_fail: case cstate_history_what_integrate_begin: case cstate_history_what_integrate_begin_undo: case cstate_history_what_integrate_fail: continue; } } // // TODO: retrieve the author from Signed-off-by lines in the // change description. // ofp->fprintf("author %s %ld +0000\n", author->get_email_address().c_str(), when_develop_end); ofp->fprintf("committer %s %ld +0000\n", committer->get_email_address().c_str(), when_completed); // FIXME: what if the description inclues a "data %ld\n" line? // It seems odd that there is no length indicator, like "data" has. nstring commit_message = nstring::format("%s\n%s\n", cp->brief_description_get().c_str(), cp->description_get().c_str()); ofp->fprintf("data %ld\n", commit_message.length()); ofp << commit_message; for (size_t count = 0; ; ++count) { fstate_src_ty * fstate_src = change_file_nth(cp, count, view_path_first); if (!fstate_src) break; one_more_file(cp, fstate_src); } ofp->fputs("\n"); } // vim: set ts=8 sw=4 et :