diff --git a/.clang-tidy b/.clang-tidy index cefd2c6..5246243 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -2,29 +2,20 @@ Checks: > -*, bugprone-*, + -bugprone-easily-swappable-parameters, + -bugprone-narrowing-conversions, + -bugprone-implicit-widening-of-multiplication-result, clang-analyzer-*, - modernize-*, - -modernize-use-trailing-return-type, - performance-*, - readability-braces-around-statements, + cppcoreguidelines-init-variables, + misc-no-recursion, + concurrency-mt-unsafe, readability-else-after-return, - readability-identifier-naming, + readability-make-member-function-const, readability-redundant-*, readability-simplify-*, -CheckOptions: - readability-identifier-naming.ClassCase: CamelCase - readability-identifier-naming.EnumCase: CamelCase - readability-identifier-naming.FunctionCase: camelBack - readability-identifier-naming.MemberCase: camelBack - readability-identifier-naming.MemberPrefix: m_ - readability-identifier-naming.MethodCase: camelBack - readability-identifier-naming.NamespaceCase: CamelCase - readability-identifier-naming.ParameterCase: camelBack - readability-identifier-naming.PrivateMemberPrefix: m_ - readability-identifier-naming.StaticConstantCase: UPPER_CASE - readability-identifier-naming.StaticConstantPrefix: k - readability-identifier-naming.VariableCase: camelBack -WarningsAsErrors: "*" + modernize-use-override, + modernize-use-nullptr, + modernize-deprecated-headers, HeaderFilterRegex: ".*" FormatStyle: file diff --git a/.gitea/workflows/ci-image.yml b/.gitea/workflows/ci-image.yml new file mode 100644 index 0000000..cf2f52c --- /dev/null +++ b/.gitea/workflows/ci-image.yml @@ -0,0 +1,22 @@ +name: Rebuild CI Image + +on: + schedule: + - cron: '0 6 * * 1' + workflow_dispatch: + +jobs: + build: + runs-on: alpine + env: + IMAGE: git.aramjonghu.nl/aramjonghu/zshell-ci:latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Build image + run: docker build -t "$IMAGE" -f ci/Dockerfile . + + - name: Push image + run: docker push "$IMAGE" diff --git a/.gitea/workflows/cpp.yml b/.gitea/workflows/cpp.yml new file mode 100644 index 0000000..ffe41a3 --- /dev/null +++ b/.gitea/workflows/cpp.yml @@ -0,0 +1,29 @@ +name: C++ + +on: + pull_request: + +jobs: + build: + runs-on: alpine + container: + image: git.aramjonghu.nl/aramjonghu/zshell-ci:latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Configure + run: cmake -B build -G Ninja -DENABLE_MODULES=plugin -DCMAKE_BUILD_TYPE=Release + + - name: Build + run: ninja -C build + + - name: clang-tidy + continue-on-error: true + run: | + set -o pipefail + run-clang-tidy -p build -j $(nproc) -header-filter="Plugins/.*" 2>&1 | \ + grep -v 'Suppressed\|non-user\|non-system\|unknown argument.*mno-direct' diff --git a/CMakeLists.txt b/CMakeLists.txt index a2e2def..ec4d8e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,35 @@ cmake_minimum_required(VERSION 3.19) -project(ZShell) +if(NOT DEFINED VERSION) + execute_process( + COMMAND git describe --tags --abbrev=0 + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_LAST_TAG + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + + if (GIT_LAST_TAG) + string(REGEX REPLACE "^v" "" GIT_LAST_TAG "${GIT_LAST_TAG}") + + string(REPLACE "." ";" VERSION_LIST "${GIT_LAST_TAG}") + list(GET VERSION_LIST 0 VERSION_MAJOR) + list(GET VERSION_LIST 1 VERSION_MINOR) + + execute_process( + COMMAND git rev-list v${VERSION_MAJOR}.${VERSION_MINOR}.0..HEAD --count + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE VERSION_PATCH + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + ) + endif() +endif() + +set(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") + +project(ZShell VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) +message(STATUS "ZShell version: ${VERSION}") set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -15,11 +44,11 @@ set(INSTALL_QSCONFDIR "etc/xdg/quickshell/zshell" CACHE STRING "Quickshell confi set(INSTALL_GREETERCONFDIR "etc/xdg/quickshell/zshell-greeter" CACHE STRING "Quickshell greeter install dir") add_compile_options( - -Wall -Wextra -Wpedantic -Wshadow -Wconversion - -Wold-style-cast -Wnull-dereference -Wdouble-promotion - -Wformat=2 -Wfloat-equal -Woverloaded-virtual - -Wsign-conversion -Wredundant-decls -Wswitch - -Wunreachable-code + -Wall -Wextra -Wpedantic -Wshadow -Wconversion + -Wold-style-cast -Wnull-dereference -Wdouble-promotion + -Wformat=2 -Wfloat-equal -Woverloaded-virtual + -Wsign-conversion -Wredundant-decls -Wswitch + -Wunreachable-code ) @@ -30,8 +59,8 @@ endif() if("shell" IN_LIST ENABLE_MODULES) foreach(dir assets scripts Components Config Modules Daemons Drawers Effects Helpers Paths) - install(DIRECTORY ${dir} DESTINATION "${INSTALL_QSCONFDIR}") - endforeach() + install(DIRECTORY ${dir} DESTINATION "${INSTALL_QSCONFDIR}") + endforeach() # Disable watching for changes file(READ shell.qml SHELL_QML) diff --git a/Plugins/ZShell/CMakeLists.txt b/Plugins/ZShell/CMakeLists.txt index 2457613..edf225f 100644 --- a/Plugins/ZShell/CMakeLists.txt +++ b/Plugins/ZShell/CMakeLists.txt @@ -9,7 +9,7 @@ pkg_check_modules(Cava IMPORTED_TARGET libcava QUIET) pkg_check_modules(GLIB REQUIRED glib-2.0 gobject-2.0 gio-2.0) if(NOT Cava_FOUND) - pkg_check_modules(Cava IMPORTED_TARGET cava REQUIRED) + pkg_check_modules(Cava IMPORTED_TARGET cava REQUIRED) endif() if(NOT TARGET Sensors::Sensors) @@ -24,48 +24,50 @@ set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml") qt_standard_project_setup(REQUIRES 6.9) function(qml_module arg_TARGET) - cmake_parse_arguments(PARSE_ARGV 1 arg "" "URI" "SOURCES;LIBRARIES") - qt_add_qml_module(${arg_TARGET} - URI ${arg_URI} - VERSION 1.0 - SOURCES ${arg_SOURCES} - ) + cmake_parse_arguments(PARSE_ARGV 1 arg "" "URI" "SOURCES;LIBRARIES") + qt_add_qml_module(${arg_TARGET} + URI ${arg_URI} + VERSION 1.0 + SOURCES ${arg_SOURCES} + ) - qt_query_qml_module(${arg_TARGET} - URI module_uri - VERSION module_version - PLUGIN_TARGET module_plugin_target - TARGET_PATH module_target_path - QMLDIR module_qmldir - TYPEINFO module_typeinfo - ) + qt_query_qml_module(${arg_TARGET} + URI module_uri + VERSION module_version + PLUGIN_TARGET module_plugin_target + TARGET_PATH module_target_path + QMLDIR module_qmldir + TYPEINFO module_typeinfo + ) set(module_dir "${INSTALL_QMLDIR}/${module_target_path}") - install(TARGETS ${arg_TARGET} LIBRARY DESTINATION "${module_dir}" RUNTIME DESTINATION "${module_dir}") - install(TARGETS "${module_plugin_target}" LIBRARY DESTINATION "${module_dir}" RUNTIME DESTINATION "${module_dir}") - install(FILES "${module_qmldir}" DESTINATION "${module_dir}") - install(FILES "${module_typeinfo}" DESTINATION "${module_dir}") - target_link_libraries(${arg_TARGET} PRIVATE Qt::Core Qt::Qml ${arg_LIBRARIES}) + install(TARGETS ${arg_TARGET} LIBRARY DESTINATION "${module_dir}" RUNTIME DESTINATION "${module_dir}") + install(TARGETS "${module_plugin_target}" LIBRARY DESTINATION "${module_dir}" RUNTIME DESTINATION "${module_dir}") + install(FILES "${module_qmldir}" DESTINATION "${module_dir}") + install(FILES "${module_typeinfo}" DESTINATION "${module_dir}") + target_link_libraries(${arg_TARGET} PRIVATE Qt::Core Qt::Qml ${arg_LIBRARIES}) endfunction() qml_module(ZShell - URI ZShell - SOURCES - writefile.hpp writefile.cpp - appdb.hpp appdb.cpp - imageanalyser.hpp imageanalyser.cpp + URI ZShell + SOURCES + writefile.hpp writefile.cpp + appdb.hpp appdb.cpp + imageanalyser.hpp imageanalyser.cpp requests.hpp requests.cpp toaster.hpp toaster.cpp qalculator.hpp qalculator.cpp zutils.hpp zutils.cpp - LIBRARIES - Qt::Gui - Qt::Quick - Qt::Concurrent - Qt::Sql + LIBRARIES + Qt::Gui + Qt::Quick + Qt::Concurrent + Qt::Sql Qt::DBus PkgConfig::Qalculate ) +target_compile_definitions(ZShell PRIVATE ZSHELL_VERSION="${VERSION}") + add_subdirectory(Models) add_subdirectory(Internal) add_subdirectory(Services) diff --git a/Plugins/ZShell/zutils.cpp b/Plugins/ZShell/zutils.cpp index c26bd0f..ec0449f 100644 --- a/Plugins/ZShell/zutils.cpp +++ b/Plugins/ZShell/zutils.cpp @@ -3,9 +3,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -142,4 +144,16 @@ qreal ZUtils::clamp(qreal value, qreal min, qreal max) { return qBound(min, value, max); } +#ifndef ZSHELL_VERSION +#define ZSHELL_VERSION "" +#endif + +QString ZUtils::version() const { + return QStringLiteral(ZSHELL_VERSION); +} + +QString ZUtils::qtVersion() const { + return QStringLiteral(QT_VERSION_STR); +} + } // namespace ZShell diff --git a/Plugins/ZShell/zutils.hpp b/Plugins/ZShell/zutils.hpp index fdc413d..54cfb5f 100644 --- a/Plugins/ZShell/zutils.hpp +++ b/Plugins/ZShell/zutils.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -26,6 +27,9 @@ Q_INVOKABLE static bool deleteFile(const QUrl& path); Q_INVOKABLE static QString toLocalFile(const QUrl& url); Q_INVOKABLE static qreal clamp(qreal value, qreal min, qreal max); + +[[nodiscard]] QString version() const; +[[nodiscard]] QString qtVersion() const; }; } // namespace ZShell diff --git a/ci/Dockerfile b/ci/Dockerfile new file mode 100644 index 0000000..dd94cce --- /dev/null +++ b/ci/Dockerfile @@ -0,0 +1,43 @@ +FROM archlinux:latest + +RUN pacman -Syu --noconfirm + +# Build toolchain +RUN pacman -S --noconfirm \ + base-devel \ + cmake \ + ninja \ + clang \ + lld \ + nodejs \ + git + +# Qt6 +RUN pacman -S --noconfirm \ + qt6-base \ + qt6-declarative \ + qt6-shadertools \ + qt6-5compat \ + qt6-canvaspainter + +# Project-specific dependencies +RUN pacman -S --noconfirm \ + libqalculate \ + pipewire \ + aubio \ + cava \ + lm_sensors \ + glib2 + +# AUR: libcava (provides development headers for cava) +RUN pacman -S --needed --noconfirm sudo && \ + useradd -m builder && \ + echo "builder ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \ + su builder -c " \ + git clone https://aur.archlinux.org/libcava.git /tmp/libcava && \ + cd /tmp/libcava && \ + makepkg -si --noconfirm \ + " && \ + rm -rf /tmp/libcava && \ + userdel -r builder && \ + sed -i '/^builder/d' /etc/sudoers