Add sdktool

Add a tool to ease configuration of Qt versions, tool chains
and kits with Qt Creator for the SDK and similar systems.

Change-Id: I9727dd25ea359a935ea494b035a59411eb3529b8
Reviewed-by: Tim Jenssen <tim.jenssen@digia.com>
This commit is contained in:
Tobias Hunger
2012-09-18 15:58:07 +02:00
committed by Tim Jenssen
parent 9c2afc4f29
commit 4f36ad63ce
32 changed files with 3782 additions and 2 deletions

View File

@@ -80,7 +80,8 @@ Project {
"src/plugins/welcome/welcome.qbs",
"src/share/share.qbs",
"src/tools/qtcdebugger/qtcdebugger.qbs",
"src/tools/qtpromaker/qtpromaker.qbs"
"src/tools/qtpromaker/qtpromaker.qbs",
"src/tools/sdktool/sdktool.qbs"
]
Product {

View File

@@ -0,0 +1,135 @@
The SDK tool can be used to set up Qt versions, tool chains and kits
in Qt Creator.
There still is a lot of knowledge about Qt Creator internals required
to use this tool!
Note that some tool chains/Qt versions/kits may require settings not
available via command line switches. All operations will add any parameter
followed by another parameter in the form "<TYPE>:<VALUE>" to the
configuration that they create.
Currently supported types are int, bool, QString, QByteArray and QVariantList.
Dependencies:
The SDK tool depends on the Utils library of Qt Creator and Qt itself.
Please make sure both libraries are found by setting PATH/LD_LIBRARY_PATH.
Usage:
Qt Creator SDK setup tool.
Usage:./sdktool <ARGS> <OPERATION> <OPERATION_ARGS>
ARGS:
--help|-h Print this help text
--sdkpath=PATH|-s PATH Set the path to the SDK files
OPERATION:
One of:
addKeys add settings to Qt Creator configuration
addKit add a Kit to Qt Creator
addQt add a Qt version to Qt Creator
addTC add a tool chain to Qt Creator
findKey find a key in the settings of Qt Creator
find find a value in the settings of Qt Creator
get get settings from Qt Creator configuration
rmKeys remove settings from Qt Creator configuration
rmKit remove a Kit from Qt Creator
rmQt remove a Qt version from Qt Creator
rmTC remove a tool chain from Qt Creator
OPERATION_ARGS:
use "--help <OPERATION>" to get help on the arguments required for an operation.
Help for individual operations can be retrieved using
./sdktool --help addKit
Examples:
Add a tool chain:
./sdktool addTC \
--id "ProjectExplorer.ToolChain.Gcc:my_test_TC" \
--name "Test TC" \
--path /usr/bin/g++ \
--abi x86-linux-generic-elf-64bit \
--supportedAbis x86-linux-generic-elf-64bit,x86-linux-generic-elf-32bit \
ADDITIONAL_INTEGER_PARAMETER int:42 \
ADDITIONAL_STRING_PARAMETER "QString:some string" \
Tricky parts:
- The id has to be in the form "ToolChainType:some_unique_part", where the
tool chain type must be one of (as of Qt Creator 2.6):
* ProjectExplorer.ToolChain.Msvc for Microsoft MSVC compilers
(Note: This one will be autodetected anyway, so there is little
need to add it from the sdktool)
* ProjectExplorer.ToolChain.WinCE for Windows CE tool chain by
Microsoft (Note: This one will be autodetected anyway, so there
is little need to add it from the sdktool)
* ProjectExplorer.ToolChain.Gcc for a normal GCC (linux/mac)
* Qt4ProjectManager.ToolChain.Android for the Android tool chain
* ProjectExplorer.ToolChain.Clang for the Clang compiler
* ProjectExplorer.ToolChain.LinuxIcc for the LinuxICC compiler
* ProjectExplorer.ToolChain.Mingw for the Mingw compiler
Check the classes derived from ProjectExplorer::ToolChain for their
Ids.
The some_unique_part can be anything. Creator uses GUIDs by default,
but any string is fine for the SDK to use.
- The ABI needs to be in a format that ProjectExplorer::Abi::fromString(...)
can parse.
Add a Qt version:
./sdktool addQt \
--id "my_test_Qt" \
--name "Test Qt" \
--qmake /home/code/build/qt4-4/bin/qmake \
--type Qt4ProjectManager.QtVersion.Desktop \
Tricky parts:
- The id can be any unique string. In creator this is set as the autodetection
source of the Qt version.
- type must be the string returned by BaseQtVersion::type().
Currently these are (Qt Creator 2.6):
* Qt4ProjectManager.QtVersion.Android for Android
* Qt4ProjectManager.QtVersion.Desktop for a desktop Qt
* RemoteLinux.EmbeddedLinuxQt for an embedded linux Qt
* Qt4ProjectManager.QtVersion.Maemo for an Maemo Qt
* Qt4ProjectManager.QtVersion.QNX.BlackBerry for Qt on BlackBerry
* Qt4ProjectManager.QtVersion.QNX.QNX for Qt on QNX
* Qt4ProjectManager.QtVersion.Simulator for Qt running in the Qt simulator
* Qt4ProjectManager.QtVersion.WinCE for Qt on WinCE
Add a Kit using the newly set up tool chain and Qt version:
./sdktool addKit \
--id "my_test_kit" \
--name "Test Kit" \
--debuggerengine 1 \
--debugger /tmp/gdb-test \
--devicetype Desktop \
--sysroot /tmp/sysroot \
--toolchain "ProjectExplorer.ToolChain.Gcc:my_test_TC" \
--qt "my_test_Qt" \
--mkspec "testspec" \
Tricky parts:
- debuggerengine is the integer used in the enum Debugger::DebuggerEngineType
The most important type is 1 for GDB.
- devicetype is the string returned IDevice::type()
Currently these are (Qt Creator 2.6):
* Android.Device.Type for Android devices
* Desktop for code running on the local desktop
* BBOsType for BlackBerry devices
* HarmattanOsType for N9/N950 devices based on Harmattan
* Maemo5OsType for N900 devices based on Maemo
- toolchain is one of the ids used when setting up toolchains with sdktool addTC.
- qt is one of the ids used when setting up Qt versions with sdktool addQt.

View File

@@ -0,0 +1,264 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "addkeysoperation.h"
#include <iostream>
QString AddKeysOperation::name() const
{
return QLatin1String("addKeys");
}
QString AddKeysOperation::helpText() const
{
return QLatin1String("add settings to Qt Creator configuration");
}
QString AddKeysOperation::argumentsHelpText() const
{
return QLatin1String("A file (profiles, qtversions or toolchains) followed by one or more Tuples\n"
"<KEY> <TYPE>:<VALUE> are required. KEY needs to start with\n"
"the name of the file to insert data into (minus the .xml extension).");
}
bool AddKeysOperation::setArguments(const QStringList &args)
{
for (int i = 0; i < args.count(); ++i) {
const QString current = args.at(i);
const QString next = ((i + 1) < args.count()) ? args.at(i + 1) : QString();
if (m_file.isNull()) {
m_file = current;
continue;
}
if (next.isNull())
return false;
++i;
KeyValuePair pair(current, next);
if (pair.key.isEmpty() || !pair.value.isValid())
return false;
m_data << pair;
}
return !m_file.isEmpty();
}
int AddKeysOperation::execute() const
{
if (m_data.isEmpty())
return 0;
QVariantMap map = load(m_file);
map = addKeys(map, m_data);
if (map.isEmpty())
return 1;
// Write data again:
return save(map, m_file) ? 0 : 2;
}
#ifdef WITH_TESTS
bool AddKeysOperation::test() const
{
QVariantMap testMap;
QVariantMap subKeys;
subKeys.insert(QLatin1String("subsubkeys"), QVariantMap());
subKeys.insert(QLatin1String("testbool"), true);
testMap.insert(QLatin1String("subkeys"), subKeys);
subKeys.clear();
testMap.insert(QLatin1String("subkeys2"), subKeys);
testMap.insert(QLatin1String("testint"), 23);
KeyValuePairList data;
data.append(KeyValuePair(QLatin1String("bool-true"), QString::fromLatin1("bool:trUe")));
data.append(KeyValuePair(QLatin1String("bool-false"), QString::fromLatin1("bool:false")));
data.append(KeyValuePair(QLatin1String("int"), QString::fromLatin1("int:42")));
data.append(KeyValuePair(QLatin1String("qstring"), QString::fromLatin1("QString:test string.")));
data.append(KeyValuePair(QLatin1String("qbytearray"), QString::fromLatin1("QByteArray:test array.")));
data.append(KeyValuePair(QLatin1String("subkeys/qbytearray"), QString::fromLatin1("QByteArray:test array.")));
data.append(KeyValuePair(QLatin1String("subkeys/newsubkeys/qbytearray"), QString::fromLatin1("QByteArray:test array.")));
data.append(KeyValuePair(QLatin1String("newsub/1/2/3/qbytearray"), QString::fromLatin1("QByteArray:test array.")));
data.append(KeyValuePair(QLatin1String("newsub/1/2.1/3/qbytearray"), QString::fromLatin1("QByteArray:test array.")));
QVariantMap result = addKeys(testMap, data);
if (!result.count() == 8)
return false;
// subkeys:
QVariantMap cur = result.value(QLatin1String("subkeys")).toMap();
if (cur.count() != 4
|| !cur.contains(QLatin1String("qbytearray"))
|| !cur.contains(QLatin1String("testbool"))
|| !cur.contains(QLatin1String("subsubkeys"))
|| !cur.contains(QLatin1String("newsubkeys")))
return false;
// subkeys/newsubkeys:
QVariantMap tmp = cur;
cur = cur.value(QLatin1String("newsubkeys")).toMap();
if (cur.count() != 1
|| !cur.contains(QLatin1String("qbytearray")))
return false;
// subkeys/subsubkeys:
cur = tmp.value(QLatin1String("subsubkeys")).toMap();
if (cur.count() != 0)
return false;
// newsub:
cur = result.value(QLatin1String("newsub")).toMap();
if (cur.count() != 1
|| !cur.contains(QLatin1String("1")))
return false;
// newsub/1:
cur = cur.value(QLatin1String("1")).toMap();
if (cur.count() != 2
|| !cur.contains(QLatin1String("2"))
|| !cur.contains(QLatin1String("2.1")))
return false;
// newsub/1/2:
tmp = cur;
cur = cur.value(QLatin1String("2")).toMap();
if (cur.count() != 1
|| !cur.contains(QLatin1String("3")))
return false;
// newsub/1/2/3:
cur = cur.value(QLatin1String("3")).toMap();
if (cur.count() != 1
|| !cur.contains(QLatin1String("qbytearray")))
return false;
// newsub/1/2.1:
cur = tmp.value(QLatin1String("2.1")).toMap();
if (cur.count() != 1
|| !cur.contains(QLatin1String("3")))
return false;
// newsub/1/2.1/3:
cur = cur.value(QLatin1String("3")).toMap();
if (cur.count() != 1
|| !cur.contains(QLatin1String("qbytearray")))
return false;
// subkeys2:
cur = result.value(QLatin1String("subkeys2")).toMap();
if (cur.count() != 0)
return false;
// values:
if (!result.contains(QLatin1String("bool-true")) || !result.value(QLatin1String("bool-true")).toBool())
return false;
if (!result.contains(QLatin1String("bool-false")) || result.value(QLatin1String("bool-false")).toBool())
return false;
if (!result.contains(QLatin1String("int")) || result.value(QLatin1String("int")).toInt() != 42)
return false;
if (!result.contains(QLatin1String("qstring"))
|| result.value(QLatin1String("qstring")).toString() != QLatin1String("test string."))
return false;
if (!result.contains(QLatin1String("qbytearray"))
|| result.value(QLatin1String("qbytearray")).toByteArray() != "test array.")
return false;
// Make sure we do not overwrite data:
// preexisting:
data.clear();
data.append(KeyValuePair(QLatin1String("testint"), QString::fromLatin1("int:4")));
result = addKeys(testMap, data);
if (!result.isEmpty())
return false;
data.clear();
data.append(KeyValuePair(QLatin1String("subkeys/testbool"), QString::fromLatin1("int:24")));
result = addKeys(testMap, data);
if (!result.isEmpty())
return false;
// data inserted before:
data.clear();
data.append(KeyValuePair(QLatin1String("bool-true"), QString::fromLatin1("bool:trUe")));
data.append(KeyValuePair(QLatin1String("bool-true"), QString::fromLatin1("bool:trUe")));
result = addKeys(testMap, data);
if (!result.isEmpty())
return false;
return true;
}
#endif
QVariantMap AddKeysOperation::addKeys(const QVariantMap &map, const KeyValuePairList &additions)
{
// Insert data:
QVariantMap result = map;
foreach (const KeyValuePair &p, additions) {
QList<QVariantMap> stack;
// Set up a stack of QVariantMaps along the path we take:
stack.append(result);
for (int i = 0; i < p.key.count() - 1; ++i) {
QVariantMap subMap;
if (stack.last().contains(p.key.at(i)))
subMap = stack.last().value(p.key.at(i)).toMap();
stack.append(subMap);
}
// insert
Q_ASSERT(stack.count() == p.key.count());
if (stack.last().contains(p.key.last())) {
std::cerr << "DEBUG: Adding key " << qPrintable(p.key.join(QLatin1String("/"))) << " which already exists." << std::endl;
return QVariantMap();
}
stack.last().insert(p.key.last(), p.value);
// Generate new resultset by folding maps back in:
QVariantMap foldBack = stack.takeLast();
for (int i = p.key.count() - 2; i >= 0; --i) { // skip last key, that is already taken care of
const QString k = p.key.at(i);
QVariantMap current = stack.takeLast();
current.insert(k, foldBack);
foldBack = current;
}
Q_ASSERT(stack.count() == 0);
Q_ASSERT(foldBack != map);
result = foldBack;
}
return result;
}

View File

@@ -0,0 +1,59 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#ifndef ADDKEYSOPERATION_H
#define ADDKEYSOPERATION_H
#include "operation.h"
class AddKeysOperation : public Operation
{
public:
QString name() const;
QString helpText() const;
QString argumentsHelpText() const;
bool setArguments(const QStringList &args);
int execute() const;
#ifdef WITH_TESTS
bool test() const;
#endif
static QVariantMap addKeys(const QVariantMap &map, const KeyValuePairList &additions);
private:
QString m_file;
QList<KeyValuePair> m_data;
};
#endif // ADDKEYSOPERATION_H

View File

@@ -0,0 +1,382 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "addkitoperation.h"
#include "addkeysoperation.h"
#include "findkeyoperation.h"
#include "findvalueoperation.h"
#include "getoperation.h"
#include "rmkeysoperation.h"
#include "settings.h"
#include <iostream>
// Qt version file stuff:
static char PREFIX[] = "Profile.";
static char VERSION[] = "Version";
static char COUNT[] = "Profile.Count";
static char DEFAULT[] = "Profile.Default";
// Kit:
static char ID[] = "PE.Profile.Id";
static char DISPLAYNAME[] = "PE.Profile.Name";
static char ICON[] = "PE.Profile.Icon";
static char AUTODETECTED[] = "PE.Profile.Autodetected";
static char DATA[] = "PE.Profile.Data";
// Standard KitInformation:
static char DEBUGGER[] = "Debugger.Information";
static char DEBUGGER_ENGINE[] = "EngineType";
static char DEBUGGER_BINARY[] = "Binary";
static char DEVICE_TYPE[] = "PE.Profile.DeviceType";
static char SYSROOT[] = "PE.Profile.SysRoot";
static char TOOLCHAIN[] = "PE.Profile.ToolChain";
static char MKSPEC[] = "QtPM4.mkSpecInformation";
static char QT[] = "QtSupport.QtInformation";
QString AddKitOperation::name() const
{
return QLatin1String("addKit");
}
QString AddKitOperation::helpText() const
{
return QLatin1String("add a Kit to Qt Creator");
}
QString AddKitOperation::argumentsHelpText() const
{
return QLatin1String(" --id <ID> id of the new kit.\n"
" --name <NAME> display name of the new kit.\n"
" --icon <PATH> icon of the new kit.\n"
" --debuggerengine <ENGINE> debuggerengine of the new kit.\n"
" --debugger <PATH> debugger of the new kit.\n"
" --devicetype <TYPE> device type of the new kit.\n"
" --sysroot <PATH> sysroot of the new kit.\n"
" --toolchain <ID> tool chain of the new kit.\n"
" --qt <ID> Qt of the new kit.\n"
" --mkspec <PATH> mkspec of the new kit.\n"
" <KEY> <TYPE:VALUE> extra key value pairs\n");
}
bool AddKitOperation::setArguments(const QStringList &args)
{
m_debuggerEngine = 0;
for (int i = 0; i < args.count(); ++i) {
const QString current = args.at(i);
const QString next = ((i + 1) < args.count()) ? args.at(i + 1) : QString();
if (current == QLatin1String("--id")) {
if (next.isNull())
return false;
++i; // skip next;
m_id = next;
continue;
}
if (current == QLatin1String("--name")) {
if (next.isNull())
return false;
++i; // skip next;
m_displayName = next;
continue;
}
if (current == QLatin1String("--icon")) {
if (next.isNull())
return false;
++i; // skip next;
m_icon = next;
continue;
}
if (current == QLatin1String("--debuggerengine")) {
if (next.isNull())
return false;
++i; // skip next;
bool ok;
m_debuggerEngine = next.toInt(&ok);
if (!ok) {
std::cerr << "Debugger type is not an integer!" << std::endl;
return false;
}
continue;
}
if (current == QLatin1String("--debugger")) {
if (next.isNull())
return false;
++i; // skip next;
m_debugger = next;
continue;
}
if (current == QLatin1String("--devicetype")) {
if (next.isNull())
return false;
++i; // skip next;
m_deviceType = next;
continue;
}
if (current == QLatin1String("--sysroot")) {
if (next.isNull())
return false;
++i; // skip next;
m_sysRoot = next;
continue;
}
if (current == QLatin1String("--toolchain")) {
if (next.isNull())
return false;
++i; // skip next;
m_tc = next;
continue;
}
if (current == QLatin1String("--qt")) {
if (next.isNull())
return false;
++i; // skip next;
m_qt = next;
continue;
}
if (current == QLatin1String("--mkspec")) {
if (next.isNull())
return false;
++i; // skip next;
m_mkspec = next;
continue;
}
if (next.isNull())
return false;
++i; // skip next;
KeyValuePair pair(current, next);
if (!pair.value.isValid())
return false;
m_extra << pair;
}
if (m_icon.isEmpty())
m_icon = QLatin1String(":///DESKTOP///");
return !m_id.isEmpty() && !m_displayName.isEmpty() && !m_deviceType.isEmpty();
}
int AddKitOperation::execute() const
{
QVariantMap map = load(QLatin1String("profiles"));
if (map.isEmpty())
map = initializeKits();
map = addKit(map, m_id, m_displayName, m_icon, m_debuggerEngine, m_debugger,
m_deviceType, m_sysRoot, m_tc, m_qt, m_mkspec, m_extra);
if (map.isEmpty())
return -2;
return save(map, QLatin1String("profiles")) ? 0 : -3;
}
#ifdef WITH_TESTS
bool AddKitOperation::test() const
{
QVariantMap map = initializeKits();
if (!map.count() == 3
|| !map.contains(QLatin1String(VERSION))
|| map.value(QLatin1String(VERSION)).toInt() != 1
|| !map.contains(QLatin1String(COUNT))
|| map.value(QLatin1String(COUNT)).toInt() != 0
|| !map.contains(QLatin1String(DEFAULT))
|| map.value(QLatin1String(DEFAULT)).toInt() != -1)
return false;
map = addKit(map, QLatin1String("testId"), QLatin1String("Test Qt Version"), QLatin1String("/tmp/icon.png"),
1, QLatin1String("/usr/bin/gdb-test"),
QLatin1String("Desktop"), QString(),
QLatin1String("{some-tc-id}"), QLatin1String("{some-qt-id}"), QLatin1String("unsupported/mkspec"),
KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue"))));
if (!map.count() == 4
|| !map.contains(QLatin1String(VERSION))
|| map.value(QLatin1String(VERSION)).toInt() != 1
|| !map.contains(QLatin1String(COUNT))
|| map.value(QLatin1String(COUNT)).toInt() != 1
|| !map.contains(QLatin1String(DEFAULT))
|| map.value(QLatin1String(DEFAULT)).toInt() != 0
|| !map.contains(QLatin1String("Profile.0")))
return false;
QVariantMap profile0 = map.value(QLatin1String("Profile.0")).toMap();
if (!profile0.count() == 6
|| !profile0.contains(QLatin1String(ID))
|| profile0.value(QLatin1String(ID)).toString() != QLatin1String("testId")
|| !profile0.contains(QLatin1String(DISPLAYNAME))
|| profile0.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("Test Qt Version")
|| !profile0.contains(QLatin1String(AUTODETECTED))
|| profile0.value(QLatin1String(AUTODETECTED)).toBool() != true)
return false;
// Ignore existing ids:
QVariantMap result = addKit(map, QLatin1String("testId"), QLatin1String("Test Qt Version X"), QLatin1String("/tmp/icon3.png"),
1, QLatin1String("/usr/bin/gdb-test3"),
QLatin1String("Desktop"), QString(),
QLatin1String("{some-tc-id3}"), QLatin1String("{some-qt-id3}"), QLatin1String("unsupported/mkspec3"),
KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue3"))));
if (!result.isEmpty())
return false;
// Make sure name is unique:
map = addKit(map, QLatin1String("testId2"), QLatin1String("Test Qt Version"), QLatin1String("/tmp/icon2.png"),
1, QLatin1String("/usr/bin/gdb-test2"),
QLatin1String("Desktop"), QString(),
QLatin1String("{some-tc-id2}"), QLatin1String("{some-qt-id2}"), QLatin1String("unsupported/mkspec2"),
KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue2"))));
if (!map.count() == 5
|| !map.contains(QLatin1String(VERSION))
|| map.value(QLatin1String(VERSION)).toInt() != 1
|| !map.contains(QLatin1String(COUNT))
|| map.value(QLatin1String(COUNT)).toInt() != 2
|| !map.contains(QLatin1String(DEFAULT))
|| map.value(QLatin1String(DEFAULT)).toInt() != 0
|| !map.contains(QLatin1String("Profile.0"))
|| !map.contains(QLatin1String("Profile.1")))
if (map.value(QLatin1String("Profile.0")) != profile0)
return false;
QVariantMap profile1 = map.value(QLatin1String("Profile.1")).toMap();
if (!profile1.count() == 6
|| !profile1.contains(QLatin1String(ID))
|| profile1.value(QLatin1String(ID)).toString() != QLatin1String("testId2")
|| !profile1.contains(QLatin1String(DISPLAYNAME))
|| profile1.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("Test Qt Version2")
|| !profile1.contains(QLatin1String(AUTODETECTED))
|| profile1.value(QLatin1String(AUTODETECTED)).toBool() != true)
return false;
return true;
}
#endif
QVariantMap AddKitOperation::addKit(const QVariantMap &map,
const QString &id, const QString &displayName, const QString &icon,
const quint32 &debuggerType, const QString &debugger,
const QString &deviceType, const QString &sysRoot,
const QString &tc, const QString &qt, const QString &mkspec,
const KeyValuePairList &extra)
{
// Sanity check: Make sure autodetection source is not in use already:
QStringList valueKeys = FindValueOperation::findValues(map, QVariant(id));
bool hasId = false;
foreach (const QString &k, valueKeys) {
if (k.endsWith(QString(QLatin1Char('/')) + QLatin1String(ID))) {
hasId = true;
break;
}
}
if (hasId) {
std::cerr << "Error: Id " << qPrintable(id) << " already defined as kit." << std::endl;
return QVariantMap();
}
// Find position to insert:
bool ok;
int count = GetOperation::get(map, QLatin1String(COUNT)).toInt(&ok);
if (!ok || count < 0) {
std::cerr << "Error: Count found in kits file seems wrong." << std::endl;
return QVariantMap();
}
const QString kit = QString::fromLatin1(PREFIX) + QString::number(count);
int defaultKit = GetOperation::get(map, QLatin1String(DEFAULT)).toInt(&ok);
if (!ok) {
std::cerr << "Error: Default kit seems wrong." << std::endl;
return QVariantMap();
}
if (defaultKit < 0)
defaultKit = 0;
// remove data:
QStringList toRemove;
toRemove << QLatin1String(COUNT) << QLatin1String(DEFAULT);
QVariantMap cleaned = RmKeysOperation::rmKeys(map, toRemove);
// Sanity check: Make sure displayName is unique.
QStringList nameKeys = FindKeyOperation::findKey(map, QLatin1String(DISPLAYNAME));
QStringList nameList;
foreach (const QString nameKey, nameKeys)
nameList << GetOperation::get(map, nameKey).toString();
const QString uniqueName = makeUnique(displayName, nameList);
// insert data:
KeyValuePairList data;
data << KeyValuePair(QStringList() << kit << QLatin1String(ID), QVariant(id));
data << KeyValuePair(QStringList() << kit << QLatin1String(DISPLAYNAME), QVariant(uniqueName));
data << KeyValuePair(QStringList() << kit << QLatin1String(ICON), QVariant(icon));
data << KeyValuePair(QStringList() << kit << QLatin1String(AUTODETECTED), QVariant(true));
data << KeyValuePair(QStringList() << kit << QLatin1String(DATA)
<< QLatin1String(DEBUGGER) << QLatin1String(DEBUGGER_ENGINE), QVariant(debuggerType));
data << KeyValuePair(QStringList() << kit << QLatin1String(DATA)
<< QLatin1String(DEBUGGER) << QLatin1String(DEBUGGER_BINARY), QVariant(debugger));
data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << DEVICE_TYPE, QVariant(deviceType));
data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << SYSROOT, QVariant(sysRoot));
data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << TOOLCHAIN, QVariant(tc));
data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << QT, QVariant(qt));
data << KeyValuePair(QStringList() << kit << QLatin1String(DATA) << MKSPEC, QVariant(mkspec));
data << KeyValuePair(QStringList() << QLatin1String(DEFAULT), QVariant(defaultKit));
data << KeyValuePair(QStringList() << QLatin1String(COUNT), QVariant(count + 1));
KeyValuePairList qtExtraList;
foreach (const KeyValuePair &pair, extra)
qtExtraList << KeyValuePair(QStringList() << kit << pair.key, pair.value);
data.append(qtExtraList);
return AddKeysOperation::addKeys(cleaned, data);
}
QVariantMap AddKitOperation::initializeKits()
{
QVariantMap map;
map.insert(QLatin1String(VERSION), 1);
map.insert(QLatin1String(DEFAULT), -1);
map.insert(QLatin1String(COUNT), 0);
return map;
}

