/*************************************************************************** * Copyright (C) 2004 by ian reinhart geiser * * geiseri@kde.org * * * * 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., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include "specsupport.h" #include "tdevproject.h" #include "tdevmakefrontend.h" #include "distpart_widget.h" #include #include #include #include #include #include #include #include #include //#include #include #include #include /// \FIXME This is at least the fifth place in the tdevelop code something like this exists TQString TQRegExp_escape(const TQString& str ) { return TQRegExp::escape(str); } SpecSupport::SpecSupport(DistpartPart *part) : packageBase(), m_part(part) { dir = ""; // srcPackagePushButton = new TQPushButton(i18n("Src Package"),area()); // buildAllPushButton = new TQPushButton(i18n("Src/Binary Packages"),area()); // exportSPECPushButton = new TQPushButton(i18n("Export SPEC File"),area()); // importSPECPushButton = new TQPushButton(i18n("Import SPEC File"),area()); // // // // connect(buildAllPushButton, TQT_SIGNAL(clicked()), // this, TQT_SLOT(slotbuildAllPushButtonPressed())); // connect(exportSPECPushButton, TQT_SIGNAL(clicked()), // this, TQT_SLOT(slotexportSPECPushButtonPressed())); // connect(importSPECPushButton, TQT_SIGNAL(clicked()), // this, TQT_SLOT(slotimportSPECPushButtonPressed())); // connect(srcPackagePushButton, TQT_SIGNAL(clicked()), // this, TQT_SLOT(slotsrcPackagePushButtonPressed())); parseDotRpmmacros(); } SpecSupport::~SpecSupport() { } // TQPushButton* buildAllPushButton; void SpecSupport::slotbuildAllPushButtonPressed() { TQMap::Iterator it; TQFile file1(dir + "/" + getAppSource()); TQFile file2(*(map.find("_sourcedir")) + "/" + getAppSource()); if (!file2.exists()) { if (!file1.exists()) { TQMessageBox::critical(0 ,i18n("Error"),i18n("You need to create a source archive first.")); return; } else if (TDevMakeFrontend *makeFrontend = m_part->extension("TDevelop/MakeFrontend")) makeFrontend->queueCommand(dir,"cd " + TDEProcess::quote(dir) + " && cp " + TDEProcess::quote(getAppSource()) + " " + TDEProcess::quote(*(map.find("_sourcedir")))); } if (TDevMakeFrontend *makeFrontend = m_part->extension("TDevelop/MakeFrontend")) makeFrontend->queueCommand(dir,"cd " + TDEProcess::quote((((it = map.find("_specdir")) != map.end()) ? (*it) : dir)) + " && rpmbuild -ba " + m_part->project()->projectName() + ".spec"); } // TQPushButton* exportSPECPushButton; void SpecSupport::slotexportSPECPushButtonPressed() { TQMap::Iterator it; TQString specname = ((it = map.find("_specdir")) != map.end()) ? (*it) : (m_part->project()->projectDirectory()); specname += ("/" + m_part->project()->projectName() + ".spec"); TQFile file(specname); if(file.open(IO_WriteOnly)) { TQTextStream stream(&file); stream << generatePackage(); file.close(); } else { kdDebug() << "TODO : intercept write error in SpecSupport::slotexportSPECPushButtonPressed()"; } } TQString SpecSupport::getInfo(TQString s, TQString motif) { TQRegExp re(motif + "[ \t]*([^ \t].*[^ \t])[ \t]*"); if (re.exactMatch(s)) return re.cap(1); return TQString(); } // TQPushButton* importSPECPushButton; void SpecSupport::slotimportSPECPushButtonPressed() { TQString fileName = KFileDialog::getOpenFileName(dir,"*.spec"); if( fileName.isEmpty()) return; TQFile file(fileName); if(file.open(IO_ReadOnly)) { TQTextStream stream(&file); while (!stream.atEnd()) { TQString s = stream.readLine(); TQString 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")) { TQString desc; while (!stream.atEnd()) { TQString str = stream.readLine(); if (str.startsWith("%")) break; else desc += str + "\n"; } setAppDescription(desc); } else if (s.startsWith("%changelog")) { TQString change; while (!stream.atEnd()) { TQString str = stream.readLine(); if (str.startsWith("%")) break; else change += str + "\n"; } setAppChangelog(change); } } } } void SpecSupport::slotAddFileButtonPressed(){ TQString filename = KFileDialog::getOpenFileName (); } // TQPushButton* srcPackagePushButton; void SpecSupport::slotsrcPackagePushButtonPressed() { TQMap::Iterator it; TQFile file1(dir + "/" + getAppSource()); TQFile file2(*(map.find("_sourcedir")) + "/" + getAppSource()); if (!file2.exists()) { if (!file1.exists()) { TQMessageBox::critical(0,i18n("Error"),i18n("You need to create a source archive first.")); return; } else if (TDevMakeFrontend *makeFrontend = m_part->extension("TDevelop/MakeFrontend")) makeFrontend->queueCommand(dir,"cd " + TDEProcess::quote(dir) + " && cp " + TDEProcess::quote(getAppSource()) + " " + TDEProcess::quote(*(map.find("_sourcedir")))); } if (TDevMakeFrontend *makeFrontend = m_part->extension("TDevelop/MakeFrontend")) makeFrontend->queueCommand(dir,"cd " + TDEProcess::quote((((it = map.find("_specdir")) != map.end()) ? (*it) : dir)) + " && rpmbuild -bs " + m_part->project()->projectName() + ".spec"); } void SpecSupport::parseDotRpmmacros() { TQFile dotfile(TQDir::homeDirPath() + "/.rpmmacros"); if (!dotfile.open(IO_ReadOnly)) { // TQErrorMessage * msg = new TQErrorMessage(this); // msg->message("It seems you don't have a ~/.rpmmacros\nYou may experience problems building packages.\n"); // msg->exec(); return; } TQTextStream 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()) { TQString s = stream.readLine(); TQRegExp re("%([^ \t]*)[ \t][ \t]*([^\t]*)$"); if(re.exactMatch(s)) { TQRegExp subst("%\\{([^%]*)\\}"); TQString value = re.cap(2).stripWhiteSpace(); while(subst.search(value) != -1) { value.replace(TQRegExp("%\\{"+ TQRegExp_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 TQString & name) { TQMap::Iterator it; if((it = map.find(name)) != map.end()) { TQDir dir(*it); if (!dir.exists()) return dir.mkdir(*it); } return false; } TQString SpecSupport::generatePackage( ) { TQString spec; spec += "# This spec file was generated by KDevelop \n"; spec += "# Please report any problem to KDevelop Team \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; }