#!/usr/bin/env bash # SPDX-FileCopyrightText: 2026 Marco Allegretti # SPDX-License-Identifier: EUPL-1.2 set -euo pipefail repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" cd "$repo_dir" fail() { printf '%s\n' "$1" >&2 exit 1 } require_line() { local file="$1" local pattern="$2" local message="$3" grep -Eq "$pattern" "$file" || fail "$message" } reject_line() { local file="$1" local pattern="$2" local message="$3" ! grep -Eq "$pattern" "$file" || fail "$message" } readonly spdx_copyright_tag='SPDX-FileCopyrightText' readonly spdx_license_tag='SPDX-License-Identifier' readonly shift_copyright_pattern="${spdx_copyright_tag}: 2026 Marco Allegretti" readonly shift_license_pattern="${spdx_license_tag}: EUPL-1[.]2" require_line CMakeLists.txt '^add_subdirectory\(cursors\)$' \ "top-level build must install the Shift cursor theme" require_line CMakeLists.txt '^add_subdirectory\(desktoptheme\)$' \ "top-level build must install the Shift Plasma desktop themes" require_line lookandfeel/metadata.json '"Id": "org\.shift\.mobile"' \ "look-and-feel id must remain org.shift.mobile" require_line lookandfeel/metadata.json '"Name": "SHIFT"' \ "look-and-feel visible name must be SHIFT" require_line color-schemes/ShiftDark.colors '^ColorScheme=ShiftDark$' \ "dark color scheme id must remain ShiftDark" require_line color-schemes/ShiftDark.colors '^Name=SHIFT Dark$' \ "dark color scheme visible name must be SHIFT Dark" require_line color-schemes/ShiftLight.colors '^ColorScheme=ShiftLight$' \ "light color scheme id must remain ShiftLight" require_line color-schemes/ShiftLight.colors '^Name=SHIFT Light$' \ "light color scheme visible name must be SHIFT Light" require_line icons/org.shift.icons/index.theme '^Name=SHIFT$' \ "icon theme visible name must be SHIFT" require_line kwin/decorations/org.shift.decoration/metadata.json '"Name": "SHIFT"' \ "window decoration visible name must be SHIFT" require_line wallpapers/SHIFT/metadata.json '"Name": "SHIFT"' \ "wallpaper visible name must be SHIFT" require_line desktoptheme/shift-dark/metadata.json '"Id": "shift-dark"' \ "dark Plasma desktop theme id must be shift-dark" require_line desktoptheme/shift-dark/metadata.json '"Name": "SHIFT Dark"' \ "dark Plasma desktop theme visible name must be SHIFT Dark" require_line desktoptheme/shift-light/metadata.json '"Id": "shift-light"' \ "light Plasma desktop theme id must be shift-light" require_line desktoptheme/shift-light/metadata.json '"Name": "SHIFT Light"' \ "light Plasma desktop theme visible name must be SHIFT Light" require_line cursors/shift-cursors/index.theme '^Name=SHIFT$' \ "cursor theme visible name must be SHIFT" for desktop_asset in \ desktoptheme/shift-dark/widgets/panel-background.svg \ desktoptheme/shift-dark/solid/widgets/panel-background.svg \ desktoptheme/shift-dark/widgets/background.svg \ desktoptheme/shift-dark/widgets/translucentbackground.svg \ desktoptheme/shift-light/widgets/panel-background.svg \ desktoptheme/shift-light/solid/widgets/panel-background.svg \ desktoptheme/shift-light/widgets/background.svg \ desktoptheme/shift-light/widgets/translucentbackground.svg; do [[ -f "$desktop_asset" ]] || fail "Shift desktop theme must provide $desktop_asset" require_line "$desktop_asset" "$shift_copyright_pattern" \ "$desktop_asset must attribute Shift-owned work to Marco Allegretti" require_line "$desktop_asset" "$shift_license_pattern" \ "$desktop_asset must use EUPL-1.2" done require_line lookandfeel/contents/defaults '^ColorScheme=ShiftDark$' \ "look-and-feel defaults must select ShiftDark" require_line lookandfeel/contents/defaults '^Theme=org\.shift\.icons$' \ "look-and-feel defaults must select org.shift.icons" require_line lookandfeel/contents/defaults '^cursorTheme=shift-cursors$' \ "look-and-feel defaults must select shift-cursors" require_line lookandfeel/contents/defaults '^name=shift-dark$' \ "look-and-feel defaults must select the Shift dark Plasma desktop theme" require_line lookandfeel/contents/defaults '^theme=org\.shift\.decoration$' \ "look-and-feel defaults must select org.shift.decoration" require_line lookandfeel/contents/defaults '^widgetStyle=Breeze$' \ "look-and-feel defaults must keep Breeze widget style until Shift ships a QQC2 style" reject_line lookandfeel/contents/defaults 'breeze-dark|breeze-light|breeze_cursors|org\.kde\.Breeze' \ "look-and-feel defaults must not select Breeze desktop, cursor, or splash themes" reject_line lookandfeel/contents/defaults 'widgetStyle=Shift|widgetStyle=SHIFT|widgetStyle=org\.shift' \ "look-and-feel defaults must not reference a non-existent Shift widget style" [[ -f lookandfeel/contents/splash/Splash.qml ]] || fail "look-and-feel must provide a Shift splash implementation" reject_line lookandfeel/contents/logout/Logout.qml 'plasma_lookandfeel_org\.kde\.lookandfeel' \ "look-and-feel QML must use the Shift translation domain" require_line lookandfeel/contents/logout/Logout.qml 'plasma_lookandfeel_org\.shift\.mobile' \ "look-and-feel logout QML must use plasma_lookandfeel_org.shift.mobile" require_line lookandfeel/Messages.sh 'plasma_lookandfeel_org\.shift\.mobile\.pot' \ "look-and-feel Messages.sh must generate the Shift translation domain" if [[ -f preview.sh ]]; then require_line preview.sh 'PLASMA_THEME=shift-light' \ "preview light mode must select the Shift light Plasma desktop theme" require_line preview.sh 'PLASMA_THEME=shift-dark' \ "preview dark mode must select the Shift dark Plasma desktop theme" reject_line preview.sh 'PLASMA_THEME=breeze-' \ "preview must not select Breeze Plasma desktop themes" require_line preview.sh 'Shift does not ship a QQC2 style plugin yet' \ "preview must document the Breeze QQC2 fallback" reject_line preview.sh 'QT_QUICK_CONTROLS_STYLE=org\.shift|QT_QUICK_CONTROLS_STYLE=SHIFT|QT_QUICK_CONTROLS_STYLE=Shift' \ "preview must not reference a non-existent Shift QQC2 style" else require_line .gitignore '^preview[.]sh$' \ "preview.sh is a local developer script and must remain ignored when absent from CI" fi require_line bin/startplasmamobile.in 'Shift does not ship a QQC2 style plugin yet' \ "runtime launcher must document the Breeze QQC2 fallback" require_line HACKING.md 'Shift does not ship a QQC2 style plugin yet' \ "HACKING.md must document the Breeze QQC2 fallback" require_line .kde-ci.yml 'plasma/qqc2-breeze-style' \ "CI must keep the Breeze QQC2 runtime dependency until Shift ships a QQC2 style" reject_line bin/startplasmamobile.in 'QT_QUICK_CONTROLS_STYLE=org\.shift|QT_QUICK_CONTROLS_STYLE=SHIFT|QT_QUICK_CONTROLS_STYLE=Shift' \ "runtime launcher must not reference a non-existent Shift QQC2 style" generic_attribution_pattern='Shift contributor[s]|SHIFT Contributor[s]' if grep -RInE "$generic_attribution_pattern" \ .reuse \ color-schemes/CMakeLists.txt \ cursors \ desktoptheme \ fonts/CMakeLists.txt \ fonts/README.md \ icons/sc-places-start-here-shift.svg \ kwin/decorations/org.shift.decoration/metadata.json \ lookandfeel/contents/splash \ lookandfeel/metadata.json \ org.shift.mobile.metainfo.xml \ shell/metadata.json \ tests/check-shift-theme-identity.sh >/dev/null; then fail "Shift-owned theme identity files must not use generic Shift contributor attribution" fi for license_file in \ color-schemes/CMakeLists.txt \ cursors/CMakeLists.txt \ desktoptheme/CMakeLists.txt \ desktoptheme/shift-dark/plasmarc \ desktoptheme/shift-light/plasmarc \ fonts/CMakeLists.txt \ fonts/README.md \ icons/sc-places-start-here-shift.svg \ lookandfeel/contents/splash/Splash.qml \ tests/check-shift-theme-identity.sh; do require_line "$license_file" "$shift_copyright_pattern" \ "$license_file must attribute Shift-owned work to Marco Allegretti" require_line "$license_file" "$shift_license_pattern" \ "$license_file must use EUPL-1.2" done for metadata_file in \ desktoptheme/shift-dark/metadata.json \ desktoptheme/shift-light/metadata.json \ kwin/decorations/org.shift.decoration/metadata.json; do require_line "$metadata_file" '"Name": "Marco Allegretti"' \ "$metadata_file must attribute Shift-owned metadata to Marco Allegretti" require_line "$metadata_file" '"License": "EUPL-1\.2"' \ "$metadata_file must use EUPL-1.2" done for author_file in \ lookandfeel/metadata.json \ shell/metadata.json \ org.shift.mobile.metainfo.xml; do require_line "$author_file" 'Marco Allegretti' \ "$author_file must not use generic Shift contributor attribution" done result='shift-theme-identity-ok' printf '%s\n' "$result"