Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/nextcloudcmd-provisioning-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: GPL-2.0-or-later
name: nextcloudcmd provisioning tests
on:
pull_request:
types: [opened, reopened, synchronize, ready_for_review]
paths:
- 'src/cmd/**'
- 'test/testnextcloudcmdprovisioning.cpp'
- 'test/CMakeLists.txt'
- '.github/workflows/nextcloudcmd-provisioning-tests.yml'
jobs:
build:
if: ${{ !github.event.pull_request.draft }}
name: nextcloudcmd provisioning tests
runs-on: ubuntu-latest
container: ghcr.io/nextcloud/continuous-integration-client-qt6:client-sid-6.10.2-2
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 1
- name: Configure and compile
run: |
mkdir build
cd build
cmake .. -G Ninja -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ -DCMAKE_BUILD_TYPE=Debug -DQT_MAJOR_VERSION=6 -DQUICK_COMPILER=ON -DBUILD_UPDATER=ON -DBUILD_TESTING=1 -DCMAKE_CXX_FLAGS=-Werror
ninja nextcloudcmd NextcloudCmdProvisioningTest
- name: Run provisioning tests
run: |
cd build
useradd -m -s /bin/bash test
chown -R test:test .
su -c 'xvfb-run ctest -R NextcloudCmdProvisioning --output-on-failure' test
2 changes: 1 addition & 1 deletion src/cmd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ if(NOT BUILD_LIBRARIES_ONLY)
ecm_mark_nongui_executable(nextcloudcmd)
set_target_properties(nextcloudcmd PROPERTIES RUNTIME_OUTPUT_NAME "${APPLICATION_EXECUTABLE}cmd")

target_link_libraries(nextcloudcmd cmdCore)
target_link_libraries(nextcloudcmd cmdCore nextcloudCore)

