summaryrefslogtreecommitdiffstats
path: root/parts/distpart/specsupport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'parts/distpart/specsupport.cpp')
-rw-r--r--parts/distpart/specsupport.cpp315
1 files changed, 315 insertions, 0 deletions
diff --git a/parts/distpart/specsupport.cpp b/parts/distpart/specsupport.cpp
new file mode 100644
index 00000000..b9ba6e1e
--- /dev/null
+++ b/parts/distpart/specsupport.cpp
@@ -0,0 +1,315 @@
+/***************************************************************************
+ * Copyright (C) 2004 by ian reinhart geiser *
+ * *
+ * 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. *
+ * *
+ * 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 General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include "specsupport.h"
+#include "kdevproject.h"
+#include "kdevmakefrontend.h"
+#include "distpart_widget.h"
+
+#include <kdebug.h>
+#include <kfiledialog.h>
+#include <klocale.h>
+#include <kprocess.h>
+#include <qfile.h>
+#include <qdir.h>
+#include <qerrormessage.h>
+#include <qregexp.h>
+#include <qpushbutton.h>
+//#include <qvbox.h>
+#include <qgroupbox.h>
+#include <qtabwidget.h>
+#include <qmessagebox.h>
+
+/// \FIXME This is at least the fifth place in the kdevelop code something like this exists
+QString QRegExp_escape(const QString& str )
+{
+#if QT_VERSION >= 0x030100
+ return QRegExp::escape(str);
+#else
+ // this block is copyrighted by Trolltech AS (GPL)
+ static const char meta[] = "$()*+.?[\\]^{|}";
+ QString quoted = str;
+ int i = 0;
+
+ while ( i < (int) quoted.length() ) {
+ if ( strchr(meta, quoted[i].latin1()) != 0 )
+ quoted.insert( i++, "\\" );
+ i++;
+ }
+ return quoted;
+#endif
+}
+
+SpecSupport::SpecSupport(DistpartPart *part) : packageBase(), m_part(part) {
+ dir = "";
+
+// srcPackagePushButton = new QPushButton(i18n("Src Package"),area());
+// buildAllPushButton = new QPushButton(i18n("Src/Binary Packages"),area());
+// exportSPECPushButton = new QPushButton(i18n("Export SPEC File"),area());
+// importSPECPushButton = new QPushButton(i18n("Import SPEC File"),area());
+//
+//
+//
+// connect(buildAllPushButton, SIGNAL(clicked()),
+// this, SLOT(slotbuildAllPushButtonPressed()));
+// connect(exportSPECPushButton, SIGNAL(clicked()),
+// this, SLOT(slotexportSPECPushButtonPressed()));
+// connect(importSPECPushButton, SIGNAL(clicked()),
+// this, SLOT(slotimportSPECPushButtonPressed()));
+// connect(srcPackagePushButton, SIGNAL(clicked()),
+// this, SLOT(slotsrcPackagePushButtonPressed()));
+
+ parseDotRpmmacros();
+}
+
+SpecSupport::~SpecSupport() {
+}
+
+// QPushButton* buildAllPushButton;
+void SpecSupport::slotbuildAllPushButtonPressed() {
+ QMap<QString,QString>::Iterator it;
+ QFile file1(dir + "/" + getAppSource());
+ QFile file2(*(map.find("_sourcedir")) + "/" + getAppSource());
+ if (!file2.exists()) {
+ if (!file1.exists()) {
+ QMessageBox::critical(0 ,i18n("Error"),i18n("You need to create a source archive first."));
+ return;
+ }
+ else
+ if (KDevMakeFrontend *makeFrontend = m_part->extension<KDevMakeFrontend>("KDevelop/MakeFrontend"))
+ makeFrontend->queueCommand(dir,"cd " + KProcess::quote(dir) +
+ " && cp " + KProcess::quote(getAppSource()) + " " + KProcess::quote(*(map.find("_sourcedir"))));
+ }
+ if (KDevMakeFrontend *makeFrontend = m_part->extension<KDevMakeFrontend>("KDevelop/MakeFrontend"))
+ makeFrontend->queueCommand(dir,"cd " + KProcess::quote((((it = map.find("_specdir")) != map.end()) ? (*it) : dir)) +
+ " && rpmbuild -ba " + m_part->project()->projectName() + ".spec");
+}
+
+// QPushButton* exportSPECPushButton;
+void SpecSupport::slotexportSPECPushButtonPressed() {
+ QMap<QString,QString>::Iterator it;
+ QString specname = ((it = map.find("_specdir")) != map.end()) ? (*it) : (m_part->project()->projectDirectory());
+ specname += ("/" + m_part->project()->projectName() + ".spec");
+ QFile file(specname);
+
+ if(file.open(IO_WriteOnly)) {
+ QTextStream stream(&file);
+ stream << generatePackage();
+ file.close();
+ } else {
+ kdDebug() << "TODO : intercept write error in SpecSupport::slotexportSPECPushButtonPressed()";
+ }
+}
+
+QString SpecSupport::getInfo(QString s, QString motif) {
+ QRegExp re(motif + "[ \t]*([^ \t].*[^ \t])[ \t]*");
+ if (re.exactMatch(s))
+ return re.cap(1);
+ return QString::null;
+}
+
+// QPushButton* importSPECPushButton;
+void SpecSupport::slotimportSPECPushButtonPressed() {
+ QString fileName = KFileDialog::getOpenFileName(dir,"*.spec");
+ if( fileName.isEmpty())
+ return;
+ QFile file(fileName);
+
+ if(file.open(IO_ReadOnly)) {
+ QTextStream stream(&file);
+
+ while (!stream.atEnd()) {
+ QString s = stream.readLine();
+ QString info;
+ if (!(info = getInfo(s,"Name:")).isEmpty())
+ setAppName(info);
+ else if (!(info = getInfo(s,"Version:")).isEmpty())
+ setAppVersion(info);
+ else if (!(info = getInfo(s,"Release:")).isEmpty())
+ setAppRevision(info);
+ else if (!(info = getInfo(s,"Vendor:")).isEmpty())
+ setAppVendor(info);
+ else if (!(info = getInfo(s,"Copyright:")).isEmpty())
+ setAppLicense(info);
+ else if (!(info = getInfo(s,"Summary:")).isEmpty())
+ setAppSummary(info);
+ else if (!(info = getInfo(s,"Group:")).isEmpty())
+ setAppGroup(info);
+ else if (!(info = getInfo(s,"Packager:")).isEmpty())
+ setAppPackager(info);
+ else if (s.startsWith("%description")) {
+ QString desc;
+ while (!stream.atEnd()) {
+ QString str = stream.readLine();
+ if (str.startsWith("%")) break;
+ else desc += str + "\n";
+ }
+ setAppDescription(desc);
+ }
+ else if (s.startsWith("%changelog")) {
+ QString change;
+ while (!stream.atEnd()) {
+ QString str = stream.readLine();
+ if (str.startsWith("%")) break;
+ else change += str + "\n";
+ }
+ setAppChangelog(change);
+ }
+ }
+ }
+}
+
+void SpecSupport::slotAddFileButtonPressed(){
+QString filename = KFileDialog::getOpenFileName ();
+}
+
+// QPushButton* srcPackagePushButton;
+void SpecSupport::slotsrcPackagePushButtonPressed() {
+ QMap<QString,QString>::Iterator it;
+
+ QFile file1(dir + "/" + getAppSource());
+ QFile file2(*(map.find("_sourcedir")) + "/" + getAppSource());
+ if (!file2.exists()) {
+ if (!file1.exists()) {
+ QMessageBox::critical(0,i18n("Error"),i18n("You need to create a source archive first."));
+ return;
+ }
+ else
+ if (KDevMakeFrontend *makeFrontend = m_part->extension<KDevMakeFrontend>("KDevelop/MakeFrontend"))
+ makeFrontend->queueCommand(dir,"cd " + KProcess::quote(dir) +
+ " && cp " + KProcess::quote(getAppSource()) + " " + KProcess::quote(*(map.find("_sourcedir"))));
+ }
+ if (KDevMakeFrontend *makeFrontend = m_part->extension<KDevMakeFrontend>("KDevelop/MakeFrontend"))
+ makeFrontend->queueCommand(dir,"cd " + KProcess::quote((((it = map.find("_specdir")) != map.end()) ? (*it) : dir)) +
+ " && rpmbuild -bs " + m_part->project()->projectName() + ".spec");
+}
+
+void SpecSupport::parseDotRpmmacros() {
+ QFile dotfile(QDir::homeDirPath() + "/.rpmmacros");
+
+ if (!dotfile.open(IO_ReadOnly)) {
+// QErrorMessage * msg = new QErrorMessage(this);
+// msg->message("It seems you don't have a ~/.rpmmacros\nYou may experience problems building packages.\n");
+// msg->exec();
+ return;
+ }
+ QTextStream stream(&dotfile);
+
+ // Perhaps will it appear as a necessity to parse the global rpm config file?
+
+ // Pre defined macros :
+ map.insert("name",getAppName());
+
+ // .rpmmacros parsing :
+ while (!stream.atEnd()) {
+ QString s = stream.readLine();
+ QRegExp re("%([^ \t]*)[ \t][ \t]*([^\t]*)$");
+ if(re.exactMatch(s)) {
+ QRegExp subst("%\\{([^%]*)\\}");
+ QString value = re.cap(2).stripWhiteSpace();
+
+ while(subst.search(value) != -1) {
+ value.replace(QRegExp("%\\{"+ QRegExp_escape( subst.cap(1) ) +"\\}"),*map.find(subst.cap(1)));
+ }
+ map.insert(re.cap(1),value);
+ }
+ }
+ dotfile.close();
+
+ // create directories if necessary :
+ createRpmDirectoryFromMacro("_topdir");
+ createRpmDirectoryFromMacro("_tmppath");
+ createRpmDirectoryFromMacro("_builddir");
+ createRpmDirectoryFromMacro("_rpmdir");
+ createRpmDirectoryFromMacro("_sourcedir");
+ createRpmDirectoryFromMacro("_specdir");
+ createRpmDirectoryFromMacro("_srcrpmdir");
+}
+
+bool SpecSupport::createRpmDirectoryFromMacro(const QString & name) {
+ QMap<QString,QString>::Iterator it;
+ if((it = map.find(name)) != map.end()) {
+ QDir dir(*it);
+ if (!dir.exists()) return dir.mkdir(*it);
+ }
+ return false;
+}
+
+QString SpecSupport::generatePackage( )
+{
+ QString spec;
+ spec += "# This spec file was generated by KDevelop \n";
+ spec += "# Please report any problem to KDevelop Team <[email protected]> \n";
+ spec += "# Thanks to Matthias Saou for his explanations on http://freshrpms.net/docs/fight.html\n\n";
+
+ spec += "Name: " + getAppName() + "\n";
+ spec += "Version: " + getAppVersion() + "\n";
+ spec += "Release: " + getAppRevision() + "\n";
+ spec += "Vendor: " + getAppVendor() + "\n";
+ spec += "Copyright: " + getAppLicense() + "\n";
+ spec += "Summary: " + getAppSummary() + "\n";
+ spec += "Group: " + getAppGroup() + "\n";
+ spec += "Packager: " + getAppPackager() + "\n";
+ spec += "BuildRoot: %{_tmppath}/%{name}-root \n";
+ spec += "Source: " + getAppSource() + "\n";
+
+ spec += "\n";
+ spec += "%description\n";
+ spec += getAppDescription()+ "\n";
+
+ spec += "\n";
+ spec += "%prep\n";
+ spec += "%setup\n";
+ spec += "CFLAGS=\"$RPM_OPT_FLAGS\" CXXFLAGS=\"$RPM_OPT_FLAGS\" ./configure \\ \n";
+ spec += "--target=" + getAppArch() + "\n";
+ spec += "--disable-debug --enable-debug=no \n";
+
+ spec += "\n";
+ spec += "%build\n";
+ spec += "%configure\n";
+ spec += "make\n";
+
+ spec += "\n";
+ spec += "%install\n";
+ spec += "rm -rf %{buildroot}\n";
+ spec += "%makeinstall\n";
+
+ spec += "\n";
+ spec += "%clean\n";
+ spec += "rm -rf %{buildroot}\n";
+
+ spec += "\n";
+ spec += "%post -p /sbin/ldconfig\n";
+
+ spec += "%postun -p /sbin/ldconfig\n";
+
+ spec += "%files\n";
+ spec += "%defattr(-, root, root)\n";
+ spec += "%doc AUTHORS COPYING ChangeLog NEWS README TODO\n";
+ spec += "%{_bindir}/*\n";
+ spec += "%{_libdir}/*.so.*\n";
+ spec += "%{_datadir}/%{name}\n";
+ spec += "%{_mandir}/man8/*\n";
+
+ spec += "%changelog\n";
+ spec += getAppChangelog() + "\n";
+
+ return spec;
+}