Rename qFlipperTool to qFlipper-cli

This commit is contained in:
Georgii Surkov 2022-03-21 17:45:46 +03:00
parent d550f8e2b6
commit 358e869e2c
11 changed files with 75 additions and 75 deletions

View File

@ -96,9 +96,9 @@ See [contrib](./contrib) for available options.
## Project structure
- `application` - The main graphical application, written mostly in QML.
- `cli` - The command line interface, provides nearly all main application's functionality.
- `backend` - The backend library, written in C++. Takes care of most of the logic.
- `dfu` - Low level library for accessing USB and DFU devices.
- `tool` - The command line interface, provides nearly all main application's functionality.
- `plugins` - Protobuf-based communication protocol support.
- `3rdparty` - Third-party libraries.
- `contrib` - Contributed packages and scripts.

View File

@ -18,7 +18,7 @@ cd "$BUILD_DIRECTORY"
qmake -spec macx-clang CONFIG+=release CONFIG+=x86_64 -o Makefile ../$PROJECT.pro
make qmake_all && make -j9 > /dev/null && make install
macdeployqt $PROJECT.app -executable=$PROJECT.app/Contents/MacOS/${PROJECT}Tool -qmldir=$PROJECT_DIR/Application -verbose=1
macdeployqt $PROJECT.app -executable=$PROJECT.app/Contents/MacOS/${PROJECT}-cli -qmldir=$PROJECT_DIR/Application -verbose=1
FAILED_LIBS_COUNT=`otool -L $PROJECT.app/Contents/Frameworks/*.dylib | grep /usr/local -c || true`
FAILED_APPS_COUNT=`otool -L $PROJECT.app/Contents/MacOS/* | grep /usr/local -c || true`

View File

@ -18,7 +18,7 @@ set WINDEPLOYQT=%QT_BIN_DIR%\windeployqt.exe
set JOM=%QT_DIR%\Tools\QtCreator\bin\jom.exe
set TARGET=qFlipper
set TESTS_TOOL=%TARGET%Tool
set TARGET_CLI=%TARGET%-cli
set PROTO_TARGET=flipperproto
set DRIVER_TOOL=FlipperDriverTool
@ -51,7 +51,7 @@ cd %DIST_DIR%
%WINDEPLOYQT% --release --no-compiler-runtime --dir %DIST_DIR% %PLUGINS_DIR%/%PROTO_TARGET%0.dll &&^
%WINDEPLOYQT% --release --no-compiler-runtime --qmldir %QML_DIR% %TARGET%.exe &&^
%WINDEPLOYQT% --release --no-compiler-runtime %TESTS_TOOL%.exe || goto error
%WINDEPLOYQT% --release --no-compiler-runtime %TARGET_CLI%.exe || goto error
rem Copy OpenSSL binaries
copy /Y %OPENSSL_DIR%\*.dll .
@ -70,7 +70,7 @@ copy /Y %VCREDIST2010_EXE% .
if defined SIGNING_TOOL (
rem Sign the executables
call %SIGNING_TOOL% %DIST_DIR%\%TARGET%.exe || goto error
call %SIGNING_TOOL% %DIST_DIR%\%TESTS_TOOL%.exe || goto error
call %SIGNING_TOOL% %DIST_DIR%\%TARGET_CLI%.exe || goto error
call %SIGNING_TOOL% %DIST_DIR%\%DRIVER_TOOL%.exe || goto error
)

View File

@ -1,12 +1,12 @@
# qFlipperTool
# qFlipper-cli
### A non-interactive text mode interface for qFlipper
This program is mostly meant for testing purposes, although it can also provide all of the qFlipper's features from the comfort of the terminal emulator.
## Running:
### Windows:
`<Program_files_directory>\qFlipper\qFlipperTool.exe [args] [parameters]`
`<Program_files_directory>\qFlipper\qFlipper-cli.exe [args] [parameters]`
### MacOS:
`<Applications_directory>/qFlipper.app/Contents/MacOS/qFlipperTool [args] [parameters]`
`<Applications_directory>/qFlipper.app/Contents/MacOS/qFlipper-cli [args] [parameters]`
### Linux:
`<AppImage_directory>/qFlipper-x86_64-x.y.z.AppImage cli [args] [parameters]`