View File

@@ -0,0 +1,76 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#ifndef ADDKITOPERATION_H
#define ADDKITOPERATION_H
#include "operation.h"
#include <QString>
class AddKitOperation : public Operation
{
public:
QString name() const;
QString helpText() const;
QString argumentsHelpText() const;
bool setArguments(const QStringList &args);
int execute() const;
#ifdef WITH_TESTS
bool test() const;
#endif
static QVariantMap addKit(const QVariantMap &map,
const QString &id, const QString &displayName, const QString &icon,
const quint32 &debuggerType, const QString &debugger,
const QString &deviceType, const QString &sysRoot,
const QString &tc, const QString &qt, const QString &mkspec,
const KeyValuePairList &extra);
static QVariantMap initializeKits();
private:
QString m_id;
QString m_displayName;
QString m_icon;
quint32 m_debuggerEngine;
QString m_debugger;
QString m_deviceType;
QString m_sysRoot;
QString m_tc;
QString m_qt;
QString m_mkspec;
KeyValuePairList m_extra;
};
#endif // ADDKITOPERATION_H

View File

@@ -0,0 +1,280 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "addqtoperation.h"
#include "addkeysoperation.h"
#include "findkeyoperation.h"
#include "findvalueoperation.h"
#include "getoperation.h"
#include "rmkeysoperation.h"
#include "settings.h"
#include <iostream>
// Qt version file stuff:
static char PREFIX[] = "QtVersion.";
static char VERSION[] = "Version";
// BaseQtVersion:
static char ID[] = "Id";
static char DISPLAYNAME[] = "Name";
static char AUTODETECTED[] = "isAutodetected";
static char AUTODETECTION_SOURCE[] = "autodetectionSource";
static char QMAKE[] = "QMakePath";
static char TYPE[] = "QtVersion.Type";
QString AddQtOperation::name() const
{
return QLatin1String("addQt");
}
QString AddQtOperation::helpText() const
{
return QLatin1String("add a Qt version to Qt Creator");
}
QString AddQtOperation::argumentsHelpText() const
{
return QLatin1String(" --id <ID> id of the new Qt version. (required)\n"
" --name <NAME> display name of the new Qt version. (required)\n"
" --qmake <PATH> path to qmake. (required)\n"
" --type <TYPE> type of Qt version to add. (required)\n"
" --noauto do not mark tool chain as autodetected.\n"
" <KEY> <TYPE:VALUE> extra key value pairs\n");
}
bool AddQtOperation::setArguments(const QStringList &args)
{
for (int i = 0; i < args.count(); ++i) {
const QString current = args.at(i);
const QString next = ((i + 1) < args.count()) ? args.at(i + 1) : QString();
if (current == QLatin1String("--id")) {
if (next.isNull())
return false;
++i; // skip next;
m_id = next;
continue;
}
if (current == QLatin1String("--name")) {
if (next.isNull())
return false;
++i; // skip next;
m_displayName = next;
continue;
}
if (current == QLatin1String("--qmake")) {
if (next.isNull())
return false;
++i; // skip next;
m_qmake = next;
continue;
}
if (current == QLatin1String("--type")) {
if (next.isNull())
return false;
++i; // skip next;
m_type = next;
continue;
}
if (next.isNull())
return false;
++i; // skip next;
KeyValuePair pair(current, next);
if (!pair.value.isValid())
return false;
m_extra << pair;
}
return !m_id.isEmpty() && !m_displayName.isEmpty() && !m_qmake.isEmpty() && !m_type.isEmpty();
}
int AddQtOperation::execute() const
{
QVariantMap map = load(QLatin1String("qtversions"));
if (map.isEmpty())
map = initializeQtVersions();
map = addQt(map, m_id, m_displayName, m_type, m_qmake, m_extra);
if (map.isEmpty())
return -2;
return save(map, QLatin1String("qtversions")) ? 0 : -3;
}
#ifdef WITH_TESTS
bool AddQtOperation::test() const
{
QVariantMap map = initializeQtVersions();
if (!map.count() == 1
|| !map.contains(QLatin1String(VERSION))
|| map.value(QLatin1String(VERSION)).toInt() != 1)
return false;
map = addQt(map, QLatin1String("testId"), QLatin1String("Test Qt Version"), QLatin1String("testType"),
QLatin1String("/tmp/test/qmake"),
KeyValuePairList() << KeyValuePair(QLatin1String("extraData"), QVariant(QLatin1String("extraValue"))));
if (!map.count() == 2
|| !map.contains(QLatin1String(VERSION))
|| map.value(QLatin1String(VERSION)).toInt() != 1
|| !map.contains(QLatin1String("QtVersion.0")))
return false;
QVariantMap version0 = map.value(QLatin1String("QtVersion.0")).toMap();
if (!version0.count() == 6
|| !version0.contains(QLatin1String(ID))
|| version0.value(QLatin1String(ID)).toInt() != -1
|| !version0.contains(QLatin1String(DISPLAYNAME))
|| version0.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("Test Qt Version")
|| !version0.contains(QLatin1String(AUTODETECTED))
|| version0.value(QLatin1String(AUTODETECTED)).toBool() != true
|| !version0.contains(QLatin1String(AUTODETECTION_SOURCE))
|| version0.value(QLatin1String(AUTODETECTION_SOURCE)).toString() != QLatin1String("testId")
|| !version0.contains(QLatin1String(TYPE))
|| version0.value(QLatin1String(TYPE)).toString() != QLatin1String("testType")
|| !version0.contains(QLatin1String(QMAKE))
|| version0.value(QLatin1String(QMAKE)).toString() != QLatin1String("/tmp/test/qmake")
|| !version0.contains(QLatin1String("extraData"))
|| version0.value(QLatin1String("extraData")).toString() != QLatin1String("extraValue"))
return false;
// Ignore existing ids:
QVariantMap result = addQt(map, QLatin1String("testId"), QLatin1String("Test Qt Version2"), QLatin1String("testType2"),
QLatin1String("/tmp/test/qmake2"),
KeyValuePairList() << KeyValuePair(QLatin1String("extraData"), QVariant(QLatin1String("extraValue"))));
if (!result.isEmpty())
return false;
// Make sure name is unique:
map = addQt(map, QLatin1String("testId2"), QLatin1String("Test Qt Version"), QLatin1String("testType3"),
QLatin1String("/tmp/test/qmake2"),
KeyValuePairList() << KeyValuePair(QLatin1String("extraData"), QVariant(QLatin1String("extraValue"))));
if (!map.count() == 3
|| !map.contains(QLatin1String(VERSION))
|| map.value(QLatin1String(VERSION)).toInt() != 1
|| !map.contains(QLatin1String("QtVersion.0"))
|| !map.contains(QLatin1String("QtVersion.1")))
return false;
if (map.value(QLatin1String("QtVersion.0")) != version0)
return false;
QVariantMap version1 = map.value(QLatin1String("QtVersion.1")).toMap();
if (!version1.count() == 6
|| !version1.contains(QLatin1String(ID))
|| version1.value(QLatin1String(ID)).toInt() != -1
|| !version1.contains(QLatin1String(DISPLAYNAME))
|| version1.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("Test Qt Version2")
|| !version1.contains(QLatin1String(AUTODETECTED))
|| version1.value(QLatin1String(AUTODETECTED)).toBool() != true
|| !version1.contains(QLatin1String(AUTODETECTION_SOURCE))
|| version1.value(QLatin1String(AUTODETECTION_SOURCE)).toString() != QLatin1String("testId2")
|| !version1.contains(QLatin1String(TYPE))
|| version1.value(QLatin1String(TYPE)).toString() != QLatin1String("testType3")
|| !version1.contains(QLatin1String(QMAKE))
|| version1.value(QLatin1String(QMAKE)).toString() != QLatin1String("/tmp/test/qmake2")
|| !version1.contains(QLatin1String("extraData"))
|| version1.value(QLatin1String("extraData")).toString() != QLatin1String("extraValue"))
return false;
return true;
}
#endif
QVariantMap AddQtOperation::addQt(const QVariantMap &map,
const QString &id, const QString &displayName, const QString &type,
const QString &qmake, const KeyValuePairList &extra)
{
// Sanity check: Make sure autodetection source is not in use already:
QStringList valueKeys = FindValueOperation::findValues(map, id);
bool hasId = false;
foreach (const QString &k, valueKeys) {
if (k.endsWith(QString(QLatin1Char('/')) + QLatin1String(AUTODETECTION_SOURCE))) {
hasId = true;
break;
}
}
if (hasId) {
std::cerr << "Error: Id " << qPrintable(id) << " already defined as Qt versions." << std::endl;
return QVariantMap();
}
// Find position to insert:
int versionCount = 0;
for (QVariantMap::const_iterator i = map.begin(); i != map.end(); ++i) {
if (!i.key().startsWith(QLatin1String(PREFIX)))
continue;
QString number = i.key().mid(QString::fromLatin1(PREFIX).count());
bool ok;
int count = number.toInt(&ok);
if (ok && count >= versionCount)
versionCount = count + 1;
}
const QString qt = QString::fromLatin1(PREFIX) + QString::number(versionCount);
// Sanity check: Make sure displayName is unique.
QStringList nameKeys = FindKeyOperation::findKey(map, QLatin1String(DISPLAYNAME));
QStringList nameList;
foreach (const QString nameKey, nameKeys)
nameList << GetOperation::get(map, nameKey).toString();
const QString uniqueName = makeUnique(displayName, nameList);
// insert data:
KeyValuePairList data;
data << KeyValuePair(QStringList() << qt << QLatin1String(ID), QVariant(-1));
data << KeyValuePair(QStringList() << qt << QLatin1String(DISPLAYNAME), QVariant(uniqueName));
data << KeyValuePair(QStringList() << qt << QLatin1String(AUTODETECTED), QVariant(true));
data << KeyValuePair(QStringList() << qt << QLatin1String(AUTODETECTION_SOURCE), QVariant(id));
data << KeyValuePair(QStringList() << qt << QLatin1String(QMAKE), QVariant(qmake));
data << KeyValuePair(QStringList() << qt << QLatin1String(TYPE), QVariant(type));
KeyValuePairList qtExtraList;
foreach (const KeyValuePair &pair, extra)
qtExtraList << KeyValuePair(QStringList() << qt << pair.key, pair.value);
data.append(qtExtraList);
return AddKeysOperation::addKeys(map, data);
}
QVariantMap AddQtOperation::initializeQtVersions()
{
QVariantMap map;
map.insert(QLatin1String(VERSION), 1);
return map;
}