if(BUILD_OWNCLOUD_OSX_BUNDLE)
set_target_properties(nextcloudcmd PROPERTIES
Expand Down
223 changes: 177 additions & 46 deletions src/cmd/cmd.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/*
* SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2014 ownCloud GmbH
Expand All @@ -6,8 +6,10 @@

#include <cstdlib>
#include <iostream>
#include <qcoreapplication.h>

Check failure on line 9 in src/cmd/cmd.cpp

View workflow job for this annotation

GitHub Actions / build

src/cmd/cmd.cpp:9:10 [clang-diagnostic-error]

'qcoreapplication.h' file not found
#include <QDir>
#include <QStringList>
#include <QTimer>
#include <QUrl>
#include <QFile>
#include <QFileInfo>
Expand All @@ -17,15 +19,23 @@
#include <qdebug.h>

#include "account.h"
#include "accountmanager.h"
#include "accountsetupcommandlinemanager.h"
#include "folderman.h"
#include "configfile.h" // ONLY ACCESS THE STATIC FUNCTIONS!
#ifdef TOKEN_AUTH_ONLY
# include "creds/tokencredentials.h"
#else
# include "creds/httpcredentials.h"
#endif
#include "creds/webflowcredentials.h"
#include "networkjobs.h"
#include "simplesslerrorhandler.h"
#include "syncengine.h"
#include "common/filesystembase.h"
#include "common/syncjournaldb.h"
#include "common/utility.h"
#include "common/vfs.h"
#include "config.h"
#include "csync_exclude.h"

Expand All @@ -46,7 +56,7 @@
#endif

using namespace OCC;

using namespace Qt::StringLiterals;

static void nullMessageHandler(QtMsgType, const QMessageLogContext &, const QString &)
{
Expand All @@ -56,7 +66,7 @@
{
QString source_dir;
QString target_url;
QString remotePath = QStringLiteral("/");
QString remotePath = u"/"_s;
QString config_directory;
QString user;
QString password;
Expand Down Expand Up @@ -161,6 +171,7 @@
std::cout << binaryName << " - command line " APPLICATION_NAME " client tool" << std::endl;
std::cout << "" << std::endl;
std::cout << "Usage: " << binaryName << " [OPTION] <source_dir> <server_url>" << std::endl;
std::cout << " " << binaryName << " --userid <user> --serverurl <url> [--apppassword <pass>] [OPTION]" << std::endl;

Check warning on line 174 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this use of "std::cout" with a logger.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2P&open=AZ__d53zQBqvZgmXwm2P&pullRequest=10608
std::cout << "" << std::endl;
std::cout << "A proxy can either be set manually using --httpproxy." << std::endl;
std::cout << "Otherwise, the setting from a configured sync client will be used." << std::endl;
Expand All @@ -183,8 +194,16 @@
std::cout << " --version, -v Display version and exit" << std::endl;
std::cout << " --logdebug More verbose logging" << std::endl;
std::cout << " --path Path to a folder on a remote server" << std::endl;
std::cout << " --confdir [dir] Use the given configuration directory" << std::endl;

Check warning on line 197 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this use of "std::cout" with a logger.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2Q&open=AZ__d53zQBqvZgmXwm2Q&pullRequest=10608
std::cout << "" << std::endl;
std::cout << "Account provisioning options (non-interactive setup):" << std::endl;

Check warning on line 199 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this use of "std::cout" with a logger.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2R&open=AZ__d53zQBqvZgmXwm2R&pullRequest=10608
std::cout << " --userid [user] The user ID to configure" << std::endl;

Check warning on line 200 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this use of "std::cout" with a logger.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2S&open=AZ__d53zQBqvZgmXwm2S&pullRequest=10608
std::cout << " --apppassword [pass] The app password for authentication (optional)" << std::endl;

Check warning on line 201 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this use of "std::cout" with a logger.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2T&open=AZ__d53zQBqvZgmXwm2T&pullRequest=10608
std::cout << " --serverurl [url] The base URL of the Nextcloud server" << std::endl;

Check warning on line 202 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this use of "std::cout" with a logger.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2U&open=AZ__d53zQBqvZgmXwm2U&pullRequest=10608
std::cout << " --localdirpath [path] Local folder path for sync (optional)" << std::endl;

Check warning on line 203 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this use of "std::cout" with a logger.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2V&open=AZ__d53zQBqvZgmXwm2V&pullRequest=10608
std::cout << " --remotedirpath [path] Remote folder path to sync, default /" << std::endl;

Check warning on line 204 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this use of "std::cout" with a logger.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2W&open=AZ__d53zQBqvZgmXwm2W&pullRequest=10608
std::cout << " --isvfsenabled [0|1] Enable virtual files (1) or disable (0)" << std::endl;

Check warning on line 205 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this use of "std::cout" with a logger.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2X&open=AZ__d53zQBqvZgmXwm2X&pullRequest=10608
std::cout << "" << std::endl;

Check warning on line 206 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this use of "std::cout" with a logger.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2Y&open=AZ__d53zQBqvZgmXwm2Y&pullRequest=10608
exit(0);
}

void showVersion()
Expand All @@ -193,83 +212,114 @@
exit(0);
}

void parseOptions(const QStringList &app_args, CmdOptions *options)
enum class CommandMode {
HelpMode,
SyncingMode,
ProvisioningMode,
UnknownMode,
};

CommandMode parseOptions(const QStringList &app_args, CmdOptions *options)

Check warning on line 222 in src/cmd/cmd.cpp

View workflow job for this annotation

GitHub Actions / build

src/cmd/cmd.cpp:222:13 [readability-function-cognitive-complexity]

function 'parseOptions' has cognitive complexity of 39 (threshold 25)

Check warning on line 222 in src/cmd/cmd.cpp

View workflow job for this annotation

GitHub Actions / build

src/cmd/cmd.cpp:222:13 [modernize-use-trailing-return-type]

use a trailing return type for this function

Check warning on line 222 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "options" of type "struct CmdOptions *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2b&open=AZ__d53zQBqvZgmXwm2b&pullRequest=10608

Check failure on line 222 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this function to reduce its Cognitive Complexity from 56 to the 25 allowed.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2Z&open=AZ__d53zQBqvZgmXwm2Z&pullRequest=10608
{
QStringList args(app_args);
auto result = CommandMode::UnknownMode;

auto args(app_args);

int argCount = args.count();
const auto argCount = args.count();

if (argCount < 3) {
if (argCount >= 2) {
const QString option = args.at(1);
if (option == "-v" || option == "--version") {
showVersion();
// Detect provisioning mode: --userid flag present means no positional args required
const auto provisionMode = args.contains(QStringLiteral("--userid"));
if (provisionMode) {
result = CommandMode::ProvisioningMode;
}

if (!provisionMode) {
if (argCount < 3) {
if (argCount >= 2) {
const QString option = args.at(1);

Check warning on line 239 in src/cmd/cmd.cpp

View workflow job for this annotation

GitHub Actions / build

src/cmd/cmd.cpp:239:31 [cppcoreguidelines-init-variables]

variable 'option' is not initialized
if (option == "-v" || option == "--version") {

Check failure on line 240 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this code to not nest more than 3 if|for|do|while|switch statements.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2a&open=AZ__d53zQBqvZgmXwm2a&pullRequest=10608
showVersion();
}
}
help();
result = CommandMode::HelpMode;
return result;
}
help();
}

options->target_url = args.takeLast();
options->target_url = args.takeLast();

options->source_dir = args.takeLast();
if (!options->source_dir.endsWith('/')) {
options->source_dir.append('/');
}
QFileInfo fi(options->source_dir);
if (!fi.exists()) {
std::cerr << "Source dir '" << qPrintable(options->source_dir) << "' does not exist." << std::endl;
exit(1);
options->source_dir = args.takeLast();
if (!options->source_dir.endsWith('/')) {
options->source_dir.append('/');
}
auto sourceDirFileInfo = QFileInfo{options->source_dir};

Check warning on line 255 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "sourceDirFileInfo" of type "class QFileInfo" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2c&open=AZ__d53zQBqvZgmXwm2c&pullRequest=10608
if (!sourceDirFileInfo.exists()) {
std::cerr << "Source dir '" << qPrintable(options->source_dir) << "' does not exist." << std::endl;
exit(1);
}
options->source_dir = sourceDirFileInfo.absoluteFilePath();
}
options->source_dir = fi.absoluteFilePath();

QStringListIterator it(args);
auto it = QStringListIterator{args};

Check warning on line 263 in src/cmd/cmd.cpp

View workflow job for this annotation

GitHub Actions / build

src/cmd/cmd.cpp:263:10 [readability-identifier-length]

variable name 'it' is too short, expected at least 3 characters
// skip file name;
if (it.hasNext())
it.next();

while (it.hasNext()) {
const QString option = it.next();
const auto option = it.next();

if (option == "--httpproxy" && !it.peekNext().startsWith("-")) {
if (option == u"--httpproxy"_s && it.hasNext() && !it.peekNext().startsWith(u"-"_s)) {

Check warning on line 271 in src/cmd/cmd.cpp

View workflow job for this annotation

GitHub Actions / build

src/cmd/cmd.cpp:271:94 [bugprone-branch-clone]

repeated branch in conditional chain
options->proxy = it.next();
} else if (option == "-s" || option == "--silent") {
} else if (option == u"-s"_s || option == u"--silent"_s) {
options->silent = true;
} else if (option == "--trust") {
} else if (option == u"--trust"_s) {
options->trustSSL = true;
} else if (option == "-n") {
} else if (option == u"-n"_s) {
options->useNetrc = true;
} else if (option == "-h") {
} else if (option == u"-h"_s) {
options->ignoreHiddenFiles = false;
} else if (option == "--non-interactive") {
} else if (option == u"--non-interactive"_s) {
options->interactive = false;
} else if ((option == "-u" || option == "--user") && !it.peekNext().startsWith("-")) {
} else if ((option == u"-u"_s || option == u"--user"_s) && it.hasNext() && !it.peekNext().startsWith(u"-"_s)) {
options->user = it.next();
} else if ((option == "-p" || option == "--password") && !it.peekNext().startsWith("-")) {
} else if ((option == u"-p"_s || option == u"--password"_s) && it.hasNext() && !it.peekNext().startsWith(u"-"_s)) {
options->password = it.next();
} else if (option == "--exclude" && !it.peekNext().startsWith("-")) {
} else if (option == u"--exclude"_s && it.hasNext() && !it.peekNext().startsWith(u"-"_s)) {
options->exclude = it.next();
} else if (option == "--unsyncedfolders" && !it.peekNext().startsWith("-")) {
} else if (option == u"--unsyncedfolders"_s && it.hasNext() && !it.peekNext().startsWith(u"-"_s)) {
options->unsyncedfolders = it.next();
} else if (option == "--max-sync-retries" && !it.peekNext().startsWith("-")) {
} else if (option == u"--max-sync-retries"_s && it.hasNext() && !it.peekNext().startsWith(u"-"_s)) {
options->restartTimes = it.next().toInt();
} else if (option == "--uplimit" && !it.peekNext().startsWith("-")) {
} else if (option == u"--uplimit"_s && it.hasNext() && !it.peekNext().startsWith(u"-"_s)) {
options->uplimit = it.next().toInt() * 1000;
} else if (option == "--downlimit" && !it.peekNext().startsWith("-")) {
} else if (option == u"--downlimit"_s && it.hasNext() && !it.peekNext().startsWith(u"-"_s)) {
options->downlimit = it.next().toInt() * 1000;
} else if (option == "--logdebug") {
} else if (option == u"--logdebug"_s) {
Logger::instance()->setLogFile("-");
Logger::instance()->setLogDebug(true);
} else if (option == "--path" && !it.peekNext().startsWith("-")) {
} else if (option == u"--path"_s && it.hasNext() && !it.peekNext().startsWith(u"-"_s)) {
options->remotePath = it.next();
}
else {
help();
} else if (option == u"--confdir"_s && it.hasNext() && !it.peekNext().startsWith(u"--"_s)) {
options->config_directory = it.next();
} else {
QString errorMessage;

Check warning on line 305 in src/cmd/cmd.cpp

View workflow job for this annotation

GitHub Actions / build

src/cmd/cmd.cpp:305:21 [cppcoreguidelines-init-variables]

variable 'errorMessage' is not initialized
if (!AccountSetupCommandLineManager::instance()->parseCommandlineOption(option, it, errorMessage)) {
help();
result = CommandMode::HelpMode;
return result;
}
}
}

if (options->target_url.isEmpty() || options->source_dir.isEmpty()) {
if (!provisionMode && (options->target_url.isEmpty() || options->source_dir.isEmpty())) {
result = CommandMode::HelpMode;
help();
return result;
} else if (!provisionMode) {

Check warning on line 318 in src/cmd/cmd.cpp

View workflow job for this annotation

GitHub Actions / build

src/cmd/cmd.cpp:318:7 [readability-else-after-return]

do not use 'else' after 'return'
result = CommandMode::SyncingMode;
}

return result;
}

/* If the selective sync list is different from before, we need to disable the read from db
Expand All @@ -292,6 +342,56 @@
}
}

[[nodiscard]] bool setupAccountsOnly()

Check warning on line 345 in src/cmd/cmd.cpp

View workflow job for this annotation

GitHub Actions / build

src/cmd/cmd.cpp:345:20 [modernize-use-trailing-return-type]

use a trailing return type for this function
{
auto result = false;

ConfigFile cfg;

Check warning on line 349 in src/cmd/cmd.cpp

View workflow job for this annotation

GitHub Actions / build

src/cmd/cmd.cpp:349:16 [cppcoreguidelines-init-variables]

variable 'cfg' is not initialized

Check warning on line 349 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "cfg" of type "class OCC::ConfigFile" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2d&open=AZ__d53zQBqvZgmXwm2d&pullRequest=10608
const auto tryMigrate = cfg.overrideServerUrl().isEmpty();
auto accountsRestoreResult = AccountManager::AccountsRestoreFailure;
if (accountsRestoreResult = AccountManager::instance()->restore(tryMigrate);
accountsRestoreResult == AccountManager::AccountsRestoreFailure) {
qWarning() << "restoring existing user accounts failed";
return result;
}

result = true;
return result;
}

[[nodiscard]] bool setupAccountsAndFolders()

Check warning on line 362 in src/cmd/cmd.cpp

View workflow job for this annotation

GitHub Actions / build

src/cmd/cmd.cpp:362:20 [modernize-use-trailing-return-type]

use a trailing return type for this function
{
auto result = false;

auto folderManager = FolderMan::instance();

Check warning on line 366 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Unmodified variable "folderManager" of type "class OCC::FolderMan *" should be const-qualified.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2e&open=AZ__d53zQBqvZgmXwm2e&pullRequest=10608
ConfigFile configFile;
configFile.setMigrationPhase(ConfigFile::MigrationPhase::SetupUsers);
if (!setupAccountsOnly()) {
return result;
}

configFile.setMigrationPhase(ConfigFile::MigrationPhase::SetupFolders);
const auto foldersListSize = folderManager->setupFolders();
folderManager->setSyncEnabled(true);

const auto prettyNamesList = [](const QList<AccountStatePtr> &accounts) {
QStringList list;
for (const auto &account : accounts) {
list << account->account()->prettyName().prepend("- ");
}
return list.join("\n");
};

const auto accounts = AccountManager::instance()->accounts();
const auto accountsListSize = accounts.size();

qWarning() << foldersListSize << "folder(s) migrated";
qWarning() << accountsListSize << "account(s) migrated:" << prettyNamesList(accounts);

result = true;
return result;
}

int main(int argc, char **argv)
{
#ifdef Q_OS_WIN
Expand All @@ -301,7 +401,7 @@

#ifdef Q_OS_WIN
// Ensure OpenSSL config file is only loaded from app directory
QString opensslConf = QCoreApplication::applicationDirPath() + QStringLiteral("/openssl.cnf");
QString opensslConf = QCoreApplication::applicationDirPath() + u"/openssl.cnf"_s;
qputenv("OPENSSL_CONF", opensslConf.toLocal8Bit());
#endif

Expand All @@ -315,14 +415,45 @@
options.uplimit = 0;
options.downlimit = 0;

parseOptions(app.arguments(), &options);
const auto commandMode = parseOptions(app.arguments(), &options);

Check warning on line 418 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "." with "::" for access to "QCoreApplication::arguments".

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2g&open=AZ__d53zQBqvZgmXwm2g&pullRequest=10608

if (commandMode == CommandMode::HelpMode) {
return 0;
}

if (options.silent) {
qInstallMessageHandler(nullMessageHandler);
} else {
qSetMessagePattern("%{time MM-dd hh:mm:ss:zzz} [ %{type} %{category} ]%{if-debug}\t[ %{function} ]%{endif}:\t%{message}");
}

if (!options.config_directory.isEmpty()) {
if (!ConfigFile::setConfDir(options.config_directory)) {

Check warning on line 431 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Merge this "if" statement with the enclosing one.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2f&open=AZ__d53zQBqvZgmXwm2f&pullRequest=10608
std::cerr << "Invalid confdir '" << qPrintable(options.config_directory) << "', disabling." << std::endl;

Check warning on line 432 in src/cmd/cmd.cpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace this use of "std::cerr" with a logger.

See more on https://sonarcloud.io/project/issues?id=nextcloud_desktop&issues=AZ__d53zQBqvZgmXwm2h&open=AZ__d53zQBqvZgmXwm2h&pullRequest=10608
}
}

if (commandMode == CommandMode::ProvisioningMode) {
if (!setupAccountsAndFolders()) {
qWarning() << "Restoring existing accounts failed. Skip creation of a new account. See prior messages for a detailed error.";
return -1;
}

if (AccountSetupCommandLineManager::instance()->isCommandLineParsed()) {
if (AccountSetupCommandLineManager::instance()->setupAccountFromCommandLine()) {
return 0;
} else {
qWarning() << "Creation of the account failed. See prior messages for a detailed error.";
return -1;
}
} else {
AccountSetupCommandLineManager::destroy();
qWarning() << "Missing mandatory command line options for provisioning mode";
help();
return -1;
}
}

AccountPtr account = Account::create();

if (!account) {
Expand Down
Loading
Loading