2#include <QCoreApplication>
4#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
7#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
8#include <QStringDecoder>
21 static_cast<void (QProcess::*)(
int, QProcess::ExitStatus)
>(
24 static_cast<void (
Executor::*)(
int, QProcess::ExitStatus)
>(
25 &Executor::finished));
32void Executor::executeNext() {
34 if (!m_execQueue.isEmpty()) {
35 const execQueueItem &i = m_execQueue.head();
37 if (!i.workingDir.isEmpty())
38 m_process.setWorkingDirectory(i.workingDir);
39 if (i.app.startsWith(
"wsl ")) {
40 QStringList tmp = i.args;
42 tmp.prepend(app.remove(0, 4));
43 m_process.start(
"wsl", tmp);
45 m_process.start(i.app, i.args);
46 if (!i.input.isEmpty()) {
47 m_process.waitForStarted(-1);
48 QByteArray data = i.input.toUtf8();
49 if (m_process.write(data) != data.length()) {
51 dbg() <<
"Not all data written to process:" << i.id <<
" " << i.app;
55 m_process.closeWriteChannel();
69 bool readStdout,
bool readStderr) {
70 execute(
id, QString(), app, args, QString(), readStdout, readStderr);
83 const QStringList &args,
bool readStdout,
85 execute(
id, workDir, app, args, QString(), readStdout, readStderr);
98 QString input,
bool readStdout,
bool readStderr) {
99 execute(
id, QString(), app, args, input, readStdout, readStderr);
114 const QStringList &args, QString input,
bool readStdout,
121 dbg() <<
"Trying to execute nothing...";
125 QString appPath = app;
126 if (!appPath.startsWith(
"wsl "))
128 QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(app);
129 m_execQueue.push_back(
130 {id, appPath, args, input, readStdout, readStderr, workDir});
144static QString decodeAssumingUtf8(QByteArray in) {
145#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
146 QTextCodec *codec = QTextCodec::codecForName(
"UTF-8");
147 QTextCodec::ConverterState state;
148 QString out = codec->toUnicode(in.constData(), in.size(), &state);
149 if (!state.invalidChars)
151 codec = QTextCodec::codecForUtfText(in);
152 return codec->toUnicode(in);
154 auto converter = QStringDecoder(QStringDecoder::Utf8);
155 return converter(in);
172 QString input, QString *process_out,
173 QString *process_err) {
175 if (app.startsWith(
"wsl ")) {
176 QStringList tmp = args;
177 tmp.prepend(app.remove(0, 4));
178 internal.start(
"wsl", tmp);
180 internal.start(app, args);
181 if (!input.isEmpty()) {
182 QByteArray data = input.toUtf8();
183 internal.waitForStarted(-1);
184 if (internal.write(data) != data.length()) {
186 dbg() <<
"Not all input written:" << app;
189 internal.closeWriteChannel();
191 internal.waitForFinished(-1);
192 if (internal.exitStatus() == QProcess::NormalExit) {
193 QString pout = decodeAssumingUtf8(internal.readAllStandardOutput());
194 QString perr = decodeAssumingUtf8(internal.readAllStandardError());
195 if (process_out != Q_NULLPTR)
197 if (process_err != Q_NULLPTR)
199 return internal.exitCode();
214 QString *process_out, QString *process_err) {
215 return executeBlocking(app, args, QString(), process_out, process_err);
224 m_process.setEnvironment(env);
234 if (running || m_execQueue.isEmpty())
236 return m_execQueue.dequeue().id;
244void Executor::finished(
int exitCode, QProcess::ExitStatus exitStatus) {
245 execQueueItem i = m_execQueue.dequeue();
247 if (exitStatus == QProcess::NormalExit) {
250 output = decodeAssumingUtf8(m_process.readAllStandardOutput());
251 if (i.readStderr || exitCode != 0) {
252 err = decodeAssumingUtf8(m_process.readAllStandardError());
255 dbg() << exitCode << err;
259 emit finished(i.id, exitCode, output, err);
Executes external commands for handleing password, git and other data.
Executor(QObject *parent=0)
Executor::Executor executes external applications.
static int executeBlocking(QString app, const QStringList &args, QString input=QString(), QString *process_out=Q_NULLPTR, QString *process_err=Q_NULLPTR)
Executor::executeBlocking blocking version of the executor, takes input and presents it as stdin.
void execute(int id, const QString &app, const QStringList &args, bool readStdout, bool readStderr=true)
Executor::execute execute an app.
int cancelNext()
Executor::cancelNext cancels execution of first process in queue if it's not already running.
void setEnvironment(const QStringList &env)
Executor::setEnvironment set environment variables for executor processes.
void starting()
starting signal that is emited when process starts