Пример #1
0
void CMakeTool::fetchFromCapabilities() const
{
    Utils::SynchronousProcessResponse response = run({ "-E", "capabilities" }, true);
    if (response.result != Utils::SynchronousProcessResponse::Finished)
        return;

    auto doc = QJsonDocument::fromJson(response.stdOut().toUtf8());
    if (!doc.isObject())
        return;

    const QVariantMap data = doc.object().toVariantMap();
    m_hasServerMode = data.value("serverMode").toBool();
    const QVariantList generatorList = data.value("generators").toList();
    for (const QVariant &v : generatorList) {
        const QVariantMap gen = v.toMap();
        m_generators.append(Generator(gen.value("name").toString(),
                                      gen.value("extraGenerators").toStringList(),
                                      gen.value("platformSupport").toBool(),
                                      gen.value("toolsetSupport").toBool()));
    }

    const QVariantMap versionInfo = data.value("version").toMap();
    m_version.major = versionInfo.value("major").toInt();
    m_version.minor = versionInfo.value("minor").toInt();
    m_version.patch = versionInfo.value("patch").toInt();
    m_version.fullVersion = versionInfo.value("string").toByteArray();
}
Пример #2
0
TextEditor::Keywords CMakeTool::keywords()
{
    if (m_functions.isEmpty()) {
        Utils::SynchronousProcessResponse response;
        response = run({ "--help-command-list" });
        if (response.result == Utils::SynchronousProcessResponse::Finished)
            m_functions = response.stdOut().split('\n');

        response = run({ "--help-commands" });
        if (response.result == Utils::SynchronousProcessResponse::Finished)
            parseFunctionDetailsOutput(response.stdOut());

        response = run({ "--help-property-list" });
        if (response.result == Utils::SynchronousProcessResponse::Finished)
            m_variables = parseVariableOutput(response.stdOut());

        response = run({ "--help-variable-list" });
        if (response.result == Utils::SynchronousProcessResponse::Finished) {
            m_variables.append(parseVariableOutput(response.stdOut()));
            m_variables = Utils::filteredUnique(m_variables);
            Utils::sort(m_variables);
        }
    }

    return TextEditor::Keywords(m_variables, m_functions, m_functionArgs);
}
Пример #3
0
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;
}
Пример #4
0
void CMakeTool::fetchGeneratorsFromHelp() const
{
    Utils::SynchronousProcessResponse response = run({ "--help" });
    if (response.result != Utils::SynchronousProcessResponse::Finished)
        return;

    bool inGeneratorSection = false;
    QHash<QString, QStringList> generatorInfo;
    const QStringList lines = response.stdOut().split('\n');
    foreach (const QString &line, lines) {
        if (line.isEmpty())
            continue;
        if (line == "Generators") {
            inGeneratorSection = true;
            continue;
        }
        if (!inGeneratorSection)
            continue;

        if (line.startsWith("  ") && line.at(3) != ' ') {
            int pos = line.indexOf('=');
            if (pos < 0)
                pos = line.length();
            if (pos >= 0) {
                --pos;
                while (pos > 2 && line.at(pos).isSpace())
                    --pos;
            }
            if (pos > 2) {
                const QString fullName = line.mid(2, pos - 1);
                const int dashPos = fullName.indexOf(" - ");
                QString generator;
                QString extra;
                if (dashPos < 0) {
                    generator = fullName;
                } else {
                    extra = fullName.mid(0, dashPos);
                    generator = fullName.mid(dashPos + 3);
                }
                QStringList value = generatorInfo.value(generator);
                if (!extra.isEmpty())
                    value.append(extra);
                generatorInfo.insert(generator, value);
            }
        }
    }

    // Populate genertor list:
    for (auto it = generatorInfo.constBegin(); it != generatorInfo.constEnd(); ++it)
        m_generators.append(Generator(it.key(), it.value()));
}
Пример #5
0
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());
}
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);
}
Пример #7
0
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();
}
Пример #9
0
void CMakeTool::fetchVersionFromVersionOutput() const
{
    Utils::SynchronousProcessResponse response = run({ "--version" });
    if (response.result != Utils::SynchronousProcessResponse::Finished)
        return;

    QRegularExpression versionLine("^cmake version ((\\d+).(\\d+).(\\d+).*)$");
    const QString responseText = response.stdOut();
    for (const QStringRef &line : responseText.splitRef(QLatin1Char('\n'))) {
        QRegularExpressionMatch match = versionLine.match(line);
        if (!match.hasMatch())
            continue;

        m_version.major = match.captured(2).toInt();
        m_version.minor = match.captured(3).toInt();
        m_version.patch = match.captured(4).toInt();
        m_version.fullVersion = match.captured(1).toUtf8();
        break;
    }
}
Пример #10
0
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;
}
Пример #11
0
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();
    }
}
Пример #12
0
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();
    }
}
Пример #13
0
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;
}