forked from quickshell/quickshell
		
	core/command: rewrite command parser with CLI11
This commit is contained in:
		
							parent
							
								
									bdbf5b9af9
								
							
						
					
					
						commit
						291179ede2
					
				
					 7 changed files with 185 additions and 129 deletions
				
			
		| 
						 | 
					@ -15,6 +15,7 @@ Checks: >
 | 
				
			||||||
  -cppcoreguidelines-non-private-member-variables-in-classes,
 | 
					  -cppcoreguidelines-non-private-member-variables-in-classes,
 | 
				
			||||||
  -cppcoreguidelines-avoid-goto,
 | 
					  -cppcoreguidelines-avoid-goto,
 | 
				
			||||||
  -cppcoreguidelines-pro-bounds-array-to-pointer-decay,
 | 
					  -cppcoreguidelines-pro-bounds-array-to-pointer-decay,
 | 
				
			||||||
 | 
					  -cppcoreguidelines-avoid-do-while,
 | 
				
			||||||
  google-build-using-namespace.
 | 
					  google-build-using-namespace.
 | 
				
			||||||
  google-explicit-constructor,
 | 
					  google-explicit-constructor,
 | 
				
			||||||
  google-global-names-in-headers,
 | 
					  google-global-names-in-headers,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								BUILD.md
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								BUILD.md
									
										
									
									
									
								
							| 
						 | 
					@ -9,6 +9,7 @@ Quickshell has a set of base dependencies you will always need, names vary by di
 | 
				
			||||||
- `qt6base`
 | 
					- `qt6base`
 | 
				
			||||||
- `qt6declarative`
 | 
					- `qt6declarative`
 | 
				
			||||||
- `pkg-config`
 | 
					- `pkg-config`
 | 
				
			||||||
 | 
					- `cli11`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
We recommend an implicit dependency on `qt6svg`. If it is not installed, svg images and
 | 
					We recommend an implicit dependency on `qt6svg`. If it is not installed, svg images and
 | 
				
			||||||
svg icons will not work, including system ones.
 | 
					svg icons will not work, including system ones.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@
 | 
				
			||||||
  cmake,
 | 
					  cmake,
 | 
				
			||||||
  ninja,
 | 
					  ninja,
 | 
				
			||||||
  qt6,
 | 
					  qt6,
 | 
				
			||||||
 | 
					  cli11,
 | 
				
			||||||
  jemalloc,
 | 
					  jemalloc,
 | 
				
			||||||
  wayland,
 | 
					  wayland,
 | 
				
			||||||
  wayland-protocols,
 | 
					  wayland-protocols,
 | 
				
			||||||