View File

@ -1,4 +1,4 @@
#include "tool.h"
#include "cli.h"
#include <QDebug>
#include <QLoggingCategory>
@ -9,9 +9,9 @@
#include "flipperzero/flipperzero.h"
#include "flipperzero/devicestate.h"
Q_LOGGING_CATEGORY(LOG_TOOL, "TOOL")
Q_LOGGING_CATEGORY(LOG_CLI, "CLI")
Tool::Tool(int argc, char *argv[]):
Cli::Cli(int argc, char *argv[]):
QCoreApplication(argc, argv),
m_pendingOperation(NoOperation),
m_repeatCount(1)
@ -23,21 +23,21 @@ Tool::Tool(int argc, char *argv[]):
processOptions();
processArguments();
qCInfo(LOG_TOOL) << "Waiting for devices...";
qCInfo(LOG_CLI) << "Waiting for devices...";
}
Tool::~Tool()
Cli::~Cli()
{}
void Tool::onBackendStateChanged()
void Cli::onBackendStateChanged()
{
const auto state = m_backend.backendState();
if(state == ApplicationBackend::BackendState::ErrorOccured) {
qCCritical(LOG_TOOL).nospace() << "An error has occured: " << m_backend.errorType() << ". Exiting.";
qCCritical(LOG_CLI).nospace() << "An error has occured: " << m_backend.errorType() << ". Exiting.";
return exit(-1);
} else if(state == ApplicationBackend::BackendState::WaitingForDevices) {
qCCritical(LOG_TOOL) << "All devices disconnected. Exiting.";
qCCritical(LOG_CLI) << "All devices disconnected. Exiting.";
return exit(0);
} else if(state == ApplicationBackend::BackendState::Ready) {
@ -47,7 +47,7 @@ void Tool::onBackendStateChanged()
return;
} else if(m_backend.firmwareUpdateState() == ApplicationBackend::FirmwareUpdateState::ErrorOccured) {
qCCritical(LOG_TOOL) << "Failed to get firmware updates. Exiting.";
qCCritical(LOG_CLI) << "Failed to get firmware updates. Exiting.";
return exit(-1);
}
@ -57,7 +57,7 @@ void Tool::onBackendStateChanged()
startPendingOperation();
} else {
// ... But there are special cases when we might have to wait for the firmware update to become available.
connect(&m_backend, &ApplicationBackend::firmwareUpdateStateChanged, this, &Tool::onUpdateStateChanged);
connect(&m_backend, &ApplicationBackend::firmwareUpdateStateChanged, this, &Cli::onUpdateStateChanged);
}
} else if(state == ApplicationBackend::BackendState::Finished) {
@ -65,33 +65,33 @@ void Tool::onBackendStateChanged()
}
}
void Tool::onUpdateStateChanged()
void Cli::onUpdateStateChanged()
{
if(m_backend.firmwareUpdateState() == ApplicationBackend::FirmwareUpdateState::ErrorOccured) {
qCCritical(LOG_TOOL) << "Failed to get firmware updates. Exiting.";
qCCritical(LOG_CLI) << "Failed to get firmware updates. Exiting.";
return exit(-1);
}
const auto isFirmwareReady = m_backend.firmwareUpdateState() != ApplicationBackend::FirmwareUpdateState::Checking &&
m_backend.firmwareUpdateState() != ApplicationBackend::FirmwareUpdateState::Unknown;
if(isFirmwareReady) {
disconnect(&m_backend, &ApplicationBackend::firmwareUpdateStateChanged, this, &Tool::onUpdateStateChanged);
disconnect(&m_backend, &ApplicationBackend::firmwareUpdateStateChanged, this, &Cli::onUpdateStateChanged);
startPendingOperation();
}
}
void Tool::initConnections()
void Cli::initConnections()
{
connect(&m_backend, &ApplicationBackend::backendStateChanged, this, &Tool::onBackendStateChanged);
connect(&m_backend, &ApplicationBackend::backendStateChanged, this, &Cli::onBackendStateChanged);
}
void Tool::initLogger()
void Cli::initLogger()
{
qInstallMessageHandler(Logger::messageOutput);
globalLogger->setLogLevel(Logger::Terse);
}
void Tool::initParser()
void Cli::initParser()
{
m_parser.addPositionalArgument(QStringLiteral("backup"), QStringLiteral("Backup Internal Memory contents"), QStringLiteral("{backup <target_directory>,"));
m_parser.addPositionalArgument(QStringLiteral("restore"), QStringLiteral("Restore Internal Memory contents"), QStringLiteral("restore <source_directory>,"));
@ -114,14 +114,14 @@ void Tool::initParser()
m_parser.process(*this);
}
void Tool::processOptions()
void Cli::processOptions()
{
processDebugLevelOption();
processRepeatNumberOption();
processUpdateChannelOption();
}
void Tool::processArguments()
void Cli::processArguments()
{
const auto args = m_parser.positionalArguments();
@ -146,7 +146,7 @@ void Tool::processArguments()
}
}
void Tool::processDebugLevelOption()
void Cli::processDebugLevelOption()
{
const auto &debugLevelOption = m_options[DebugLevelOption];
@ -158,14 +158,14 @@ void Tool::processDebugLevelOption()
const auto num = m_parser.value(debugLevelOption).toInt(&canConvert);
if(!canConvert || (num < 0 || num > 2)) {
qCCritical(LOG_TOOL) << "Debug level must be one of the following values: 0, 1, 2.";
qCCritical(LOG_CLI) << "Debug level must be one of the following values: 0, 1, 2.";
std::exit(-1);
}
globalLogger->setLogLevel((Logger::LogLevel)num);
}
void Tool::processRepeatNumberOption()
void Cli::processRepeatNumberOption()
{
const auto &repeatNumberOption = m_options[RepeatNumberOption];
@ -177,16 +177,16 @@ void Tool::processRepeatNumberOption()
const auto num = m_parser.value(repeatNumberOption).toInt(&canConvert);
if(!canConvert || (num < 0)) {
qCCritical(LOG_TOOL) << "Repeat number must be a whole non-negative number.";
qCCritical(LOG_CLI) << "Repeat number must be a whole non-negative number.";
std::exit(-1);
}
qCInfo(LOG_TOOL).noquote() << "Will repeat the operation" << (num ? QStringLiteral("%1 times.").arg(num) : QStringLiteral("indefinitely."));
qCInfo(LOG_CLI).noquote() << "Will repeat the operation" << (num ? QStringLiteral("%1 times.").arg(num) : QStringLiteral("indefinitely."));
m_repeatCount = num ? num : -1;
}
void Tool::processUpdateChannelOption()
void Cli::processUpdateChannelOption()
{
const auto &updateChannelOption = m_options[UpdateChannelOption];
@ -203,83 +203,83 @@ void Tool::processUpdateChannelOption()
const auto channelName = m_parser.value(updateChannelOption);
if(!allowedChannelNames.contains(channelName)) {
qCCritical(LOG_TOOL) << "Unknown update channel. Possible channels are:" << allowedChannelNames;
qCCritical(LOG_CLI) << "Unknown update channel. Possible channels are:" << allowedChannelNames;
std::exit(-1);
}
globalPrefs->setFirmwareUpdateChannel(channelName);
}
void Tool::beginDefaultAction()
void Cli::beginDefaultAction()
{
qCInfo(LOG_TOOL) << "Performing full firmware update...";
qCInfo(LOG_CLI) << "Performing full firmware update...";
m_pendingOperation = DefaultAction;
}
void Tool::beginBackup()
void Cli::beginBackup()
{
verifyArgumentCount(2);
m_fileParameter = QUrl::fromLocalFile(m_parser.positionalArguments().at(1));
qCInfo(LOG_TOOL).noquote().nospace() << "Performing internal storage backup to " << m_fileParameter << "...";
qCInfo(LOG_CLI).noquote().nospace() << "Performing internal storage backup to " << m_fileParameter << "...";
m_pendingOperation = Backup;
}
void Tool::beginRestore()
void Cli::beginRestore()
{
verifyArgumentCount(2);
m_fileParameter = QUrl::fromLocalFile(m_parser.positionalArguments().at(1));
qCInfo(LOG_TOOL).noquote().nospace() << "Performing internal restore from " << m_fileParameter << "...";
qCInfo(LOG_CLI).noquote().nospace() << "Performing internal restore from " << m_fileParameter << "...";
m_pendingOperation = Restore;
}
void Tool::beginErase()
void Cli::beginErase()
{
verifyArgumentCount(1);
qCInfo(LOG_TOOL) << "Performing device factory reset...";
qCInfo(LOG_CLI) << "Performing device factory reset...";
m_pendingOperation = Erase;
}
void Tool::beginWipe()
void Cli::beginWipe()
{
qCCritical(LOG_TOOL) << "Wipe is not implemented yet. Sorry!";
qCCritical(LOG_CLI) << "Wipe is not implemented yet. Sorry!";
std::exit(-1);
}
void Tool::beginFirmware()
void Cli::beginFirmware()
{
verifyArgumentCount(2);
const auto arg = m_parser.positionalArguments().at(1);
if(!arg.endsWith(QStringLiteral(".dfu"), Qt::CaseInsensitive)) {
qCCritical(LOG_TOOL) << "Please provide a firmware file in DFUse format.";
qCCritical(LOG_CLI) << "Please provide a firmware file in DFUse format.";
std::exit(-1);
}
m_fileParameter = QUrl::fromLocalFile(arg);
qCInfo(LOG_TOOL).noquote().nospace() << "Performing Firmware installation from " << m_fileParameter << "...";
qCInfo(LOG_CLI).noquote().nospace() << "Performing Firmware installation from " << m_fileParameter << "...";
m_pendingOperation = Firmware;
}
void Tool::beginCore2Radio()
void Cli::beginCore2Radio()
{
verifyArgumentCount(2);
const auto arg = m_parser.positionalArguments().at(1);
if(!arg.endsWith(QStringLiteral(".bin"), Qt::CaseInsensitive)) {
qCCritical(LOG_TOOL) << "Please provide a firmware file in .bin format.";
qCCritical(LOG_CLI) << "Please provide a firmware file in .bin format.";
std::exit(-1);
}
m_fileParameter = QUrl::fromLocalFile(arg);
qCInfo(LOG_TOOL).noquote().nospace() << "Performing Radio Firmware installation from " << m_fileParameter << "...";
qCInfo(LOG_CLI).noquote().nospace() << "Performing Radio Firmware installation from " << m_fileParameter << "...";
m_pendingOperation = Core2Radio;
}
void Tool::beginCore2FUS()
void Cli::beginCore2FUS()
{
verifyArgumentCount(3);
@ -288,7 +288,7 @@ void Tool::beginCore2FUS()
const auto &arg2 = args[2];
if(!arg1.endsWith(QStringLiteral(".bin"), Qt::CaseInsensitive)) {
qCCritical(LOG_TOOL) << "Please provide a firmware file in .bin format.";
qCCritical(LOG_CLI) << "Please provide a firmware file in .bin format.";
std::exit(-1);
}
@ -298,17 +298,17 @@ void Tool::beginCore2FUS()
m_core2Address = arg2.toULong(&canConvert, 16);
if(!canConvert) {
qCCritical(LOG_TOOL) << "Please provide a valid hexadecimal address.";
qCCritical(LOG_CLI) << "Please provide a valid hexadecimal address.";
std::exit(-1);
}
m_pendingOperation = Core2FUS;
}
void Tool::startPendingOperation()
void Cli::startPendingOperation()
{
if(m_repeatCount == 0) {
qCInfo(LOG_TOOL) << "All done! Thank you.";
qCInfo(LOG_CLI) << "All done! Thank you.";
return exit(0);
} else if(m_repeatCount > 0) {
@ -333,17 +333,17 @@ void Tool::startPendingOperation()
} else if(m_pendingOperation == Core2FUS) {
m_backend.installFUS(m_fileParameter, m_core2Address);
} else {
qCCritical(LOG_TOOL) << "Unhandled operation. Probably a bug!";
qCCritical(LOG_CLI) << "Unhandled operation. Probably a bug!";
exit(-1);
}
}
void Tool::verifyArgumentCount(int num)
void Cli::verifyArgumentCount(int num)
{
const auto argCount = m_parser.positionalArguments().size();
if(argCount != num) {
qCCritical(LOG_TOOL).nospace() << "Expected " << num << " arguments, got " << argCount << ". Exiting.";
qCCritical(LOG_CLI).nospace() << "Expected " << num << " arguments, got " << argCount << ". Exiting.";
std::exit(-1);
}
}

