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.
tdesdk/cervisia/cvsservice/repository.cpp

267 lines
6.8 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 "repository.h"
#include <tqdir.h>
#include <tqfile.h>
#include <tqstring.h>
#include <kapplication.h>
#include <kconfig.h>
#include <kdirwatch.h>
#include <kstandarddirs.h>
#include "sshagent.h"
struct Repository::Private
{
Private() : compressionLevel(0) {}
TQString configFileName;
TQString workingCopy;
TQString location;
TQString client;
TQString rsh;
TQString server;
int compressionLevel;
bool retrieveCvsignoreFile;
void readConfig();
void readGeneralConfig();
};
Repository::Repository()
: TQObject()
, DCOPObject("CvsRepository")
, d(new Private)
{
d->readGeneralConfig();
// other cvsservice instances might change the configuration file
// so we watch it for changes
d->configFileName = locate("config", "cvsservicerc");
KDirWatch* fileWatcher = new KDirWatch(this);
connect(fileWatcher, TQT_SIGNAL(dirty(const TQString&)),
this, TQT_SLOT(slotConfigDirty(const TQString&)));
fileWatcher->addFile(d->configFileName);
}
Repository::Repository(const TQString& repository)
: TQObject()
, DCOPObject()
, d(new Private)
{
d->location = repository;
d->readGeneralConfig();
d->readConfig();
// other cvsservice instances might change the configuration file
// so we watch it for changes
d->configFileName = locate("config", "cvsservicerc");
KDirWatch* fileWatcher = new KDirWatch(this);
connect(fileWatcher, TQT_SIGNAL(dirty(const TQString&)),
this, TQT_SLOT(slotConfigDirty(const TQString&)));
fileWatcher->addFile(d->configFileName);
}
Repository::~Repository()
{
delete d;
}
TQString Repository::cvsClient() const
{
TQString client(d->client);
// suppress reading of the '.cvsrc' file
client += " -f";
// we don't need the command line option if there is no compression level set
if( d->compressionLevel > 0 )
{
client += " -z" + TQString::number(d->compressionLevel) + " ";
}
return client;
}
TQString Repository::clientOnly() const
{
return d->client;
}
TQString Repository::rsh() const
{
return d->rsh;
}
TQString Repository::server() const
{
return d->server;
}
bool Repository::setWorkingCopy(const TQString& dirName)
{
const TQFileInfo fi(dirName);
const TQString path = fi.absFilePath();
// is this really a cvs-controlled directory?
const TQFileInfo cvsDirInfo(path + "/CVS");
if( !cvsDirInfo.exists() || !cvsDirInfo.isDir() ||
!TQFile::exists( cvsDirInfo.filePath() + "/Entries" ) ||
!TQFile::exists( cvsDirInfo.filePath() + "/Repository" ) ||
!TQFile::exists( cvsDirInfo.filePath() + "/Root" ) )
return false;
d->workingCopy = path;
d->location = TQString();
// determine path to the repository
TQFile rootFile(path + "/CVS/Root");
if( rootFile.open(IO_ReadOnly) )
{
TQTextStream stream(&rootFile);
d->location = stream.readLine();
}
rootFile.close();
// add identities (ssh-add) to ssh-agent
// TODO CL make sure this is called only once
if( d->location.contains(":ext:", false) > 0 )
{
SshAgent ssh;
ssh.addSshIdentities();
}
TQDir::setCurrent(path);
d->readConfig();
return true;
}
TQString Repository::workingCopy() const
{
return d->workingCopy;
}
TQString Repository::location() const
{
return d->location;
}
bool Repository::retrieveCvsignoreFile() const
{
return d->retrieveCvsignoreFile;
}
void Repository::slotConfigDirty(const TQString& fileName)
{
if( fileName == d->configFileName )
{
// reread the configuration data from disk
kapp->config()->reparseConfiguration();
d->readConfig();
}
}
void Repository::Private::readGeneralConfig()
{
KConfig* config = kapp->config();
// get path to cvs client programm
config->setGroup("General");
client = config->readPathEntry("CVSPath", "cvs");
}
void Repository::Private::readConfig()
{
KConfig* config = kapp->config();
// Sometimes the location can be unequal to the entry in the CVS/Root.
//
// This can happen when the checkout was done with a repository name
// like :pserver:user@cvs.kde.org:/home/kde. When cvs then saves the
// name into the .cvspass file, it adds the default cvs port to it like
// this :pserver:user@cvs.kde.org:2401/home/kde. This name is then also
// used for the configuration group.
//
// In order to be able to read this group, we then have to manually add
// the port number to it.
TQString repositoryGroup = TQString::fromLatin1("Repository-") + location;
if( !config->hasGroup(repositoryGroup) )
{
// find the position of the first path separator
const int insertPos = repositoryGroup.find('/');
if( insertPos > 0 )
{
// add port to location
// (1) :pserver:user@hostname.com:/path
if( repositoryGroup.at(insertPos - 1) == ':' )
repositoryGroup.insert(insertPos, "2401");
// (2) :pserver:user@hostname.com/path
else
repositoryGroup.insert(insertPos, ":2401");
}
}
config->setGroup(repositoryGroup);
// should we retrieve the CVSROOT/cvsignore file from the cvs server?
retrieveCvsignoreFile = config->readBoolEntry("RetrieveCvsignore", false);
// see if there is a specific compression level set for this repository
compressionLevel = config->readNumEntry("Compression", -1);
// use default global compression level instead?
if( compressionLevel < 0 )
{
KConfigGroupSaver cs(config, "General");
compressionLevel = config->readNumEntry("Compression", 0);
}
// get remote shell client to access the remote repository
rsh = config->readPathEntry("rsh");
// get program to start on the server side
server = config->readEntry("cvs_server");
}
#include "repository.moc"