| 
						 | 
					@ -52,6 +53,7 @@
 | 
				
			||||||
  buildInputs = [
 | 
					  buildInputs = [
 | 
				
			||||||
    qt6.qtbase
 | 
					    qt6.qtbase
 | 
				
			||||||
    qt6.qtdeclarative
 | 
					    qt6.qtdeclarative
 | 
				
			||||||
 | 
					    cli11
 | 
				
			||||||
  ]
 | 
					  ]
 | 
				
			||||||
  ++ (lib.optional withJemalloc jemalloc)
 | 
					  ++ (lib.optional withJemalloc jemalloc)
 | 
				
			||||||
  ++ (lib.optional withQtSvg qt6.qtsvg)
 | 
					  ++ (lib.optional withQtSvg qt6.qtsvg)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,5 @@
 | 
				
			||||||
 | 
					find_package(CLI11 CONFIG REQUIRED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
qt_add_library(quickshell-core STATIC
 | 
					qt_add_library(quickshell-core STATIC
 | 
				
			||||||
	main.cpp
 | 
						main.cpp
 | 
				
			||||||
	plugin.cpp
 | 
						plugin.cpp
 | 
				
			||||||
| 
						 | 
					@ -44,7 +46,7 @@ qt_add_library(quickshell-core STATIC
 | 
				
			||||||
set_source_files_properties(main.cpp PROPERTIES COMPILE_DEFINITIONS GIT_REVISION="${GIT_REVISION}")
 | 
					set_source_files_properties(main.cpp PROPERTIES COMPILE_DEFINITIONS GIT_REVISION="${GIT_REVISION}")
 | 
				
			||||||
qt_add_qml_module(quickshell-core URI Quickshell VERSION 0.1)
 | 
					qt_add_qml_module(quickshell-core URI Quickshell VERSION 0.1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_link_libraries(quickshell-core PRIVATE ${QT_DEPS} Qt6::QuickPrivate)
 | 
					target_link_libraries(quickshell-core PRIVATE ${QT_DEPS} Qt6::QuickPrivate CLI11::CLI11)
 | 
				
			||||||
qs_pch(quickshell-core)
 | 
					qs_pch(quickshell-core)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_link_libraries(quickshell PRIVATE quickshell-coreplugin)
 | 
					target_link_libraries(quickshell PRIVATE quickshell-coreplugin)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,9 +81,7 @@ void LogMessage::formatMessage(
 | 
				
			||||||
	if (color && msg.type == QtFatalMsg) stream << "\033[0m";
 | 
						if (color && msg.type == QtFatalMsg) stream << "\033[0m";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
LogManager::LogManager()
 | 
					LogManager::LogManager(): stdoutStream(stdout) {}
 | 
				
			||||||
    : colorLogs(qEnvironmentVariableIsEmpty("NO_COLOR"))
 | 
					 | 
				
			||||||
    , stdoutStream(stdout) {}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void LogManager::messageHandler(
 | 
					void LogManager::messageHandler(
 | 
				
			||||||
    QtMsgType type,
 | 
					    QtMsgType type,
 | 
				
			||||||
| 
						 | 
					@ -105,8 +103,9 @@ LogManager* LogManager::instance() {
 | 
				
			||||||
	return instance;
 | 
						return instance;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void LogManager::init() {
 | 
					void LogManager::init(bool color) {
 | 
				
			||||||
	auto* instance = LogManager::instance();
 | 
						auto* instance = LogManager::instance();
 | 
				
			||||||
 | 
						instance->colorLogs = color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qInstallMessageHandler(&LogManager::messageHandler);
 | 
						qInstallMessageHandler(&LogManager::messageHandler);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -203,6 +202,8 @@ void ThreadLogging::initFs() {
 | 
				
			||||||
		  << path;
 | 
							  << path;
 | 
				
			||||||
		delete file;
 | 
							delete file;
 | 
				
			||||||
		file = nullptr;
 | 
							file = nullptr;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							qInfo() << "Saving logs to" << path;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// buffered by WriteBuffer
 | 
						// buffered by WriteBuffer
 | 
				
			||||||
| 
						 | 
					@ -212,6 +213,8 @@ void ThreadLogging::initFs() {
 | 
				
			||||||
		  << detailedPath;
 | 
							  << detailedPath;
 | 
				
			||||||
		delete detailedFile;
 | 
							delete detailedFile;
 | 
				
			||||||
		detailedFile = nullptr;
 | 
							detailedFile = nullptr;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							qCInfo(logLogging) << "Saving detailed logs to" << path;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qCDebug(logLogging) << "Copying memfd logs to log file...";
 | 
						qCDebug(logLogging) << "Copying memfd logs to log file...";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,11 +58,11 @@ class LogManager: public QObject {
 | 
				
			||||||
	Q_OBJECT;
 | 
						Q_OBJECT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	static void init();
 | 
						static void init(bool color);
 | 
				
			||||||
	static void initFs();
 | 
						static void initFs();
 | 
				
			||||||
	static LogManager* instance();
 | 
						static LogManager* instance();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool colorLogs;
 | 
						bool colorLogs = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
signals:
 | 
					signals:
 | 
				
			||||||
	void logMessage(LogMessage msg);
 | 
						void logMessage(LogMessage msg);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,9 +1,11 @@
 | 
				
			||||||
#include "main.hpp"
 | 
					#include "main.hpp"
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <CLI/CLI.hpp> // NOLINT: Need to include this for impls of some CLI11 classes
 | 
				
			||||||
 | 
					#include <CLI/App.hpp>
 | 
				
			||||||
 | 
					#include <CLI/Validators.hpp>
 | 
				
			||||||
#include <qapplication.h>
 | 
					#include <qapplication.h>
 | 
				
			||||||
#include <qcommandlineoption.h>
 | 
					 | 
				
			||||||
#include <qcommandlineparser.h>
 | 
					 | 
				
			||||||
#include <qcoreapplication.h>
 | 
					#include <qcoreapplication.h>
 | 
				
			||||||
#include <qcryptographichash.h>
 | 
					#include <qcryptographichash.h>
 | 
				
			||||||
#include <qdir.h>
 | 
					#include <qdir.h>
 | 
				
			||||||
| 
						 | 
					@ -28,87 +30,132 @@
 | 
				
			||||||
#include "rootwrapper.hpp"
 | 
					#include "rootwrapper.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int qs_main(int argc, char** argv) {
 | 
					int qs_main(int argc, char** argv) {
 | 
				
			||||||
	QString configFilePath;
 | 
					
 | 
				
			||||||
 | 
						auto qArgC = 1;
 | 
				
			||||||
 | 
						auto* qArgV = argv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto noColor = !qEnvironmentVariableIsEmpty("NO_COLOR");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QString workingDirectory;
 | 
						QString workingDirectory;
 | 
				
			||||||
 | 
						QString configFilePath;
 | 
				
			||||||
 | 
						QString shellId;
 | 
				
			||||||
 | 
						auto printInfo = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto debugPort = -1;
 | 
				
			||||||
 | 
						auto waitForDebug = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto useQApplication = false;
 | 
						auto useQApplication = false;
 | 
				
			||||||
	auto nativeTextRendering = false;
 | 
						auto nativeTextRendering = false;
 | 
				
			||||||
	auto desktopSettingsAware = true;
 | 
						auto desktopSettingsAware = true;
 | 
				
			||||||
	auto shellId = QString();
 | 
					 | 
				
			||||||
	QHash<QString, QString> envOverrides;
 | 
						QHash<QString, QString> envOverrides;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int debugPort = -1;
 | 
					 | 
				
			||||||
	bool waitForDebug = false;
 | 
					 | 
				
			||||||
	bool printCurrent = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		const auto app = QCoreApplication(argc, argv);
 | 
							auto app = CLI::App("");
 | 
				
			||||||
		QCoreApplication::setApplicationName("quickshell");
 | 
					
 | 
				
			||||||
		QCoreApplication::setApplicationVersion("0.1.0 (" GIT_REVISION ")");
 | 
							class QStringOption {
 | 
				
			||||||
 | 
							public:
 | 
				
			||||||
 | 
								QStringOption() = default;
 | 
				
			||||||
 | 
								QStringOption& operator=(const std::string& str) {
 | 
				
			||||||
 | 
									this->str = QString::fromStdString(str);
 | 
				
			||||||
 | 
									return *this;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								QString& operator*() { return this->str; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private:
 | 
				
			||||||
 | 
								QString str;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							class QStringRefOption {
 | 
				
			||||||
 | 
							public:
 | 
				
			||||||
 | 
								QStringRefOption(QString* str): str(str) {}
 | 
				
			||||||
 | 
								QStringRefOption& operator=(const std::string& str) {
 | 
				
			||||||
 | 
									*this->str = QString::fromStdString(str);
 | 
				
			||||||
 | 
									return *this;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private:
 | 
				
			||||||
 | 
								QString* str;
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// ---
 | 
				
			||||||
 | 
							QStringOption path;
 | 
				
			||||||
 | 
							QStringOption manifest;
 | 
				
			||||||
 | 
							QStringOption config;
 | 
				
			||||||
 | 
							QStringRefOption workdirRef(&workingDirectory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto* selection = app.add_option_group(
 | 
				
			||||||
 | 
							    "Config Selection",
 | 
				
			||||||
 | 
							    "Select a configuration to run (defaults to $XDG_CONFIG_HOME/quickshell/shell.qml)"
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto* pathArg =
 | 
				
			||||||
 | 
							    selection->add_option("-p,--path", path, "Path to a QML file to run. (Env:QS_CONFIG_PATH)");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto* mfArg = selection->add_option(
 | 
				
			||||||
 | 
							    "-m,--manifest",
 | 
				
			||||||
 | 
							    manifest,
 | 
				
			||||||
 | 
							    "Path to a manifest containing configurations. (Env:QS_MANIFEST)\n"
 | 
				
			||||||
 | 
							    "(Defaults to $XDG_CONFIG_HOME/quickshell/manifest.conf)"
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto* cfgArg = selection->add_option(
 | 
				
			||||||
 | 
							    "-c,--config",
 | 
				
			||||||
 | 
							    config,
 | 
				
			||||||
 | 
							    "Name of a configuration within a manifest. (Env:QS_CONFIG_NAME)"
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							selection->add_option("-d,--workdir", workdirRef, "Initial working directory.");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							pathArg->excludes(mfArg, cfgArg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// ---
 | 
				
			||||||
 | 
							auto* debug = app.add_option_group("Debugging");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto* debugPortArg = debug
 | 
				
			||||||
 | 
							                         ->add_option(
 | 
				
			||||||
 | 
							                             "--debugport",
 | 
				
			||||||
 | 
							                             debugPort,
 | 
				
			||||||
 | 
							                             "Open the given port for a QML debugger to connect to."
 | 
				
			||||||
 | 
							                         )
 | 
				
			||||||
 | 
							                         ->check(CLI::Range(0, 65535));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							debug
 | 
				
			||||||
 | 
							    ->add_flag(
 | 
				
			||||||
 | 
							        "--waitfordebug",
 | 
				
			||||||
 | 
							        waitForDebug,
 | 
				
			||||||
 | 
							        "Wait for a debugger to attach to the given port before launching."
 | 
				
			||||||
 | 
							    )
 | 
				
			||||||
 | 
							    ->needs(debugPortArg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// ---
 | 
				
			||||||
 | 
							app.add_flag("--info", printInfo, "Print information about the shell")->excludes(debugPortArg);
 | 
				
			||||||
 | 
							app.add_flag("--no-color", noColor, "Do not color the log output. (Env:NO_COLOR)");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// ---
 | 
				
			||||||
 | 
							QStringOption logpath;
 | 
				
			||||||
 | 
							auto* readLog = app.add_subcommand("read-log", "Read a quickshell log file.");
 | 
				
			||||||
 | 
							readLog->add_option("path", logpath, "Path to the log file to read")->required();
 | 
				
			||||||
 | 
							readLog->add_flag("--no-color", noColor, "Do not color the log output. (Env:NO_COLOR)");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							CLI11_PARSE(app, argc, argv);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const auto qApplication = QCoreApplication(qArgC, qArgV);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Start log manager - has to happen with an active event loop or offthread can't be started.
 | 
							// Start log manager - has to happen with an active event loop or offthread can't be started.
 | 
				
			||||||
		LogManager::init();
 | 
							LogManager::init(!noColor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		QCommandLineParser parser;
 | 
							if (*readLog) {
 | 
				
			||||||
		parser.addHelpOption();
 | 
								auto file = QFile(*logpath);
 | 
				
			||||||
		parser.addVersionOption();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// clang-format off
 | 
					 | 
				
			||||||
		auto currentOption = QCommandLineOption("current", "Print information about the manifest and defaults.");
 | 
					 | 
				
			||||||
		auto manifestOption = QCommandLineOption({"m", "manifest"}, "Path to a configuration manifest.", "path");
 | 
					 | 
				
			||||||
		auto configOption = QCommandLineOption({"c", "config"}, "Name of a configuration in the manifest.", "name");
 | 
					 | 
				
			||||||
		auto pathOption = QCommandLineOption({"p", "path"}, "Path to a configuration file.", "path");
 | 
					 | 
				
			||||||
		auto workdirOption = QCommandLineOption({"d", "workdir"}, "Initial working directory.", "path");
 | 
					 | 
				
			||||||
		auto debugPortOption = QCommandLineOption("debugport", "Enable the QML debugger.", "port");
 | 
					 | 
				
			||||||
		auto debugWaitOption = QCommandLineOption("waitfordebug", "Wait for debugger connection before launching.");
 | 
					 | 
				
			||||||
		auto readLogOption = QCommandLineOption("read-log", "Read a quickshell log file to stdout.", "path");
 | 
					 | 
				
			||||||
		// clang-format on
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		parser.addOption(currentOption);
 | 
					 | 
				
			||||||
		parser.addOption(manifestOption);
 | 
					 | 
				
			||||||
		parser.addOption(configOption);
 | 
					 | 
				
			||||||
		parser.addOption(pathOption);
 | 
					 | 
				
			||||||
		parser.addOption(workdirOption);
 | 
					 | 
				
			||||||
		parser.addOption(debugPortOption);
 | 
					 | 
				
			||||||
		parser.addOption(debugWaitOption);
 | 
					 | 
				
			||||||
		parser.addOption(readLogOption);
 | 
					 | 
				
			||||||
		parser.process(app);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		auto logOption = parser.value(readLogOption);
 | 
					 | 
				
			||||||
		if (!logOption.isEmpty()) {
 | 
					 | 
				
			||||||
			auto file = QFile(logOption);
 | 
					 | 
				
			||||||
			if (!file.open(QFile::ReadOnly)) {
 | 
								if (!file.open(QFile::ReadOnly)) {
 | 
				
			||||||
				qCritical() << "Failed to open log for reading:" << logOption;
 | 
									qCritical() << "Failed to open log for reading:" << *logpath;
 | 
				
			||||||
				return -1;
 | 
									return -1;
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				qInfo() << "Reading log" << logOption;
 | 
									qInfo() << "Reading log" << *logpath;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return qs::log::readEncodedLogs(&file) ? 0 : -1;
 | 
								return qs::log::readEncodedLogs(&file) ? 0 : -1;
 | 
				
			||||||
		}
 | 
							} else {
 | 
				
			||||||
 | 
					 | 
				
			||||||
		auto debugPortStr = parser.value(debugPortOption);
 | 
					 | 
				
			||||||
		if (!debugPortStr.isEmpty()) {
 | 
					 | 
				
			||||||
			auto ok = false;
 | 
					 | 
				
			||||||
			debugPort = debugPortStr.toInt(&ok);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (!ok) {
 | 
					 | 
				
			||||||
				qCritical() << "Debug port must be a valid port number.";
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (parser.isSet(debugWaitOption)) {
 | 
					 | 
				
			||||||
			if (debugPort == -1) {
 | 
					 | 
				
			||||||
				qCritical() << "Cannot wait for debugger without a debug port set.";
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			waitForDebug = true;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			printCurrent = parser.isSet(currentOption);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// NOLINTBEGIN
 | 
								// NOLINTBEGIN
 | 
				
			||||||
#define CHECK(rname, name, level, label, expr)                                                     \
 | 
					#define CHECK(rname, name, level, label, expr)                                                     \
 | 
				
			||||||
| 
						 | 
					@ -116,7 +163,7 @@ int qs_main(int argc, char** argv) {
 | 
				
			||||||
	if (rname.isEmpty() && !name.isEmpty()) {                                                        \
 | 
						if (rname.isEmpty() && !name.isEmpty()) {                                                        \
 | 
				
			||||||
		rname = name;                                                                                  \
 | 
							rname = name;                                                                                  \
 | 
				
			||||||
		rname##Level = level;                                                                          \
 | 
							rname##Level = level;                                                                          \
 | 
				
			||||||
		if (!printCurrent) goto label;                                                                 \
 | 
							if (!printInfo) goto label;                                                                    \
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define OPTSTR(name) (name.isEmpty() ? "(unset)" : name.toStdString())
 | 
					#define OPTSTR(name) (name.isEmpty() ? "(unset)" : name.toStdString())
 | 
				
			||||||
| 
						 | 
					@ -133,7 +180,7 @@ int qs_main(int argc, char** argv) {
 | 
				
			||||||
				// clang-format on
 | 
									// clang-format on
 | 
				
			||||||
				// NOLINTEND
 | 
									// NOLINTEND
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (printCurrent) {
 | 
									if (printInfo) {
 | 
				
			||||||
					// clang-format off
 | 
										// clang-format off
 | 
				
			||||||
					std::cout << "Base path: " << OPTSTR(basePath) << "\n";
 | 
										std::cout << "Base path: " << OPTSTR(basePath) << "\n";
 | 
				
			||||||
					std::cout << " - Environment (QS_BASE_PATH): " << OPTSTR(envBasePath) << "\n";
 | 
										std::cout << " - Environment (QS_BASE_PATH): " << OPTSTR(envBasePath) << "\n";
 | 
				
			||||||
| 
						 | 
					@ -147,11 +194,11 @@ int qs_main(int argc, char** argv) {
 | 
				
			||||||
			int configPathLevel = 10;
 | 
								int configPathLevel = 10;
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				// NOLINTBEGIN
 | 
									// NOLINTBEGIN
 | 
				
			||||||
				CHECK(configPath, optionConfigPath, 0, foundpath, parser.value(pathOption));
 | 
									CHECK(configPath, optionConfigPath, 0, foundpath, *path);
 | 
				
			||||||
				CHECK(configPath, envConfigPath, 1, foundpath, qEnvironmentVariable("QS_CONFIG_PATH"));
 | 
									CHECK(configPath, envConfigPath, 1, foundpath, qEnvironmentVariable("QS_CONFIG_PATH"));
 | 
				
			||||||
				// NOLINTEND
 | 
									// NOLINTEND
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (printCurrent) {
 | 
									if (printInfo) {
 | 
				
			||||||
					// clang-format off
 | 
										// clang-format off
 | 
				
			||||||
					std::cout << "\nConfig path: " << OPTSTR(configPath) << "\n";
 | 
										std::cout << "\nConfig path: " << OPTSTR(configPath) << "\n";
 | 
				
			||||||
					std::cout << " - Option: " << OPTSTR(optionConfigPath) << "\n";
 | 
										std::cout << " - Option: " << OPTSTR(optionConfigPath) << "\n";
 | 
				
			||||||
| 
						 | 
					@ -166,13 +213,13 @@ int qs_main(int argc, char** argv) {
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				// NOLINTBEGIN
 | 
									// NOLINTBEGIN
 | 
				
			||||||
				// clang-format off
 | 
									// clang-format off
 | 
				
			||||||
				CHECK(manifestPath, optionManifestPath, 0, foundmf, parser.value(manifestOption));
 | 
									CHECK(manifestPath, optionManifestPath, 0, foundmf, *manifest);
 | 
				
			||||||
				CHECK(manifestPath, envManifestPath, 1, foundmf, qEnvironmentVariable("QS_MANIFEST"));
 | 
									CHECK(manifestPath, envManifestPath, 1, foundmf, qEnvironmentVariable("QS_MANIFEST"));
 | 
				
			||||||
				CHECK(manifestPath, defaultManifestPath, 2, foundmf, QDir(basePath).filePath("manifest.conf"));
 | 
									CHECK(manifestPath, defaultManifestPath, 2, foundmf, QDir(basePath).filePath("manifest.conf"));
 | 
				
			||||||
				// clang-format on
 | 
									// clang-format on
 | 
				
			||||||
				// NOLINTEND
 | 
									// NOLINTEND
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (printCurrent) {
 | 
									if (printInfo) {
 | 
				
			||||||
					// clang-format off
 | 
										// clang-format off
 | 
				
			||||||
					std::cout << "\nManifest path: " << OPTSTR(manifestPath) << "\n";
 | 
										std::cout << "\nManifest path: " << OPTSTR(manifestPath) << "\n";
 | 
				
			||||||
					std::cout << " - Option: " << OPTSTR(optionManifestPath) << "\n";
 | 
										std::cout << " - Option: " << OPTSTR(optionManifestPath) << "\n";
 | 
				
			||||||
| 
						 | 
					@ -187,11 +234,11 @@ int qs_main(int argc, char** argv) {
 | 
				
			||||||
			int configNameLevel = 10;
 | 
								int configNameLevel = 10;
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				// NOLINTBEGIN
 | 
									// NOLINTBEGIN
 | 
				
			||||||
				CHECK(configName, optionConfigName, 0, foundname, parser.value(configOption));
 | 
									CHECK(configName, optionConfigName, 0, foundname, *config);
 | 
				
			||||||
				CHECK(configName, envConfigName, 1, foundname, qEnvironmentVariable("QS_CONFIG_NAME"));
 | 
									CHECK(configName, envConfigName, 1, foundname, qEnvironmentVariable("QS_CONFIG_NAME"));
 | 
				
			||||||
				// NOLINTEND
 | 
									// NOLINTEND
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (printCurrent) {
 | 
									if (printInfo) {
 | 
				
			||||||
					// clang-format off
 | 
										// clang-format off
 | 
				
			||||||
					std::cout << "\nConfig name: " << OPTSTR(configName) << "\n";
 | 
										std::cout << "\nConfig name: " << OPTSTR(configName) << "\n";
 | 
				
			||||||
					std::cout << " - Option: " << OPTSTR(optionConfigName) << "\n";
 | 
										std::cout << " - Option: " << OPTSTR(optionConfigName) << "\n";
 | 
				
			||||||
| 
						 | 
					@ -201,11 +248,6 @@ int qs_main(int argc, char** argv) {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		foundname:;
 | 
							foundname:;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (configPathLevel == 0 && configNameLevel == 0) {
 | 
					 | 
				
			||||||
				qCritical() << "Pass only one of --path or --config";
 | 
					 | 
				
			||||||
				return -1;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (!configPath.isEmpty() && configPathLevel <= configNameLevel) {
 | 
								if (!configPath.isEmpty() && configPathLevel <= configNameLevel) {
 | 
				
			||||||
				configFilePath = configPath;
 | 
									configFilePath = configPath;
 | 
				
			||||||
			} else if (!configName.isEmpty()) {
 | 
								} else if (!configName.isEmpty()) {
 | 
				
			||||||
| 
						 | 
					@ -299,60 +341,56 @@ int qs_main(int argc, char** argv) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			shellId = QCryptographicHash::hash(configFilePath.toUtf8(), QCryptographicHash::Md5).toHex();
 | 
								shellId = QCryptographicHash::hash(configFilePath.toUtf8(), QCryptographicHash::Md5).toHex();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			qInfo() << "config file path:" << configFilePath;
 | 
								qInfo() << "Config file path:" << configFilePath;
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!QFile(configFilePath).exists()) {
 | 
								if (!QFile(configFilePath).exists()) {
 | 
				
			||||||
			qCritical() << "config file does not exist";
 | 
									qCritical() << "config file does not exist";
 | 
				
			||||||
			return -1;
 | 
									return -1;
 | 
				
			||||||
		}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (parser.isSet(workdirOption)) {
 | 
								auto file = QFile(configFilePath);
 | 
				
			||||||
			workingDirectory = parser.value(workdirOption);
 | 
								if (!file.open(QFile::ReadOnly | QFile::Text)) {
 | 
				
			||||||
		}
 | 
									qCritical() << "could not open config file";
 | 
				
			||||||
 | 
									return -1;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto file = QFile(configFilePath);
 | 
								auto stream = QTextStream(&file);
 | 
				
			||||||
		if (!file.open(QFile::ReadOnly | QFile::Text)) {
 | 
								while (!stream.atEnd()) {
 | 
				
			||||||
			qCritical() << "could not open config file";
 | 
									auto line = stream.readLine().trimmed();
 | 
				
			||||||
			return -1;
 | 
									if (line.startsWith("//@ pragma ")) {
 | 
				
			||||||
		}
 | 
										auto pragma = line.sliced(11).trimmed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto stream = QTextStream(&file);
 | 
										if (pragma == "UseQApplication") useQApplication = true;
 | 
				
			||||||
		while (!stream.atEnd()) {
 | 
										else if (pragma == "NativeTextRendering") nativeTextRendering = true;
 | 
				
			||||||
			auto line = stream.readLine().trimmed();
 | 
										else if (pragma == "IgnoreSystemSettings") desktopSettingsAware = false;
 | 
				
			||||||
			if (line.startsWith("//@ pragma ")) {
 | 
										else if (pragma.startsWith("Env ")) {
 | 
				
			||||||
				auto pragma = line.sliced(11).trimmed();
 | 
											auto envPragma = pragma.sliced(4);
 | 
				
			||||||
 | 
											auto splitIdx = envPragma.indexOf('=');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (pragma == "UseQApplication") useQApplication = true;
 | 
											if (splitIdx == -1) {
 | 
				
			||||||
				else if (pragma == "NativeTextRendering") nativeTextRendering = true;
 | 
												qCritical() << "Env pragma" << pragma << "not in the form 'VAR = VALUE'";
 | 
				
			||||||
				else if (pragma == "IgnoreSystemSettings") desktopSettingsAware = false;
 | 
												return -1;
 | 
				
			||||||
				else if (pragma.startsWith("Env ")) {
 | 
											}
 | 
				
			||||||
					auto envPragma = pragma.sliced(4);
 | 
					 | 
				
			||||||
					auto splitIdx = envPragma.indexOf('=');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (splitIdx == -1) {
 | 
											auto var = envPragma.sliced(0, splitIdx).trimmed();
 | 
				
			||||||
						qCritical() << "Env pragma" << pragma << "not in the form 'VAR = VALUE'";
 | 
											auto val = envPragma.sliced(splitIdx + 1).trimmed();
 | 
				
			||||||
 | 
											envOverrides.insert(var, val);
 | 
				
			||||||
 | 
										} else if (pragma.startsWith("ShellId ")) {
 | 
				
			||||||
 | 
											shellId = pragma.sliced(8).trimmed();
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											qCritical() << "Unrecognized pragma" << pragma;
 | 
				
			||||||
						return -1;
 | 
											return -1;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
									} else if (line.startsWith("import")) break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					auto var = envPragma.sliced(0, splitIdx).trimmed();
 | 
								file.close();
 | 
				
			||||||
					auto val = envPragma.sliced(splitIdx + 1).trimmed();
 | 
					 | 
				
			||||||
					envOverrides.insert(var, val);
 | 
					 | 
				
			||||||
				} else if (pragma.startsWith("ShellId ")) {
 | 
					 | 
				
			||||||
					shellId = pragma.sliced(8).trimmed();
 | 
					 | 
				
			||||||
				} else {
 | 
					 | 
				
			||||||
					qCritical() << "Unrecognized pragma" << pragma;
 | 
					 | 
				
			||||||
					return -1;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			} else if (line.startsWith("import")) break;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		file.close();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	qInfo() << "shell id:" << shellId;
 | 
						qInfo() << "Shell ID:" << shellId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (printCurrent) return 0;
 | 
						if (printInfo) return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (auto [var, val]: envOverrides.asKeyValueRange()) {
 | 
						for (auto [var, val]: envOverrides.asKeyValueRange()) {
 | 
				
			||||||
		qputenv(var.toUtf8(), val.toUtf8());
 | 
							qputenv(var.toUtf8(), val.toUtf8());
 | 
				
			||||||
| 
						 | 
					@ -360,6 +398,15 @@ int qs_main(int argc, char** argv) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QsPaths::init(shellId);
 | 
						QsPaths::init(shellId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (auto* cacheDir = QsPaths::instance()->cacheDir()) {
 | 
				
			||||||
 | 
							auto qmlCacheDir = cacheDir->filePath("qml-engine-cache");
 | 
				
			||||||
 | 
							qputenv("QML_DISK_CACHE_PATH", qmlCacheDir.toLocal8Bit());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!qEnvironmentVariableIsSet("QML_DISK_CACHE")) {
 | 
				
			||||||
 | 
								qputenv("QML_DISK_CACHE", "aot,qmlc");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// While the simple animation driver can lead to better animations in some cases,
 | 
						// While the simple animation driver can lead to better animations in some cases,
 | 
				
			||||||
	// it also can cause excessive repainting at excessively high framerates which can
 | 
						// it also can cause excessive repainting at excessively high framerates which can
 | 
				
			||||||
	// lead to noticeable amounts of gpu usage, including overheating on some systems.
 | 
						// lead to noticeable amounts of gpu usage, including overheating on some systems.
 | 
				
			||||||
| 
						 | 
					@ -401,9 +448,9 @@ int qs_main(int argc, char** argv) {
 | 
				
			||||||
	QGuiApplication* app = nullptr;
 | 
						QGuiApplication* app = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (useQApplication) {
 | 
						if (useQApplication) {
 | 
				
			||||||
		app = new QApplication(argc, argv);
 | 
							app = new QApplication(qArgC, qArgV);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		app = new QGuiApplication(argc, argv);
 | 
							app = new QGuiApplication(qArgC, qArgV);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	LogManager::initFs();
 | 
						LogManager::initFs();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue