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.
tdevelop/vcs/cvsservice/cvsdir.cpp

322 lines
8.5 KiB

/***************************************************************************
* Copyright (C) 2003 by Mario Scalas *
* mario.scalas@libero.it *
* *
* 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. *
* *
***************************************************************************/
#include <tqfile.h>
#include <tqtextstream.h>
#include "cvsdir.h"
///////////////////////////////////////////////////////////////////////////////
// class CVSDir
///////////////////////////////////////////////////////////////////////////////
CVSDir::CVSDir() : TQDir()
{
}
///////////////////////////////////////////////////////////////////////////////
CVSDir::CVSDir( const TQDir &dir )
: TQDir( dir )
{
// We deal with absolute paths only
convertToAbs();
m_cvsDir = absPath() + TQDir::separator() + "CVS";
if (isValid())
refreshEntriesCache();
}
///////////////////////////////////////////////////////////////////////////////
CVSDir::CVSDir( const CVSDir &aCvsDir )
: TQDir( aCvsDir )
{
*this = aCvsDir;
}
///////////////////////////////////////////////////////////////////////////////
CVSDir &CVSDir::operator=( const CVSDir &aCvsDir )
{
m_cvsDir = aCvsDir.m_cvsDir;
m_cachedEntries = aCvsDir.m_cachedEntries;
TQDir::operator=( aCvsDir );
return *this;
}
///////////////////////////////////////////////////////////////////////////////
CVSDir::~CVSDir()
{
}
///////////////////////////////////////////////////////////////////////////////
bool CVSDir::isValid() const
{
return exists() &&
TQFile::exists( entriesFileName() ) &&
TQFile::exists( rootFileName() ) &&
TQFile::exists( repoFileName() );
}
///////////////////////////////////////////////////////////////////////////////
TQString CVSDir::entriesFileName() const
{
return m_cvsDir + TQDir::separator() + "Entries";
}
///////////////////////////////////////////////////////////////////////////////
TQString CVSDir::rootFileName() const
{
return m_cvsDir + TQDir::separator() + "Root";
}
///////////////////////////////////////////////////////////////////////////////
TQString CVSDir::repoFileName() const
{
return m_cvsDir + TQDir::separator() + "Repository";
}
///////////////////////////////////////////////////////////////////////////////
TQString CVSDir::cvsIgnoreFileName() const
{
return absPath() + TQDir::separator() + ".cvsignore";
}
///////////////////////////////////////////////////////////////////////////////
TQString CVSDir::repository() const
{
// The content of CVS/Repository is a single line with the path into the
// repository of the modules checked out in this directory (just like
// "tdevelop/parts/cvsservice"): so we can read a single line of the file
// and we are done!
TQString content;
if (!isValid())
return TQString();
TQByteArray bytes = cacheFile( repoFileName() );
TQTextStream t( bytes, IO_ReadOnly );
content += t.readLine();
return content;
}
///////////////////////////////////////////////////////////////////////////////
TQString CVSDir::root() const
{
// Same as CVSDir::repository() but CVS/Root contains the path of the
// CVS server as used in "cvs -d <server-path>" (in example:
// ":pserver:marios@cvs.kde.org:/home/kde")
TQString content;
if (!isValid())
return TQString();
TQByteArray bytes = cacheFile( repoFileName() );
TQTextStream t( bytes, IO_ReadOnly );
content += t.readLine();
return content;
}
///////////////////////////////////////////////////////////////////////////////
TQByteArray CVSDir::cacheFile( const TQString &fileName )
{
TQFile f( fileName );
if (!f.open( IO_ReadOnly ))
return TQByteArray();
return f.readAll();
}
///////////////////////////////////////////////////////////////////////////////
TQStringList CVSDir::registeredEntryList() const
{
TQStringList l;
if (!isValid())
return l;
TQByteArray bytes = cacheFile( entriesFileName() );
TQTextStream t( bytes, IO_ReadOnly );
CVSEntry entry;
while (!t.eof())
{
TQString line = t.readLine();
entry.parse( line, *this );
if (entry.isValid())
l.append( entry.fileName() );
}
return l;
}
///////////////////////////////////////////////////////////////////////////////
bool CVSDir::isRegistered( const TQString fileName ) const
{
CVSEntry entry = fileStatus( fileName );
return entry.isValid() && entry.fileName() == fileName;
}
///////////////////////////////////////////////////////////////////////////////
void CVSDir::refreshEntriesCache() const
{
m_cachedEntries.clear();
TQByteArray bytes = cacheFile( entriesFileName() );
TQTextStream t( bytes, IO_ReadOnly );
CVSEntry entry;
while (!t.eof())
{
TQString line = t.readLine();
entry.parse( line, *this );
if (entry.isValid())
m_cachedEntries[ entry.fileName() ] = entry;
}
}
///////////////////////////////////////////////////////////////////////////////
CVSEntry CVSDir::fileStatus( const TQString &fileName, bool refreshCache ) const
{
if (refreshCache)
refreshEntriesCache();
if (m_cachedEntries.contains( fileName ))
{
return m_cachedEntries[ fileName ];
}
else
return CVSEntry( fileName, *this ); // Just the file name
}
///////////////////////////////////////////////////////////////////////////////
void CVSDir::ignoreFile( const TQString &fileName )
{
if (!isValid())
return;
TQFile f( cvsIgnoreFileName() );
if (!f.open( IO_ReadOnly))
return;
TQByteArray cachedFile = f.readAll();
TQTextStream t( cachedFile, IO_ReadOnly | IO_WriteOnly );
TQString readFileName;
bool found = false;
while (!t.eof() && !found)
{
readFileName = t.readLine();
found = (fileName == readFileName);
}
f.close();
if (!found)
{
f.open( IO_WriteOnly );
t << fileName << "\n";
f.writeBlock( cachedFile );
f.close();
}
}
///////////////////////////////////////////////////////////////////////////////
void CVSDir::doNotIgnoreFile( const TQString &fileName )
{
if (!isValid())
return;
// 1. Read all .ignore file in memory
TQFile f( cvsIgnoreFileName() );
if (!f.open( IO_ReadOnly ))
return; // No .cvsignore file? Nothing to do then!
TQByteArray cachedFile = f.readAll();
TQTextIStream is( cachedFile );
TQByteArray cachedOutputFile;
TQTextOStream os( cachedOutputFile );
bool removed = false;
while (!is.eof())
{
TQString readLine = is.readLine();
if (readLine != fileName)
os << readLine << "\n"; // TQTextStream::readLine() eats the "\n" ...
else
removed = true;
}
f.close();
if (removed)
{
f.open( IO_WriteOnly );
f.writeBlock( cachedOutputFile );
f.close();
}
}
///////////////////////////////////////////////////////////////////////////////
VCSFileInfoMap CVSDir::dirStatus() const
{
VCSFileInfoMap vcsInfo;
/// Convert to VCSFileInfoMap: \FIXME : any speed improvement here?
TQStringList entries = registeredEntryList();
TQStringList::const_iterator it = entries.begin(), end = entries.end();
for ( ; it != end; ++it)
{
const TQString &fileName = (*it);
const CVSEntry entry = fileStatus( fileName );
vcsInfo.insert( fileName, entry.toVCSFileInfo() );
}
return vcsInfo;
}
///////////////////////////////////////////////////////////////////////////////
VCSFileInfoMap *CVSDir::cacheableDirStatus() const
{
VCSFileInfoMap *vcsInfo = new VCSFileInfoMap;
/// Convert to VCSFileInfoMap: \FIXME : any speed improvement here?
TQStringList entries = registeredEntryList();
TQStringList::const_iterator it = entries.begin(), end = entries.end();
for ( ; it != end; ++it)
{
const TQString &fileName = (*it);
const CVSEntry entry = fileStatus( fileName );
vcsInfo->insert( fileName, entry.toVCSFileInfo() );
}
return vcsInfo;
}