/*************************************************************************** * 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 #include #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 // "kdevelop/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 " (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; }