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.
1009 lines
26 KiB
1009 lines
26 KiB
/*
|
|
* Copyright (c) 2002-2004 Christian Loose <christian.loose@kdemail.net>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Library 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
|
|
* Library General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public License
|
|
* along with this program; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#include "cvsservice.h"
|
|
|
|
#include <tqintdict.h>
|
|
#include <tqstring.h>
|
|
|
|
#include <dcopref.h>
|
|
#include <dcopclient.h>
|
|
#include <kapplication.h>
|
|
#include <kconfig.h>
|
|
#include <klocale.h>
|
|
#include <kmessagebox.h>
|
|
#include <kprocess.h>
|
|
|
|
#include "cvsjob.h"
|
|
#include "cvsloginjob.h"
|
|
#include "cvsserviceutils.h"
|
|
#include "repository.h"
|
|
#include "sshagent.h"
|
|
|
|
|
|
static const char SINGLE_JOB_ID[] = "NonConcurrentJob";
|
|
static const char REDIRECT_STDERR[] = "2>&1";
|
|
|
|
enum WatchEvents { None=0, All=1, Commits=2, Edits=4, Unedits=8 };
|
|
|
|
struct CvsService::Private
|
|
{
|
|
Private() : singleCvsJob(0), lastJobId(0), repository(0) {}
|
|
~Private()
|
|
{
|
|
delete repository;
|
|
delete singleCvsJob;
|
|
}
|
|
|
|
CvsJob* singleCvsJob; // non-concurrent cvs job, like update or commit
|
|
DCOPRef singleJobRef; // DCOP reference to non-concurrent cvs job
|
|
TQIntDict<CvsJob> cvsJobs; // concurrent cvs jobs, like diff or annotate
|
|
TQIntDict<CvsLoginJob> loginJobs;
|
|
unsigned lastJobId;
|
|
|
|
TQCString appId; // cache the DCOP clients app id
|
|
|
|
Repository* repository;
|
|
|
|
CvsJob* createCvsJob();
|
|
DCOPRef setupNonConcurrentJob(Repository* repo = 0);
|
|
|
|
bool hasWorkingCopy();
|
|
bool hasRunningJob();
|
|
};
|
|
|
|
|
|
CvsService::CvsService()
|
|
: DCOPObject("CvsService")
|
|
, d(new Private)
|
|
{
|
|
d->appId = kapp->dcopClient()->appId();
|
|
|
|
// create non-concurrent cvs job
|
|
d->singleCvsJob = new CvsJob(SINGLE_JOB_ID);
|
|
d->singleJobRef.setRef(d->appId, d->singleCvsJob->objId());
|
|
|
|
// create repository manager
|
|
d->repository = new Repository();
|
|
|
|
d->cvsJobs.setAutoDelete(true);
|
|
d->loginJobs.setAutoDelete(true);
|
|
|
|
KConfig* config = kapp->config();
|
|
KConfigGroupSaver cs(config, "General");
|
|
if( config->readBoolEntry("UseSshAgent", false) )
|
|
{
|
|
// use the existing or start a new ssh-agent
|
|
SshAgent ssh;
|
|
// TODO CL do we need the return value?
|
|
//bool res = ssh.querySshAgent();
|
|
ssh.querySshAgent();
|
|
}
|
|
}
|
|
|
|
|
|
CvsService::~CvsService()
|
|
{
|
|
// kill the ssh-agent (when we started it)
|
|
SshAgent ssh;
|
|
ssh.killSshAgent();
|
|
|
|
d->cvsJobs.clear();
|
|
d->loginJobs.clear();
|
|
delete d;
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::add(const TQStringList& files, bool isBinary)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// cvs add [-kb] [FILES]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "add";
|
|
|
|
if( isBinary )
|
|
*d->singleCvsJob << "-kb";
|
|
|
|
*d->singleCvsJob << CvsServiceUtils::joinFileList(files) << REDIRECT_STDERR;
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::addWatch(const TQStringList& files, int events)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "watch add";
|
|
|
|
if( events != All )
|
|
{
|
|
if( events & Commits )
|
|
*d->singleCvsJob << "-a commit";
|
|
if( events & Edits )
|
|
*d->singleCvsJob << "-a edit";
|
|
if( events & Unedits )
|
|
*d->singleCvsJob << "-a unedit";
|
|
}
|
|
|
|
*d->singleCvsJob << CvsServiceUtils::joinFileList(files);
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::annotate(const TQString& fileName, const TQString& revision)
|
|
{
|
|
if( !d->hasWorkingCopy() )
|
|
return DCOPRef();
|
|
|
|
// create a cvs job
|
|
CvsJob* job = d->createCvsJob();
|
|
|
|
// assemble the command line
|
|
// (cvs log [FILE] && cvs annotate [-r rev] [FILE])
|
|
TQString quotedName = KProcess::quote(fileName);
|
|
TQString cvsClient = d->repository->cvsClient();
|
|
|
|
*job << "(" << cvsClient << "log" << quotedName << "&&"
|
|
<< cvsClient << "annotate";
|
|
|
|
if( !revision.isEmpty() )
|
|
*job << "-r" << revision;
|
|
|
|
// *Hack*
|
|
// because the string "Annotations for blabla" is
|
|
// printed to stderr even with option -Q.
|
|
*job << quotedName << ")" << REDIRECT_STDERR;
|
|
|
|
// return a DCOP reference to the cvs job
|
|
return DCOPRef(d->appId, job->objId());
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::checkout(const TQString& workingDir, const TQString& repository,
|
|
const TQString& module, const TQString& tag,
|
|
bool pruneDirs)
|
|
{
|
|
if( d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
Repository repo(repository);
|
|
|
|
// assemble the command line
|
|
// cd [DIRECTORY] && cvs -d [REPOSITORY] checkout [-r tag] [-P] [MODULE]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << "cd" << KProcess::quote(workingDir) << "&&"
|
|
<< repo.cvsClient()
|
|
<< "-d" << repository
|
|
<< "checkout";
|
|
|
|
if( !tag.isEmpty() )
|
|
*d->singleCvsJob << "-r" << tag;
|
|
|
|
if( pruneDirs )
|
|
*d->singleCvsJob << "-P";
|
|
|
|
*d->singleCvsJob << module;
|
|
|
|
return d->setupNonConcurrentJob(&repo);
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::checkout(const TQString& workingDir, const TQString& repository,
|
|
const TQString& module, const TQString& tag,
|
|
bool pruneDirs, const TQString& alias, bool exportOnly)
|
|
{
|
|
if( d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
Repository repo(repository);
|
|
|
|
// assemble the command line
|
|
// cd [DIRECTORY] && cvs -d [REPOSITORY] co [-r tag] [-P] [-d alias] [MODULE]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << "cd" << KProcess::quote(workingDir) << "&&"
|
|
<< repo.cvsClient()
|
|
<< "-d" << repository;
|
|
if( exportOnly)
|
|
*d->singleCvsJob << "export";
|
|
else
|
|
*d->singleCvsJob << "checkout";
|
|
|
|
if( !tag.isEmpty() )
|
|
*d->singleCvsJob << "-r" << tag;
|
|
|
|
if( pruneDirs && !exportOnly )
|
|
*d->singleCvsJob << "-P";
|
|
|
|
if( !alias.isEmpty() )
|
|
*d->singleCvsJob << "-d" << alias;
|
|
|
|
*d->singleCvsJob << module;
|
|
|
|
return d->setupNonConcurrentJob(&repo);
|
|
}
|
|
|
|
DCOPRef CvsService::checkout(const TQString& workingDir, const TQString& repository,
|
|
const TQString& module, const TQString& tag,
|
|
bool pruneDirs, const TQString& alias, bool exportOnly,
|
|
bool recursive)
|
|
{
|
|
if( d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
Repository repo(repository);
|
|
|
|
// assemble the command line
|
|
// cd [DIRECTORY] && cvs -d [REPOSITORY] co [-r tag] [-P] [-d alias] [MODULE]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << "cd" << KProcess::quote(workingDir) << "&&"
|
|
<< repo.cvsClient()
|
|
<< "-d" << repository;
|
|
if( exportOnly)
|
|
*d->singleCvsJob << "export";
|
|
else
|
|
*d->singleCvsJob << "checkout";
|
|
|
|
if( !tag.isEmpty() )
|
|
*d->singleCvsJob << "-r" << tag;
|
|
|
|
if( pruneDirs && !exportOnly )
|
|
*d->singleCvsJob << "-P";
|
|
|
|
if( !alias.isEmpty() )
|
|
*d->singleCvsJob << "-d" << alias;
|
|
|
|
if( ! recursive )
|
|
*d->singleCvsJob << "-l";
|
|
|
|
*d->singleCvsJob << module;
|
|
|
|
return d->setupNonConcurrentJob(&repo);
|
|
}
|
|
|
|
DCOPRef CvsService::commit(const TQStringList& files, const TQString& commitMessage,
|
|
bool recursive)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// cvs commit [-l] [-m MESSAGE] [FILES]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "commit";
|
|
|
|
if( !recursive )
|
|
*d->singleCvsJob << "-l";
|
|
|
|
*d->singleCvsJob << "-m" << KProcess::quote(commitMessage)
|
|
<< CvsServiceUtils::joinFileList(files) << REDIRECT_STDERR;
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::createRepository(const TQString& repository)
|
|
{
|
|
if( d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// cvs -d [REPOSITORY] init
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << "mkdir -p" << KProcess::quote(repository) << "&&"
|
|
<< d->repository->cvsClient()
|
|
<< "-d" << KProcess::quote(repository)
|
|
<< "init";
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::createTag(const TQStringList& files, const TQString& tag,
|
|
bool branch, bool force)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// cvs tag [-b] [-F] [TAG] [FILES]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "tag";
|
|
|
|
if( branch )
|
|
*d->singleCvsJob << "-b";
|
|
|
|
if( force )
|
|
*d->singleCvsJob << "-F";
|
|
|
|
*d->singleCvsJob << KProcess::quote(tag)
|
|
<< CvsServiceUtils::joinFileList(files);
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::deleteTag(const TQStringList& files, const TQString& tag,
|
|
bool branch, bool force)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// cvs tag -d [-b] [-F] [TAG] [FILES]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "tag" << "-d";
|
|
|
|
if( branch )
|
|
*d->singleCvsJob << "-b";
|
|
|
|
if( force )
|
|
*d->singleCvsJob << "-F";
|
|
|
|
*d->singleCvsJob << KProcess::quote(tag)
|
|
<< CvsServiceUtils::joinFileList(files);
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::downloadCvsIgnoreFile(const TQString& repository,
|
|
const TQString& outputFile)
|
|
{
|
|
Repository repo(repository);
|
|
|
|
// create a cvs job
|
|
CvsJob* job = d->createCvsJob();
|
|
|
|
// assemble the command line
|
|
// cvs -d [REPOSITORY] -q checkout -p CVSROOT/cvsignore > [OUTPUTFILE]
|
|
*job << repo.cvsClient() << "-d" << repository
|
|
<< "-q checkout -p CVSROOT/cvsignore >"
|
|
<< KProcess::quote(outputFile);
|
|
|
|
// return a DCOP reference to the cvs job
|
|
return DCOPRef(d->appId, job->objId());
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::downloadRevision(const TQString& fileName,
|
|
const TQString& revision,
|
|
const TQString& outputFile)
|
|
{
|
|
if( !d->hasWorkingCopy() )
|
|
return DCOPRef();
|
|
|
|
// create a cvs job
|
|
CvsJob* job = d->createCvsJob();
|
|
|
|
// assemble the command line
|
|
// cvs update -p -r [REV] [FILE] > [OUTPUTFILE]
|
|
*job << d->repository->cvsClient() << "update -p";
|
|
|
|
if( !revision.isEmpty() )
|
|
*job << "-r" << KProcess::quote(revision);
|
|
|
|
*job << KProcess::quote(fileName) << ">" << KProcess::quote(outputFile);
|
|
|
|
// return a DCOP reference to the cvs job
|
|
return DCOPRef(d->appId, job->objId());
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::downloadRevision(const TQString& fileName,
|
|
const TQString& revA,
|
|
const TQString& outputFileA,
|
|
const TQString& revB,
|
|
const TQString& outputFileB)
|
|
{
|
|
if( !d->hasWorkingCopy() )
|
|
return DCOPRef();
|
|
|
|
// create a cvs job
|
|
CvsJob* job = d->createCvsJob();
|
|
|
|
// assemble the command line
|
|
// cvs update -p -r [REVA] [FILE] > [OUTPUTFILEA] ;
|
|
// cvs update -p -r [REVB] [FILE] > [OUTPUTFILEB]
|
|
*job << d->repository->cvsClient() << "update -p"
|
|
<< "-r" << KProcess::quote(revA)
|
|
<< KProcess::quote(fileName) << ">" << KProcess::quote(outputFileA)
|
|
<< ";" << d->repository->cvsClient() << "update -p"
|
|
<< "-r" << KProcess::quote(revB)
|
|
<< KProcess::quote(fileName) << ">" << KProcess::quote(outputFileB);
|
|
|
|
// return a DCOP reference to the cvs job
|
|
return DCOPRef(d->appId, job->objId());
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::diff(const TQString& fileName, const TQString& revA,
|
|
const TQString& revB, const TQString& diffOptions,
|
|
unsigned contextLines)
|
|
{
|
|
// cvs diff [DIFFOPTIONS] -U CONTEXTLINES [-r REVA] {-r REVB] [FILE]
|
|
TQString format = "-U" + TQString::number(contextLines);
|
|
return diff(fileName, revA, revB, diffOptions, format);
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::diff(const TQString& fileName, const TQString& revA,
|
|
const TQString& revB, const TQString& diffOptions,
|
|
const TQString& format)
|
|
{
|
|
if( !d->hasWorkingCopy() )
|
|
return DCOPRef();
|
|
|
|
// create a cvs job
|
|
CvsJob* job = d->createCvsJob();
|
|
|
|
// assemble the command line
|
|
// cvs diff [DIFFOPTIONS] [FORMAT] [-r REVA] {-r REVB] [FILE]
|
|
*job << d->repository->cvsClient() << "diff" << diffOptions
|
|
<< format;
|
|
|
|
if( !revA.isEmpty() )
|
|
*job << "-r" << KProcess::quote(revA);
|
|
|
|
if( !revB.isEmpty() )
|
|
*job << "-r" << KProcess::quote(revB);
|
|
|
|
*job << KProcess::quote(fileName);
|
|
|
|
// return a DCOP reference to the cvs job
|
|
return DCOPRef(d->appId, job->objId());
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::edit(const TQStringList& files)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// cvs edit [FILES]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "edit"
|
|
<< CvsServiceUtils::joinFileList(files);
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::editors(const TQStringList& files)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// cvs editors [FILES]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "editors"
|
|
<< CvsServiceUtils::joinFileList(files);
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::history()
|
|
{
|
|
if( !d->hasWorkingCopy() )
|
|
return DCOPRef();
|
|
|
|
// create a cvs job
|
|
CvsJob* job = d->createCvsJob();
|
|
|
|
// assemble the command line
|
|
// cvs history -e -a
|
|
*job << d->repository->cvsClient() << "history -e -a";
|
|
|
|
// return a DCOP reference to the cvs job
|
|
return DCOPRef(d->appId, job->objId());
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::import(const TQString& workingDir, const TQString& repository,
|
|
const TQString& module, const TQString& ignoreList,
|
|
const TQString& comment, const TQString& vendorTag,
|
|
const TQString& releaseTag, bool importAsBinary)
|
|
{
|
|
if( d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
Repository repo(repository);
|
|
|
|
// assemble the command line
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << "cd" << KProcess::quote(workingDir) << "&&"
|
|
<< repo.cvsClient()
|
|
<< "-d" << repository
|
|
<< "import";
|
|
|
|
if( importAsBinary )
|
|
*d->singleCvsJob << "-kb";
|
|
|
|
const TQString ignore = ignoreList.stripWhiteSpace();
|
|
if( !ignore.isEmpty() )
|
|
*d->singleCvsJob << "-I" << KProcess::quote(ignore);
|
|
|
|
TQString logMessage = comment.stripWhiteSpace();
|
|
logMessage.prepend("\"");
|
|
logMessage.append("\"");
|
|
*d->singleCvsJob << "-m" << logMessage;
|
|
|
|
*d->singleCvsJob << module << vendorTag << releaseTag;
|
|
|
|
return d->setupNonConcurrentJob(&repo);
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::import(const TQString& workingDir, const TQString& repository,
|
|
const TQString& module, const TQString& ignoreList,
|
|
const TQString& comment, const TQString& vendorTag,
|
|
const TQString& releaseTag, bool importAsBinary,
|
|
bool useModificationTime)
|
|
{
|
|
if( d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
Repository repo(repository);
|
|
|
|
// assemble the command line
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << "cd" << KProcess::quote(workingDir) << "&&"
|
|
<< repo.cvsClient()
|
|
<< "-d" << repository
|
|
<< "import";
|
|
|
|
if( importAsBinary )
|
|
*d->singleCvsJob << "-kb";
|
|
|
|
if( useModificationTime )
|
|
*d->singleCvsJob << "-d";
|
|
|
|
const TQString ignore = ignoreList.stripWhiteSpace();
|
|
if( !ignore.isEmpty() )
|
|
*d->singleCvsJob << "-I" << KProcess::quote(ignore);
|
|
|
|
TQString logMessage = comment.stripWhiteSpace();
|
|
logMessage.prepend("\"");
|
|
logMessage.append("\"");
|
|
*d->singleCvsJob << "-m" << logMessage;
|
|
|
|
*d->singleCvsJob << module << vendorTag << releaseTag;
|
|
|
|
return d->setupNonConcurrentJob(&repo);
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::lock(const TQStringList& files)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// cvs admin -l [FILES]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "admin -l"
|
|
<< CvsServiceUtils::joinFileList(files);
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::log(const TQString& fileName)
|
|
{
|
|
if( !d->hasWorkingCopy() )
|
|
return DCOPRef();
|
|
|
|
// create a cvs job
|
|
CvsJob* job = d->createCvsJob();
|
|
|
|
// assemble the command line
|
|
// cvs log [FILE]
|
|
*job << d->repository->cvsClient() << "log" << KProcess::quote(fileName);
|
|
|
|
// return a DCOP reference to the cvs job
|
|
return DCOPRef(d->appId, job->objId());
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::login(const TQString& repository)
|
|
{
|
|
if( repository.isEmpty() )
|
|
return DCOPRef();
|
|
|
|
Repository repo(repository);
|
|
|
|
// create a cvs job
|
|
++(d->lastJobId);
|
|
|
|
CvsLoginJob* job = new CvsLoginJob(d->lastJobId);
|
|
d->loginJobs.insert(d->lastJobId, job);
|
|
|
|
// TODO: CVS_SERVER doesn't work ATM
|
|
// job->setServer(repo.server());
|
|
|
|
// assemble the command line
|
|
// cvs -d [REPOSITORY] login
|
|
job->setCvsClient(repo.clientOnly().local8Bit());
|
|
job->setRepository(repository.local8Bit());
|
|
|
|
// return a DCOP reference to the cvs job
|
|
return DCOPRef(d->appId, job->objId());
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::logout(const TQString& repository)
|
|
{
|
|
if( repository.isEmpty() )
|
|
return DCOPRef();
|
|
|
|
Repository repo(repository);
|
|
|
|
// create a cvs job
|
|
++(d->lastJobId);
|
|
|
|
CvsJob* job = new CvsJob(d->lastJobId);
|
|
d->cvsJobs.insert(d->lastJobId, job);
|
|
|
|
job->setRSH(repo.rsh());
|
|
job->setServer(repo.server());
|
|
job->setDirectory(repo.workingCopy());
|
|
|
|
// assemble the command line
|
|
// cvs -d [REPOSITORY] logout
|
|
*job << repo.cvsClient() << "-d" << repository << "logout";
|
|
|
|
// return a DCOP reference to the cvs job
|
|
return DCOPRef(d->appId, job->objId());
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::makePatch()
|
|
{
|
|
return makePatch("", "-u");
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::makePatch(const TQString& diffOptions, const TQString& format)
|
|
{
|
|
if( !d->hasWorkingCopy() )
|
|
return DCOPRef();
|
|
|
|
// create a cvs job
|
|
CvsJob* job = d->createCvsJob();
|
|
|
|
// assemble the command line
|
|
// cvs diff [DIFFOPTIONS] [FORMAT] -R 2>/dev/null
|
|
*job << d->repository->cvsClient() << "diff" << diffOptions << format << "-R"
|
|
<< "2>/dev/null";
|
|
|
|
// return a DCOP reference to the cvs job
|
|
return DCOPRef(d->appId, job->objId());
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::moduleList(const TQString& repository)
|
|
{
|
|
Repository repo(repository);
|
|
|
|
// create a cvs job
|
|
++(d->lastJobId);
|
|
|
|
CvsJob* job = new CvsJob(d->lastJobId);
|
|
d->cvsJobs.insert(d->lastJobId, job);
|
|
|
|
job->setRSH(repo.rsh());
|
|
job->setServer(repo.server());
|
|
job->setDirectory(repo.workingCopy());
|
|
|
|
// assemble the command line
|
|
// cvs -d [REPOSITORY] checkout -c
|
|
*job << repo.cvsClient() << "-d" << repository << "checkout -c";
|
|
|
|
// return a DCOP reference to the cvs job
|
|
return DCOPRef(d->appId, job->objId());
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::remove(const TQStringList& files, bool recursive)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// cvs remove -f [-l] [FILES]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "remove -f";
|
|
|
|
if( !recursive )
|
|
*d->singleCvsJob << "-l";
|
|
|
|
*d->singleCvsJob << CvsServiceUtils::joinFileList(files) << REDIRECT_STDERR;
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::removeWatch(const TQStringList& files, int events)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "watch remove";
|
|
|
|
if( events != All )
|
|
{
|
|
if( events & Commits )
|
|
*d->singleCvsJob << "-a commit";
|
|
if( events & Edits )
|
|
*d->singleCvsJob << "-a edit";
|
|
if( events & Unedits )
|
|
*d->singleCvsJob << "-a unedit";
|
|
}
|
|
|
|
*d->singleCvsJob << CvsServiceUtils::joinFileList(files);
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::rlog(const TQString& repository, const TQString& module,
|
|
bool recursive)
|
|
{
|
|
Repository repo(repository);
|
|
|
|
// create a cvs job
|
|
++(d->lastJobId);
|
|
|
|
CvsJob* job = new CvsJob(d->lastJobId);
|
|
d->cvsJobs.insert(d->lastJobId, job);
|
|
|
|
job->setRSH(repo.rsh());
|
|
job->setServer(repo.server());
|
|
|
|
// assemble the command line
|
|
// cvs -d [REPOSITORY] rlog [-l] [MODULE]
|
|
*job << repo.cvsClient() << "-d" << repository << "rlog";
|
|
|
|
if( !recursive )
|
|
*job << "-l";
|
|
|
|
*job << module;
|
|
|
|
// return a DCOP reference to the cvs job
|
|
return DCOPRef(d->appId, job->objId());
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::simulateUpdate(const TQStringList& files, bool recursive,
|
|
bool createDirs, bool pruneDirs)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// cvs -n update [-l] [-d] [-P] [FILES]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "-n -q update";
|
|
|
|
if( !recursive )
|
|
*d->singleCvsJob << "-l";
|
|
|
|
if( createDirs )
|
|
*d->singleCvsJob << "-d";
|
|
|
|
if( pruneDirs )
|
|
*d->singleCvsJob << "-P";
|
|
|
|
*d->singleCvsJob << CvsServiceUtils::joinFileList(files) << REDIRECT_STDERR;
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::status(const TQStringList& files, bool recursive, bool tagInfo)
|
|
{
|
|
if( !d->hasWorkingCopy() )
|
|
return DCOPRef();
|
|
|
|
// create a cvs job
|
|
CvsJob* job = d->createCvsJob();
|
|
|
|
// assemble the command line
|
|
// cvs status [-l] [-v] [FILES]
|
|
*job << d->repository->cvsClient() << "status";
|
|
|
|
if( !recursive )
|
|
*job << "-l";
|
|
|
|
if( tagInfo )
|
|
*job << "-v";
|
|
|
|
*job << CvsServiceUtils::joinFileList(files);
|
|
|
|
// return a DCOP reference to the cvs job
|
|
return DCOPRef(d->appId, job->objId());
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::unedit(const TQStringList& files)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// echo y | cvs unedit [FILES]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << "echo y |"
|
|
<< d->repository->cvsClient() << "unedit"
|
|
<< CvsServiceUtils::joinFileList(files);
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::unlock(const TQStringList& files)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// cvs admin -u [FILES]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "admin -u"
|
|
<< CvsServiceUtils::joinFileList(files);
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::update(const TQStringList& files, bool recursive,
|
|
bool createDirs, bool pruneDirs, const TQString& extraOpt)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// cvs update [-l] [-d] [-P] [EXTRAOPTIONS] [FILES]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "-q update";
|
|
|
|
if( !recursive )
|
|
*d->singleCvsJob << "-l";
|
|
|
|
if( createDirs )
|
|
*d->singleCvsJob << "-d";
|
|
|
|
if( pruneDirs )
|
|
*d->singleCvsJob << "-P";
|
|
|
|
*d->singleCvsJob << extraOpt << CvsServiceUtils::joinFileList(files)
|
|
<< REDIRECT_STDERR;
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::watchers(const TQStringList& files)
|
|
{
|
|
if( !d->hasWorkingCopy() || d->hasRunningJob() )
|
|
return DCOPRef();
|
|
|
|
// assemble the command line
|
|
// cvs watchers [FILES]
|
|
d->singleCvsJob->clearCvsCommand();
|
|
|
|
*d->singleCvsJob << d->repository->cvsClient() << "watchers"
|
|
<< CvsServiceUtils::joinFileList(files);
|
|
|
|
return d->setupNonConcurrentJob();
|
|
}
|
|
|
|
|
|
void CvsService::quit()
|
|
{
|
|
kapp->quit();
|
|
}
|
|
|
|
|
|
CvsJob* CvsService::Private::createCvsJob()
|
|
{
|
|
++lastJobId;
|
|
|
|
// create a cvs job
|
|
CvsJob* job = new CvsJob(lastJobId);
|
|
cvsJobs.insert(lastJobId, job);
|
|
|
|
job->setRSH(repository->rsh());
|
|
job->setServer(repository->server());
|
|
job->setDirectory(repository->workingCopy());
|
|
|
|
return job;
|
|
}
|
|
|
|
|
|
DCOPRef CvsService::Private::setupNonConcurrentJob(Repository* repo)
|
|
{
|
|
// no explicit repository provided?
|
|
if( !repo )
|
|
repo = repository;
|
|
|
|
singleCvsJob->setRSH(repo->rsh());
|
|
singleCvsJob->setServer(repo->server());
|
|
singleCvsJob->setDirectory(repo->workingCopy());
|
|
|
|
return singleJobRef;
|
|
}
|
|
|
|
|
|
bool CvsService::Private::hasWorkingCopy()
|
|
{
|
|
if( repository->workingCopy().isEmpty() )
|
|
{
|
|
KMessageBox::sorry(0, i18n("You have to set a local working copy "
|
|
"directory before you can use this function!"));
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CvsService::Private::hasRunningJob()
|
|
{
|
|
bool result = singleCvsJob->isRunning();
|
|
|
|
if( result )
|
|
KMessageBox::sorry(0, i18n("There is already a job running"));
|
|
|
|
return result;
|
|
}
|