KDevelop API Documentation

specsupport.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2004 by ian reinhart geiser                             *
00003  *   geiseri@kde.org                                                       *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 #include "specsupport.h"
00022 #include "kdevproject.h"
00023 #include "kdevmakefrontend.h"
00024 #include "distpart_widget.h"
00025 
00026 #include <kdebug.h>
00027 #include <kfiledialog.h>
00028 #include <klocale.h>
00029 #include <kprocess.h>
00030 #include <qfile.h>
00031 #include <qdir.h>
00032 #include <qerrormessage.h>
00033 #include <qregexp.h>
00034 #include <qpushbutton.h>
00035 //#include <qvbox.h>
00036 #include <qgroupbox.h>
00037 #include <qtabwidget.h>
00038 #include <qmessagebox.h>
00039 
00041 QString QRegExp_escape(const QString& str )
00042 {
00043 #if QT_VERSION >= 0x030100
00044     return QRegExp::escape(str);
00045 #else
00046     // this block is copyrighted by Trolltech AS (GPL)
00047     static const char meta[] = "$()*+.?[\\]^{|}";
00048     QString quoted = str;
00049     int i = 0;
00050 
00051     while ( i < (int) quoted.length() ) {
00052        if ( strchr(meta, quoted[i].latin1()) != 0 )
00053            quoted.insert( i++, "\\" );
00054        i++;
00055     }
00056     return quoted;
00057 #endif
00058 }
00059 
00060 SpecSupport::SpecSupport(DistpartPart *part) : packageBase(), m_part(part) {
00061     dir = "";
00062 
00063 //     srcPackagePushButton = new QPushButton(i18n("Src Package"),area());
00064 //     buildAllPushButton = new QPushButton(i18n("Src/Binary Packages"),area());
00065 //     exportSPECPushButton = new QPushButton(i18n("Export SPEC File"),area());
00066 //     importSPECPushButton = new QPushButton(i18n("Import SPEC File"),area());
00067 // 
00068 // 
00069 // 
00070 //     connect(buildAllPushButton, SIGNAL(clicked()),
00071 //             this, SLOT(slotbuildAllPushButtonPressed()));
00072 //     connect(exportSPECPushButton, SIGNAL(clicked()),
00073 //             this, SLOT(slotexportSPECPushButtonPressed()));
00074 //     connect(importSPECPushButton, SIGNAL(clicked()),
00075 //             this, SLOT(slotimportSPECPushButtonPressed()));
00076 //     connect(srcPackagePushButton, SIGNAL(clicked()),
00077 //             this, SLOT(slotsrcPackagePushButtonPressed()));
00078 
00079     parseDotRpmmacros();
00080 }
00081 
00082 SpecSupport::~SpecSupport() {
00083 }
00084 
00085 //    QPushButton* buildAllPushButton;
00086 void SpecSupport::slotbuildAllPushButtonPressed() {
00087     QMap<QString,QString>::Iterator it;
00088     QFile file1(dir + "/" + getAppSource());
00089     QFile file2(*(map.find("_sourcedir")) + "/" + getAppSource());
00090     if (!file2.exists()) {
00091     if (!file1.exists()) {
00092         QMessageBox::critical(m_part->widget(),i18n("Error"),i18n("You need to create a source archive first."));
00093         return;
00094     }
00095     else
00096         m_part->makeFrontend()->queueCommand(dir,"cd " + KProcess::quote(dir) + 
00097         " && cp " + KProcess::quote(getAppSource()) + " " + KProcess::quote(*(map.find("_sourcedir"))));
00098     }
00099     m_part->makeFrontend()->queueCommand(dir,"cd " + KProcess::quote((((it = map.find("_specdir")) != map.end()) ? (*it) : dir)) +
00100          " && rpmbuild -ba " + m_part->project()->projectName() + ".spec");
00101 }
00102 
00103 //    QPushButton* exportSPECPushButton;
00104 void SpecSupport::slotexportSPECPushButtonPressed() {
00105     QMap<QString,QString>::Iterator it;
00106     QString specname = ((it = map.find("_specdir")) != map.end()) ? (*it) : (m_part->project()->projectDirectory());
00107     specname += ("/" + m_part->project()->projectName() + ".spec");
00108     QFile file(specname);
00109 
00110     if(file.open(IO_WriteOnly)) {
00111         QTextStream stream(&file);
00112     stream << generatePackage();
00113         file.close();
00114     } else {
00115         kdDebug() << "TODO : intercept write error in SpecSupport::slotexportSPECPushButtonPressed()";
00116     }
00117 }
00118 
00119 QString SpecSupport::getInfo(QString s, QString motif) {
00120     QRegExp re(motif + "[ \t]*([^ \t].*[^ \t])[ \t]*");
00121     if (re.exactMatch(s))
00122         return re.cap(1);
00123     return QString::null;
00124 }
00125 
00126 //    QPushButton* importSPECPushButton;
00127 void SpecSupport::slotimportSPECPushButtonPressed() {
00128        QString fileName = KFileDialog::getOpenFileName(dir,"*.spec");
00129        if( fileName.isEmpty())
00130                return;
00131     QFile file(fileName);
00132  
00133     if(file.open(IO_ReadOnly)) {
00134         QTextStream stream(&file);
00135 
00136         while (!stream.atEnd()) {
00137             QString s = stream.readLine();
00138             QString info;
00139             if (!(info = getInfo(s,"Name:")).isEmpty())
00140                 setAppName(info);
00141             else if (!(info = getInfo(s,"Version:")).isEmpty())
00142                 setAppVersion(info);
00143             else if (!(info = getInfo(s,"Release:")).isEmpty())
00144                 setAppRevision(info);
00145             else if (!(info = getInfo(s,"Vendor:")).isEmpty())
00146                 setAppVendor(info);
00147             else if (!(info = getInfo(s,"Copyright:")).isEmpty())
00148                 setAppLicense(info);
00149             else if (!(info = getInfo(s,"Summary:")).isEmpty())
00150                 setAppSummary(info);
00151             else if (!(info = getInfo(s,"Group:")).isEmpty())
00152                 setAppGroup(info);
00153             else if (!(info = getInfo(s,"Packager:")).isEmpty())
00154                 setAppPackager(info);
00155             else if (s.startsWith("%description")) {
00156                 QString desc;
00157                 while (!stream.atEnd()) {
00158                     QString str = stream.readLine();
00159                     if (str.startsWith("%")) break;
00160                     else desc += str + "\n";
00161                 }
00162                 setAppDescription(desc);
00163             }
00164         else if (s.startsWith("%changelog")) {
00165         QString change;
00166         while (!stream.atEnd()) {
00167             QString str = stream.readLine();
00168             if (str.startsWith("%")) break;
00169                     else change += str + "\n";
00170                 }
00171         setAppChangelog(change);
00172             }
00173         }
00174     }
00175 }
00176 
00177 //    QPushButton* srcPackagePushButton;
00178 void SpecSupport::slotsrcPackagePushButtonPressed() {
00179     QMap<QString,QString>::Iterator it;
00180 
00181     QFile file1(dir + "/" + getAppSource());
00182     QFile file2(*(map.find("_sourcedir")) + "/" + getAppSource());
00183     if (!file2.exists()) {
00184     if (!file1.exists()) {
00185         QMessageBox::critical(m_part->widget(),i18n("Error"),i18n("You need to create a source archive first."));
00186         return;
00187     }
00188     else
00189         m_part->makeFrontend()->queueCommand(dir,"cd " + KProcess::quote(dir) + 
00190         " && cp " + KProcess::quote(getAppSource()) + " " + KProcess::quote(*(map.find("_sourcedir"))));
00191     }
00192     m_part->makeFrontend()->queueCommand(dir,"cd " + KProcess::quote((((it = map.find("_specdir")) != map.end()) ? (*it) : dir)) +
00193          " && rpmbuild -bs " + m_part->project()->projectName() + ".spec");
00194 }
00195 
00196 void SpecSupport::parseDotRpmmacros() {
00197     QFile dotfile(QDir::homeDirPath() + "/.rpmmacros");
00198 
00199     if (!dotfile.open(IO_ReadOnly)) {
00200 //        QErrorMessage * msg = new QErrorMessage(this);
00201 //        msg->message("It seems you don't have a ~/.rpmmacros\nYou may experience problems building packages.\n");
00202 //        msg->exec();
00203         return;
00204     }
00205     QTextStream stream(&dotfile);
00206 
00207     // Perhaps will it appear as a necessity to parse the global rpm config file?
00208 
00209     // Pre defined macros :
00210     map.insert("name",getAppName());
00211 
00212     // .rpmmacros parsing :
00213     while (!stream.atEnd()) {
00214         QString s = stream.readLine();
00215         QRegExp re("%([^ \t]*)[ \t][ \t]*([^\t]*)$");
00216         if(re.exactMatch(s)) {
00217             QRegExp subst("%\\{([^%]*)\\}");
00218             QString value = re.cap(2).stripWhiteSpace();
00219 
00220             while(subst.search(value) != -1) {
00221                 value.replace(QRegExp("%\\{"+ QRegExp_escape( subst.cap(1) ) +"\\}"),*map.find(subst.cap(1)));
00222             }
00223             map.insert(re.cap(1),value);
00224         }
00225     }
00226     dotfile.close();
00227 
00228     // create directories if necessary :
00229     createRpmDirectoryFromMacro("_topdir");
00230     createRpmDirectoryFromMacro("_tmppath");
00231     createRpmDirectoryFromMacro("_builddir");
00232     createRpmDirectoryFromMacro("_rpmdir");
00233     createRpmDirectoryFromMacro("_sourcedir");
00234     createRpmDirectoryFromMacro("_specdir");
00235     createRpmDirectoryFromMacro("_srcrpmdir");
00236 }
00237 
00238 bool SpecSupport::createRpmDirectoryFromMacro(const QString & name) {
00239     QMap<QString,QString>::Iterator it;
00240     if((it = map.find(name)) != map.end()) {
00241         QDir dir(*it);
00242         if (!dir.exists()) return dir.mkdir(*it);
00243     }
00244     return false;
00245 }
00246 
00247 QString SpecSupport::generatePackage( )
00248 {
00249     QString spec;
00250         spec += "# This spec file was generated by KDevelop \n";
00251         spec += "# Please report any problem to KDevelop Team <kdevelop-devel@kdevelop.org> \n";
00252         spec += "# Thanks to Matthias Saou for his explanations on http://freshrpms.net/docs/fight.html\n\n";
00253 
00254         spec += "Name: " + getAppName() + "\n";
00255         spec += "Version: " + getAppVersion() + "\n";
00256         spec += "Release: " + getAppRevision() + "\n";
00257         spec += "Vendor: " + getAppVendor() + "\n";
00258         spec += "Copyright: " + getAppLicense() + "\n";
00259         spec += "Summary: " + getAppSummary() + "\n";
00260         spec += "Group: " + getAppGroup() + "\n";
00261         spec += "Packager: " + getAppPackager() + "\n";
00262         spec += "BuildRoot:  %{_tmppath}/%{name}-root \n";
00263         spec += "Source: " + getAppSource() + "\n";
00264 
00265         spec += "\n";
00266         spec += "%description\n";
00267         spec += getAppDescription()+ "\n";
00268 
00269         spec += "\n";
00270         spec += "%prep\n";
00271         spec += "%setup\n";
00272         spec += "CFLAGS=\"$RPM_OPT_FLAGS\" CXXFLAGS=\"$RPM_OPT_FLAGS\" ./configure \\ \n";
00273         spec += "--target=" + getAppArch() + "\n";
00274     spec += "--disable-debug --enable-debug=no \n";
00275 
00276         spec += "\n";
00277         spec += "%build\n";
00278         spec += "%configure\n";
00279         spec += "make\n";
00280 
00281         spec += "\n";
00282         spec += "%install\n";
00283         spec += "rm -rf %{buildroot}\n";
00284         spec += "%makeinstall\n";
00285 
00286         spec += "\n";
00287         spec += "%clean\n";
00288         spec += "rm -rf %{buildroot}\n";
00289 
00290         spec += "\n";
00291         spec += "%post -p /sbin/ldconfig\n";
00292 
00293         spec += "%postun -p /sbin/ldconfig\n";
00294 
00295         spec += "%files\n";
00296         spec += "%defattr(-, root, root)\n";
00297         spec += "%doc AUTHORS COPYING ChangeLog NEWS README TODO\n";
00298         spec += "%{_bindir}/*\n";
00299         spec += "%{_libdir}/*.so.*\n";
00300         spec += "%{_datadir}/%{name}\n";
00301         spec += "%{_mandir}/man8/*\n";
00302 
00303         spec += "%changelog\n";
00304         spec += getAppChangelog() + "\n";
00305     
00306     return spec;
00307 }
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:39 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003