00001
#include "specsupport.h"
00002
#include "specsupport.moc"
00003
#include "kdevproject.h"
00004
#include "kdevmakefrontend.h"
00005
#include "distpart_widget.h"
00006
00007
#include <kdebug.h>
00008
#include <kfiledialog.h>
00009
#include <klocale.h>
00010
#include <qfile.h>
00011
#include <qdir.h>
00012
#include <qerrormessage.h>
00013
#include <qregexp.h>
00014
#include <qpushbutton.h>
00015
#include <qvbox.h>
00016
#include <qgroupbox.h>
00017
#include <qtabwidget.h>
00018
#include <qmessagebox.h>
00019
00021 QString QRegExp_escape(
const QString& str )
00022 {
00023
#if QT_VERSION >= 0x030100
00024
return QRegExp::escape(str);
00025
#else
00026
00027
static const char meta[] =
"$()*+.?[\\]^{|}";
00028
QString quoted = str;
00029
int i = 0;
00030
00031
while ( i < (
int) quoted.length() ) {
00032
if ( strchr(meta, quoted[i].latin1()) != 0 )
00033 quoted.insert( i++,
"\\" );
00034 i++;
00035 }
00036
return quoted;
00037
#endif
00038
}
00039
00040 SpecSupport::SpecSupport(
DistpartPart * part) :
packageBase(part,"Rpm") {
00041
00042
m_part = part;
00043
00044
srcPackagePushButton =
new QPushButton(i18n(
"Src Package"),
area());
00045
buildAllPushButton =
new QPushButton(i18n(
"Src/Binary Packages"),
area());
00046
exportSPECPushButton =
new QPushButton(i18n(
"Export SPEC File"),
area());
00047
importSPECPushButton =
new QPushButton(i18n(
"Import SPEC File"),
area());
00048
00049
00050
00051 connect(
buildAllPushButton, SIGNAL(clicked()),
00052
this, SLOT(
slotbuildAllPushButtonPressed()));
00053 connect(
exportSPECPushButton, SIGNAL(clicked()),
00054
this, SLOT(
slotexportSPECPushButtonPressed()));
00055 connect(
importSPECPushButton, SIGNAL(clicked()),
00056
this, SLOT(
slotimportSPECPushButtonPressed()));
00057 connect(
srcPackagePushButton, SIGNAL(clicked()),
00058
this, SLOT(
slotsrcPackagePushButtonPressed()));
00059
00060
parseDotRpmmacros();
00061 }
00062
00063 SpecSupport::~SpecSupport() {
00064 }
00065
00066
00067 void SpecSupport::slotbuildAllPushButtonPressed() {
00068
QMap<QString,QString>::Iterator it;
00069
QFile file1(dir +
"/" +
getAppSource());
00070
QFile file2(*(
map.find(
"_sourcedir")) +
"/" +
getAppSource());
00071
if (!file2.exists()) {
00072
if (!file1.exists()) {
00073 QMessageBox::critical(
this,i18n(
"Error"),i18n(
"You need to create a source archive first!"));
00074
return;
00075 }
00076
else
00077
m_part->
makeFrontend()->
queueCommand(dir,
"cd " + dir +
" && cp " +
getAppSource() +
" " + *(
map.find(
"_sourcedir")));
00078 }
00079
m_part->
makeFrontend()->
queueCommand(dir,
"cd " + (((it =
map.find(
"_specdir")) !=
map.end()) ? (*it) : dir) +
" && rpmbuild -ba " +
m_part->
project()->
projectName() +
".spec");
00080 }
00081
00082
00083 void SpecSupport::slotexportSPECPushButtonPressed() {
00084
QMap<QString,QString>::Iterator it;
00085
QString specname = ((it =
map.find(
"_specdir")) !=
map.end()) ? (*it) : (
m_part->
project()->
projectDirectory());
00086 specname += (
"/" +
m_part->
project()->
projectName() +
".spec");
00087
QFile file(specname);
00088
00089
if(
file.open(IO_WriteOnly)) {
00090
QTextStream stream(&
file);
00091
00092 stream <<
"# This spec file was generated by KDevelop" <<
"\n"
00093 <<
"# Please report any problem to KDevelop Team <kdevelop-devel@kdevelop.org>" <<
"\n"
00094 <<
"# Thanks to Matthias Saou for his explanations on http://freshrpms.net/docs/fight.html\n\n";
00095
00096 stream <<
"Name: " <<
getAppName() <<
"\n";
00097 stream <<
"Version: " <<
getAppVersion() <<
"\n";
00098 stream <<
"Release: " <<
getAppRevision() <<
"\n";
00099 stream <<
"Vendor: " <<
getAppVendor() <<
"\n";
00100 stream <<
"Copyright: " <<
getAppLicense() <<
"\n";
00101 stream <<
"Summary: " <<
getAppSummary() <<
"\n";
00102 stream <<
"Group: " <<
getAppGroup() <<
"\n";
00103 stream <<
"Packager: " <<
getAppPackager() <<
"\n";
00104 stream <<
"BuildRoot: " <<
"%{_tmppath}/%{name}-root" <<
"\n";
00105 stream <<
"Source: " <<
getAppSource() <<
"\n";
00106
00107 stream <<
"\n";
00108 stream <<
"%description\n";
00109 stream <<
getAppDescription()<<
"\n";
00110
00111 stream <<
"\n";
00112 stream <<
"%prep\n";
00113 stream <<
"%setup\n";
00114 stream <<
"CFLAGS=\"$RPM_OPT_FLAGS\" CXXFLAGS=\"$RPM_OPT_FLAGS\" ./configure \\" <<
"\n";
00115 stream <<
"--target=" <<
getAppArch() <<
"\n";
00116
00117 stream <<
"\n";
00118 stream <<
"%build\n";
00119 stream <<
"%configure\n";
00120 stream <<
"make\n";
00121
00122 stream <<
"\n";
00123 stream <<
"%install\n";
00124 stream <<
"rm -rf %{buildroot}\n";
00125 stream <<
"%makeinstall\n";
00126
00127 stream <<
"\n";
00128 stream <<
"%clean\n";
00129 stream <<
"rm -rf %{buildroot}\n";
00130
00131 stream <<
"\n";
00132 stream <<
"%post -p /sbin/ldconfig\n";
00133
00134 stream <<
"%postun -p /sbin/ldconfig\n";
00135
00136 stream <<
"%files\n";
00137 stream <<
"%defattr(-, root, root)\n";
00138 stream <<
"%doc AUTHORS COPYING ChangeLog NEWS README TODO\n";
00139 stream <<
"%{_bindir}/*\n";
00140 stream <<
"%{_libdir}/*.so.*\n";
00141 stream <<
"%{_datadir}/%{name}\n";
00142 stream <<
"%{_mandir}/man8/*\n";
00143
00144 stream <<
"%changelog\n";
00145 stream <<
getAppChangelog() <<
"\n";
00146
00147
00148
file.close();
00149 }
else {
00150
kdDebug() <<
"TODO : intercept write error in SpecSupport::slotexportSPECPushButtonPressed()";
00151 }
00152 }
00153
00154 QString SpecSupport::getInfo(
QString s,
QString motif) {
00155
QRegExp re(motif +
"[ \t]*([^ \t].*[^ \t])[ \t]*");
00156
if (re.exactMatch(s))
00157
return re.cap(1);
00158
return QString::null;
00159 }
00160
00161
00162 void SpecSupport::slotimportSPECPushButtonPressed() {
00163
QString fileName = KFileDialog::getOpenFileName(dir,
"*.spec");
00164
if( fileName.isEmpty())
00165
return;
00166
QFile file(fileName);
00167
if(
file.open(IO_ReadOnly)) {
00168
QTextStream stream(&
file);
00169
00170
while (!stream.atEnd()) {
00171
QString s = stream.readLine();
00172
QString info;
00173
if (!(info =
getInfo(s,
"Name:")).isEmpty())
00174 setAppName(info);
00175
else if (!(info = getInfo(s,
"Version:")).isEmpty())
00176 setAppVersion(info);
00177
else if (!(info = getInfo(s,
"Release:")).isEmpty())
00178 setAppRevision(info);
00179
else if (!(info = getInfo(s,
"Vendor:")).isEmpty())
00180 setAppVendor(info);
00181
else if (!(info = getInfo(s,
"Copyright:")).isEmpty())
00182 setAppLicense(info);
00183
else if (!(info = getInfo(s,
"Summary:")).isEmpty())
00184 setAppSummary(info);
00185
else if (!(info = getInfo(s,
"Group:")).isEmpty())
00186 setAppGroup(info);
00187
else if (!(info = getInfo(s,
"Packager:")).isEmpty())
00188 setAppPackager(info);
00189
else if (s.startsWith(
"%description")) {
00190
QString desc;
00191
while (!stream.atEnd()) {
00192
QString str = stream.readLine();
00193
if (str.startsWith(
"%"))
break;
00194
else desc += str +
"\n";
00195 }
00196 setAppDescription(desc);
00197 }
00198
else if (s.startsWith(
"%changelog")) {
00199
QString change;
00200
while (!stream.atEnd()) {
00201
QString str = stream.readLine();
00202
if (str.startsWith(
"%"))
break;
00203
else change += str +
"\n";
00204 }
00205 setAppChangelog(change);
00206 }
00207 }
00208 }
00209 }
00210
00211
00212 void SpecSupport::slotsrcPackagePushButtonPressed() {
00213
QMap<QString,QString>::Iterator it;
00214
00215
QFile file1(dir +
"/" +
getAppSource());
00216
QFile file2(*(
map.find(
"_sourcedir")) +
"/" +
getAppSource());
00217
if (!file2.exists()) {
00218
if (!file1.exists()) {
00219 QMessageBox::critical(
this,i18n(
"Error"),i18n(
"You need to create a source archive first!"));
00220
return;
00221 }
00222
else
00223
m_part->
makeFrontend()->
queueCommand(dir,
"cd " + dir +
" && cp " +
getAppSource() +
" " + *(
map.find(
"_sourcedir")));
00224 }
00225
m_part->
makeFrontend()->
queueCommand(dir,
"cd " + (((it =
map.find(
"_specdir")) !=
map.end()) ? (*it) : dir) +
" && rpmbuild -bs " +
m_part->
project()->
projectName() +
".spec");
00226 }
00227
00228 void SpecSupport::parseDotRpmmacros() {
00229
QFile dotfile(QDir::homeDirPath() +
"/.rpmmacros");
00230
00231
if (!dotfile.open(IO_ReadOnly)) {
00232
00233
00234
00235
return;
00236 }
00237
QTextStream stream(&dotfile);
00238
00239
00240
00241
00242
map.insert(
"name",
getAppName());
00243
00244
00245
while (!stream.atEnd()) {
00246
QString s = stream.readLine();
00247
QRegExp re(
"%([^ \t]*)[ \t][ \t]*([^\t]*)$");
00248
if(re.exactMatch(s)) {
00249
QRegExp subst(
"%\\{([^%]*)\\}");
00250
QString value = re.cap(2).stripWhiteSpace();
00251
00252
while(subst.search(value) != -1) {
00253 value.replace(
QRegExp(
"%\\{"+
QRegExp_escape( subst.cap(1) ) +
"\\}"),*
map.find(subst.cap(1)));
00254 }
00255
map.insert(re.cap(1),value);
00256 }
00257 }
00258 dotfile.close();
00259
00260
00261
createRpmDirectoryFromMacro(
"_topdir");
00262
createRpmDirectoryFromMacro(
"_tmppath");
00263
createRpmDirectoryFromMacro(
"_builddir");
00264
createRpmDirectoryFromMacro(
"_rpmdir");
00265
createRpmDirectoryFromMacro(
"_sourcedir");
00266
createRpmDirectoryFromMacro(
"_specdir");
00267
createRpmDirectoryFromMacro(
"_srcrpmdir");
00268 }
00269
00270 bool SpecSupport::createRpmDirectoryFromMacro(
const QString & name) {
00271
QMap<QString,QString>::Iterator it;
00272
if((it =
map.find(name)) !=
map.end()) {
00273
QDir dir(*it);
00274
if (!dir.exists())
return dir.mkdir(*it);
00275 }
00276
return false;
00277 }