diff options
-rw-r--r-- | .travis.yml | 46 | ||||
-rw-r--r-- | CMakeLists.txt | 14 | ||||
-rw-r--r-- | jobs/apigen.yaml | 57 | ||||
-rw-r--r-- | jobs/preamble.mustache | 3 | ||||
-rw-r--r-- | jobs/{{base}}.cpp.mustache | 76 | ||||
-rw-r--r-- | jobs/{{base}}.h.mustache | 65 |
6 files changed, 248 insertions, 13 deletions
diff --git a/.travis.yml b/.travis.yml index 24a182cf..b8917ef1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,40 @@ language: cpp + +addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-precise-3.8 + packages: + - g++-5 + - clang-3.8 + - qt5-default + matrix: include: - - os: linux - dist: trusty - compiler: gcc - - os: linux - dist: trusty - compiler: clang - - os: osx + - os: linux + env: [ ENV_EVAL="CC=gcc-5 && CXX=g++-5" ] + - os: linux + env: [ ENV_EVAL="CC=clang-3.8 && CXX=clang++-3.8" ] + - os: osx + env: [ ENV_EVAL="brew update && brew install qt5 && CMAKE_PREFIX_PATH=/usr/local/opt/qt" ] + install: - - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; else sudo apt-get update -qq; fi - - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install qt5; export PATH="$PATH:/usr/local/opt/qt/bin"; else sudo apt-get install -y qt5-default; fi - - mkdir build && cd build - - cmake .. -script: - - cmake --build . --target all +- eval "${ENV_EVAL}" +- git clone https://github.com/QMatrixClient/matrix-doc.git +- git clone --recursive https://github.com/KitsuneRal/api-generator.git +- pushd api-generator +- cmake -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} . +- cmake --build . +- popd + +before_script: +- mkdir build && cd build +- cmake -DMATRIX_DOC_PATH="matrix-doc" -DAPIGEN_PATH="api-generator/api-generator" -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} .. +- cmake --build . --target update-api + +script: cmake --build . + notifications: webhooks: urls: diff --git a/CMakeLists.txt b/CMakeLists.txt index e55335ec..f4358521 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -86,6 +86,20 @@ set(libqmatrixclient_SRCS aux_source_directory(jobs/generated libqmatrixclient_job_SRCS) +if (MATRIX_DOC_PATH AND APIGEN_PATH) + add_custom_target(update-api + ${APIGEN_PATH} --config jobs/apigen.yaml --out jobs/generated + ${MATRIX_DOC_PATH}/api/client-server + content-repo.yaml- cas_login_redirect.yaml- cas_login_ticket.yaml- + old_sync.yaml- room_initial_sync.yaml- + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + SOURCES jobs/apigen.yaml jobs/{{base}}.h.mustache jobs/{{base}}.cpp.mustache + VERBATIM + ) +endif() + +aux_source_directory(jobs/generated libqmatrixclient_job_SRCS) + set(example_SRCS examples/qmc-example.cpp) add_library(qmatrixclient ${libqmatrixclient_SRCS} ${libqmatrixclient_job_SRCS}) diff --git a/jobs/apigen.yaml b/jobs/apigen.yaml new file mode 100644 index 00000000..69662a5d --- /dev/null +++ b/jobs/apigen.yaml @@ -0,0 +1,57 @@ +preprocess: + "%CLIENT_RELEASE_LABEL%": r0 + "%CLIENT_MAJOR_VERSION%": r0 + +# Structure: +# swaggerType: <targetTypeSpec> +# OR +# swaggerType: +# - swaggerFormat: <targetTypeSpec> +# - /swaggerFormatRegEx/: <targetTypeSpec> +# - //: <targetTypeSpec> # default, if the format doesn't mach anything above +# WHERE +# targetTypeSpec = targetType OR +# { type: targetType, imports: <filename OR [ filenames... ]>, <other attributes...> } +types: + integer: + - int64: qint64 + - int32: qint32 + - //: int + number: + - float: float + - //: double + boolean: bool + string: + - byte: &QByteArray { type: QByteArray, imports: <QtCore/QByteArray> } + - binary: *QByteArray + - date: + type: QDate + avoidCopy?: true + imports: <QtCore/QDate> + - dateTime: + type: QDateTime + avoidCopy?: true + imports: <QtCore/QDateTime> + - //: { type: QString, imports: <QtCore/QString> } + file: + type: QByteArray + imports: <QtCore/QByteArray> + "returnFile?": true + object: { type: QJsonObject, "avoidCopy?": true, imports: <QtCore/QJsonObject> } + array: { type: "QVector<{{1}}>", "avoidCopy?": true, imports: <QtCore/QVector> } + +#operations: + +env: +# preamble: preamble.mustache + copyrightName: Kitsune Ral + copyrightEmail: <kitsune-ral@users.sf.net> +# imports: { set: } +# returnFile?: { bool: false } + +templates: +- "{{base}}.h.mustache" +- "{{base}}.cpp.mustache" + +#outFilesList: apifiles.txt + diff --git a/jobs/preamble.mustache b/jobs/preamble.mustache new file mode 100644 index 00000000..3ba87d61 --- /dev/null +++ b/jobs/preamble.mustache @@ -0,0 +1,3 @@ +/****************************************************************************** + * THIS FILE IS GENERATED - ANY EDITS WILL BE OVERWRITTEN + */ diff --git a/jobs/{{base}}.cpp.mustache b/jobs/{{base}}.cpp.mustache new file mode 100644 index 00000000..c9b0eb5e --- /dev/null +++ b/jobs/{{base}}.cpp.mustache @@ -0,0 +1,76 @@ +{{#@filePartial}}preamble{{/@filePartial}} + +#include "{{filenameBase}}.h" + +{{#operations}} +#include "../converters.h" + +#include <QtCore/QStringBuilder> + +using namespace QMatrixClient; + + {{#returns?}} +class {{#@cap}}{{operationId}}{{/@cap}}Job::Private +{ + public: + {{#returns}} + {{type}} {{name}}; + {{/returns}} +}; + {{/returns?}} + +static const auto basePath = QStringLiteral("{{basePathWithoutHost}}"); + + {{#operation}} +{{#@cap}}{{operationId}}{{/@cap}}Job::{{#@cap}}{{operationId}}{{/@cap}}Job(const ConnectionData* connection{{#allParams}}, {{!}} + {{#avoidCopy?}}const {{dataType}}&{{/avoidCopy?}}{{^avoidCopy?}}{{dataType}}{{/avoidCopy?}} {{paramName}} + {{/allParams}}) + : BaseJob(connection, HttpVerb::{{#@cap}}{{#@tolower}}{{httpMethod}}{{/@tolower}}{{/@cap}}, "{{#@cap}}{{operationId}}{{/@cap}}Job" + , basePath{{#pathParts}} % {{part}}{{/pathParts}} + , Query { {{#queryParams}} + { "{{baseName}}", toJson({{paramName}}).toString() }{{#hasMore}}, {{/hasMore}} + {{/queryParams}} } + , Data { {{#bodyParams}} + { "{{baseName}}", toJson({{paramName}}) }{{#hasMore}}, {{/hasMore}} + {{/bodyParams}} } + {{#skipAuth}}, false{{/skipAuth}} + ){{#returns?}}, d(new Private){{/returns?}} +{ } + {{/operation}} + + {{#returns?}} +{{className}}Job::~{{className}}Job() +{ + delete d; +} + + {{#returns}} +{{type}} {{className}}Job::{{name}}() const +{ + return d->{{name}}; +} + {{/returns}} + + {{#returnFile?}} +BaseJob::Status {{className}}Job::parseReply(QByteArray data) +{ + {{#returns}}{{name}}{{/returns}} = data; + return Success; +} + {{/returnFile?}} + {{^returnFile?}} +BaseJob::Status {{className}}Job::parseJson(const QJsonDocument& data) +{ + auto json = data.object(); + {{#returns}} + {{#required?}} + if (!json.contains("{{name}}") + return { JsonParseError, "{{name}} not found in the response" }; + {{/required?}} + d->{{name}} = fromJson<{{type}}>(json.value("{{name}}")); + {{/returns}} + return Success; +} + {{/returnFile?}} + {{/returns?}} +{{/operations}} diff --git a/jobs/{{base}}.h.mustache b/jobs/{{base}}.h.mustache new file mode 100644 index 00000000..6fb9caef --- /dev/null +++ b/jobs/{{base}}.h.mustache @@ -0,0 +1,65 @@ +{{#@filePartial}}preamble{{/@filePartial}} + +#pragma once + +{{#operations}} +#include "../basejob.h" +{{/operations}} + +{{#imports}} +#include {{.}} +{{/imports}} + +{{#models}} +#include <QtCore/QJsonValue> {{! FIXME: This should probably go inside imports }} +{{/models}} + +namespace QMatrixClient +{ +{{#models}} + // Data structures + {{#model}} + struct {{classname}} + { + {{#vars}} + {{datatype}} {{name}}; + {{/vars}} + operator QJsonValue() const { return {}; } + }; + {{/model}} +{{/models}} +{{#operations}} + // Operations + {{#operation}} + class {{#@cap}}{{operationId}}{{/@cap}}Job : public BaseJob + { + public: + {{#@cap}}{{operationId}}{{/@cap}}Job(const ConnectionData* connection + {{#allParams}} + , {{!}} + {{#avoidCopy?}}const {{dataType}}&{{/avoidCopy?}} + {{^avoidCopy?}}{{dataType}}{{/avoidCopy?}} {{paramName}} + {{/allParams}}); + {{#returns?}} + virtual {{className}}Job(); + + {{#returns}} + {{type}} {{name}}() const; + {{/returns}} + + protected: + {{#returnFile?}} + Status parseReply(QByteArray data) override; + {{/returnFile?}} + {{^returnFile}} + Status parseJson(const JsonDocument& data) override; + {{/returnFile}} + + private: + class Private; + Private* d; + {{/returns?}} + }; + {{/operation}} +{{/operations}} +} // namespace QMatrixClient |