summaryrefslogtreecommitdiff
path: root/src/lib/jsextensions
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@digia.com>2013-07-03 11:24:18 +0200
committerJoerg Bornemann <joerg.bornemann@digia.com>2013-07-03 14:54:57 +0200
commitea32d49bdad1ca8959c5254f9ad28956c3d9e5f2 (patch)
tree7356bccac68a7a4a8d20bfe6227d8130eb6b4126 /src/lib/jsextensions
parentbdd0c7768b84e9ca1f2b758ecc7c82cceb43f4d5 (diff)
downloadqbs-ea32d49bdad1ca8959c5254f9ad28956c3d9e5f2.tar.gz
Improve JS extension class "Process".
- Get rid of irrelevant functionality. - Add ability to retrieve stderr output and exit code. - Make it possible to tell a process to throw a JS exception on failure. - Use above feature in DarwinGCC.qbs. This will make problems such as QBS-348 easier to diagnose in the future. - Remove nonsensical checks and conversions. Change-Id: Ie823a21c2cb86c66269c120069cf1d2022d9aa05 Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
Diffstat (limited to 'src/lib/jsextensions')
-rw-r--r--src/lib/jsextensions/process.cpp120
-rw-r--r--src/lib/jsextensions/process.h22
2 files changed, 71 insertions, 71 deletions
diff --git a/src/lib/jsextensions/process.cpp b/src/lib/jsextensions/process.cpp
index 900bb9284..3938192d6 100644
--- a/src/lib/jsextensions/process.cpp
+++ b/src/lib/jsextensions/process.cpp
@@ -29,11 +29,13 @@
#include "process.h"
+#include <logging/translator.h>
#include <tools/hostosinfo.h>
#include <QProcess>
#include <QScriptEngine>
#include <QScriptValue>
+#include <QTextCodec>
#include <QTextStream>
namespace qbs {
@@ -62,7 +64,7 @@ QScriptValue Process::ctor(QScriptContext *context, QScriptEngine *engine)
// Get environment
QVariant v = engine->property("_qbs_procenv");
if (!v.isNull())
- t->qenvironment
+ t->m_environment
= QProcessEnvironment(*reinterpret_cast<QProcessEnvironment*>(v.value<void*>()));
return obj;
@@ -70,132 +72,124 @@ QScriptValue Process::ctor(QScriptContext *context, QScriptEngine *engine)
Process::~Process()
{
- delete qstream;
- delete qprocess;
+ delete m_textStream;
+ delete m_qProcess;
}
Process::Process(QScriptContext *context)
{
Q_UNUSED(context);
Q_ASSERT(thisObject().engine() == engine());
- Process *t = this;
- t->qprocess = new QProcess;
- t->qstream = new QTextStream(t->qprocess);
+ m_qProcess = new QProcess;
+ m_textStream = new QTextStream(m_qProcess);
}
QString Process::getEnv(const QString &name)
{
Q_ASSERT(thisObject().engine() == engine());
- return qenvironment.value(name);
+ return m_environment.value(name);
}
void Process::setEnv(const QString &name, const QString &value)
{
Q_ASSERT(thisObject().engine() == engine());
- qenvironment.insert(name, value);
+ m_environment.insert(name, value);
}
bool Process::start(const QString &program, const QStringList &arguments)
{
Q_ASSERT(thisObject().engine() == engine());
- Process *t = qscriptvalue_cast<Process*>(thisObject());
- t->qprocess->setProcessEnvironment(qenvironment);
- t->qprocess->start(program, arguments);
- return t->qprocess->waitForStarted();
+ m_qProcess->setProcessEnvironment(m_environment);
+ m_qProcess->start(program, arguments);
+ return m_qProcess->waitForStarted();
}
-int Process::exec(const QString &program, const QStringList &arguments)
+int Process::exec(const QString &program, const QStringList &arguments, bool throwOnError)
{
Q_ASSERT(thisObject().engine() == engine());
- Process *t = qscriptvalue_cast<Process*>(thisObject());
- t->qprocess->setProcessEnvironment(qenvironment);
- t->qprocess->start(program, arguments);
- if (!t->qprocess->waitForStarted())
+ m_qProcess->setProcessEnvironment(m_environment);
+ m_qProcess->start(program, arguments);
+ if (!m_qProcess->waitForStarted()) {
+ if (throwOnError) {
+ context()->throwError(Tr::tr("Error running '%1': %2")
+ .arg(program, m_qProcess->errorString()));
+ }
return -1;
- qprocess->closeWriteChannel();
- qprocess->waitForFinished();
- return qprocess->exitCode();
+ }
+ m_qProcess->closeWriteChannel();
+ m_qProcess->waitForFinished();
+ if (throwOnError) {
+ if (m_qProcess->error() != QProcess::UnknownError) {
+ context()->throwError(Tr::tr("Error running '%1': %2")
+ .arg(program, m_qProcess->errorString()));
+ } else if (m_qProcess->exitCode() != 0) {
+ QString errorMessage = Tr::tr("Process '%1' finished with exit code %2.")
+ .arg(program).arg(m_qProcess->exitCode());
+ const QString stdErr = readStdErr();
+ if (!stdErr.isEmpty())
+ errorMessage.append(Tr::tr(" The standard error output was:\n")).append(stdErr);
+ context()->throwError(errorMessage);
+ }
+ }
+ return m_qProcess->exitCode();
}
void Process::close()
{
Q_ASSERT(thisObject().engine() == engine());
- Process *t = qscriptvalue_cast<Process*>(thisObject());
- delete t->qprocess;
- t->qprocess = 0;
- delete t->qstream;
- t->qstream = 0;
-}
-
-void Process::closeWriteChannel()
-{
- Q_ASSERT(thisObject().engine() == engine());
- Process *t = this;
-
- t->qprocess->closeWriteChannel();
+ delete m_qProcess;
+ m_qProcess = 0;
+ delete m_textStream;
+ m_textStream = 0;
}
bool Process::waitForFinished(int msecs)
{
Q_ASSERT(thisObject().engine() == engine());
- Process *t = this;
- return t->qprocess->waitForFinished(msecs);
+ return m_qProcess->waitForFinished(msecs);
}
void Process::setCodec(const QString &codec)
{
Q_ASSERT(thisObject().engine() == engine());
- Process *t = qscriptvalue_cast<Process*>(thisObject());
- if (!t->qstream)
- return;
- t->qstream->setCodec(qPrintable(codec));
+ m_textStream->setCodec(qPrintable(codec));
}
QString Process::readLine()
{
- Process *t = qscriptvalue_cast<Process*>(thisObject());
- if (!t->qprocess)
- return QString();
- return t->qstream->readLine();
+ return m_textStream->readLine();
+}
+
+QString Process::readStdOut()
+{
+ return m_textStream->readAll();
}
-QString Process::readAll()
+QString Process::readStdErr()
{
- Process *t = qscriptvalue_cast<Process*>(thisObject());
- if (!t->qprocess)
- return QString();
- return t->qstream->readAll();
+ return m_textStream->codec()->toUnicode(m_qProcess->readAllStandardError());
}
-bool Process::atEof() const
+int Process::exitCode() const
{
- Process *t = qscriptvalue_cast<Process*>(thisObject());
- if (!t->qstream)
- return true;
- return t->qstream->atEnd();
+ return m_qProcess->exitCode();
}
void Process::write(const QString &str)
{
- Process *t = qscriptvalue_cast<Process*>(thisObject());
- if (!t->qstream)
- return;
- (*t->qstream) << str;
+ (*m_textStream) << str;
}
void Process::writeLine(const QString &str)
{
- Process *t = qscriptvalue_cast<Process*>(thisObject());
- if (!t->qstream)
- return;
- (*t->qstream) << str;
+ (*m_textStream) << str;
if (HostOsInfo::isWindowsHost())
- (*t->qstream) << '\r';
- (*t->qstream) << '\n';
+ (*m_textStream) << '\r';
+ (*m_textStream) << '\n';
}
} // namespace Internal
diff --git a/src/lib/jsextensions/process.h b/src/lib/jsextensions/process.h
index dc4cdc432..b2a99daa9 100644
--- a/src/lib/jsextensions/process.h
+++ b/src/lib/jsextensions/process.h
@@ -52,24 +52,30 @@ public:
static QScriptValue ctor(QScriptContext *context, QScriptEngine *engine);
Process(QScriptContext *context);
~Process();
+
Q_INVOKABLE QString getEnv(const QString &name);
Q_INVOKABLE void setEnv(const QString &name, const QString &value);
+ Q_INVOKABLE void setCodec(const QString &codec);
+
Q_INVOKABLE bool start(const QString &program, const QStringList &arguments);
- Q_INVOKABLE int exec(const QString &program, const QStringList &arguments);
+ Q_INVOKABLE int exec(const QString &program, const QStringList &arguments,
+ bool throwOnError = false);
Q_INVOKABLE void close();
- Q_INVOKABLE void closeWriteChannel();
Q_INVOKABLE bool waitForFinished(int msecs = 30000);
- Q_INVOKABLE void setCodec(const QString &codec);
+
Q_INVOKABLE QString readLine();
- Q_INVOKABLE QString readAll();
- Q_INVOKABLE bool atEof() const;
+ Q_INVOKABLE QString readStdOut();
+ Q_INVOKABLE QString readStdErr();
+
Q_INVOKABLE void write(const QString &str);
Q_INVOKABLE void writeLine(const QString &str);
+ Q_INVOKABLE int exitCode() const;
+
private:
- QProcess *qprocess;
- QProcessEnvironment qenvironment;
- QTextStream *qstream;
+ QProcess *m_qProcess;
+ QProcessEnvironment m_environment;
+ QTextStream *m_textStream;
};
} // namespace Internal