//
// 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 :