View File

@ -6,7 +6,7 @@
#include "applicationbackend.h"
class Tool : public QCoreApplication
class Cli : public QCoreApplication
{
Q_OBJECT
@ -29,8 +29,8 @@ class Tool : public QCoreApplication
};
public:
Tool(int argc, char *argv[]);
~Tool();
Cli(int argc, char *argv[]);
~Cli();
private slots:
void onBackendStateChanged();

View File

@ -3,7 +3,7 @@ QT += serialport network
include(../qflipper_common.pri)
TARGET = $${NAME}Tool
TARGET = $${NAME}-cli
DESTDIR = $$OUT_PWD/..
CONFIG += c++11 console
@ -58,10 +58,10 @@ DEPENDPATH += \
SOURCES += \
main.cpp \
tool.cpp
cli.cpp
HEADERS += \
tool.h
cli.h
unix:!macx {
target.path = $$PREFIX/bin

View File

@ -1,4 +1,4 @@
#include "tool.h"
#include "cli.h"
#include <QSettings>
@ -6,11 +6,11 @@ int main(int argc, char *argv[])
{
QSettings::setDefaultFormat(QSettings::IniFormat);
QCoreApplication::setApplicationName(QStringLiteral("%1Tool").arg(APP_NAME));
QCoreApplication::setApplicationName(QStringLiteral("%1-cli").arg(APP_NAME));
QCoreApplication::setApplicationVersion(APP_VERSION);
QCoreApplication::setOrganizationName(QStringLiteral("Flipper Devices Inc"));
QCoreApplication::setOrganizationDomain(QStringLiteral("flipperdevices.com"));
Tool a(argc, argv);
Cli a(argc, argv);
return a.exec();
}

View File

@ -11,7 +11,7 @@ elif [[ "$1" = 'gui' ]]; then
"$this_dir"/usr/bin/qFlipper "$@"
elif [[ "$1" = 'cli' ]]; then
shift 1
"$this_dir"/usr/bin/qFlipperTool "$@"
"$this_dir"/usr/bin/qFlipper-cli "$@"
else
echo 'Usage: <Appimage> {[gui], cli} [parameters]'
exit 255

View File

@ -31,15 +31,15 @@ LicenseData LICENSE
Section "-Main Application"
IfFileExists "${UNINSTALL_EXE}" 0 +2
ExecWait "${UNINSTALL_EXE} /S"
SetOutPath $INSTDIR
File /r "build\${NAME}\*"
ExecWait "${VCREDIST2010_EXE} /passive /norestart"
ExecWait "${VCREDIST2019_EXE} /install /passive /norestart"
WriteUninstaller "${UNINSTALL_EXE}"
WriteRegStr HKLM "${UNINSTALL_REG_PATH}" "DisplayName" "${NAME}"
WriteRegStr HKLM "${UNINSTALL_REG_PATH}" "UninstallString" "$\"${UNINSTALL_EXE}$\""
WriteRegStr HKLM "${UNINSTALL_REG_PATH}" "QuietUninstallString" "$\"${UNINSTALL_EXE}$\" /S"
@ -64,7 +64,7 @@ Section "-Cleanup"
Delete ${VCREDIST2019_EXE}
Delete ${VCREDIST2010_EXE}
Delete ${DRIVER_TOOL_EXE}
${GetSize} "$INSTDIR" "/S=0K" $0 $1 $2
IntFmt $0 "0x%08X" $0
WriteRegDWORD HKLM "${UNINSTALL_REG_PATH}" "EstimatedSize" "$0"

View File

@ -6,9 +6,9 @@ SUBDIRS += \
backend \
dfu \
plugins \
tool
cli
backend.depends = dfu plugins
application.depends = backend
tool.depends = backend
cli.depends = backend
plugins.depends = 3rdparty