You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdesvn/src/svnfrontend/commandexec.cpp

651 lines
21 KiB

/***************************************************************************
* Copyright (C) 2005-2007 by Rajko Albrecht *
* ral@alwins-world.de *
* *
* 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 2 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, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
#include "commandexec.h"
#include "tdesvnsettings.h"
#include "svnactions.h"
#include "dummydisplay.h"
#include "targets.hpp"
#include "url.hpp"
#include "dirent.hpp"
#include "sub2qt.h"
#include "ktranslateurl.h"
#include "sshagent.h"
#include "rangeinput_impl.h"
#include "copymoveview_impl.h"
#include <kapp.h>
#include <kglobal.h>
#include <kdebug.h>
#include <kmessagebox.h>
#include <kcmdlineargs.h>
#include <klocale.h>
#include <kdialogbase.h>
#include <ktextbrowser.h>
#include <tqfile.h>
#include <tqtextstream.h>
#include <tqvaluelist.h>
#include <tqvbox.h>
class pCPart
{
public:
pCPart();
~pCPart();
TQString cmd;
TQStringList url;
bool ask_revision;
bool rev_set;
bool outfile_set;
bool single_revision;
bool force;
int log_limit;
SvnActions*m_SvnWrapper;
KCmdLineArgs *args;
svn::Revision start,end;
// for output
TQFile toStdout,toStderr;
TQString outfile;
TQTextStream Stdout,Stderr;
DummyDisplay * disp;
TQMap<int,svn::Revision> extraRevisions;
TQMap<int,TQString> baseUrls;
};
pCPart::pCPart()
:cmd(""),url(),ask_revision(false),rev_set(false),outfile_set(false),single_revision(false),log_limit(0)
{
m_SvnWrapper = 0;
start = svn::Revision::UNDEFINED;
end = svn::Revision::UNDEFINED;
toStdout.open(IO_WriteOnly, stdout);
toStderr.open(IO_WriteOnly, stderr);
Stdout.setDevice(TQT_TQIODEVICE(&toStdout));
Stderr.setDevice(TQT_TQIODEVICE(&toStderr));
disp = new DummyDisplay();
m_SvnWrapper = new SvnActions(disp,0,true);
}
pCPart::~pCPart()
{
delete m_SvnWrapper;
delete disp;
}
CommandExec::CommandExec(TQObject*parent, const char *name,KCmdLineArgs *args)
: TQObject(parent,name)
{
m_pCPart = new pCPart;
m_pCPart->args = args;
SshAgent ag;
ag.querySshAgent();
connect(m_pCPart->m_SvnWrapper,TQT_SIGNAL(clientException(const TQString&)),this,TQT_SLOT(clientException(const TQString&)));
connect(m_pCPart->m_SvnWrapper,TQT_SIGNAL(sendNotify(const TQString&)),this,TQT_SLOT(slotNotifyMessage(const TQString&)));
m_pCPart->m_SvnWrapper->reInitClient();
}
CommandExec::~CommandExec()
{
delete m_pCPart;
}
int CommandExec::exec()
{
if (!m_pCPart->args) {
return -1;
}
m_lastMessages = "";
m_lastMessagesLines = 0;
m_pCPart->m_SvnWrapper->reInitClient();
bool dont_check_second = false;
bool dont_check_all = false;
bool path_only = false;
bool no_revision = false;
bool check_force=false;
if (m_pCPart->args->count()>=2) {
m_pCPart->cmd=m_pCPart->args->arg(1);
m_pCPart->cmd=m_pCPart->cmd.lower();
}
TQString slotCmd;
if (!TQString::compare(m_pCPart->cmd,"log")) {
slotCmd=TQT_SLOT(slotCmd_log());
} else if (!TQString::compare(m_pCPart->cmd,"cat")) {
slotCmd=TQT_SLOT(slotCmd_cat());
m_pCPart->single_revision=true;
} else if (!TQString::compare(m_pCPart->cmd,"get")) {
slotCmd=TQT_SLOT(slotCmd_get());
m_pCPart->single_revision=true;
} else if (!TQString::compare(m_pCPart->cmd,"help")) {
slotCmd=TQT_SLOT(slotCmd_help());
} else if (!TQString::compare(m_pCPart->cmd,"blame")||
!TQString::compare(m_pCPart->cmd,"annotate")) {
slotCmd=TQT_SLOT(slotCmd_blame());
} else if (!TQString::compare(m_pCPart->cmd,"update")) {
slotCmd=TQT_SLOT(slotCmd_update());
m_pCPart->single_revision=true;
} else if (!TQString::compare(m_pCPart->cmd,"diff")) {
m_pCPart->start = svn::Revision::WORKING;
slotCmd=TQT_SLOT(slotCmd_diff());
} else if (!TQString::compare(m_pCPart->cmd,"info")) {
slotCmd=TQT_SLOT(slotCmd_info());
m_pCPart->single_revision=true;
} else if (!TQString::compare(m_pCPart->cmd,"commit")||
!TQString::compare(m_pCPart->cmd,"ci")) {
slotCmd=TQT_SLOT(slotCmd_commit());
} else if (!TQString::compare(m_pCPart->cmd,"list")||
!TQString::compare(m_pCPart->cmd,"ls")) {
slotCmd=TQT_SLOT(slotCmd_list());
} else if (!TQString::compare(m_pCPart->cmd,"copy")||
!TQString::compare(m_pCPart->cmd,"cp")) {
slotCmd=TQT_SLOT(slotCmd_copy());
dont_check_second = true;
} else if (!TQString::compare(m_pCPart->cmd,"move")||
!TQString::compare(m_pCPart->cmd,"rename")||
!TQString::compare(m_pCPart->cmd,"mv")) {
slotCmd=TQT_SLOT(slotCmd_move());
dont_check_second = true;
} else if (!TQString::compare(m_pCPart->cmd,"checkout")||
!TQString::compare(m_pCPart->cmd,"co")) {
slotCmd=TQT_SLOT(slotCmd_checkout());
dont_check_second = true;
} else if (!TQString::compare(m_pCPart->cmd,"checkoutto")||
!TQString::compare(m_pCPart->cmd,"coto")) {
slotCmd=TQT_SLOT(slotCmd_checkoutto());
dont_check_second = true;
} else if (!TQString::compare(m_pCPart->cmd,"export")) {
slotCmd=TQT_SLOT(slotCmd_export());
dont_check_second = true;
} else if (!TQString::compare(m_pCPart->cmd,"exportto")) {
slotCmd=TQT_SLOT(slotCmd_exportto());
dont_check_second = true;
} else if (!TQString::compare(m_pCPart->cmd,"delete")||
!TQString::compare(m_pCPart->cmd,"del")||
!TQString::compare(m_pCPart->cmd,"rm")||
!TQString::compare(m_pCPart->cmd,"remove")) {
slotCmd=TQT_SLOT(slotCmd_delete());
} else if (!TQString::compare(m_pCPart->cmd,"add")) {
slotCmd=TQT_SLOT(slotCmd_add());
dont_check_all = true;
path_only=true;
} else if (!TQString::compare(m_pCPart->cmd,"undo")||
!TQString::compare(m_pCPart->cmd,"revert")) {
slotCmd=TQT_SLOT(slotCmd_revert());
} else if (!TQString::compare(m_pCPart->cmd,"checknew")||
!TQString::compare(m_pCPart->cmd,"addnew")) {
slotCmd=TQT_SLOT(slotCmd_addnew());
} else if (!TQString::compare(m_pCPart->cmd,"switch")) {
slotCmd=TQT_SLOT(slotCmd_switch());
} else if (!TQString::compare(m_pCPart->cmd,"tree")) {
slotCmd=TQT_SLOT(slotCmd_tree());
} else if (!TQString::compare(m_pCPart->cmd,"lock")) {
slotCmd=TQT_SLOT(slotCmd_lock());
no_revision = true;
check_force=true;
} else if (!TQString::compare(m_pCPart->cmd,"unlock")) {
slotCmd=TQT_SLOT(slotCmd_unlock());
no_revision=true;
check_force=true;
}
bool found = connect(this,TQT_SIGNAL(executeMe()),this,slotCmd.ascii());
if (!found) {
slotCmd=i18n("Command \"%1\" not implemented or known").tqarg(m_pCPart->cmd);
KMessageBox::sorry(0,slotCmd,i18n("SVN Error"));
return -1;
}
TQString tmp,query,proto,v;
TQMap<TQString,TQString> q;
KURL tmpurl;
TQString mainProto;
TQString _baseurl;
for (int j = 2; j<m_pCPart->args->count();++j) {
tmpurl = helpers::KTranslateUrl::translateSystemUrl(m_pCPart->args->url(j).prettyURL());
query = tmpurl.query();
q = m_pCPart->args->url(j).queryItems();
if (q.find("rev")!=q.end()) {
v = q["rev"];
} else {
v = "";
}
tmpurl.setProtocol(svn::Url::transformProtokoll(tmpurl.protocol()));
if (tmpurl.protocol().find("ssh")!=-1) {
SshAgent ag;
// this class itself checks if done before
ag.addSshIdentities();
}
m_pCPart->extraRevisions[j-2]=svn::Revision::HEAD;
if (tmpurl.isLocalFile() && (j==2 || !dont_check_second) && !dont_check_all) {
if (m_pCPart->m_SvnWrapper->isLocalWorkingCopy("file://"+tmpurl.path(),_baseurl)) {
tmp = tmpurl.path();
m_pCPart->baseUrls[j-2]=_baseurl;
m_pCPart->extraRevisions[j-2]=svn::Revision::WORKING;
if (j==2) mainProto = "";
} else {
tmp = "file://"+tmpurl.path();
if (j==2) mainProto = "file://";
}
} else if (path_only){
tmp = tmpurl.path();
} else {
tmp = tmpurl.url();
if (j==2) mainProto=tmpurl.protocol();
}
if ( (j>2 && dont_check_second) || dont_check_all) {
if (mainProto.isEmpty()) {
tmp = tmpurl.path();
}
}
TQStringList l = TQStringList::split('?',tmp);
if (l.count()>0) {
tmp=l[0];
}
while (tmp.endsWith("/")) {
tmp.truncate(tmp.length()-1);
}
m_pCPart->url.append(tmp);
if ( (j>2 && dont_check_second) || dont_check_all) {
continue;
}
svn::Revision re = v;
if (re) {
m_pCPart->extraRevisions[j-2]=re;
}
}
if (m_pCPart->url.count()==0) {
m_pCPart->url.append(".");
}
if (!no_revision)
{
if (m_pCPart->args->isSet("R"))
{
m_pCPart->ask_revision = true;
if (!askRevision())
{
return 0;
}
}
else if (m_pCPart->args->isSet("r"))
{
scanRevision();
}
}
m_pCPart->force=check_force && m_pCPart->args->isSet("f");
if (m_pCPart->args->isSet("o")) {
m_pCPart->outfile_set=true;
m_pCPart->outfile = m_pCPart->args->getOption("o");
}
if (m_pCPart->args->isSet("l")) {
TQString s = m_pCPart->args->getOption("l");
m_pCPart->log_limit = s.toInt();
if (m_pCPart->log_limit<0) {
m_pCPart->log_limit = 0;
}
}
emit executeMe();
if (Kdesvnsettings::self()->cmdline_show_logwindow() &&
m_lastMessagesLines >= Kdesvnsettings::self()->cmdline_log_minline()) {
KDialogBase dlg (
TQT_TQWIDGET(KApplication::activeModalWidget()),
"execution_log",
true,
i18n("Execution log"),
KDialogBase::Ok);
TQWidget* Dialog1Layout = dlg.makeVBoxMainWidget();
KTextBrowser*ptr = new KTextBrowser(Dialog1Layout);
ptr->setText(m_lastMessages);
dlg.resize(dlg.configDialogSize(*(Kdesvnsettings::self()->config()),"tdesvn_cmd_log"));
dlg.exec();
dlg.saveDialogSize(*(Kdesvnsettings::self()->config()),"tdesvn_cmd_log",false);
}
return 0;
}
/*!
\fn CommandExec::clientException(const TQString&)
*/
void CommandExec::clientException(const TQString&what)
{
m_pCPart->Stderr<<what<<endl;
KMessageBox::sorry(0,what,i18n("SVN Error"));
}
/*!
\fn CommandExec::slotCmdLog
*/
void CommandExec::slotCmd_log()
{
int limit = m_pCPart->log_limit;
if (m_pCPart->end == svn::Revision::UNDEFINED) {
m_pCPart->end = svn::Revision::HEAD;
limit = 0;
}
if (m_pCPart->start == svn::Revision::UNDEFINED) {
m_pCPart->start = 1;
limit = 0;
}
bool list = Kdesvnsettings::self()->log_always_list_changed_files();
if (m_pCPart->extraRevisions[0]==svn::Revision::WORKING) {
m_pCPart->extraRevisions[0]=svn::Revision::UNDEFINED;
}
m_pCPart->m_SvnWrapper->makeLog(m_pCPart->start,m_pCPart->end,m_pCPart->extraRevisions[0],m_pCPart->url[0],list,limit);
}
/*!
\fn CommandExec::slotCmdLog
*/
void CommandExec::slotCmd_tree()
{
if (m_pCPart->end == svn::Revision::UNDEFINED) {
m_pCPart->end = svn::Revision::HEAD;
}
if (m_pCPart->start == svn::Revision::UNDEFINED) {
m_pCPart->start = 1;
}
m_pCPart->m_SvnWrapper->makeTree(m_pCPart->url[0],m_pCPart->extraRevisions[0],m_pCPart->start,m_pCPart->end);
}
void CommandExec::slotCmd_checkout()
{
m_pCPart->m_SvnWrapper->CheckoutExport(m_pCPart->url[0],false);
}
void CommandExec::slotCmd_checkoutto()
{
m_pCPart->m_SvnWrapper->CheckoutExport(m_pCPart->url[0],false,true);
}
void CommandExec::slotCmd_export()
{
m_pCPart->m_SvnWrapper->CheckoutExport(m_pCPart->url[0],true);
}
void CommandExec::slotCmd_exportto()
{
m_pCPart->m_SvnWrapper->CheckoutExport(m_pCPart->url[0],true,true);
}
void CommandExec::slotCmd_blame()
{
if (!m_pCPart->end) {
m_pCPart->end = svn::Revision::HEAD;
}
if (!m_pCPart->start) {
m_pCPart->start = 1;
}
m_pCPart->m_SvnWrapper->makeBlame(m_pCPart->start,m_pCPart->end,m_pCPart->url[0]);
}
void CommandExec::slotCmd_cat()
{
if (m_pCPart->extraRevisions.find(0)!=m_pCPart->extraRevisions.end()) {
m_pCPart->rev_set=true;
m_pCPart->start=m_pCPart->extraRevisions[0];
} else {
m_pCPart->end = svn::Revision::HEAD;
}
m_pCPart->m_SvnWrapper->slotMakeCat(
(m_pCPart->rev_set?m_pCPart->start:m_pCPart->end),m_pCPart->url[0],m_pCPart->url[0]
,(m_pCPart->rev_set?m_pCPart->start:m_pCPart->end),0);
}
void CommandExec::slotCmd_get()
{
if (m_pCPart->extraRevisions.find(0)!=m_pCPart->extraRevisions.end()) {
m_pCPart->rev_set=true;
m_pCPart->start=m_pCPart->extraRevisions[0];
} else {
m_pCPart->end = svn::Revision::HEAD;
}
if (!m_pCPart->outfile_set || m_pCPart->outfile.isEmpty()) {
clientException(i18n("\"GET\" requires output file!"));
return;
}
m_pCPart->m_SvnWrapper->makeGet((m_pCPart->rev_set?m_pCPart->start:m_pCPart->end),m_pCPart->url[0], m_pCPart->outfile,
(m_pCPart->rev_set?m_pCPart->start:m_pCPart->end));
}
void CommandExec::slotCmd_update()
{
m_pCPart->m_SvnWrapper->makeUpdate(m_pCPart->url,
(m_pCPart->rev_set?m_pCPart->start:svn::Revision::HEAD),true);
}
void CommandExec::slotCmd_diff()
{
if (m_pCPart->url.count()==1) {
if (!m_pCPart->rev_set && !svn::Url::isValid(m_pCPart->url[0])) {
m_pCPart->start = svn::Revision::BASE;
m_pCPart->end = svn::Revision::WORKING;
}
m_pCPart->m_SvnWrapper->makeDiff(m_pCPart->url[0],m_pCPart->start,m_pCPart->url[0],m_pCPart->end);
} else {
svn::Revision r1 = svn::Revision::HEAD;
svn::Revision r2 = svn::Revision::HEAD;
if (m_pCPart->extraRevisions.find(0)!=m_pCPart->extraRevisions.end()) {
r1 = m_pCPart->extraRevisions[0];
} else if (!svn::Url::isValid(m_pCPart->url[0])) {
r1 = svn::Revision::WORKING;
}
if (m_pCPart->extraRevisions.find(1)!=m_pCPart->extraRevisions.end()) {
r2 = m_pCPart->extraRevisions[1];
} else if (!svn::Url::isValid(m_pCPart->url[1])) {
r2 = svn::Revision::WORKING;
}
m_pCPart->m_SvnWrapper->makeDiff(m_pCPart->url[0],r1,m_pCPart->url[1],r2);
}
}
void CommandExec::slotCmd_info()
{
if (m_pCPart->extraRevisions.find(0)!=m_pCPart->extraRevisions.end()) {
m_pCPart->rev_set=true;
m_pCPart->start=m_pCPart->extraRevisions[0];
}
m_pCPart->m_SvnWrapper->makeInfo(m_pCPart->url,(m_pCPart->rev_set?m_pCPart->start:m_pCPart->end),svn::Revision::UNDEFINED,false);
}
void CommandExec::slotCmd_commit()
{
TQValueList<svn::Path> targets;
for (unsigned j=0; j<m_pCPart->url.count();++j) {
targets.push_back(svn::Path(m_pCPart->url[j]));
}
m_pCPart->m_SvnWrapper->makeCommit(svn::Targets(targets));
}
void CommandExec::slotCmd_list()
{
svn::DirEntries res;
svn::Revision rev = m_pCPart->end;
if (m_pCPart->rev_set){
rev = m_pCPart->start;
} else if (m_pCPart->extraRevisions[0]) {
rev = m_pCPart->extraRevisions[0];
}
if (!m_pCPart->m_SvnWrapper->makeList(m_pCPart->url[0],res,rev,false)) {
return;
}
for (unsigned int i = 0; i < res.count();++i) {
TQString d = svn::DateTime(res[i]->time()).toString(TQString("yyyy-MM-dd hh:mm::ss"));
m_pCPart->Stdout
<< (res[i]->kind()==svn_node_dir?"D":"F")<<" "
<< d << " "
<< res[i]->name()<<endl;
}
}
void CommandExec::slotCmd_copy()
{
TQString target;
if (m_pCPart->url.count()<2) {
bool force_move,ok;
target = CopyMoveView_impl::getMoveCopyTo(&ok,&force_move,false,
m_pCPart->url[0],"",0,"move_name");
if (!ok) {
return;
}
} else {
target = m_pCPart->url[1];
}
if (m_pCPart->extraRevisions.find(0)!=m_pCPart->extraRevisions.end()) {
m_pCPart->rev_set=true;
m_pCPart->start=m_pCPart->extraRevisions[0];
} else {
m_pCPart->end = svn::Revision::HEAD;
}
m_pCPart->m_SvnWrapper->makeCopy(m_pCPart->url[0],target,(m_pCPart->rev_set?m_pCPart->start:m_pCPart->end));
}
void CommandExec::slotCmd_move()
{
bool force_move,ok;
force_move = false;
TQString target;
if (m_pCPart->url.count()<2) {
target = CopyMoveView_impl::getMoveCopyTo(&ok,&force_move,true,
m_pCPart->url[0],"",0,"move_name");
if (!ok) {
return;
}
} else {
target = m_pCPart->url[1];
}
m_pCPart->m_SvnWrapper->makeMove(m_pCPart->url[0],target,force_move);
}
void CommandExec::slotCmd_delete()
{
m_pCPart->m_SvnWrapper->makeDelete(m_pCPart->url);
}
void CommandExec::slotCmd_add()
{
m_pCPart->m_SvnWrapper->addItems(m_pCPart->url,svn::DepthInfinity);
}
void CommandExec::slotCmd_revert()
{
m_pCPart->m_SvnWrapper->slotRevertItems(m_pCPart->url);
}
void CommandExec::slotCmd_addnew()
{
m_pCPart->m_SvnWrapper->checkAddItems(m_pCPart->url[0]);
}
/*!
\fn CommandExec::scanRevision()
*/
bool CommandExec::scanRevision()
{
TQString revstring = m_pCPart->args->getOption("r");
TQStringList revl = TQStringList::split(":",revstring);
if (revl.count()==0) {
return false;
}
m_pCPart->start = revl[0];
if (revl.count()>1) {
m_pCPart->end = revl[1];
}
m_pCPart->rev_set=true;
return true;
}
void CommandExec::slotNotifyMessage(const TQString&msg)
{
m_pCPart->m_SvnWrapper->slotExtraLogMsg(msg);
if (Kdesvnsettings::self()->cmdline_show_logwindow()) {
++m_lastMessagesLines;
if (!m_lastMessages.isEmpty()) m_lastMessages.append("\n");
m_lastMessages.append(msg);
}
}
bool CommandExec::askRevision()
{
TQString _head = m_pCPart->cmd+" - Revision";
KDialogBase dlg(
0,
"Revisiondlg",
true,
_head,
KDialogBase::Ok|KDialogBase::Cancel);
TQWidget* Dialog1Layout = dlg.makeVBoxMainWidget();
Rangeinput_impl*rdlg;
rdlg = new Rangeinput_impl(Dialog1Layout);
dlg.resize( TQSize(120,60).expandedTo(dlg.tqminimumSizeHint()));
rdlg->setStartOnly(m_pCPart->single_revision);
if (dlg.exec()==TQDialog::Accepted) {
Rangeinput_impl::revision_range range = rdlg->getRange();
m_pCPart->start = range.first;
m_pCPart->end = range.second;
m_pCPart->rev_set = true;
return true;
}
return false;
}
/*!
\fn CommandExec::slotCmd_switch()
*/
void CommandExec::slotCmd_switch()
{
TQString base;
if (m_pCPart->url.count()>1) {
clientException(i18n("May only switch one url at time!"));
return;
}
if (m_pCPart->baseUrls.find(0)==m_pCPart->baseUrls.end()) {
clientException(i18n("Switch only on working copies!"));
return;
}
base = m_pCPart->baseUrls[0];
m_pCPart->m_SvnWrapper->makeSwitch(m_pCPart->url[0],base);
}
void CommandExec::slotCmd_lock()
{
m_pCPart->m_SvnWrapper->makeLock(m_pCPart->url[0],"",m_pCPart->force);
}
void CommandExec::slotCmd_unlock()
{
m_pCPart->m_SvnWrapper->makeUnlock(m_pCPart->url[0],m_pCPart->force);
}
#include "commandexec.moc"