bool AndroidRunnerWorkerBase::runAdb(const QStringList &args, int timeoutS) { Utils::SynchronousProcess adb; adb.setTimeoutS(timeoutS); Utils::SynchronousProcessResponse response = adb.run(m_adb, selector() + args); m_lastRunAdbError = response.exitMessage(m_adb, timeoutS); m_lastRunAdbRawOutput = response.allRawOutput(); return response.result == Utils::SynchronousProcessResponse::Finished; }
bool AndroidManager::checkCertificateExists(const QString &keystorePath, const QString &keystorePasswd, const QString &alias) { // assumes that the keystore password is correct QStringList arguments = { "-list", "-keystore", keystorePath, "--storepass", keystorePasswd, "-alias", alias }; Utils::SynchronousProcess proc; proc.setTimeoutS(10); Utils::SynchronousProcessResponse response = proc.run(AndroidConfigurations::currentConfig().keytoolPath().toString(), arguments); return response.result == Utils::SynchronousProcessResponse::Finished && response.exitCode == 0; }
void MainWindow::test() { QStringList args = QApplication::arguments(); args.pop_front(); const QString cmd = args.front(); args.pop_front(); Utils::SynchronousProcess process; process.setTimeoutS(2); qDebug() << "Async: " << cmd << args; connect(&process, SIGNAL(stdOut(QString,bool)), this, SLOT(append(QString))); connect(&process, SIGNAL(stdErr(QString,bool)), this, SLOT(append(QString))); const Utils::SynchronousProcessResponse resp = process.run(cmd, args); qDebug() << resp; }
static int updateVersionHelper(const QString &command) { Utils::SynchronousProcess process; Utils::SynchronousProcessResponse response = process.runBlocking(command, QStringList() << QLatin1String("--version")); if (response.result != Utils::SynchronousProcessResponse::Finished) return 0; // Astyle prints the version on stdout or stderr, depending on platform const int version = parseVersion(response.stdOut().trimmed()); if (version != 0) return version; return parseVersion(response.stdErr().trimmed()); }
bool AndroidManager::checkKeystorePassword(const QString &keystorePath, const QString &keystorePasswd) { if (keystorePasswd.isEmpty()) return false; QStringList arguments; arguments << QLatin1String("-list") << QLatin1String("-keystore") << keystorePath << QLatin1String("--storepass") << keystorePasswd; Utils::SynchronousProcess proc; proc.setTimeoutS(10); Utils::SynchronousProcessResponse response = proc.run(AndroidConfigurations::currentConfig().keytoolPath().toString(), arguments); return (response.result == Utils::SynchronousProcessResponse::Finished && response.exitCode == 0); }
ClangExecutableVersion clangExecutableVersion(const QString &executable) { const ClangExecutableVersion invalidVersion; // Sanity checks const QFileInfo fileInfo(executable); const bool isExecutableFile = fileInfo.isFile() && fileInfo.isExecutable(); if (!isExecutableFile) return invalidVersion; // Get version output Utils::Environment environment = Utils::Environment::systemEnvironment(); Utils::Environment::setupEnglishOutput(&environment); Utils::SynchronousProcess runner; runner.setEnvironment(environment.toStringList()); runner.setTimeoutS(10); // We would prefer "-dumpversion", but that one returns some old version number. const QStringList arguments(QLatin1String(("--version"))); const Utils::SynchronousProcessResponse response = runner.runBlocking(executable, arguments); if (response.result != Utils::SynchronousProcessResponse::Finished) return invalidVersion; const QString output = response.stdOut(); // Parse version output const QRegularExpression re(QLatin1String("clang version (\\d+)\\.(\\d+)\\.(\\d+)")); const QRegularExpressionMatch reMatch = re.match(output); if (re.captureCount() != 3) return invalidVersion; const QString majorString = reMatch.captured(1); bool convertedSuccessfully = false; const int major = majorString.toInt(&convertedSuccessfully); if (!convertedSuccessfully) return invalidVersion; const QString minorString = reMatch.captured(2); const int minor = minorString.toInt(&convertedSuccessfully); if (!convertedSuccessfully) return invalidVersion; const QString patchString = reMatch.captured(3); const int patch = patchString.toInt(&convertedSuccessfully); if (!convertedSuccessfully) return invalidVersion; return ClangExecutableVersion(major, minor, patch); }
void IosProbe::detectDeveloperPaths() { QString program = QLatin1String("/usr/bin/xcode-select"); QStringList arguments(QLatin1String("--print-path")); Utils::SynchronousProcess selectedXcode; selectedXcode.setTimeoutS(5); Utils::SynchronousProcessResponse response = selectedXcode.run(program, arguments); if (response.result != Utils::SynchronousProcessResponse::Finished) { qCWarning(probeLog) << QString::fromLatin1("Could not detect selected xcode with /usr/bin/xcode-select"); } else { QString path = response.stdOut(); path.chop(1); addDeveloperPath(path); } addDeveloperPath(QLatin1String("/Applications/Xcode.app/Contents/Developer")); }
void AndroidCreateKeystoreCertificate::on_buttonBox_accepted() { if (!validateUserInput()) return; m_keystoreFilePath = Utils::FileName::fromString(QFileDialog::getSaveFileName(this, tr("Keystore file name"), QDir::homePath() + QLatin1String("/android_release.keystore"), tr("Keystore files (*.keystore *.jks)"))); if (m_keystoreFilePath.isEmpty()) return; QString distinguishedNames(QString::fromLatin1("CN=%1, O=%2, L=%3, C=%4") .arg(ui->commonNameLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,"))) .arg(ui->organizationNameLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,"))) .arg(ui->localityNameLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,"))) .arg(ui->countryLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,")))); if (ui->organizationUnitLineEdit->text().length()) distinguishedNames += QLatin1String(", OU=") + ui->organizationUnitLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,")); if (ui->stateNameLineEdit->text().length()) distinguishedNames += QLatin1String(", S=") + ui->stateNameLineEdit->text().replace(QLatin1Char(','), QLatin1String("\\,")); const QString command = AndroidConfigurations::currentConfig().keytoolPath().toString(); QStringList params; params << QLatin1String("-genkey") << QLatin1String("-keyalg") << QLatin1String("RSA") << QLatin1String("-keystore") << m_keystoreFilePath.toString() << QLatin1String("-storepass") << keystorePassword() << QLatin1String("-alias") << certificateAlias() << QLatin1String("-keysize") << ui->keySizeSpinBox->text() << QLatin1String("-validity") << ui->validitySpinBox->text() << QLatin1String("-keypass") << certificatePassword() << QLatin1String("-dname") << distinguishedNames; Utils::SynchronousProcess genKeyCertProc; genKeyCertProc.setTimeoutS(15); Utils::SynchronousProcessResponse response = genKeyCertProc.run(command, params); if (response.result != Utils::SynchronousProcessResponse::Finished || response.exitCode != 0) { QMessageBox::critical(this, tr("Error"), response.exitMessage(command, 15) + QLatin1Char('\n') + response.allOutput()); return; } accept(); }
bool AndroidRunnerWorkerBase::adbShellAmNeedsQuotes() { // Between Android SDK Tools version 24.3.1 and 24.3.4 the quoting // needs for the 'adb shell am start ...' parameters changed. // Run a test to find out on what side of the fence we live. // The command will fail with a complaint about the "--dummy" // option on newer SDKs, and with "No intent supplied" on older ones. // In case the test itself fails assume a new SDK. Utils::SynchronousProcess adb; adb.setTimeoutS(10); Utils::SynchronousProcessResponse response = adb.run(m_adb, selector() << "shell" << "am" << "start" << "-e" << "dummy" << "dummy --dummy"); if (response.result == Utils::SynchronousProcessResponse::StartFailed || response.result != Utils::SynchronousProcessResponse::Finished) return true; const QString output = response.allOutput(); const bool oldSdk = output.contains("Error: No intent supplied"); return !oldSdk; }
void ArtisticStyleSettings::createDocumentationFile() const { Utils::SynchronousProcess process; process.setTimeoutS(2); Utils::SynchronousProcessResponse response = process.runBlocking(command(), QStringList() << QLatin1String("-h")); if (response.result != Utils::SynchronousProcessResponse::Finished) return; QFile file(documentationFilePath()); const QFileInfo fi(file); if (!fi.exists()) fi.dir().mkpath(fi.absolutePath()); if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) return; bool contextWritten = false; QXmlStreamWriter stream(&file); stream.setAutoFormatting(true); stream.writeStartDocument("1.0", true); stream.writeComment("Created " + QDateTime::currentDateTime().toString(Qt::ISODate)); stream.writeStartElement(Constants::DOCUMENTATION_XMLROOT); // astyle writes its output to 'error'... const QStringList lines = response.stdErr().split(QLatin1Char('\n')); QStringList keys; QStringList docu; for (QString line : lines) { line = line.trimmed(); if ((line.startsWith("--") && !line.startsWith("---")) || line.startsWith("OR ")) { const QStringList rawKeys = line.split(" OR ", QString::SkipEmptyParts); for (QString k : rawKeys) { k = k.trimmed(); k.remove('#'); keys << k; if (k.startsWith("--")) keys << k.right(k.size() - 2); } } else { if (line.isEmpty()) { if (!keys.isEmpty()) { // Write entry stream.writeStartElement(Constants::DOCUMENTATION_XMLENTRY); stream.writeStartElement(Constants::DOCUMENTATION_XMLKEYS); for (const QString &key : keys) stream.writeTextElement(Constants::DOCUMENTATION_XMLKEY, key); stream.writeEndElement(); const QString text = "<p><span class=\"option\">" + keys.filter(QRegExp("^\\-")).join(", ") + "</span></p><p>" + (docu.join(' ').toHtmlEscaped()) + "</p>"; stream.writeTextElement(Constants::DOCUMENTATION_XMLDOC, text); stream.writeEndElement(); contextWritten = true; } keys.clear(); docu.clear(); } else if (!keys.isEmpty()) { docu << line; } } } stream.writeEndElement(); stream.writeEndDocument(); // An empty file causes error messages and a contextless file preventing this function to run // again in order to generate the documentation successfully. Thus delete the file. if (!contextWritten) { file.close(); file.remove(); } }
void UncrustifySettings::createDocumentationFile() const { Utils::SynchronousProcess process; process.setTimeoutS(2); Utils::SynchronousProcessResponse response = process.run(command(), QStringList() << QLatin1String("--show-config")); if (response.result != Utils::SynchronousProcessResponse::Finished) return; QFile file(documentationFilePath()); const QFileInfo fi(file); if (!fi.exists()) fi.dir().mkpath(fi.absolutePath()); if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) return; bool contextWritten = false; QXmlStreamWriter stream(&file); stream.setAutoFormatting(true); stream.writeStartDocument("1.0", true); stream.writeComment("Created " + QDateTime::currentDateTime().toString(Qt::ISODate)); stream.writeStartElement(Constants::DOCUMENTATION_XMLROOT); const QStringList lines = response.allOutput().split(QLatin1Char('\n')); const int totalLines = lines.count(); for (int i = 0; i < totalLines; ++i) { const QString &line = lines.at(i); if (line.startsWith('#') || line.trimmed().isEmpty()) continue; const int firstSpace = line.indexOf(' '); const QString keyword = line.left(firstSpace); const QString options = line.right(line.size() - firstSpace).trimmed(); QStringList docu; while (++i < totalLines) { const QString &subline = lines.at(i); if (line.startsWith('#') || subline.trimmed().isEmpty()) { const QString text = "<p><span class=\"option\">" + keyword + "</span> <span class=\"param\">" + options + "</span></p><p>" + docu.join(' ').toHtmlEscaped() + "</p>"; stream.writeStartElement(Constants::DOCUMENTATION_XMLENTRY); stream.writeTextElement(Constants::DOCUMENTATION_XMLKEY, keyword); stream.writeTextElement(Constants::DOCUMENTATION_XMLDOC, text); stream.writeEndElement(); contextWritten = true; break; } else { docu << subline; } } } stream.writeEndElement(); stream.writeEndDocument(); // An empty file causes error messages and a contextless file preventing this function to run // again in order to generate the documentation successfully. Thus delete the file. if (!contextWritten) { file.close(); file.remove(); } }
Utils::SynchronousProcessResponse VcsCommand::runVcs(const QStringList &arguments, int timeoutMS, Utils::ExitCodeInterpreter *interpreter) { Utils::SynchronousProcessResponse response; OutputProxy outputProxy; if (d->m_binaryPath.isEmpty()) { response.result = Utils::SynchronousProcessResponse::StartFailed; return response; } if (!(d->m_flags & VcsBasePlugin::SuppressCommandLogging)) emit outputProxy.appendCommand(d->m_workingDirectory, d->m_binaryPath, arguments); const bool sshPromptConfigured = !d->m_sshPasswordPrompt.isEmpty(); if (debugExecution) { QDebug nsp = qDebug().nospace(); nsp << "Command::runVcs" << d->m_workingDirectory << d->m_binaryPath << arguments << timeoutMS; if (d->m_flags & VcsBasePlugin::ShowStdOutInLogWindow) nsp << "stdout"; if (d->m_flags & VcsBasePlugin::SuppressStdErrInLogWindow) nsp << "suppress_stderr"; if (d->m_flags & VcsBasePlugin::SuppressFailMessageInLogWindow) nsp << "suppress_fail_msg"; if (d->m_flags & VcsBasePlugin::MergeOutputChannels) nsp << "merge_channels"; if (d->m_flags & VcsBasePlugin::SshPasswordPrompt) nsp << "ssh (" << sshPromptConfigured << ')'; if (d->m_flags & VcsBasePlugin::SuppressCommandLogging) nsp << "suppress_log"; if (d->m_flags & VcsBasePlugin::ForceCLocale) nsp << "c_locale"; if (d->m_flags & VcsBasePlugin::FullySynchronously) nsp << "fully_synchronously"; if (d->m_flags & VcsBasePlugin::ExpectRepoChanges) nsp << "expect_repo_changes"; if (d->m_codec) nsp << " Codec: " << d->m_codec->name(); } // TODO tell the document manager about expected repository changes // if (d->m_flags & ExpectRepoChanges) // Core::DocumentManager::expectDirectoryChange(d->m_workingDirectory); if (d->m_flags & VcsBasePlugin::FullySynchronously) { response = runSynchronous(arguments, timeoutMS, interpreter); } else { Utils::SynchronousProcess process; process.setExitCodeInterpreter(interpreter); connect(this, &VcsCommand::terminate, &process, &Utils::SynchronousProcess::terminate); if (!d->m_workingDirectory.isEmpty()) process.setWorkingDirectory(d->m_workingDirectory); QProcessEnvironment env = d->m_environment; VcsBasePlugin::setProcessEnvironment(&env, (d->m_flags & VcsBasePlugin::ForceCLocale), d->m_sshPasswordPrompt); process.setProcessEnvironment(env); process.setTimeout(timeoutMS); if (d->m_codec) process.setCodec(d->m_codec); // Suppress terminal on UNIX for ssh prompts if it is configured. if (sshPromptConfigured && (d->m_flags & VcsBasePlugin::SshPasswordPrompt)) process.setFlags(Utils::SynchronousProcess::UnixTerminalDisabled); // connect stderr to the output window if desired if (d->m_flags & VcsBasePlugin::MergeOutputChannels) { process.setProcessChannelMode(QProcess::MergedChannels); } else if (d->m_progressiveOutput || !(d->m_flags & VcsBasePlugin::SuppressStdErrInLogWindow)) { process.setStdErrBufferedSignalsEnabled(true); connect(&process, &Utils::SynchronousProcess::stdErrBuffered, this, &VcsCommand::bufferedError); } // connect stdout to the output window if desired if (d->m_progressParser || d->m_progressiveOutput || (d->m_flags & VcsBasePlugin::ShowStdOutInLogWindow)) { process.setStdOutBufferedSignalsEnabled(true); connect(&process, &Utils::SynchronousProcess::stdOutBuffered, this, &VcsCommand::bufferedOutput); } process.setTimeOutMessageBoxEnabled(true); // Run! response = process.run(d->m_binaryPath.toString(), arguments); } if (!d->m_aborted) { // Success/Fail message in appropriate window? if (response.result == Utils::SynchronousProcessResponse::Finished) { if (d->m_flags & VcsBasePlugin::ShowSuccessMessage) { emit outputProxy.appendMessage(response.exitMessage(d->m_binaryPath.toUserOutput(), timeoutMS)); } } else if (!(d->m_flags & VcsBasePlugin::SuppressFailMessageInLogWindow)) { emit outputProxy.appendError(response.exitMessage(d->m_binaryPath.toUserOutput(), timeoutMS)); } } emitRepositoryChanged(); return response; }