View File

@@ -0,0 +1,67 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#ifndef ADDQTOPERATION_H
#define ADDQTOPERATION_H
#include "operation.h"
#include <QString>
class AddQtOperation : public Operation
{
public:
QString name() const;
QString helpText() const;
QString argumentsHelpText() const;
bool setArguments(const QStringList &args);
int execute() const;
#ifdef WITH_TESTS
bool test() const;
#endif
static QVariantMap addQt(const QVariantMap &map,
const QString &id, const QString &displayName, const QString &type,
const QString &qmake, const KeyValuePairList &extra);
static QVariantMap initializeQtVersions();
private:
QString m_id; // actually this is the autodetectionSource
QString m_displayName;
QString m_type;
QString m_qmake;
KeyValuePairList m_extra;
};
#endif // ADDQTOPERATION_H

View File

@@ -0,0 +1,280 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "addtoolchainoperation.h"
#include "addkeysoperation.h"
#include "findkeyoperation.h"
#include "findvalueoperation.h"
#include "getoperation.h"
#include "rmkeysoperation.h"
#include "settings.h"
#include <iostream>
// ToolChain file stuff:
static char COUNT[] = "ToolChain.Count";
static char PREFIX[] = "ToolChain.";
static char VERSION[] = "Version";
// ToolChain:
static char ID[] = "ProjectExplorer.ToolChain.Id";
static char DISPLAYNAME[] = "ProjectExplorer.ToolChain.DisplayName";
static char AUTODETECTED[] = "ProjectExplorer.ToolChain.Autodetect";
// GCC ToolChain:
static char PATH[] = "ProjectExplorer.GccToolChain.Path";
static char TARGET_ABI[] = "ProjectExplorer.GccToolChain.TargetAbi";
static char SUPPORTED_ABIS[] = "ProjectExplorer.GccToolChain.SupportedAbis";
QString AddToolChainOperation::name() const
{
return QLatin1String("addTC");
}
QString AddToolChainOperation::helpText() const
{
return QLatin1String("add a tool chain to Qt Creator");
}
QString AddToolChainOperation::argumentsHelpText() const
{
return QLatin1String(" --id <ID> id of the new tool chain.\n"
" --name <NAME> display name of the new tool chain.\n"
" --path <PATH> path to the compiler.\n"
" --abi <ABI STRING> ABI of the compiler.\n"
" --supportedAbis <ABI STRING>,<ABI STRING> list of ABIs supported by the compiler.\n"
" <KEY> <TYPE:VALUE> extra key value pairs\n");
}
bool AddToolChainOperation::setArguments(const QStringList &args)
{
for (int i = 0; i < args.count(); ++i) {
const QString current = args.at(i);
const QString next = ((i + 1) < args.count()) ? args.at(i + 1) : QString();
if (current == QLatin1String("--id")) {
if (next.isNull())
return false;
++i; // skip next;
m_id = next;
continue;
}
if (current == QLatin1String("--name")) {
if (next.isNull())
return false;
++i; // skip next;
m_displayName = next;
continue;
}
if (current == QLatin1String("--path")) {
if (next.isNull())
return false;
++i; // skip next;
m_path = next;
continue;
}
if (current == QLatin1String("--abi")) {
if (next.isNull())
return false;
++i; // skip next;
m_targetAbi = next;
continue;
}
if (current == QLatin1String("--supportedAbis")) {
if (next.isNull())
return false;
++i; // skip next;
m_supportedAbis = next;
continue;
}
if (next.isNull())
return false;
++i; // skip next;
KeyValuePair pair(current, next);
if (!pair.value.isValid())
return false;
m_extra << pair;
}
if (m_supportedAbis.isEmpty())
m_supportedAbis = m_targetAbi;
return !m_id.isEmpty() && !m_displayName.isEmpty() && !m_path.isEmpty() && !m_targetAbi.isEmpty();
}
int AddToolChainOperation::execute() const
{
QVariantMap map = load(QLatin1String("toolchains"));
if (map.isEmpty())
map = initializeToolChains();
map = addToolChain(map, m_id, m_displayName, m_path, m_targetAbi, m_supportedAbis, m_extra);
if (map.isEmpty())
return -2;
return save(map, QLatin1String("toolchains")) ? 0 : -3;
}
#ifdef WITH_TESTS
bool AddToolChainOperation::test() const
{
QVariantMap map = initializeToolChains();
// Add toolchain:
map = addToolChain(map, QLatin1String("testId"), QLatin1String("name"), QLatin1String("/tmp/test"),
QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue"))));
if (!map.value(QLatin1String(COUNT)).toInt() == 1
|| !map.contains(QString::fromLatin1(PREFIX) + QLatin1Char('0')))
return false;
QVariantMap tcData = map.value(QString::fromLatin1(PREFIX) + QLatin1Char('0')).toMap();
if (tcData.count() != 7
|| tcData.value(QLatin1String(ID)).toString() != QLatin1String("testId")
|| tcData.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("name")
|| tcData.value(QLatin1String(AUTODETECTED)).toBool() != true
|| tcData.value(QLatin1String(PATH)).toString() != QLatin1String("/tmp/test")
|| tcData.value(QLatin1String(TARGET_ABI)).toString() != QLatin1String("test-abi")
|| tcData.value(QLatin1String(SUPPORTED_ABIS)).toList().count() != 2
|| tcData.value(QLatin1String("ExtraKey")).toString() != QLatin1String("ExtraValue"))
return false;
// Ignore same Id:
QVariantMap unchanged = addToolChain(map, QLatin1String("testId"), QLatin1String("name2"), QLatin1String("/tmp/test2"),
QLatin1String("test-abi2"), QLatin1String("test-abi2,test-abi3"),
KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue2"))));
if (!unchanged.isEmpty())
return false;
// Make sure name stays unique:
map = addToolChain(map, QLatin1String("testId2"), QLatin1String("name"), QLatin1String("/tmp/test"),
QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue"))));
if (!map.value(QLatin1String(COUNT)).toInt() == 2
|| !map.contains(QString::fromLatin1(PREFIX) + QLatin1Char('0'))
|| !map.contains(QString::fromLatin1(PREFIX) + QLatin1Char('1')))
return false;
tcData = map.value(QString::fromLatin1(PREFIX) + QLatin1Char('0')).toMap();
if (tcData.count() != 7
|| tcData.value(QLatin1String(ID)).toString() != QLatin1String("testId")
|| tcData.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("name")
|| tcData.value(QLatin1String(AUTODETECTED)).toBool() != true
|| tcData.value(QLatin1String(PATH)).toString() != QLatin1String("/tmp/test")
|| tcData.value(QLatin1String(TARGET_ABI)).toString() != QLatin1String("test-abi")
|| tcData.value(QLatin1String(SUPPORTED_ABIS)).toList().count() != 2
|| tcData.value(QLatin1String("ExtraKey")).toString() != QLatin1String("ExtraValue"))
return false;
tcData = map.value(QString::fromLatin1(PREFIX) + QLatin1Char('1')).toMap();
if (tcData.count() != 7
|| tcData.value(QLatin1String(ID)).toString() != QLatin1String("testId2")
|| tcData.value(QLatin1String(DISPLAYNAME)).toString() != QLatin1String("name2")
|| tcData.value(QLatin1String(AUTODETECTED)).toBool() != true
|| tcData.value(QLatin1String(PATH)).toString() != QLatin1String("/tmp/test")
|| tcData.value(QLatin1String(TARGET_ABI)).toString() != QLatin1String("test-abi")
|| tcData.value(QLatin1String(SUPPORTED_ABIS)).toList().count() != 2
|| tcData.value(QLatin1String("ExtraKey")).toString() != QLatin1String("ExtraValue"))
return false;
return true;
}
#endif
QVariantMap AddToolChainOperation::addToolChain(const QVariantMap &map,
const QString &id, const QString &displayName,
const QString &path, const QString &abi,
const QString &supportedAbis, const KeyValuePairList &extra)
{
// Sanity check: Does the Id already exist?
QStringList valueKeys = FindValueOperation::findValues(map, id);
bool hasId = false;
foreach (const QString &k, valueKeys) {
if (k.endsWith(QString(QLatin1Char('/')) + QLatin1String(ID))) {
hasId = true;
break;
}
}
if (hasId) {
std::cerr << "Error: Id " << qPrintable(id) << " already defined for tool chains." << std::endl;
return QVariantMap();
}
// Find position to insert Tool Chain at:
bool ok;
int count = GetOperation::get(map, QLatin1String(COUNT)).toInt(&ok);
if (!ok || count < 0) {
std::cerr << "Error: Count found in toolchains file seems wrong." << std::endl;
return QVariantMap();
}
// Sanity check: Make sure displayName is unique.
QStringList nameKeys = FindKeyOperation::findKey(map, QLatin1String(DISPLAYNAME));
QStringList nameList;
foreach (const QString nameKey, nameKeys)
nameList << GetOperation::get(map, nameKey).toString();
const QString uniqueName = makeUnique(displayName, nameList);
QVariantMap result = RmKeysOperation::rmKeys(map, QStringList() << QLatin1String(COUNT));
std::cout << "Registering ToolChain " << count << std::endl;
const QString tc = QString::fromLatin1(PREFIX) + QString::number(count);
KeyValuePairList data;
data << KeyValuePair(QStringList() << tc << QLatin1String(ID), QVariant(id.toUtf8()));
data << KeyValuePair(QStringList() << tc << QLatin1String(DISPLAYNAME), QVariant(uniqueName));
data << KeyValuePair(QStringList() << tc << QLatin1String(AUTODETECTED), QVariant(true));
data << KeyValuePair(QStringList() << tc << QLatin1String(PATH), QVariant(path));
data << KeyValuePair(QStringList() << tc << QLatin1String(TARGET_ABI), QVariant(abi));
QVariantList abis;
QStringList abiStrings = supportedAbis.split(QLatin1Char(','));
foreach (const QString &s, abiStrings)
abis << QVariant(s);
data << KeyValuePair(QStringList() << tc << QLatin1String(SUPPORTED_ABIS), QVariant(abis));
KeyValuePairList tcExtraList;
foreach (const KeyValuePair &pair, extra)
tcExtraList << KeyValuePair(QStringList() << tc << pair.key, pair.value);
data.append(tcExtraList);
data << KeyValuePair(QLatin1String(COUNT), QVariant(count + 1));
return AddKeysOperation::addKeys(result, data);
}
QVariantMap AddToolChainOperation::initializeToolChains()
{
QVariantMap map;
map.insert(QLatin1String(COUNT), 0);
map.insert(QLatin1String(VERSION), 1);
return map;
}

View File

@@ -0,0 +1,70 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#ifndef ADDTOOLCHAINOPERATION_H
#define ADDTOOLCHAINOPERATION_H
#include "operation.h"
#include <QString>
class AddToolChainOperation : public Operation
{
public:
QString name() const;
QString helpText() const;
QString argumentsHelpText() const;
bool setArguments(const QStringList &args);
int execute() const;
#ifdef WITH_TESTS
bool test() const;
#endif
static QVariantMap addToolChain(const QVariantMap &map,
const QString &id, const QString &displayName,
const QString &path, const QString &abi,
const QString &supportedAbis,
const KeyValuePairList &extra);
static QVariantMap initializeToolChains();
private:
QString m_id;
QString m_displayName;
QString m_path;
QString m_targetAbi;
QString m_supportedAbis;
KeyValuePairList m_extra;
};
#endif // ADDTOOLCHAINOPERATION_H

View File

@@ -0,0 +1,130 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "findkeyoperation.h"
#include <iostream>
QString FindKeyOperation::name() const
{
return QLatin1String("findKey");
}
QString FindKeyOperation::helpText() const
{
return QLatin1String("find a key in the settings of Qt Creator");
}
QString FindKeyOperation::argumentsHelpText() const
{
return QLatin1String("A file (profiles, qtversions or toolchains) followed by one or more keys to search for.\n");
}
bool FindKeyOperation::setArguments(const QStringList &args)
{
for (int i = 0; i < args.count(); ++i) {
const QString current = args.at(i);
if (m_file.isNull()) {
m_file = current;
continue;
}
m_keys.append(current);
}
return (!m_file.isEmpty() && !m_keys.isEmpty());
}
int FindKeyOperation::execute() const
{
Q_ASSERT(!m_keys.isEmpty());
QVariantMap map = load(m_file);
foreach (const QString &k, m_keys) {
const QStringList result = findKey(map, k);
foreach (const QString r, result)
std::cout << qPrintable(r) << std::endl;
}
return 0;
}
#ifdef WITH_TESTS
bool FindKeyOperation::test() const
{
QVariantMap testMap;
QVariantMap subKeys;
QVariantMap cur;
cur.insert(QLatin1String("testint"), 53);
subKeys.insert(QLatin1String("subsubkeys"), cur);
subKeys.insert(QLatin1String("testbool"), true);
testMap.insert(QLatin1String("subkeys"), subKeys);
subKeys.clear();
testMap.insert(QLatin1String("subkeys2"), subKeys);
testMap.insert(QLatin1String("testint"), 23);
testMap.insert(QLatin1String("testbool"), true);
QStringList result;
result = findKey(testMap, QLatin1String("missing"));
if (!result.isEmpty())
return false;
result = findKey(testMap, QLatin1String("testint"));
if (result.count() != 2
|| !result.contains(QLatin1String("testint"))
|| !result.contains(QLatin1String("subkeys/subsubkeys/testint")))
return false;
result = findKey(testMap, QLatin1String("testbool"));
if (result.count() != 2
|| !result.contains(QLatin1String("testbool")))
return false;
return true;
}
#endif
QStringList FindKeyOperation::findKey(const QVariantMap &map, const QString &key)
{
QStringList result;
for (QVariantMap::const_iterator i = map.begin(); i != map.end(); ++i) {
if (i.key() == key) {
result << key;
continue;
}
if (i.value().type() == QVariant::Map) {
QStringList subKeyList = findKey(i.value().toMap(), key);
foreach (const QString &subKey, subKeyList)
result << i.key() + QLatin1Char('/') + subKey;
}
}
return result;
}

View File

@@ -0,0 +1,58 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#ifndef FINDKEYOPERATION_H
#define FINDKEYOPERATION_H
#include "operation.h"
class FindKeyOperation : public Operation
{
public:
QString name() const;
QString helpText() const;
QString argumentsHelpText() const;
bool setArguments(const QStringList &args);
int execute() const;
#ifdef WITH_TESTS
bool test() const;
#endif
static QStringList findKey(const QVariantMap &map, const QString &key);
private:
QString m_file;
QStringList m_keys;
};
#endif // FINDKEYOPERATION_H

View File

@@ -0,0 +1,135 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "findvalueoperation.h"
#include <iostream>
QString FindValueOperation::name() const
{
return QLatin1String("find");
}
QString FindValueOperation::helpText() const
{
return QLatin1String("find a value in the settings of Qt Creator");
}
QString FindValueOperation::argumentsHelpText() const
{
return QLatin1String("A file (profiles, qtversions or toolchains) followed by one or more type:value tupels to search for.\n");
}
bool FindValueOperation::setArguments(const QStringList &args)
{
for (int i = 0; i < args.count(); ++i) {
const QString current = args.at(i);
if (m_file.isNull()) {
m_file = current;
continue;
}
QVariant v = Operation::valueFromString(current);
if (!v.isValid())
return false;
m_values << v;
}
return (!m_file.isEmpty() && !m_values.isEmpty());
}
int FindValueOperation::execute() const
{
Q_ASSERT(!m_values.isEmpty());
QVariantMap map = load(m_file);
foreach (const QVariant &v, m_values) {
const QStringList result = findValues(map, v);
foreach (const QString &r, result)
std::cout << qPrintable(r) << std::endl;
}
return 0;
}
#ifdef WITH_TESTS
bool FindValueOperation::test() const
{
QVariantMap testMap;
QVariantMap subKeys;
QVariantMap cur;
cur.insert(QLatin1String("testint2"), 53);
subKeys.insert(QLatin1String("subsubkeys"), cur);
subKeys.insert(QLatin1String("testbool"), true);
subKeys.insert(QLatin1String("otherint"), 53);
testMap.insert(QLatin1String("subkeys"), subKeys);
subKeys.clear();
testMap.insert(QLatin1String("subkeys2"), subKeys);
testMap.insert(QLatin1String("testint"), 23);
QStringList result;
result = findValues(testMap, QVariant(23));
if (result.count() != 1
|| !result.contains(QLatin1String("testint")))
return false;
result = findValues(testMap, QVariant(53));
if (result.count() != 2
|| !result.contains(QLatin1String("subkeys/subsubkeys/testint2"))
|| !result.contains(QLatin1String("subkeys/otherint")))
return false;
result = findValues(testMap, QVariant(23456));
if (!result.isEmpty())
return false;
return true;
}
#endif
QStringList FindValueOperation::findValues(const QVariantMap &map, const QVariant &value)
{
QStringList result;
if (!value.isValid())
return result;
for (QVariantMap::const_iterator i = map.begin(); i != map.end(); ++i) {
if (i.value() == value)
result << i.key();
if (i.value().type() == QVariant::Map) {
const QStringList subKeys = findValues(i.value().toMap(), value);
foreach (const QString &subKey, subKeys)
result << i.key() + QLatin1Char('/') + subKey;
}
}
return result;
}

View File

@@ -0,0 +1,58 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#ifndef FINDVALUEOPERATION_H
#define FINDVALUEOPERATION_H
#include "operation.h"
class FindValueOperation : public Operation
{
public:
QString name() const;
QString helpText() const;
QString argumentsHelpText() const;
bool setArguments(const QStringList &args);
int execute() const;
#ifdef WITH_TESTS
bool test() const;
#endif
static QStringList findValues(const QVariantMap &map, const QVariant &value);
private:
QString m_file;
QVariantList m_values;
};
#endif // FINDVALUEOPERATION_H

View File

@@ -0,0 +1,126 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "getoperation.h"
#include <iostream>
QString GetOperation::name() const
{
return QLatin1String("get");
}
QString GetOperation::helpText() const
{
return QLatin1String("get settings from Qt Creator configuration");
}
QString GetOperation::argumentsHelpText() const
{
return QLatin1String("A file (profiles, qtversions or toolchains) followed by one or more keys to list.\n");
}
bool GetOperation::setArguments(const QStringList &args)
{
if (args.count() < 2)
return false;
m_keys = args;
m_file = m_keys.takeFirst();
return true;
}
int GetOperation::execute() const
{
Q_ASSERT(!m_keys.isEmpty());
QVariantMap map = load(m_file);
foreach (const QString &key, m_keys) {
const QVariant result = get(map, key);
if (result.isValid())
return -2;
std::cout << qPrintable(result.toString()) << std::endl;
}
return 0;
}
#ifdef WITH_TESTS
bool GetOperation::test() const
{
QVariantMap testMap;
QVariantMap subKeys;
QVariantMap cur;
cur.insert(QLatin1String("testint2"), 53);
subKeys.insert(QLatin1String("subsubkeys"), cur);
subKeys.insert(QLatin1String("testbool"), true);
testMap.insert(QLatin1String("subkeys"), subKeys);
subKeys.clear();
testMap.insert(QLatin1String("subkeys2"), subKeys);
testMap.insert(QLatin1String("testint"), 23);
QVariant result;
result = get(testMap, QLatin1String("testint"));
if (result.toString() != QLatin1String("23"))
return false;
result = get(testMap, QLatin1String("subkeys/testbool"));
if (result.toString() != QLatin1String("true"))
return false;
result = get(testMap, QLatin1String("subkeys/subsubkeys"));
if (result.type() != QVariant::Map)
return false;
result = get(testMap, QLatin1String("nonexistant"));
if (result.isValid())
return false;
return true;
}
#endif
QVariant GetOperation::get(const QVariantMap &map, const QString &key)
{
if (key.isEmpty())
return QString();
const QStringList keys = key.split(QLatin1Char('/'));
QVariantMap subMap = map;
for (int i = 0; i < keys.count() - 1; ++i) {
const QString k = keys.at(i);
if (!subMap.contains(k))
return QString();
subMap = subMap.value(k).toMap();
}
return subMap.value(keys.last());
}

View File

@@ -0,0 +1,58 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#ifndef GETOPERATION_H
#define GETOPERATION_H
#include "operation.h"
class GetOperation : public Operation
{
public:
QString name() const;
QString helpText() const;
QString argumentsHelpText() const;
bool setArguments(const QStringList &args);
int execute() const;
#ifdef WITH_TESTS
bool test() const;
#endif
static QVariant get(const QVariantMap &map, const QString &key);
private:
QStringList m_keys;
QString m_file;
};
#endif // GETOPERATION_H

185
src/tools/sdktool/main.cpp Normal file
View File

@@ -0,0 +1,185 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "settings.h"
#include "operation.h"
#include "addkeysoperation.h"
#include "addkitoperation.h"
#include "addqtoperation.h"
#include "addtoolchainoperation.h"
#include "findkeyoperation.h"
#include "findvalueoperation.h"
#include "getoperation.h"
#include "rmkeysoperation.h"
#include "rmkitoperation.h"
#include "rmqtoperation.h"
#include "rmtoolchainoperation.h"
#include <iostream>
#include <QCoreApplication>
#include <QStringList>
void printHelp(const Operation *op)
{
std::cout << "Qt Creator SDK setup tool." << std::endl;
std::cout << "Help for operation " << qPrintable(op->name()) << std::endl;
std::cout << std::endl;
std::cout << qPrintable(op->argumentsHelpText());
std::cout << std::endl;
}
void printHelp(const QList<Operation *> &operations)
{
std::cout << "Qt Creator SDK setup tool." << std::endl;
std::cout << " Usage:" << qPrintable(qApp->arguments().at(0))
<< " <ARGS> <OPERATION> <OPERATION_ARGS>" << std::endl << std::endl;
std::cout << "ARGS:" << std::endl;
std::cout << " --help|-h Print this help text" << std::endl;
std::cout << " --sdkpath=PATH|-s PATH Set the path to the SDK files" << std::endl << std::endl;
std::cout << "OPERATION:" << std::endl;
std::cout << " One of:" << std::endl;
foreach (const Operation *o, operations)
std::cout << " " << qPrintable(o->name()) << "\t\t" << qPrintable(o->helpText()) << std::endl;
std::cout << std::endl;
std::cout << "OPERATION_ARGS:" << std::endl;
std::cout << " use \"--help <OPERATION>\" to get help on the arguments required for an operation." << std::endl;
std::cout << std::endl;
}
int parseArguments(const QStringList &args, Settings *s, const QList<Operation *> &operations)
{
QStringList opArgs;
int argCount = args.count();
for (int i = 1; i < argCount; ++i) {
const QString current = args[i];
const QString next = (i + 1 < argCount) ? args[i + 1] : QString();
if (!s->operation) {
// help
if (current == QLatin1String("-h") || current == QLatin1String("--help")) {
if (!next.isEmpty()) {
foreach (Operation *o, operations) {
if (o->name() == next) {
printHelp(o);
return 0;
}
}
}
printHelp(operations);
return 0;
}
// sdkpath
if (current.startsWith(QLatin1String("--sdkpath="))) {
s->sdkPath = Utils::FileName::fromString(current.mid(10));
continue;
}
if (current == QLatin1String("-s")) {
s->sdkPath = Utils::FileName::fromString(next);
++i; // skip next;
continue;
}
// operation
foreach (Operation *o, operations) {
if (o->name() == current) {
s->operation = o;
break;
}
}
if (s->operation)
continue;
} else {
opArgs << current;
continue;
}
std::cerr << "Unknown parameter given." << std::endl << std::endl;
printHelp(operations);
return -1;
}
if (!s->operation) {
std::cerr << "No operation requested." << std::endl << std::endl;
printHelp(operations);
return -1;
}
if (!s->operation->setArguments(opArgs)) {
printHelp(s->operation);
return -1;
}
return 1;
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Settings settings;
QList<Operation *> operations;
operations << new AddKeysOperation
<< new AddKitOperation
<< new AddQtOperation
<< new AddToolChainOperation
<< new FindKeyOperation
<< new FindValueOperation
<< new GetOperation
<< new RmKeysOperation
<< new RmKitOperation
<< new RmQtOperation
<< new RmToolChainOperation;
#ifdef WITH_TESTS
std::cerr << std::endl << std::endl << "Starting tests..." << std::endl;
foreach (Operation *o, operations)
if (!o->test())
std::cerr << "!!!! Test failed for: " << qPrintable(o->name()) << " !!!!" << std::endl;
std::cerr << "Tests done." << std::endl << std::endl;
#endif
int result = parseArguments(a.arguments(), &settings, operations);
if (result <= 0)
return result;
Q_ASSERT(settings.operation);
settings.operation->execute();
return result;
}

View File

@@ -0,0 +1,131 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "operation.h"
#include "settings.h"
#include "utils/persistentsettings.h"
#include <QDir>
#include <iostream>
QVariant Operation::valueFromString(const QString &v)
{
int pos = v.indexOf(QLatin1Char(':'));
if (pos <= 0)
return QVariant();
const QString type = v.left(pos);
const QString value = v.mid(pos + 1);
if (type == QLatin1String("int")) {
return QVariant(value.toInt());
} else if (type == QLatin1String("bool")) {
const QString tmp = value.toLower();
return QVariant(tmp == QLatin1String("true") || tmp == QLatin1String("yes")
|| tmp == QLatin1String("1") || tmp == QLatin1String("on"));
} else if (type == QLatin1String("QByteArray")) {
return QVariant(value.toLocal8Bit());
} else if (type == QLatin1String("QString")) {
return QVariant(value);
} else if (type == QLatin1String("QVariantList")) {
QVariantList list;
const QStringList elements = value.split(QLatin1Char(','));
foreach (const QString &e, elements)
list << QVariant(e);
return QVariant(list);
}
return QVariant();
}
QString Operation::makeUnique(const QString &name, const QStringList &inUse)
{
QString unique = name;
int i = 1;
while (inUse.contains(unique))
unique = name + QString::number(++i);
return unique;
}
Operation::KeyValuePair::KeyValuePair(const QString &k, const QString &v) :
value(valueFromString(v))
{
key = k.split(QLatin1Char('/'));
}
Operation::KeyValuePair::KeyValuePair(const QString &k, const QVariant &v) :
value(v)
{
key = k.split(QLatin1Char('/'));
}
Operation::KeyValuePair::KeyValuePair(const QStringList &k, const QString &v) :
key(k), value(valueFromString(v))
{ }
Operation::KeyValuePair::KeyValuePair(const QStringList &k, const QVariant &v) :
key(k), value(v)
{ }
QVariantMap Operation::load(const QString &file) const
{
QVariantMap map;
// Read values from original file:
Utils::FileName path = Settings::instance()->getPath(file);
if (path.toFileInfo().exists()) {
Utils::PersistentSettingsReader reader;
if (!reader.load(path))
return QVariantMap();
map = reader.restoreValues();
} else {
std::cout << "No such file: " << qPrintable(path.toUserOutput()) << std::endl;
}
return map;
}
bool Operation::save(const QVariantMap &map, const QString &file) const
{
Utils::FileName path = Settings::instance()->getPath(file);
if (path.isEmpty()) {
std::cerr << "Error: No path found for " << qPrintable(file) << "." << std::endl;
return false;
}
Utils::FileName dir = path.parentDir();
if (!dir.toFileInfo().exists())
QDir(dir.toString()).mkpath(dir.toString());
Utils::PersistentSettingsWriter writer(path, QLatin1String("unknown"));
return writer.save(map, 0);
}

View File

@@ -0,0 +1,75 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#ifndef OPERATION_H
#define OPERATION_H
#include <utils/fileutils.h>
#include <QStringList>
#include <QVariant>
class Operation
{
public:
class KeyValuePair {
public:
KeyValuePair(const QString &k, const QString &v);
KeyValuePair(const QString &k, const QVariant &v);
KeyValuePair(const QStringList &k, const QString &v);
KeyValuePair(const QStringList &k, const QVariant &v);
QStringList key;
QVariant value;
};
typedef QList<KeyValuePair> KeyValuePairList;
virtual ~Operation() { }
virtual QString name() const = 0;
virtual QString helpText() const = 0;
virtual QString argumentsHelpText() const = 0;
virtual bool setArguments(const QStringList &args) = 0;
virtual int execute() const = 0;
#ifdef WITH_TESTS
virtual bool test() const = 0;
#endif
QVariantMap load(const QString &file) const;
bool save(const QVariantMap &map, const QString &file) const;
static QVariant valueFromString(const QString &v);
static QString makeUnique(const QString &name, const QStringList &inUse);
};
#endif // OPERATION_H

View File

@@ -0,0 +1,211 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "rmkeysoperation.h"
#include <iostream>
QString RmKeysOperation::name() const
{
return QLatin1String("rmKeys");
}
QString RmKeysOperation::helpText() const
{
return QLatin1String("remove settings from Qt Creator configuration");
}
QString RmKeysOperation::argumentsHelpText() const
{
return QLatin1String("A file (profiles, qtversions or toolchains) followed by one or more keys to remove.\n");
}
bool RmKeysOperation::setArguments(const QStringList &args)
{
if (args.count() < 2)
return false;
m_keys = args;
m_file = m_keys.takeFirst();
return true;
}
int RmKeysOperation::execute() const
{
Q_ASSERT(!m_keys.isEmpty());
QVariantMap map = load(m_file);
QVariantMap result = rmKeys(map, m_keys);
if (map == result)
return 1;
// Write data again:
return save(map, m_file) ? 0 : 2;
}
#ifdef WITH_TESTS
bool RmKeysOperation::test() const
{
QVariantMap testMap;
QVariantMap subKeys;
QVariantMap cur;
cur.insert(QLatin1String("testint2"), 53);
subKeys.insert(QLatin1String("subsubkeys"), cur);
subKeys.insert(QLatin1String("testbool"), true);
testMap.insert(QLatin1String("subkeys"), subKeys);
subKeys.clear();
testMap.insert(QLatin1String("subkeys2"), subKeys);
testMap.insert(QLatin1String("testint"), 23);
QStringList data;
QVariantMap result = rmKeys(testMap, data);
if (result != testMap)
return false;
data.append(QLatin1String("testint"));
result = rmKeys(testMap, data);
if (result.count() != 2
|| !result.contains(QLatin1String("subkeys"))
|| !result.contains(QLatin1String("subkeys2")))
return false;
cur = result.value(QLatin1String("subkeys")).toMap();
if (cur.count() != 2
|| !cur.contains(QLatin1String("subsubkeys"))
|| !cur.contains(QLatin1String("testbool")))
return false;
cur = cur.value(QLatin1String("subsubkeys")).toMap();
if (cur.count() != 1
|| !cur.contains(QLatin1String("testint2")))
return false;
cur = result.value(QLatin1String("subkeys2")).toMap();
if (cur.count() != 0)
return false;
data.clear();
data.append("subkeys/subsubkeys");
result = rmKeys(testMap, data);
if (result.count() != 3
|| !result.contains(QLatin1String("subkeys"))
|| !result.contains(QLatin1String("subkeys2"))
|| !result.contains(QLatin1String("testint")))
return false;
cur = result.value(QLatin1String("subkeys")).toMap();
if (cur.count() != 1
|| !cur.contains(QLatin1String("testbool")))
return false;
cur = result.value(QLatin1String("subkeys2")).toMap();
if (cur.count() != 0)
return false;
data.clear();
data.append("subkeys/testbool");
result = rmKeys(testMap, data);
if (result.count() != 3
|| !result.contains(QLatin1String("subkeys"))
|| !result.contains(QLatin1String("subkeys2"))
|| !result.contains(QLatin1String("testint")))
return false;
cur = result.value(QLatin1String("subkeys")).toMap();
if (cur.count() != 1
|| !cur.contains(QLatin1String("subsubkeys")))
return false;
cur = cur.value(QLatin1String("subsubkeys")).toMap();
if (cur.count() != 1
|| !cur.contains(QLatin1String("testint2")))
return false;
cur = result.value(QLatin1String("subkeys2")).toMap();
if (cur.count() != 0)
return false;
cur = result.value(QLatin1String("subkeys2")).toMap();
if (cur.count() != 0)
return false;
return true;
}
#endif
QVariantMap RmKeysOperation::rmKeys(const QVariantMap &map, const QStringList &removals)
{
QVariantMap result = map;
foreach (const QString &r, removals) {
QList<QVariantMap> stack;
const QStringList keys = r.split(QLatin1Char('/'));
// Set up a stack of QVariantMaps along the path we take:
stack.append(result);
for (int i = 0; i < keys.count() - 1; ++i) {
QVariantMap subMap;
if (stack.last().contains(keys.at(i))) {
subMap = stack.last().value(keys.at(i)).toMap();
} else {
std::cerr << "Warning: Key " << qPrintable(r) << " not found." << std::endl;
continue;
}
stack.append(subMap);
}
// remove
Q_ASSERT(stack.count() == keys.count());
if (!stack.last().contains(keys.last())) {
std::cerr << "Warning: Key " << qPrintable(r) << " not found." << std::endl;
continue;
}
stack.last().remove(keys.last());
// Generate new resultset by folding maps back in:
QVariantMap foldBack = stack.takeLast();
for (int i = keys.count() - 2; i >= 0; --i) { // skip last key, that is already taken care of
const QString k = keys.at(i);
QVariantMap current = stack.takeLast();
current.insert(k, foldBack);
foldBack = current;
}
Q_ASSERT(stack.count() == 0);
Q_ASSERT(foldBack != map);
result = foldBack;
}
return result;
}

View File

@@ -0,0 +1,58 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#ifndef RMKEYSOPERATION_H
#define RMKEYSOPERATION_H
#include "operation.h"
class RmKeysOperation : public Operation
{
public:
QString name() const;
QString helpText() const;
QString argumentsHelpText() const;
bool setArguments(const QStringList &args);
int execute() const;
#ifdef WITH_TESTS
bool test() const;
#endif
static QVariantMap rmKeys(const QVariantMap &map, const QStringList &removals);
private:
QStringList m_keys;
QString m_file;
};
#endif // RMKEYSOPERATION_H

View File

@@ -0,0 +1,209 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "rmkitoperation.h"
#include "addkeysoperation.h"
#include "addkitoperation.h"
#include "findkeyoperation.h"
#include "findvalueoperation.h"
#include "getoperation.h"
#include "rmkeysoperation.h"
#include "settings.h"
#include <iostream>
// Qt version file stuff:
static char PREFIX[] = "Profile.";
static char COUNT[] = "Profile.Count";
static char DEFAULT[] = "Profile.Default";
#ifdef WITH_TESTS
static char VERSION[] = "Version";
#endif
// Kit:
static char ID[] = "PE.Profile.Id";
QString RmKitOperation::name() const
{
return QLatin1String("rmKit");
}
QString RmKitOperation::helpText() const
{
return QLatin1String("remove a Kit from Qt Creator");
}
QString RmKitOperation::argumentsHelpText() const
{
return QLatin1String(" --id <ID> id of the new kit.\n");
}
bool RmKitOperation::setArguments(const QStringList &args)
{
if (args.count() != 2)
return false;
if (args.at(0) != QLatin1String("--id"))
return false;
m_id = args.at(1);
return !m_id.isEmpty();
}
int RmKitOperation::execute() const
{
QVariantMap map = load(QLatin1String("profiles"));
if (map.isEmpty())
map = AddKitOperation::initializeKits();
map = rmKit(map, m_id);
if (map.isEmpty())
return -2;
return save(map, QLatin1String("profiles")) ? 0 : -3;
}
#ifdef WITH_TESTS
bool RmKitOperation::test() const
{
QVariantMap map =
AddKitOperation::addKit(AddKitOperation::initializeKits(),
QLatin1String("testId"), QLatin1String("Test Qt Version"),
QLatin1String("/tmp/icon.png"),
1, QLatin1String("/usr/bin/gdb-test"),
QLatin1String("Desktop"), QString(),
QLatin1String("{some-tc-id}"), QLatin1String("{some-qt-id}"),
QLatin1String("unsupported/mkspec"),
KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue"))));
map =
AddKitOperation::addKit(map, QLatin1String("testId2"), QLatin1String("Test Qt Version"),
QLatin1String("/tmp/icon2.png"),
1, QLatin1String("/usr/bin/gdb-test2"),
QLatin1String("Desktop"), QString(),
QLatin1String("{some-tc-id2}"), QLatin1String("{some-qt-id2}"),
QLatin1String("unsupported/mkspec2"),
KeyValuePairList() << KeyValuePair(QLatin1String("PE.Profile.Data/extraData"), QVariant(QLatin1String("extraValue2"))));
QVariantMap result = rmKit(map, QLatin1String("testId"));
if (result.count() != 4
|| !result.contains("Profile.0")
|| !result.contains(QLatin1String(COUNT))
|| result.value(QLatin1String(COUNT)).toInt() != 1
|| !result.contains(QLatin1String(DEFAULT))
|| result.value(QLatin1String(DEFAULT)).toInt() != 0
|| !result.contains(QLatin1String(VERSION))
|| result.value(QLatin1String(VERSION)).toInt() != 1)
return false;
result = rmKit(map, QLatin1String("unknown"));
if (result != map)
return false;
result = rmKit(map, QLatin1String("testId2"));
if (result.count() != 4
|| !result.contains("Profile.0")
|| !result.contains(QLatin1String(COUNT))
|| result.value(QLatin1String(COUNT)).toInt() != 1
|| !result.contains(QLatin1String(DEFAULT))
|| result.value(QLatin1String(DEFAULT)).toInt() != 0
|| !result.contains(QLatin1String(VERSION))
|| result.value(QLatin1String(VERSION)).toInt() != 1)
return false;
result = rmKit(result, QLatin1String("testId"));
if (result.count() != 3
|| !result.contains(QLatin1String(COUNT))
|| result.value(QLatin1String(COUNT)).toInt() != 0
|| !result.contains(QLatin1String(DEFAULT))
|| result.value(QLatin1String(DEFAULT)).toInt() != -1
|| !result.contains(QLatin1String(VERSION))
|| result.value(QLatin1String(VERSION)).toInt() != 1)
return false;
return true;
}
#endif
QVariantMap RmKitOperation::rmKit(const QVariantMap &map, const QString &id)
{
QVariantMap result = AddKitOperation::initializeKits();
QVariantList profileList;
bool ok;
int count = GetOperation::get(map, QLatin1String(COUNT)).toInt(&ok);
if (!ok) {
std::cerr << "Error: The count found in map is not an integer.";
return map;
}
int kitPos = -1;
for (int i = 0; i < count; ++i) {
const QString key = QString::fromLatin1(PREFIX) + QString::number(i);
QVariantMap profile = map.value(key).toMap();
if (profile.value(QLatin1String(ID)).toString() == id) {
kitPos = i;
continue;
}
profileList << profile;
}
if (profileList.count() == map.count() - 3) {
std::cerr << "Error: Id was not found.";
return map;
}
int defaultKit = GetOperation::get(map, QLatin1String(DEFAULT)).toInt(&ok);
if (!ok) {
std::cerr << "Error: Could not find the default kit.";
defaultKit = -1;
}
if (defaultKit == kitPos || defaultKit < 0)
defaultKit = (count > 1) ? 0 : -1;
// remove data:
QStringList toRemove;
toRemove << QLatin1String(COUNT) << QLatin1String(DEFAULT);
result = RmKeysOperation::rmKeys(result, toRemove);
// insert data:
KeyValuePairList data;
data << KeyValuePair(QStringList() << QLatin1String(DEFAULT), QVariant(defaultKit));
data << KeyValuePair(QStringList() << QLatin1String(COUNT), QVariant(count - 1));
for (int i = 0; i < profileList.count(); ++i)
data << KeyValuePair(QStringList() << QString::fromLatin1(PREFIX) + QString::number(i),
profileList.at(i));
return AddKeysOperation::addKeys(result, data);
}

View File

@@ -0,0 +1,59 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#ifndef RMKITOPERATION_H
#define RMKITOPERATION_H
#include "operation.h"
#include <QString>
class RmKitOperation : public Operation
{
public:
QString name() const;
QString helpText() const;
QString argumentsHelpText() const;
bool setArguments(const QStringList &args);
int execute() const;
#ifdef WITH_TESTS
bool test() const;
#endif
static QVariantMap rmKit(const QVariantMap &map, const QString &id);
private:
QString m_id;
};
#endif // RMKITOPERATION_H

View File

@@ -0,0 +1,152 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "rmqtoperation.h"
#include "addkeysoperation.h"
#include "addqtoperation.h"
#include "findkeyoperation.h"
#include "findvalueoperation.h"
#include "getoperation.h"
#include "rmkeysoperation.h"
#include <iostream>
// ToolChain file stuff:
static char PREFIX[] = "QtVersion.";
// ToolChain:
static char AUTODETECTION_SOURCE[] = "autodetectionSource";
QString RmQtOperation::name() const
{
return QLatin1String("rmQt");
}
QString RmQtOperation::helpText() const
{
return QLatin1String("remove a Qt version from Qt Creator");
}
QString RmQtOperation::argumentsHelpText() const
{
return QLatin1String(" --id <ID> The id of the qt version to remove.\n");
}
bool RmQtOperation::setArguments(const QStringList &args)
{
for (int i = 0; i < args.count(); ++i) {
const QString current = args.at(i);
const QString next = ((i + 1) < args.count()) ? args.at(i + 1) : QString();
if (current == QLatin1String("--id")) {
if (next.isNull())
return false;
++i; // skip next;
m_id = next;
continue;
}
}
return !m_id.isEmpty();
}
int RmQtOperation::execute() const
{
QVariantMap map = load(QLatin1String("qtversion"));
if (map.isEmpty())
return 0;
QVariantMap result = rmQt(map, m_id);
if (result == map)
return -2;
return save(map, QLatin1String("qtversion")) ? 0 : -3;
}
#ifdef WITH_TESTS
bool RmQtOperation::test() const
{
// Add toolchain:
QVariantMap map = AddQtOperation::initializeQtVersions();
QVariantMap result = rmQt(QVariantMap(), QLatin1String("nonexistant"));
if (result != map)
return false;
map = AddQtOperation::addQt(map, QLatin1String("testId"), QLatin1String("name"), QLatin1String("type"),
QLatin1String("/tmp/test"),
KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue"))));
map = AddQtOperation::addQt(map, QLatin1String("testId2"), QLatin1String("other name"), QLatin1String("type"),
QLatin1String("/tmp/test2"),
KeyValuePairList());
result = rmQt(map, QLatin1String("nonexistant"));
if (result != map)
return false;
result = rmQt(map, QLatin1String("testId2"));
if (result == map
|| !result.contains(QLatin1String("QtVersion.0"))
|| result.value(QLatin1String("QtVersion.0")) != map.value(QLatin1String("QtVersion.0")))
return false;
result = rmQt(map, QLatin1String("testId"));
if (result == map
|| !result.contains(QLatin1String("QtVersion.0"))
|| result.value(QLatin1String("QtVersion.0")) != map.value(QLatin1String("QtVersion.1")))
return false;
result = rmQt(result, QLatin1String("testId2"));
if (result == map)
return false;
return true;
}
#endif
QVariantMap RmQtOperation::rmQt(const QVariantMap &map, const QString &id)
{
QVariantList qtList;
for (QVariantMap::const_iterator i = map.begin(); i != map.end(); ++i) {
if (!i.key().startsWith(QLatin1String(PREFIX)))
continue;
QVariantMap qtData = i.value().toMap();
if (qtData.value(QLatin1String(AUTODETECTION_SOURCE)).toString() != id)
qtList.append(qtData);
}
QVariantMap newMap = AddQtOperation::initializeQtVersions();
for (int i = 0; i < qtList.count(); ++i)
newMap.insert(QString::fromLatin1(PREFIX) + QString::number(i), qtList.at(i));
return newMap;
}

View File

@@ -0,0 +1,59 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#ifndef RMQTOPERATION_H
#define RMQTOPERATION_H
#include "operation.h"
#include <QString>
class RmQtOperation : public Operation
{
public:
QString name() const;
QString helpText() const;
QString argumentsHelpText() const;
bool setArguments(const QStringList &args);
int execute() const;
#ifdef WITH_TESTS
bool test() const;
#endif
static QVariantMap rmQt(const QVariantMap &map, const QString &id);
private:
QString m_id;
};
#endif // RMQTOPERATION_H

View File

@@ -0,0 +1,162 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "rmtoolchainoperation.h"
#include "addkeysoperation.h"
#include "addtoolchainoperation.h"
#include "findkeyoperation.h"
#include "findvalueoperation.h"
#include "getoperation.h"
#include "rmkeysoperation.h"
#include <iostream>
// ToolChain file stuff:
static char COUNT[] = "ToolChain.Count";
static char PREFIX[] = "ToolChain.";
// ToolChain:
static char ID[] = "ProjectExplorer.ToolChain.Id";
QString RmToolChainOperation::name() const
{
return QLatin1String("rmTC");
}
QString RmToolChainOperation::helpText() const
{
return QLatin1String("remove a tool chain from Qt Creator");
}
QString RmToolChainOperation::argumentsHelpText() const
{
return QLatin1String(" --id <ID> The id of the tool chain to remove.\n");
}
bool RmToolChainOperation::setArguments(const QStringList &args)
{
for (int i = 0; i < args.count(); ++i) {
const QString current = args.at(i);
const QString next = ((i + 1) < args.count()) ? args.at(i + 1) : QString();
if (current == QLatin1String("--id")) {
if (next.isNull())
return false;
++i; // skip next;
m_id = next;
continue;
}
}
return !m_id.isEmpty();
}
int RmToolChainOperation::execute() const
{
QVariantMap map = load(QLatin1String("toolchains"));
if (map.isEmpty())
return 0;
QVariantMap result = rmToolChain(map, m_id);
if (result == map)
return -2;
return save(map, QLatin1String("toolchains")) ? 0 : -3;
}
#ifdef WITH_TESTS
bool RmToolChainOperation::test() const
{
// Add toolchain:
QVariantMap map = AddToolChainOperation::initializeToolChains();
map = AddToolChainOperation::addToolChain(map, QLatin1String("testId"), QLatin1String("name"), QLatin1String("/tmp/test"),
QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
KeyValuePairList() << KeyValuePair(QLatin1String("ExtraKey"), QVariant(QLatin1String("ExtraValue"))));
map = AddToolChainOperation::addToolChain(map, QLatin1String("testId2"), QLatin1String("other name"), QLatin1String("/tmp/test2"),
QLatin1String("test-abi"), QLatin1String("test-abi,test-abi2"),
KeyValuePairList());
QVariantMap result = rmToolChain(QVariantMap(), QLatin1String("nonexistant"));
if (!result.isEmpty())
return false;
result = rmToolChain(map, QLatin1String("nonexistant"));
if (result != map)
return false;
result = rmToolChain(map, QLatin1String("testId2"));
if (result == map
|| result.value(QLatin1String(COUNT), 0).toInt() != 1
|| !result.contains(QLatin1String("ToolChain.0"))
|| result.value(QLatin1String("ToolChain.0")) != map.value(QLatin1String("ToolChain.0")))
return false;
result = rmToolChain(map, QLatin1String("testId"));
if (result == map
|| result.value(QLatin1String(COUNT), 0).toInt() != 1
|| !result.contains(QLatin1String("ToolChain.0"))
|| result.value(QLatin1String("ToolChain.0")) != map.value(QLatin1String("ToolChain.1")))
return false;
result = rmToolChain(result, QLatin1String("testId2"));
if (result == map
|| result.value(QLatin1String(COUNT), 0).toInt() != 0)
return false;
return true;
}
#endif
QVariantMap RmToolChainOperation::rmToolChain(const QVariantMap &map, const QString &id)
{
// Find count of tool chains:
bool ok;
int count = GetOperation::get(map, QLatin1String(COUNT)).toInt(&ok);
if (!ok || count < 0) {
std::cerr << "Error: Count found in toolchains file seems wrong." << std::endl;
return map;
}
QVariantList tcList;
for (int i = 0; i < count; ++i) {
QVariantMap tcData = GetOperation::get(map, QString::fromLatin1(PREFIX) + QString::number(i)).toMap();
if (tcData.value(QLatin1String(ID)).toString() != id)
tcList.append(tcData);
}
QVariantMap newMap = AddToolChainOperation::initializeToolChains();
for (int i = 0; i < tcList.count(); ++i)
newMap.insert(QString::fromLatin1(PREFIX) + QString::number(i), tcList.at(i));
newMap.insert(QLatin1String(COUNT), tcList.count());
return newMap;
}

View File

@@ -0,0 +1,59 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#ifndef RMTOOLCHAINOPERATION_H
#define RMTOOLCHAINOPERATION_H
#include "operation.h"
#include <QString>
class RmToolChainOperation : public Operation
{
public:
QString name() const;
QString helpText() const;
QString argumentsHelpText() const;
bool setArguments(const QStringList &args);
int execute() const;
#ifdef WITH_TESTS
bool test() const;
#endif
static QVariantMap rmToolChain(const QVariantMap &map, const QString &id);
private:
QString m_id;
};
#endif // RMTOOLCHAINOPERATION_H

View File

@@ -0,0 +1,44 @@
include(../../../qtcreator.pri)
include(../../libs/utils/utils.pri)
CONFIG += console
QT -= gui test
SOURCES += \
main.cpp \
addkeysoperation.cpp \
addkitoperation.cpp \
addqtoperation.cpp \
addtoolchainoperation.cpp \
findkeyoperation.cpp \
findvalueoperation.cpp \
getoperation.cpp \
operation.cpp \
rmkeysoperation.cpp \
rmkitoperation.cpp \
rmqtoperation.cpp \
rmtoolchainoperation.cpp \
settings.cpp \
HEADERS += \
addkeysoperation.h \
addkitoperation.h \
addqtoperation.h \
addtoolchainoperation.h \
findkeyoperation.h \
findvalueoperation.h \
getoperation.h \
operation.h \
rmkeysoperation.h \
rmkitoperation.h \
rmqtoperation.h \
rmtoolchainoperation.h \
settings.h \
INCLUDEPATH += \
$$PWD/../../plugins \
$$PWD/../../libs
DESTDIR=$$IDE_APP_PATH

View File

@@ -0,0 +1,40 @@
import qbs.base 1.0
import "../QtcTool.qbs" as QtcTool
QtcTool {
name: "sdktool"
Depends { name: "cpp" }
Depends { name: "Qt.core" }
Depends { name: "Utils" }
files: [
"main.cpp",
"addkeysoperation.cpp",
"addkeysoperation.h",
"addkitoperation.cpp",
"addkitoperation.h",
"addqtoperation.cpp",
"addqtoperation.h",
"addtoolchainoperation.cpp",
"addtoolchainoperation.h",
"findkeyoperation.cpp",
"findkeyoperation.h",
"findvalueoperation.cpp",
"findvalueoperation.h",
"getoperation.cpp",
"getoperation.h",
"operation.h",
"operation.cpp",
"rmkeysoperation.cpp",
"rmkeysoperation.h",
"rmkitoperation.cpp",
"rmkitoperation.h",
"rmqtoperation.cpp",
"rmqtoperation.h",
"rmtoolchainoperation.cpp",
"rmtoolchainoperation.h",
"settings.cpp",
"settings.h"
]
}

View File

@@ -0,0 +1,100 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#include "settings.h"
#include "operation.h"
#include <iostream>
#include <QCoreApplication>
#include <QFileInfo>
Settings *Settings::m_instance = 0;
Settings *Settings::instance()
{
return m_instance;
}
Settings::Settings() :
operation(0)
{
Q_ASSERT(!m_instance);
m_instance = this;
// autodetect sdk dir:
Utils::FileName sdk = Utils::FileName::fromString(QCoreApplication::applicationDirPath());
Utils::FileName qtc = sdk;
qtc.appendPath(QLatin1String("qtcreator"));
#ifdef Q_OS_WIN
qtc.append(".exe");
#endif
QFileInfo qtcFi = qtc.toFileInfo();
if (!qtcFi.exists() || !qtcFi.isFile() || !qtcFi.isExecutable()) {
// we are in src/tools/sdktool (or lib/qtcreator/bin):
qtc = sdk;
qtc.appendPath(QLatin1String("../../../bin/qtcreator"));
#ifdef Q_OS_WIN
qtc.append(".exe");
#endif
qtcFi = qtc.toFileInfo();
if (!qtcFi.exists() || !qtcFi.isFile() || !qtcFi.isExecutable())
qtc.clear();
}
if (!qtc.isEmpty()) {
sdk = qtc.parentDir();
sdk = sdk.parentDir();
sdk.appendPath(QLatin1String("share/qtcreator/Nokia/qtcreator"));
sdkPath = sdk;
}
}
Utils::FileName Settings::getPath(const QString &file)
{
Utils::FileName result = sdkPath;
if (file == QLatin1String("profiles") || file == QLatin1String("kits"))
result.appendPath(QLatin1String("profiles"));
else if (file == QLatin1String("qtversions") || file == QLatin1String("qtversion"))
result.appendPath(QLatin1String("qtversion"));
else if (file == QLatin1String("toolchains") || file == QLatin1String("toolChains"))
result.appendPath(QLatin1String("toolchains"));
else if (file == QLatin1String("toolchains") || file == QLatin1String("toolChains"))
result.appendPath(QLatin1String("toolchains"));
else if (file == QLatin1String("devices"))
result.appendPath(QLatin1String("devices"));
else if (file == QLatin1String("android"))
result.appendPath(QLatin1String("android"));
else
return Utils::FileName();
result.append(QLatin1String(".xml"));
return result;
}

View File

@@ -0,0 +1,56 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: http://www.qt-project.org/
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**************************************************************************/
#ifndef SETTINGS_H
#define SETTINGS_H
#include <utils/fileutils.h>
#include <QStringList>
class Operation;
class Settings
{
public:
Settings();
static Settings *instance();
Utils::FileName sdkPath;
Operation *operation;
Utils::FileName getPath(const QString &file);
private:
static Settings *m_instance;
};
#endif // SETTINGS_H

View File

@@ -1,7 +1,8 @@
TEMPLATE = subdirs
SUBDIRS = qtpromaker \
qmlpuppet
qmlpuppet \
sdktool
win32 {
SUBDIRS += qtcdebugger