From 86156aa1157ac3c9b7c739faa4dff4fb2221f043 Mon Sep 17 00:00:00 2001 From: ruzo Date: Fri, 24 May 2024 20:24:12 +0300 Subject: [PATCH 01/31] ref: stopped this nonesense of having everything in a single script --- .github/workflows/build.yml | 18 +- main.py | 4 + src/__init__.py | 0 src/build.py | 179 ++++++++++++++++++ src/context.py | 50 +++++ src/logger.py | 8 + src/patches.py | 31 ++++ src/theme.py | 354 ++++++++++++++++++++++++++++++++++++ src/utils.py | 41 +++++ 9 files changed, 681 insertions(+), 4 deletions(-) create mode 100644 main.py create mode 100644 src/__init__.py create mode 100644 src/build.py create mode 100644 src/context.py create mode 100644 src/logger.py create mode 100644 src/patches.py create mode 100644 src/theme.py create mode 100644 src/utils.py diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 50808380..1d4c0004 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,32 +1,42 @@ name: "Generate test artifacts" + on: + workflow_dispatch: pull_request: types: [opened, reopened, synchronize] + + jobs: build: runs-on: ubuntu-latest + steps: - name: Checkout uses: actions/checkout@v4 with: submodules: true + - uses: actions/setup-python@v5 with: python-version: "3.11" cache: "pip" + - name: Install dependencies run: pip install -r requirements.txt + - name: Install colloid specific dependencies run: sudo apt update && sudo apt install -y sassc inkscape optipng + - name: Generate themes run: | python patches/xfwm4/generate_assets.py - python ./build.py mocha --all-accents --zip -d $PWD/releases && - python ./build.py macchiato --all-accents --zip -d $PWD/releases && - python ./build.py frappe --all-accents --zip -d $PWD/releases && - python ./build.py latte --all-accents --zip -d $PWD/releases + python ./main.py mocha --all-accents --zip -d $PWD/releases && + python ./main.py macchiato --all-accents --zip -d $PWD/releases && + python ./main.py frappe --all-accents --zip -d $PWD/releases && + python ./main.py latte --all-accents --zip -d $PWD/releases + - name: Upload artifacts uses: actions/upload-artifact@v4 with: diff --git a/main.py b/main.py new file mode 100644 index 00000000..c28502c0 --- /dev/null +++ b/main.py @@ -0,0 +1,4 @@ +from src.build import main + +if __name__ == "__main__": + main() diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/build.py b/src/build.py new file mode 100644 index 00000000..27f13fd5 --- /dev/null +++ b/src/build.py @@ -0,0 +1,179 @@ +import os +import argparse +from src.patches import apply_colloid_patches +from src.theme import build_theme, init_tweaks_temp, gnome_shell_version +from src.context import Tweaks, BuildContext +from src.logger import logger +from catppuccin import PALETTE + + +THIS_DIR = os.path.dirname(os.path.realpath(__file__)) +SRC_DIR = f"{THIS_DIR}/../colloid/src" + + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument( + "flavor", + type=str, + choices=["mocha", "frappe", "macchiato", "latte"], + help="Flavor of the theme to apply.", + ) + + parser.add_argument( + "--name", + "-n", + type=str, + default="catppuccin", + dest="name", + help="Name of the theme to apply.", + ) + + parser.add_argument( + "--dest", + "-d", + type=str, + required=True, + dest="dest", + help="Destination of the files.", + ) + + parser.add_argument( + "--accent", + "-a", + type=str, + default="mauve", + nargs='+', + dest="accents", + choices=[ + "rosewater", + "flamingo", + "pink", + "mauve", + "red", + "maroon", + "peach", + "yellow", + "green", + "teal", + "sky", + "sapphire", + "blue", + "lavender", + ], + help="Accent of the theme.", + ) + + parser.add_argument( + "--all-accents", + help="Whether to build all accents", + dest="all_accents", + action="store_true", + ) + + parser.add_argument( + "--size", + "-s", + type=str, + default="standard", + dest="size", + choices=["standard", "compact"], + help="Size variant of the theme.", + ) + + parser.add_argument( + "--tweaks", + type=str, + default=[], + nargs="+", + dest="tweaks", + choices=["black", "rimless", "normal", "float"], + help="Tweaks to apply to the build.", + ) + + parser.add_argument( + "--zip", + help="Whether to bundle the theme into a zip", + type=bool, + default=False, + action=argparse.BooleanOptionalAction, + ) + + parser.add_argument( + "--patch", + help="Whether to patch the colloid submodule", + type=bool, + default=True, + action=argparse.BooleanOptionalAction, + ) + + return parser.parse_args() + + +def main(): + args = parse_args() + if args.patch: + apply_colloid_patches() + + if args.zip: + output_format = "zip" + else: + output_format = "dir" + + tweaks = Tweaks(tweaks=args.tweaks) + + palette = getattr(PALETTE, args.flavor) + + accents = args.accents + if args.all_accents: + accents = [ + "rosewater", + "flamingo", + "pink", + "mauve", + "red", + "maroon", + "peach", + "yellow", + "green", + "teal", + "sky", + "sapphire", + "blue", + "lavender", + ] + + for accent in accents: + accent = getattr(palette.colors, accent) + + tweaks = Tweaks(tweaks=args.tweaks) + + if args.zip: + output_format = "zip" + else: + output_format = "dir" + ctx = BuildContext( + build_root=args.dest, + theme_name=args.name, + flavor=palette, + accent=accent, + size=args.size, + tweaks=tweaks, + output_format=output_format, + ) + logger.info("Building temp tweaks file") + init_tweaks_temp(SRC_DIR) + logger.info("Inserting gnome-shell imports") + gnome_shell_version(args.GS_VERSION, SRC_DIR) + logger.info("Building main theme") + build_theme(ctx) + logger.info(f"Completed {palette.identifier} with {accent.identifier}") + + logger.info("Done!") + + +if __name__ == "__main__": + try: + main() + except Exception as e: + logger.error("Something went wrong when building the theme:", exc_info=e) diff --git a/src/context.py b/src/context.py new file mode 100644 index 00000000..aa64214b --- /dev/null +++ b/src/context.py @@ -0,0 +1,50 @@ +from dataclasses import dataclass +from typing import Any, Literal, List +from catppuccin.models import Flavor, Color + + +@dataclass +class Tweaks: + tweaks: List[str] + + def has(self, tweak: str) -> bool: + return tweak in self.tweaks + + def id(self) -> str: + return ",".join(self.tweaks) + + +@dataclass +class Suffix: + true_value: str + test: Any + false_value: str = "" + + +@dataclass +class BuildContext: + build_root: str + output_format: Literal["zip"] | Literal["dir"] + theme_name: str + flavor: Flavor + accent: Color + size: Literal["standard"] | Literal["compact"] + tweaks: Tweaks + + def output_dir(self) -> str: + return f"{self.build_root}/{self.build_id()}" + + def build_id(self) -> str: + return f"{self.theme_name}-{self.flavor.identifier}-{self.accent.identifier}-{self.size}+{self.tweaks.id() or 'default'}" + + def apply_suffix(self, suffix: Suffix) -> str: + if suffix.test(self): + return suffix.true_value + else: + return suffix.false_value + + +IS_DARK = Suffix(true_value="-Dark", test=lambda ctx: ctx.flavor.dark) +IS_LIGHT = Suffix(true_value="-Light", test=lambda ctx: not ctx.flavor.dark) +IS_WINDOW_NORMAL = Suffix(true_value="-Normal", test=lambda ctx: ctx.tweaks.has('normal')) +DARK_LIGHT = Suffix(true_value="-Dark", false_value="-Light", test=lambda ctx: ctx.flavor.dark) diff --git a/src/logger.py b/src/logger.py new file mode 100644 index 00000000..b6d1d2f8 --- /dev/null +++ b/src/logger.py @@ -0,0 +1,8 @@ +import logging + +logger = logging.getLogger("catppuccin-gtk") +logger.setLevel(logging.DEBUG) +ch = logging.StreamHandler() +formatter = logging.Formatter("[%(name)s] [%(levelname)s] - %(message)s") +ch.setFormatter(formatter) +logger.addHandler(ch) diff --git a/src/patches.py b/src/patches.py new file mode 100644 index 00000000..6774d755 --- /dev/null +++ b/src/patches.py @@ -0,0 +1,31 @@ +import os +import subprocess +from src.logger import logger + + +def apply_colloid_patches(): + if os.path.isfile("colloid/.patched"): + logger.info( + 'Patches seem to be applied, remove "colloid/.patched" to force application (this may fail)' + ) + return + + logger.info("Applying patches...") + # Change into colloid + for patch in [ + "plank-dark.patch", + "plank-light.patch", + "sass-palette-frappe.patch", + "sass-palette-mocha.patch", + "sass-palette-latte.patch", + "sass-palette-macchiato.patch", + ]: + path = f"./patches/colloid/{patch}" + logger.info(f"Applying patch '{patch}', located at '{path}'") + subprocess.check_call( + ["git", "apply", path, "--directory", f"colloid"]) + + with open("colloid/.patched", "w") as f: + f.write("true") + + logger.info("Patching finished.") diff --git a/src/theme.py b/src/theme.py new file mode 100644 index 00000000..b644f432 --- /dev/null +++ b/src/theme.py @@ -0,0 +1,354 @@ +import os +import shutil +import subprocess +import glob +import zipfile +from src.logger import logger +from src.utils import subst_text, translate_accent, init_tweaks_temp, write_tweak +from src.context import BuildContext, IS_DARK, IS_LIGHT, IS_WINDOW_NORMAL, DARK_LIGHT + +SASSC_OPT = ["-M", "-t", "expanded"] +THIS_DIR = os.path.dirname(os.path.realpath(__file__)) +SRC_DIR = f"{THIS_DIR}/../colloid/src" + + +def apply_tweaks(ctx: BuildContext): + write_tweak(SRC_DIR, "theme", "'default'", f"'{translate_accent(ctx.accent)}'") + + if ctx.size == "compact": + write_tweak(SRC_DIR, "compact", "'false'", "'true'") + + subst_text( + f"{SRC_DIR}/sass/_tweaks-temp.scss", + "@import 'color-palette-default';", + f"@import 'color-palette-catppuccin-{ctx.flavor.identifier}';", + ) + write_tweak(SRC_DIR, "colorscheme", "'default'", "'catppuccin'") + + if ctx.tweaks.has("black"): + write_tweak(SRC_DIR, "blackness", "'false'", "'true'") + + if ctx.tweaks.has("rimless"): + write_tweak(SRC_DIR, "rimless", "'false'", "'true'") + + if ctx.tweaks.has("normal"): + write_tweak(SRC_DIR, "window_button", "'mac'", "'normal'") + + if ctx.tweaks.has("float"): + write_tweak(SRC_DIR, "float", "'false'", "'true'") + + +def build(ctx: BuildContext): + output_dir = ctx.output_dir() + logger.info(f"Building into '{output_dir}'...") + + apply_tweaks(ctx) + + os.makedirs(output_dir, exist_ok=True) + with open(f"{output_dir}/index.theme", "w") as file: + file.write("[Desktop Entry]\n") + file.write("Type=X-GNOME-Metatheme\n") + file.write(f"Name={ctx.build_id()}\n") + file.write("Comment=An Flat Gtk+ theme based on Elegant Design\n") + file.write("Encoding=UTF-8\n") + file.write("\n") + file.write("[X-GNOME-Metatheme]\n") + file.write(f"GtkTheme={ctx.build_id()}\n") + file.write(f"MetacityTheme={ctx.build_id()}\n") + file.write(f"IconTheme=Tela-circle{ctx.apply_suffix(IS_DARK)}\n") + file.write(f"CursorTheme={ctx.flavor.name}-cursors\n") + file.write("ButtonLayout=close,minimize,maximize:menu\n") + + os.makedirs(f"{output_dir}/gnome-shell", exist_ok=True) + shutil.copyfile( + f"{SRC_DIR}/main/gnome-shell/pad-osd.css", + f"{output_dir}/gnome-shell/pad-osd.css", + ) + subprocess.check_call( + [ + "sassc", + *SASSC_OPT, + f"{SRC_DIR}/main/gnome-shell/gnome-shell{ctx.apply_suffix(DARK_LIGHT)}.scss", + f"{output_dir}/gnome-shell/gnome-shell.css", + ] + ) + + os.makedirs(f"{output_dir}/gtk-3.0", exist_ok=True) + subprocess.check_call( + [ + "sassc", + *SASSC_OPT, + f"{SRC_DIR}/main/gtk-3.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss", + f"{output_dir}/gtk-3.0/gtk.css", + ] + ) + subprocess.check_call( + [ + "sassc", + *SASSC_OPT, + f"{SRC_DIR}/main/gtk-3.0/gtk-Dark.scss", + f"{output_dir}/gtk-3.0/gtk-dark.css", + ] + ) + + os.makedirs(f"{output_dir}/gtk-4.0", exist_ok=True) + subprocess.check_call( + [ + "sassc", + *SASSC_OPT, + f"{SRC_DIR}/main/gtk-4.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss", + f"{output_dir}/gtk-4.0/gtk.css", + ] + ) + subprocess.check_call( + [ + "sassc", + *SASSC_OPT, + f"{SRC_DIR}/main/gtk-4.0/gtk-Dark.scss", + f"{output_dir}/gtk-4.0/gtk-dark.css", + ] + ) + + os.makedirs(f"{output_dir}/cinnamon", exist_ok=True) + subprocess.check_call( + [ + "sassc", + *SASSC_OPT, + f"{SRC_DIR}/main/cinnamon/cinnamon{ctx.apply_suffix(DARK_LIGHT)}.scss", + f"{output_dir}/cinnamon/cinnamon.css", + ] + ) + + os.makedirs(f"{output_dir}/metacity-1", exist_ok=True) + shutil.copyfile( + f"{SRC_DIR}/main/metacity-1/metacity-theme-3{ctx.apply_suffix(IS_WINDOW_NORMAL)}.xml", + f"{output_dir}/metacity-1/metacity-theme-3.xml", + ) + + os.makedirs(f"{output_dir}/xfwm4", exist_ok=True) + shutil.copyfile( + f"{SRC_DIR}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", + f"{output_dir}/xfwm4/themerc", + ) + + os.makedirs(f"{output_dir}-hdpi/xfwm4", exist_ok=True) + shutil.copyfile( + f"{SRC_DIR}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", + f"{output_dir}-hdpi/xfwm4/themerc", + ) + subst_text(f"{output_dir}-hdpi/xfwm4/themerc", + "button_offset=6", "button_offset=9") + + os.makedirs(f"{output_dir}-xhdpi/xfwm4", exist_ok=True) + shutil.copyfile( + f"{SRC_DIR}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", + f"{output_dir}-xhdpi/xfwm4/themerc", + ) + subst_text( + f"{output_dir}-xhdpi/xfwm4/themerc", "button_offset=6", "button_offset=12" + ) + + if not ctx.flavor.dark: + shutil.copytree( + f"{SRC_DIR}/main/plank/theme-Light-Catppuccin/", f"{output_dir}/plank" + ) + else: + shutil.copytree( + f"{SRC_DIR}/main/plank/theme-Dark-Catppuccin/", f"{output_dir}/plank" + ) + + +def make_assets(ctx: BuildContext): + output_dir = ctx.output_dir() + + os.makedirs(f"{output_dir}/cinnamon/assets", exist_ok=True) + for file in glob.glob(f"{SRC_DIR}/assets/cinnamon/theme/*.svg"): + shutil.copy(file, f"{output_dir}/cinnamon/assets") + shutil.copy( + f"{SRC_DIR}/assets/cinnamon/thumbnail{ctx.apply_suffix(DARK_LIGHT)}.svg", + f"{output_dir}/cinnamon/thumbnail.png", + ) + + os.makedirs(f"{output_dir}/gnome-shell/assets", exist_ok=True) + for file in glob.glob(f"{SRC_DIR}/assets/gnome-shell/theme/*.svg"): + shutil.copy(file, f"{output_dir}/gnome-shell/assets") + + shutil.copytree( + f"{SRC_DIR}/assets/gtk/assets", + f"{output_dir}/gtk-3.0/assets", + dirs_exist_ok=True, + ) + shutil.copytree( + f"{SRC_DIR}/assets/gtk/assets", + f"{output_dir}/gtk-4.0/assets", + dirs_exist_ok=True, + ) + shutil.copyfile( + f"{SRC_DIR}/assets/gtk/thumbnail{ctx.apply_suffix(IS_DARK)}.svg", + f"{output_dir}/gtk-3.0/thumbnail.png", + ) + shutil.copyfile( + f"{SRC_DIR}/assets/gtk/thumbnail{ctx.apply_suffix(IS_DARK)}.svg", + f"{output_dir}/gtk-4.0/thumbnail.png", + ) + + theme_color = ctx.accent.hex + + palette = ctx.flavor.colors + background = palette.base.hex + background_alt = palette.mantle.hex + titlebar = palette.overlay0.hex + + for file in glob.glob(f"{output_dir}/cinnamon/assets/*.svg"): + subst_text(file, "#5b9bf8", theme_color) + subst_text(file, "#3c84f7", theme_color) + + for file in glob.glob(f"{output_dir}/gnome-shell/assets/*.svg"): + subst_text(file, "#5b9bf8", theme_color) + subst_text(file, "#3c84f7", theme_color) + + for file in glob.glob(f"{output_dir}/gtk-3.0/assets/*.svg"): + subst_text(file, "#5b9bf8", theme_color) + subst_text(file, "#3c84f7", theme_color) + subst_text(file, "#ffffff", background) + subst_text(file, "#2c2c2c", background) + subst_text(file, "#3c3c3c", background_alt) + + for file in glob.glob(f"{output_dir}/gtk-4.0/assets/*.svg"): + subst_text(file, "#5b9bf8", theme_color) + subst_text(file, "#3c84f7", theme_color) + subst_text(file, "#ffffff", background) + subst_text(file, "#2c2c2c", background) + subst_text(file, "#3c3c3c", background_alt) + + if ctx.flavor.dark: + subst_text(f"{output_dir}/cinnamon/thumbnail.png", + "#2c2c2c", background) + subst_text(f"{output_dir}/cinnamon/thumbnail.png", + "#5b9bf8", theme_color) + + subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", + "#2c2c2c", background) + subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", + "#2c2c2c", background) + + subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", + "#5b9bf8", theme_color) + subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", + "#5b9bf8", theme_color) + else: + subst_text(f"{output_dir}/cinnamon/thumbnail.png", + "#ffffff", background) + subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#f2f2f2", titlebar) + subst_text(f"{output_dir}/cinnamon/thumbnail.png", + "#3c84f7", theme_color) + + subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#f2f2f2", titlebar) + subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", + "#3c84f7", theme_color) + + subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#f2f2f2", titlebar) + subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", + "#3c84f7", theme_color) + + for file in glob.glob(f"{SRC_DIR}/assets/cinnamon/common-assets/*.svg"): + shutil.copy(file, f"{output_dir}/cinnamon/assets") + + for file in glob.glob(f"{SRC_DIR}/assets/cinnamon/assets{ctx.apply_suffix(IS_DARK)}/*.svg"): + shutil.copy(file, f"{output_dir}/cinnamon/assets") + + for file in glob.glob(f"{SRC_DIR}/assets/gnome-shell/common-assets/*.svg"): + shutil.copy(file, f"{output_dir}/gnome-shell/assets") + + for file in glob.glob(f"{SRC_DIR}/assets/gnome-shell/assets{ctx.apply_suffix(IS_DARK)}/*.svg"): + shutil.copy(file, f"{output_dir}/gnome-shell/assets") + + for file in glob.glob(f"{SRC_DIR}/assets/gtk/symbolics/*.svg"): + shutil.copy(file, f"{output_dir}/gtk-3.0/assets") + shutil.copy(file, f"{output_dir}/gtk-4.0/assets") + + for file in glob.glob(f"{SRC_DIR}/assets/metacity-1/assets{ctx.apply_suffix(IS_WINDOW_NORMAL)}/*.svg"): + shutil.copy(file, f"{output_dir}/metacity-1/assets") + shutil.copy( + f"{SRC_DIR}/assets/metacity-1/thumbnail{ctx.apply_suffix(IS_DARK)}.png", + f"{output_dir}/metacity-1/thumbnail.png", + ) + + xfwm4_assets = f"{THIS_DIR}/patches/xfwm4/generated/assets-catppuccin-{ctx.flavor.identifier}" + for file in glob.glob(xfwm4_assets + '/*'): + shutil.copy(file, f"{output_dir}/xfwm4") + + xfwm4_assets = xfwm4_assets + "-hdpi/*" + for file in glob.glob(xfwm4_assets): + shutil.copy(file, f"{output_dir}-hdpi/xfwm4") + + xfwm4_assets = xfwm4_assets + "-xhdpi/*" + for file in glob.glob(xfwm4_assets): + shutil.copy(file, f"{output_dir}-xhdpi/xfwm4") + + +def zip_dir(path, zip_file): + for root, _, files in os.walk(path): + for file in files: + zip_file.write( + os.path.join(root, file), + os.path.relpath(os.path.join(root, file), + os.path.join(path, "..")), + ) + + +def zip_artifacts(dir_list, zip_name, remove=True): + with zipfile.ZipFile(zip_name, "w", zipfile.ZIP_DEFLATED) as zipf: + for dir in dir_list: + zip_dir(dir, zipf) + + if remove: + for dir in dir_list: + shutil.rmtree(dir) + + +def build_theme(ctx: BuildContext): + build_info = f"""Build info: + build_root: {ctx.build_root} + theme_name: {ctx.theme_name} + flavor: {ctx.flavor.identifier} + accent: {ctx.accent.identifier} + size: {ctx.size} + tweaks: {ctx.tweaks}""" + logger.info(build_info) + build(ctx) + logger.info(f"Main build complete") + + logger.info("Bundling assets...") + make_assets(ctx) + logger.info("Asset bundling done") + + if ctx.output_format == "zip": + zip_artifacts( + [ + ctx.output_dir(), + f"{ctx.output_dir()}-hdpi", + f"{ctx.output_dir()}-xhdpi", + ], + f"{ctx.build_root}/{ctx.build_id()}.zip", + True, + ) + + +def gnome_shell_version(gs_version, src_dir): + shutil.copyfile( + f"{src_dir}/sass/gnome-shell/_common.scss", + f"{src_dir}/sass/gnome-shell/_common-temp.scss", + ) + subst_text( + f"{src_dir}/sass/gnome-shell/_common-temp.scss", + "@import 'widgets-40-0';", + f"@import 'widgets-{gs_version}';", + ) + + if gs_version == "3-28": + subst_text( + f"{src_dir}/sass/gnome-shell/_common-temp.scss", + "@import 'extensions-40-0';", + f"@import 'extensions-{gs_version}';", + ) diff --git a/src/utils.py b/src/utils.py new file mode 100644 index 00000000..679cd21b --- /dev/null +++ b/src/utils.py @@ -0,0 +1,41 @@ +import re +import shutil + + +def subst_text(path, _from, to): + with open(path, "r+") as f: + content = f.read() + f.seek(0) + f.truncate() + f.write(re.sub(_from, to, content)) + + +def translate_accent(ctp_accent): + ctp_to_colloid = { + "rosewater": "pink", + "flamingo": "pink", + "pink": "pink", + "mauve": "purple", + "red": "red", + "maroon": "red", + "peach": "orange", + "yellow": "yellow", + "green": "green", + "teal": "teal", + "sky": "teal", + "sapphire": "default", + "blue": "default", + "lavender": "default", + } + return ctp_to_colloid[ctp_accent.identifier] + + +def init_tweaks_temp(src_dir): + shutil.copyfile(f"{src_dir}/sass/_tweaks.scss", + f"{src_dir}/sass/_tweaks-temp.scss") + + +def write_tweak(src_dir, key, default, value): + subst_text( + f"{src_dir}/sass/_tweaks-temp.scss", f"\\${key}: {default}", f"${key}: {value}" + ) From 77a9d2ea65e167be97bb0f2129959415045c000b Mon Sep 17 00:00:00 2001 From: ruzo Date: Sat, 25 May 2024 01:00:47 +0300 Subject: [PATCH 02/31] fix: missed variable during the refactor --- src/build.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/build.py b/src/build.py index 27f13fd5..f61c5736 100644 --- a/src/build.py +++ b/src/build.py @@ -9,6 +9,7 @@ THIS_DIR = os.path.dirname(os.path.realpath(__file__)) SRC_DIR = f"{THIS_DIR}/../colloid/src" +GS_VERSION = "46-0" def parse_args(): @@ -164,7 +165,7 @@ def main(): logger.info("Building temp tweaks file") init_tweaks_temp(SRC_DIR) logger.info("Inserting gnome-shell imports") - gnome_shell_version(args.GS_VERSION, SRC_DIR) + gnome_shell_version(GS_VERSION, SRC_DIR) logger.info("Building main theme") build_theme(ctx) logger.info(f"Completed {palette.identifier} with {accent.identifier}") From b1f5a7fade21727c3a369b1362a3285a9d75e380 Mon Sep 17 00:00:00 2001 From: ruzo Date: Sat, 25 May 2024 02:01:35 +0300 Subject: [PATCH 03/31] add: temporary dir for colloid based on flavour --- src/build.py | 12 ++++++-- src/theme.py | 87 ++++++++++++++++++++++++++-------------------------- src/utils.py | 4 +++ 3 files changed, 56 insertions(+), 47 deletions(-) diff --git a/src/build.py b/src/build.py index f61c5736..5a5c44ff 100644 --- a/src/build.py +++ b/src/build.py @@ -1,14 +1,14 @@ import os import argparse from src.patches import apply_colloid_patches -from src.theme import build_theme, init_tweaks_temp, gnome_shell_version +from src.theme import build_theme, gnome_shell_version +from src.utils import init_tweaks_temp, copy_dir from src.context import Tweaks, BuildContext from src.logger import logger from catppuccin import PALETTE THIS_DIR = os.path.dirname(os.path.realpath(__file__)) -SRC_DIR = f"{THIS_DIR}/../colloid/src" GS_VERSION = "46-0" @@ -144,6 +144,11 @@ def main(): "lavender", ] + COLLOID_DIR = f"{THIS_DIR}/../colloid/src" + SRC_DIR = f"{THIS_DIR}/../colloid-tmp-" + args.flavor + + copy_dir(COLLOID_DIR, SRC_DIR) + for accent in accents: accent = getattr(palette.colors, accent) @@ -162,12 +167,13 @@ def main(): tweaks=tweaks, output_format=output_format, ) + logger.info("Building temp tweaks file") init_tweaks_temp(SRC_DIR) logger.info("Inserting gnome-shell imports") gnome_shell_version(GS_VERSION, SRC_DIR) logger.info("Building main theme") - build_theme(ctx) + build_theme(ctx, SRC_DIR) logger.info(f"Completed {palette.identifier} with {accent.identifier}") logger.info("Done!") diff --git a/src/theme.py b/src/theme.py index b644f432..77a41955 100644 --- a/src/theme.py +++ b/src/theme.py @@ -9,40 +9,39 @@ SASSC_OPT = ["-M", "-t", "expanded"] THIS_DIR = os.path.dirname(os.path.realpath(__file__)) -SRC_DIR = f"{THIS_DIR}/../colloid/src" -def apply_tweaks(ctx: BuildContext): - write_tweak(SRC_DIR, "theme", "'default'", f"'{translate_accent(ctx.accent)}'") +def apply_tweaks(ctx: BuildContext, src_dir): + write_tweak(src_dir, "theme", "'default'", f"'{ctx.accent.identifier}'") if ctx.size == "compact": - write_tweak(SRC_DIR, "compact", "'false'", "'true'") + write_tweak(src_dir, "compact", "'false'", "'true'") subst_text( - f"{SRC_DIR}/sass/_tweaks-temp.scss", + f"{src_dir}/sass/_tweaks-temp.scss", "@import 'color-palette-default';", f"@import 'color-palette-catppuccin-{ctx.flavor.identifier}';", ) - write_tweak(SRC_DIR, "colorscheme", "'default'", "'catppuccin'") + write_tweak(src_dir, "colorscheme", "'default'", "'catppuccin'") if ctx.tweaks.has("black"): - write_tweak(SRC_DIR, "blackness", "'false'", "'true'") + write_tweak(src_dir, "blackness", "'false'", "'true'") if ctx.tweaks.has("rimless"): - write_tweak(SRC_DIR, "rimless", "'false'", "'true'") + write_tweak(src_dir, "rimless", "'false'", "'true'") if ctx.tweaks.has("normal"): - write_tweak(SRC_DIR, "window_button", "'mac'", "'normal'") + write_tweak(src_dir, "window_button", "'mac'", "'normal'") if ctx.tweaks.has("float"): - write_tweak(SRC_DIR, "float", "'false'", "'true'") + write_tweak(src_dir, "float", "'false'", "'true'") -def build(ctx: BuildContext): +def build(ctx: BuildContext, src_dir): output_dir = ctx.output_dir() logger.info(f"Building into '{output_dir}'...") - apply_tweaks(ctx) + apply_tweaks(ctx, src_dir) os.makedirs(output_dir, exist_ok=True) with open(f"{output_dir}/index.theme", "w") as file: @@ -61,14 +60,14 @@ def build(ctx: BuildContext): os.makedirs(f"{output_dir}/gnome-shell", exist_ok=True) shutil.copyfile( - f"{SRC_DIR}/main/gnome-shell/pad-osd.css", + f"{src_dir}/main/gnome-shell/pad-osd.css", f"{output_dir}/gnome-shell/pad-osd.css", ) subprocess.check_call( [ "sassc", *SASSC_OPT, - f"{SRC_DIR}/main/gnome-shell/gnome-shell{ctx.apply_suffix(DARK_LIGHT)}.scss", + f"{src_dir}/main/gnome-shell/gnome-shell{ctx.apply_suffix(DARK_LIGHT)}.scss", f"{output_dir}/gnome-shell/gnome-shell.css", ] ) @@ -78,7 +77,7 @@ def build(ctx: BuildContext): [ "sassc", *SASSC_OPT, - f"{SRC_DIR}/main/gtk-3.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss", + f"{src_dir}/main/gtk-3.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss", f"{output_dir}/gtk-3.0/gtk.css", ] ) @@ -86,7 +85,7 @@ def build(ctx: BuildContext): [ "sassc", *SASSC_OPT, - f"{SRC_DIR}/main/gtk-3.0/gtk-Dark.scss", + f"{src_dir}/main/gtk-3.0/gtk-Dark.scss", f"{output_dir}/gtk-3.0/gtk-dark.css", ] ) @@ -96,7 +95,7 @@ def build(ctx: BuildContext): [ "sassc", *SASSC_OPT, - f"{SRC_DIR}/main/gtk-4.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss", + f"{src_dir}/main/gtk-4.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss", f"{output_dir}/gtk-4.0/gtk.css", ] ) @@ -104,7 +103,7 @@ def build(ctx: BuildContext): [ "sassc", *SASSC_OPT, - f"{SRC_DIR}/main/gtk-4.0/gtk-Dark.scss", + f"{src_dir}/main/gtk-4.0/gtk-Dark.scss", f"{output_dir}/gtk-4.0/gtk-dark.css", ] ) @@ -114,26 +113,26 @@ def build(ctx: BuildContext): [ "sassc", *SASSC_OPT, - f"{SRC_DIR}/main/cinnamon/cinnamon{ctx.apply_suffix(DARK_LIGHT)}.scss", + f"{src_dir}/main/cinnamon/cinnamon{ctx.apply_suffix(DARK_LIGHT)}.scss", f"{output_dir}/cinnamon/cinnamon.css", ] ) os.makedirs(f"{output_dir}/metacity-1", exist_ok=True) shutil.copyfile( - f"{SRC_DIR}/main/metacity-1/metacity-theme-3{ctx.apply_suffix(IS_WINDOW_NORMAL)}.xml", + f"{src_dir}/main/metacity-1/metacity-theme-3{ctx.apply_suffix(IS_WINDOW_NORMAL)}.xml", f"{output_dir}/metacity-1/metacity-theme-3.xml", ) os.makedirs(f"{output_dir}/xfwm4", exist_ok=True) shutil.copyfile( - f"{SRC_DIR}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", + f"{src_dir}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", f"{output_dir}/xfwm4/themerc", ) os.makedirs(f"{output_dir}-hdpi/xfwm4", exist_ok=True) shutil.copyfile( - f"{SRC_DIR}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", + f"{src_dir}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", f"{output_dir}-hdpi/xfwm4/themerc", ) subst_text(f"{output_dir}-hdpi/xfwm4/themerc", @@ -141,7 +140,7 @@ def build(ctx: BuildContext): os.makedirs(f"{output_dir}-xhdpi/xfwm4", exist_ok=True) shutil.copyfile( - f"{SRC_DIR}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", + f"{src_dir}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", f"{output_dir}-xhdpi/xfwm4/themerc", ) subst_text( @@ -150,45 +149,45 @@ def build(ctx: BuildContext): if not ctx.flavor.dark: shutil.copytree( - f"{SRC_DIR}/main/plank/theme-Light-Catppuccin/", f"{output_dir}/plank" + f"{src_dir}/main/plank/theme-Light-Catppuccin/", f"{output_dir}/plank", dirs_exist_ok=True ) else: shutil.copytree( - f"{SRC_DIR}/main/plank/theme-Dark-Catppuccin/", f"{output_dir}/plank" + f"{src_dir}/main/plank/theme-Dark-Catppuccin/", f"{output_dir}/plank", dirs_exist_ok=True ) -def make_assets(ctx: BuildContext): +def make_assets(ctx: BuildContext, src_dir): output_dir = ctx.output_dir() os.makedirs(f"{output_dir}/cinnamon/assets", exist_ok=True) - for file in glob.glob(f"{SRC_DIR}/assets/cinnamon/theme/*.svg"): + for file in glob.glob(f"{src_dir}/assets/cinnamon/theme/*.svg"): shutil.copy(file, f"{output_dir}/cinnamon/assets") shutil.copy( - f"{SRC_DIR}/assets/cinnamon/thumbnail{ctx.apply_suffix(DARK_LIGHT)}.svg", + f"{src_dir}/assets/cinnamon/thumbnail{ctx.apply_suffix(DARK_LIGHT)}.svg", f"{output_dir}/cinnamon/thumbnail.png", ) os.makedirs(f"{output_dir}/gnome-shell/assets", exist_ok=True) - for file in glob.glob(f"{SRC_DIR}/assets/gnome-shell/theme/*.svg"): + for file in glob.glob(f"{src_dir}/assets/gnome-shell/theme/*.svg"): shutil.copy(file, f"{output_dir}/gnome-shell/assets") shutil.copytree( - f"{SRC_DIR}/assets/gtk/assets", + f"{src_dir}/assets/gtk/assets", f"{output_dir}/gtk-3.0/assets", dirs_exist_ok=True, ) shutil.copytree( - f"{SRC_DIR}/assets/gtk/assets", + f"{src_dir}/assets/gtk/assets", f"{output_dir}/gtk-4.0/assets", dirs_exist_ok=True, ) shutil.copyfile( - f"{SRC_DIR}/assets/gtk/thumbnail{ctx.apply_suffix(IS_DARK)}.svg", + f"{src_dir}/assets/gtk/thumbnail{ctx.apply_suffix(IS_DARK)}.svg", f"{output_dir}/gtk-3.0/thumbnail.png", ) shutil.copyfile( - f"{SRC_DIR}/assets/gtk/thumbnail{ctx.apply_suffix(IS_DARK)}.svg", + f"{src_dir}/assets/gtk/thumbnail{ctx.apply_suffix(IS_DARK)}.svg", f"{output_dir}/gtk-4.0/thumbnail.png", ) @@ -251,26 +250,26 @@ def make_assets(ctx: BuildContext): subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#3c84f7", theme_color) - for file in glob.glob(f"{SRC_DIR}/assets/cinnamon/common-assets/*.svg"): + for file in glob.glob(f"{src_dir}/assets/cinnamon/common-assets/*.svg"): shutil.copy(file, f"{output_dir}/cinnamon/assets") - for file in glob.glob(f"{SRC_DIR}/assets/cinnamon/assets{ctx.apply_suffix(IS_DARK)}/*.svg"): + for file in glob.glob(f"{src_dir}/assets/cinnamon/assets{ctx.apply_suffix(IS_DARK)}/*.svg"): shutil.copy(file, f"{output_dir}/cinnamon/assets") - for file in glob.glob(f"{SRC_DIR}/assets/gnome-shell/common-assets/*.svg"): + for file in glob.glob(f"{src_dir}/assets/gnome-shell/common-assets/*.svg"): shutil.copy(file, f"{output_dir}/gnome-shell/assets") - for file in glob.glob(f"{SRC_DIR}/assets/gnome-shell/assets{ctx.apply_suffix(IS_DARK)}/*.svg"): + for file in glob.glob(f"{src_dir}/assets/gnome-shell/assets{ctx.apply_suffix(IS_DARK)}/*.svg"): shutil.copy(file, f"{output_dir}/gnome-shell/assets") - for file in glob.glob(f"{SRC_DIR}/assets/gtk/symbolics/*.svg"): + for file in glob.glob(f"{src_dir}/assets/gtk/symbolics/*.svg"): shutil.copy(file, f"{output_dir}/gtk-3.0/assets") shutil.copy(file, f"{output_dir}/gtk-4.0/assets") - for file in glob.glob(f"{SRC_DIR}/assets/metacity-1/assets{ctx.apply_suffix(IS_WINDOW_NORMAL)}/*.svg"): + for file in glob.glob(f"{src_dir}/assets/metacity-1/assets{ctx.apply_suffix(IS_WINDOW_NORMAL)}/*.svg"): shutil.copy(file, f"{output_dir}/metacity-1/assets") shutil.copy( - f"{SRC_DIR}/assets/metacity-1/thumbnail{ctx.apply_suffix(IS_DARK)}.png", + f"{src_dir}/assets/metacity-1/thumbnail{ctx.apply_suffix(IS_DARK)}.png", f"{output_dir}/metacity-1/thumbnail.png", ) @@ -307,7 +306,7 @@ def zip_artifacts(dir_list, zip_name, remove=True): shutil.rmtree(dir) -def build_theme(ctx: BuildContext): +def build_theme(ctx: BuildContext, src_dir): build_info = f"""Build info: build_root: {ctx.build_root} theme_name: {ctx.theme_name} @@ -316,11 +315,11 @@ def build_theme(ctx: BuildContext): size: {ctx.size} tweaks: {ctx.tweaks}""" logger.info(build_info) - build(ctx) - logger.info(f"Main build complete") + build(ctx, src_dir) + logger.info("Main build complete") logger.info("Bundling assets...") - make_assets(ctx) + make_assets(ctx, src_dir) logger.info("Asset bundling done") if ctx.output_format == "zip": diff --git a/src/utils.py b/src/utils.py index 679cd21b..74da1b07 100644 --- a/src/utils.py +++ b/src/utils.py @@ -2,6 +2,10 @@ import shutil +def copy_dir(_from, to): + shutil.copytree(_from, to) + + def subst_text(path, _from, to): with open(path, "r+") as f: content = f.read() From 01a84eda773601b2da05d4b7a5eb4fe442fa1e57 Mon Sep 17 00:00:00 2001 From: ruzo Date: Sat, 25 May 2024 02:44:22 +0300 Subject: [PATCH 04/31] ref: improving performance on build job by executing all flavors at the same time --- .github/workflows/build.yml | 15 ++++++--------- main.py | 3 ++- src/build.py | 19 +++++++++++-------- src/patches.py | 8 ++++---- 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1d4c0004..8d31625f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,17 +1,14 @@ name: "Generate test artifacts" - on: - workflow_dispatch: pull_request: types: [opened, reopened, synchronize] - jobs: build: runs-on: ubuntu-latest - steps: + - name: Checkout uses: actions/checkout@v4 with: @@ -32,14 +29,14 @@ jobs: run: | python patches/xfwm4/generate_assets.py - python ./main.py mocha --all-accents --zip -d $PWD/releases && - python ./main.py macchiato --all-accents --zip -d $PWD/releases && - python ./main.py frappe --all-accents --zip -d $PWD/releases && - python ./main.py latte --all-accents --zip -d $PWD/releases + python ./main.py mocha --all-accents --zip -d $PWD/releases & + python ./main.py macchiato --all-accents --zip -d $PWD/releases & + python ./main.py frappe --all-accents --zip -d $PWD/releases & + python ./main.py latte --all-accents --zip -d $PWD/releases & + wait - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: '${{ github.sha }}-artifacts' path: ./releases/*.zip - diff --git a/main.py b/main.py index c28502c0..6caded49 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,5 @@ +import os from src.build import main if __name__ == "__main__": - main() + main(os.path.dirname(os.path.realpath(__file__))) diff --git a/src/build.py b/src/build.py index 5a5c44ff..7157c3a8 100644 --- a/src/build.py +++ b/src/build.py @@ -1,5 +1,7 @@ import os +import sys import argparse +import shutil from src.patches import apply_colloid_patches from src.theme import build_theme, gnome_shell_version from src.utils import init_tweaks_temp, copy_dir @@ -8,7 +10,6 @@ from catppuccin import PALETTE -THIS_DIR = os.path.dirname(os.path.realpath(__file__)) GS_VERSION = "46-0" @@ -111,10 +112,16 @@ def parse_args(): return parser.parse_args() -def main(): +def main(context): args = parse_args() + + COLLOID_DIR = f"{context}/colloid" + COLLOID_TMP_DIR = f"{context}/colloid-tmp-{args.flavor}" + copy_dir(COLLOID_DIR, COLLOID_TMP_DIR) + SRC_DIR = COLLOID_TMP_DIR + "/src" + if args.patch: - apply_colloid_patches() + apply_colloid_patches(COLLOID_TMP_DIR) if args.zip: output_format = "zip" @@ -144,11 +151,6 @@ def main(): "lavender", ] - COLLOID_DIR = f"{THIS_DIR}/../colloid/src" - SRC_DIR = f"{THIS_DIR}/../colloid-tmp-" + args.flavor - - copy_dir(COLLOID_DIR, SRC_DIR) - for accent in accents: accent = getattr(palette.colors, accent) @@ -176,6 +178,7 @@ def main(): build_theme(ctx, SRC_DIR) logger.info(f"Completed {palette.identifier} with {accent.identifier}") + shutil.rmtree(COLLOID_TMP_DIR) logger.info("Done!") diff --git a/src/patches.py b/src/patches.py index 6774d755..6d676c95 100644 --- a/src/patches.py +++ b/src/patches.py @@ -3,8 +3,8 @@ from src.logger import logger -def apply_colloid_patches(): - if os.path.isfile("colloid/.patched"): +def apply_colloid_patches(colloid_dir): + if os.path.isfile(colloid_dir + "/.patched"): logger.info( 'Patches seem to be applied, remove "colloid/.patched" to force application (this may fail)' ) @@ -23,9 +23,9 @@ def apply_colloid_patches(): path = f"./patches/colloid/{patch}" logger.info(f"Applying patch '{patch}', located at '{path}'") subprocess.check_call( - ["git", "apply", path, "--directory", f"colloid"]) + ["git", "apply", path, "--directory", colloid_dir.split('/')[-1]]) - with open("colloid/.patched", "w") as f: + with open(colloid_dir + "/.patched", "w") as f: f.write("true") logger.info("Patching finished.") From a10f881ef9ce94737c481e68df5baa60da0b6249 Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sat, 25 May 2024 13:03:48 +0100 Subject: [PATCH 05/31] refactor: remove src_dir params; centralise in build ctx --- main.py | 4 ++-- src/build.py | 32 +++++++++++++++----------------- src/context.py | 6 ++++-- src/theme.py | 20 +++++++++----------- src/utils.py | 1 - 5 files changed, 30 insertions(+), 33 deletions(-) diff --git a/main.py b/main.py index 6caded49..1eb0a466 100644 --- a/main.py +++ b/main.py @@ -1,5 +1,5 @@ import os -from src.build import main +from src.build import build if __name__ == "__main__": - main(os.path.dirname(os.path.realpath(__file__))) + build(os.path.dirname(os.path.realpath(__file__))) diff --git a/src/build.py b/src/build.py index 7157c3a8..aaa1ebd5 100644 --- a/src/build.py +++ b/src/build.py @@ -9,10 +9,6 @@ from src.logger import logger from catppuccin import PALETTE - -GS_VERSION = "46-0" - - def parse_args(): parser = argparse.ArgumentParser() parser.add_argument( @@ -112,16 +108,18 @@ def parse_args(): return parser.parse_args() -def main(context): +def build(git_root: str): args = parse_args() - COLLOID_DIR = f"{context}/colloid" - COLLOID_TMP_DIR = f"{context}/colloid-tmp-{args.flavor}" - copy_dir(COLLOID_DIR, COLLOID_TMP_DIR) - SRC_DIR = COLLOID_TMP_DIR + "/src" + colloid_dir = f"{git_root}/colloid" + colloid_tmp_dir = f"{git_root}/colloid-tmp-{args.flavor}" + + copy_dir(colloid_dir, colloid_tmp_dir) + + src_dir = colloid_tmp_dir + "/src" if args.patch: - apply_colloid_patches(COLLOID_TMP_DIR) + apply_colloid_patches(colloid_tmp_dir) if args.zip: output_format = "zip" @@ -129,7 +127,6 @@ def main(context): output_format = "dir" tweaks = Tweaks(tweaks=args.tweaks) - palette = getattr(PALETTE, args.flavor) accents = args.accents @@ -161,7 +158,8 @@ def main(context): else: output_format = "dir" ctx = BuildContext( - build_root=args.dest, + output_root=args.dest, + colloid_src_dir=src_dir, theme_name=args.name, flavor=palette, accent=accent, @@ -171,19 +169,19 @@ def main(context): ) logger.info("Building temp tweaks file") - init_tweaks_temp(SRC_DIR) + init_tweaks_temp(src_dir) logger.info("Inserting gnome-shell imports") - gnome_shell_version(GS_VERSION, SRC_DIR) + gnome_shell_version(src_dir) logger.info("Building main theme") - build_theme(ctx, SRC_DIR) + build_theme(ctx) logger.info(f"Completed {palette.identifier} with {accent.identifier}") - shutil.rmtree(COLLOID_TMP_DIR) + shutil.rmtree(colloid_tmp_dir) logger.info("Done!") if __name__ == "__main__": try: - main() + build() except Exception as e: logger.error("Something went wrong when building the theme:", exc_info=e) diff --git a/src/context.py b/src/context.py index aa64214b..af5ae8b2 100644 --- a/src/context.py +++ b/src/context.py @@ -23,8 +23,10 @@ class Suffix: @dataclass class BuildContext: - build_root: str + colloid_src_dir: str + output_root: str output_format: Literal["zip"] | Literal["dir"] + theme_name: str flavor: Flavor accent: Color @@ -32,7 +34,7 @@ class BuildContext: tweaks: Tweaks def output_dir(self) -> str: - return f"{self.build_root}/{self.build_id()}" + return f"{self.output_root}/{self.build_id()}" def build_id(self) -> str: return f"{self.theme_name}-{self.flavor.identifier}-{self.accent.identifier}-{self.size}+{self.tweaks.id() or 'default'}" diff --git a/src/theme.py b/src/theme.py index 77a41955..3f2397e2 100644 --- a/src/theme.py +++ b/src/theme.py @@ -306,9 +306,10 @@ def zip_artifacts(dir_list, zip_name, remove=True): shutil.rmtree(dir) -def build_theme(ctx: BuildContext, src_dir): +def build_theme(ctx: BuildContext): + src_dir = ctx.colloid_src_dir build_info = f"""Build info: - build_root: {ctx.build_root} + build_root: {ctx.output_root} theme_name: {ctx.theme_name} flavor: {ctx.flavor.identifier} accent: {ctx.accent.identifier} @@ -329,12 +330,16 @@ def build_theme(ctx: BuildContext, src_dir): f"{ctx.output_dir()}-hdpi", f"{ctx.output_dir()}-xhdpi", ], - f"{ctx.build_root}/{ctx.build_id()}.zip", + f"{ctx.output_root}/{ctx.build_id()}.zip", True, ) -def gnome_shell_version(gs_version, src_dir): +def gnome_shell_version(src_dir): + # Hardcoded here, Colloid checks for this on end user machines + # but we cannot do that. Old build system would've resulted in this too. + gs_version = "46-0" + shutil.copyfile( f"{src_dir}/sass/gnome-shell/_common.scss", f"{src_dir}/sass/gnome-shell/_common-temp.scss", @@ -344,10 +349,3 @@ def gnome_shell_version(gs_version, src_dir): "@import 'widgets-40-0';", f"@import 'widgets-{gs_version}';", ) - - if gs_version == "3-28": - subst_text( - f"{src_dir}/sass/gnome-shell/_common-temp.scss", - "@import 'extensions-40-0';", - f"@import 'extensions-{gs_version}';", - ) diff --git a/src/utils.py b/src/utils.py index 74da1b07..3335275b 100644 --- a/src/utils.py +++ b/src/utils.py @@ -1,7 +1,6 @@ import re import shutil - def copy_dir(_from, to): shutil.copytree(_from, to) From b629dd1e7629ad4b6c4e9fef0fec00ec5263b2de Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sat, 25 May 2024 13:26:45 +0100 Subject: [PATCH 06/31] refactor: move to scripts/, cleanup, rework tweak application --- build.py | 522 +++-------------------------------- main.py | 5 - {src => scripts}/__init__.py | 0 {src => scripts}/context.py | 14 +- {src => scripts}/logger.py | 1 + {src => scripts}/patches.py | 5 +- {src => scripts}/theme.py | 155 +++++------ {src => scripts}/utils.py | 10 +- src/build.py | 187 ------------- 9 files changed, 136 insertions(+), 763 deletions(-) delete mode 100644 main.py rename {src => scripts}/__init__.py (100%) rename {src => scripts}/context.py (78%) rename {src => scripts}/logger.py (99%) rename {src => scripts}/patches.py (85%) rename {src => scripts}/theme.py (73%) rename {src => scripts}/utils.py (74%) delete mode 100644 src/build.py diff --git a/build.py b/build.py index 2d37d3d6..7465b08f 100755 --- a/build.py +++ b/build.py @@ -1,473 +1,16 @@ -#!/usr/bin/env python3 -import os, re, shutil, subprocess, argparse, glob, logging, zipfile, sys - -from dataclasses import dataclass -from typing import Any, Literal, List - +import os +import sys +import argparse +import shutil +import time +import os + +from scripts.patches import apply_colloid_patches +from scripts.theme import build_theme, gnome_shell_version +from scripts.utils import init_tweaks_temp, copy_dir +from scripts.context import Tweaks, BuildContext +from scripts.logger import logger from catppuccin import PALETTE -from catppuccin.models import Flavor, Color - -THIS_DIR = os.path.dirname(os.path.realpath(__file__)) -SRC_DIR = f"{THIS_DIR}/colloid/src" -SASSC_OPT = ["-M", "-t", "expanded"] - -logger = logging.getLogger("catppuccin-gtk") -logger.setLevel(logging.DEBUG) -ch = logging.StreamHandler() -formatter = logging.Formatter("[%(name)s] [%(levelname)s] - %(message)s") -ch.setFormatter(formatter) -logger.addHandler(ch) - - -@dataclass -class Tweaks: - tweaks: List[str] - - def has(self, tweak: str) -> bool: - return tweak in self.tweaks - - def id(self) -> str: - return ",".join(self.tweaks) - - -@dataclass -class Suffix: - true_value: str - test: Any # callback function - false_value: str = "" - - -IS_DARK = Suffix(true_value="-Dark", test=lambda ctx: ctx.flavor.dark) -IS_LIGHT = Suffix(true_value="-Light", test=lambda ctx: not ctx.flavor.dark) -IS_WINDOW_NORMAL = Suffix(true_value="-Normal", test=lambda ctx: ctx.tweaks.has('normal')) -DARK_LIGHT = Suffix( - true_value="-Dark", false_value="-Light", test=lambda ctx: ctx.flavor.dark -) - -@dataclass -class BuildContext: - build_root: str - output_format: Literal["zip"] | Literal["dir"] - theme_name: str - flavor: Flavor - accent: Color - size: Literal["standard"] | Literal["compact"] - tweaks: Tweaks - - def output_dir(self) -> str: - suffix = "light" - if self.flavor.dark: - suffix = "dark" - return f"{self.build_root}/{self.build_id()}-{suffix}" - - def build_id(self) -> str: - return f"{self.theme_name}-{self.flavor.identifier}-{self.accent.identifier}-{self.size}+{self.tweaks.id() or 'default'}" - - def apply_suffix(self, suffix: Suffix) -> str: - if suffix.test(self): - return suffix.true_value - else: - return suffix.false_value - - -def build(ctx: BuildContext): - output_dir = ctx.output_dir() - logger.info(f"Building into '{output_dir}'...") - - apply_tweaks(ctx) - - os.makedirs(output_dir, exist_ok=True) - with open(f"{output_dir}/index.theme", "w") as file: - file.write("[Desktop Entry]\n") - file.write("Type=X-GNOME-Metatheme\n") - file.write(f"Name={ctx.build_id()}\n") - file.write("Comment=An Flat Gtk+ theme based on Elegant Design\n") - file.write("Encoding=UTF-8\n") - file.write("\n") - file.write("[X-GNOME-Metatheme]\n") - file.write(f"GtkTheme={ctx.build_id()}\n") - file.write(f"MetacityTheme={ctx.build_id()}\n") - file.write(f"IconTheme=Tela-circle{ctx.apply_suffix(IS_DARK)}\n") - file.write(f"CursorTheme={ctx.flavor.name}-cursors\n") - file.write("ButtonLayout=close,minimize,maximize:menu\n") - - os.makedirs(f"{output_dir}/gnome-shell", exist_ok=True) - shutil.copyfile( - f"{SRC_DIR}/main/gnome-shell/pad-osd.css", - f"{output_dir}/gnome-shell/pad-osd.css", - ) - subprocess.check_call( - [ - "sassc", - *SASSC_OPT, - f"{SRC_DIR}/main/gnome-shell/gnome-shell{ctx.apply_suffix(DARK_LIGHT)}.scss", - f"{output_dir}/gnome-shell/gnome-shell.css", - ] - ) - - os.makedirs(f"{output_dir}/gtk-3.0", exist_ok=True) - subprocess.check_call( - [ - "sassc", - *SASSC_OPT, - f"{SRC_DIR}/main/gtk-3.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss", - f"{output_dir}/gtk-3.0/gtk.css", - ] - ) - subprocess.check_call( - [ - "sassc", - *SASSC_OPT, - # NOTE: This uses 'Dark' for the source, but 'dark' for the destination. This is intentional. Do !!NOT!! change it without consultation - f"{SRC_DIR}/main/gtk-3.0/gtk-Dark.scss", - f"{output_dir}/gtk-3.0/gtk-dark.css", - ] - ) - - os.makedirs(f"{output_dir}/gtk-4.0", exist_ok=True) - subprocess.check_call( - [ - "sassc", - *SASSC_OPT, - f"{SRC_DIR}/main/gtk-4.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss", - f"{output_dir}/gtk-4.0/gtk.css", - ] - ) - subprocess.check_call( - [ - "sassc", - *SASSC_OPT, - # NOTE: This uses 'Dark' for the source, but 'dark' for the destination. This is intentional. Do !!NOT!! change it without consultation - f"{SRC_DIR}/main/gtk-4.0/gtk-Dark.scss", - f"{output_dir}/gtk-4.0/gtk-dark.css", - ] - ) - - os.makedirs(f"{output_dir}/cinnamon", exist_ok=True) - subprocess.check_call( - [ - "sassc", - *SASSC_OPT, - f"{SRC_DIR}/main/cinnamon/cinnamon{ctx.apply_suffix(DARK_LIGHT)}.scss", - f"{output_dir}/cinnamon/cinnamon.css", - ] - ) - - os.makedirs(f"{output_dir}/metacity-1", exist_ok=True) - shutil.copyfile( - f"{SRC_DIR}/main/metacity-1/metacity-theme-3{ctx.apply_suffix(IS_WINDOW_NORMAL)}.xml", - f"{output_dir}/metacity-1/metacity-theme-3.xml", - ) - # FIXME: Symlinks aren't working as intended - # FIXME: Do we need them? - # os.symlink( - # f"{output_dir}/metacity-1/metacity-theme-3.xml", - # f"{output_dir}/metacity-1/metacity-theme-2.xml", - # ) - # os.symlink( - # f"{output_dir}/metacity-1/metacity-theme-3.xml", - # f"{output_dir}/metacity-1/metacity-theme-1.xml", - # ) - - os.makedirs(f"{output_dir}/xfwm4", exist_ok=True) - shutil.copyfile( - f"{SRC_DIR}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", - f"{output_dir}/xfwm4/themerc", - ) - - os.makedirs(f"{output_dir}-hdpi/xfwm4", exist_ok=True) - shutil.copyfile( - f"{SRC_DIR}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", - f"{output_dir}-hdpi/xfwm4/themerc", - ) - subst_text(f"{output_dir}-hdpi/xfwm4/themerc", "button_offset=6", "button_offset=9") - - os.makedirs(f"{output_dir}-xhdpi/xfwm4", exist_ok=True) - shutil.copyfile( - f"{SRC_DIR}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", - f"{output_dir}-xhdpi/xfwm4/themerc", - ) - subst_text( - f"{output_dir}-xhdpi/xfwm4/themerc", "button_offset=6", "button_offset=12" - ) - - if not ctx.flavor.dark: - shutil.copytree( - f"{SRC_DIR}/main/plank/theme-Light-Catppuccin/", f"{output_dir}/plank", dirs_exist_ok=True - ) - else: - shutil.copytree( - f"{SRC_DIR}/main/plank/theme-Dark-Catppuccin/", f"{output_dir}/plank", dirs_exist_ok=True - ) - - -def init_tweaks_temp(): - shutil.copyfile(f"{SRC_DIR}/sass/_tweaks.scss", f"{SRC_DIR}/sass/_tweaks-temp.scss") - - -def subst_text(path, _from, to): - with open(path, "r+") as f: - content = f.read() - f.seek(0) - f.truncate() - f.write(re.sub(_from, to, content)) - - -GS_VERSION = "46-0" - -def gnome_shell_version(): - shutil.copyfile( - f"{SRC_DIR}/sass/gnome-shell/_common.scss", - f"{SRC_DIR}/sass/gnome-shell/_common-temp.scss", - ) - subst_text( - f"{SRC_DIR}/sass/gnome-shell/_common-temp.scss", - "@import 'widgets-40-0';", - f"@import 'widgets-{GS_VERSION}';", - ) - - if GS_VERSION == "3-28": - subst_text( - f"{SRC_DIR}/sass/gnome-shell/_common-temp.scss", - "@import 'extensions-40-0';", - f"@import 'extensions-{GS_VERSION}';", - ) - -def write_tweak(key, default, value): - subst_text( - f"{SRC_DIR}/sass/_tweaks-temp.scss", f"\\${key}: {default}", f"${key}: {value}" - ) - -def apply_tweaks(ctx: BuildContext): - write_tweak("theme", "'default'", f"'{ctx.accent.identifier}'") - - if ctx.size == "compact": - write_tweak("compact", "'false'", "'true'") - - subst_text( - f"{SRC_DIR}/sass/_tweaks-temp.scss", - "@import 'color-palette-default';", - f"@import 'color-palette-catppuccin-{ctx.flavor.identifier}';", - ) - write_tweak("colorscheme", "'default'", "'catppuccin'") - - if ctx.tweaks.has("black"): - write_tweak("blackness", "'false'", "'true'") - - if ctx.tweaks.has("rimless"): - write_tweak("rimless", "'false'", "'true'") - - if ctx.tweaks.has("normal"): - write_tweak("window_button", "'mac'", "'normal'") - - if ctx.tweaks.has("float"): - write_tweak("float", "'false'", "'true'") - - -def make_assets(ctx: BuildContext): - output_dir = ctx.output_dir() - - os.makedirs(f"{output_dir}/cinnamon/assets", exist_ok=True) - for file in glob.glob(f"{SRC_DIR}/assets/cinnamon/theme/*.svg"): - shutil.copy(file, f"{output_dir}/cinnamon/assets") - shutil.copy( - f"{SRC_DIR}/assets/cinnamon/thumbnail{ctx.apply_suffix(DARK_LIGHT)}.svg", - f"{output_dir}/cinnamon/thumbnail.png", - ) - - os.makedirs(f"{output_dir}/gnome-shell/assets", exist_ok=True) - for file in glob.glob(f"{SRC_DIR}/assets/gnome-shell/theme/*.svg"): - shutil.copy(file, f"{output_dir}/gnome-shell/assets") - - shutil.copytree( - f"{SRC_DIR}/assets/gtk/assets", - f"{output_dir}/gtk-3.0/assets", - dirs_exist_ok=True, - ) - shutil.copytree( - f"{SRC_DIR}/assets/gtk/assets", - f"{output_dir}/gtk-4.0/assets", - dirs_exist_ok=True, - ) - shutil.copyfile( - f"{SRC_DIR}/assets/gtk/thumbnail{ctx.apply_suffix(IS_DARK)}.svg", - f"{output_dir}/gtk-3.0/thumbnail.png", - ) - shutil.copyfile( - f"{SRC_DIR}/assets/gtk/thumbnail{ctx.apply_suffix(IS_DARK)}.svg", - f"{output_dir}/gtk-4.0/thumbnail.png", - ) - - theme_color = ctx.accent.hex - - palette = ctx.flavor.colors - background = palette.base.hex - background_alt = palette.mantle.hex - titlebar = palette.overlay0.hex - - for file in glob.glob(f"{output_dir}/cinnamon/assets/*.svg"): - subst_text(file, "#5b9bf8", theme_color) - subst_text(file, "#3c84f7", theme_color) - - for file in glob.glob(f"{output_dir}/gnome-shell/assets/*.svg"): - subst_text(file, "#5b9bf8", theme_color) - subst_text(file, "#3c84f7", theme_color) - - for file in glob.glob(f"{output_dir}/gtk-3.0/assets/*.svg"): - subst_text(file, "#5b9bf8", theme_color) - subst_text(file, "#3c84f7", theme_color) - subst_text(file, "#ffffff", background) - subst_text(file, "#2c2c2c", background) - subst_text(file, "#3c3c3c", background_alt) - - for file in glob.glob(f"{output_dir}/gtk-4.0/assets/*.svg"): - subst_text(file, "#5b9bf8", theme_color) - subst_text(file, "#3c84f7", theme_color) - subst_text(file, "#ffffff", background) - subst_text(file, "#2c2c2c", background) - subst_text(file, "#3c3c3c", background_alt) - - if ctx.flavor.dark: - subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#2c2c2c", background) - subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#5b9bf8", theme_color) - - subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#2c2c2c", background) - subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#2c2c2c", background) - - subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#5b9bf8", theme_color) - subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#5b9bf8", theme_color) - else: - subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#ffffff", background) - subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#f2f2f2", titlebar) - subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#3c84f7", theme_color) - - subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#f2f2f2", titlebar) - subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#3c84f7", theme_color) - - subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#f2f2f2", titlebar) - subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#3c84f7", theme_color) - - for file in glob.glob(f"{SRC_DIR}/assets/cinnamon/common-assets/*.svg"): - shutil.copy(file, f"{output_dir}/cinnamon/assets") - - for file in glob.glob(f"{SRC_DIR}/assets/cinnamon/assets{ctx.apply_suffix(IS_DARK)}/*.svg"): - shutil.copy(file, f"{output_dir}/cinnamon/assets") - - for file in glob.glob(f"{SRC_DIR}/assets/gnome-shell/common-assets/*.svg"): - shutil.copy(file, f"{output_dir}/gnome-shell/assets") - - for file in glob.glob(f"{SRC_DIR}/assets/gnome-shell/assets{ctx.apply_suffix(IS_DARK)}/*.svg"): - shutil.copy(file, f"{output_dir}/gnome-shell/assets") - - for file in glob.glob(f"{SRC_DIR}/assets/gtk/symbolics/*.svg"): - shutil.copy(file, f"{output_dir}/gtk-3.0/assets") - shutil.copy(file, f"{output_dir}/gtk-4.0/assets") - - for file in glob.glob(f"{SRC_DIR}/assets/metacity-1/assets{ctx.apply_suffix(IS_WINDOW_NORMAL)}/*.svg"): - shutil.copy(file, f"{output_dir}/metacity-1/assets") - shutil.copy( - f"{SRC_DIR}/assets/metacity-1/thumbnail{ctx.apply_suffix(IS_DARK)}.png", - f"{output_dir}/metacity-1/thumbnail.png", - ) - - xfwm4_assets_root = f"{THIS_DIR}/patches/xfwm4/generated/assets-catppuccin-{ctx.flavor.identifier}" - for file in glob.glob(xfwm4_assets_root + '/*'): - shutil.copy(file, f"{output_dir}/xfwm4") - - xfwm4_assets = xfwm4_assets_root + "-hdpi/*" - for file in glob.glob(xfwm4_assets): - shutil.copy(file, f"{output_dir}-hdpi/xfwm4") - - xfwm4_assets = xfwm4_assets_root + "-xhdpi/*" - for file in glob.glob(xfwm4_assets): - shutil.copy(file, f"{output_dir}-xhdpi/xfwm4") - - -def zip_dir(path, zip_file): - # Ref: https://stackoverflow.com/questions/46229764/python-zip-multiple-directories-into-one-zip-file - for root, _, files in os.walk(path): - for file in files: - zip_file.write( - os.path.join(root, file), - os.path.relpath(os.path.join(root, file), os.path.join(path, "..")), - ) - - -def zip_artifacts(dir_list, zip_name, remove=True): - with zipfile.ZipFile(zip_name, "w", zipfile.ZIP_DEFLATED) as zipf: - for dir in dir_list: - zip_dir(dir, zipf) - - if remove: - for dir in dir_list: - shutil.rmtree(dir) - - -def build_theme(ctx: BuildContext): - build_info = f"""Build info: - build_root: {ctx.build_root} - theme_name: {ctx.theme_name} - flavor: {ctx.flavor.identifier} - accent: {ctx.accent.identifier} - size: {ctx.size} - tweaks: {ctx.tweaks}""" - logger.info(build_info) - build(ctx) - logger.info(f"Main build complete") - - logger.info("Bundling assets...") - make_assets(ctx) - logger.info("Asset bundling done") - - if ctx.output_format == "zip": - zip_artifacts( - [ - ctx.output_dir(), - f"{ctx.output_dir()}-hdpi", - f"{ctx.output_dir()}-xhdpi", - ], - f"{ctx.build_root}/{ctx.build_id()}.zip", - True, - ) - - """ - if (command -v xfce4-popup-whiskermenu &> /dev/null) && $(sed -i "s|.*menu-opacity=.*|menu-opacity=95|" "$HOME/.config/xfce4/panel/whiskermenu"*".rc" &> /dev/null); then - sed -i "s|.*menu-opacity=.*|menu-opacity=95|" "$HOME/.config/xfce4/panel/whiskermenu"*".rc" - fi - - if (pgrep xfce4-session &> /dev/null); then - xfce4-panel -r - fi - """ - - -def apply_colloid_patches(): - if os.path.isfile("colloid/.patched"): - logger.info( - 'Patches seem to be applied, remove "colloid/.patched" to force application (this may fail)' - ) - return - - logger.info("Applying patches...") - # Change into colloid - for patch in [ - "plank-dark.patch", - "plank-light.patch", - "theme-func.patch", - "sass-palette-frappe.patch", - "sass-palette-mocha.patch", - "sass-palette-latte.patch", - "sass-palette-macchiato.patch", - "fixes/alt-tab-background-color.patch" - ]: - path = f"./patches/colloid/{patch}" - logger.info(f"Applying patch '{patch}', located at '{path}'") - subprocess.check_call(["git", "apply", path, "--directory", f"colloid"]) - - with open("colloid/.patched", "w") as f: - f.write("true") - - logger.info("Patching finished.") def parse_args(): parser = argparse.ArgumentParser() @@ -568,10 +111,19 @@ def parse_args(): return parser.parse_args() -def main(): +def build(): + git_root = os.path.dirname(os.path.realpath(__file__)) args = parse_args() + + colloid_dir = f"{git_root}/colloid" + colloid_tmp_dir = f"{git_root}/colloid-tmp-{args.flavor}" + + copy_dir(colloid_dir, colloid_tmp_dir) + + src_dir = colloid_tmp_dir + "/src" + if args.patch: - apply_colloid_patches() + apply_colloid_patches(colloid_tmp_dir) if args.zip: output_format = "zip" @@ -579,7 +131,6 @@ def main(): output_format = "dir" tweaks = Tweaks(tweaks=args.tweaks) - palette = getattr(PALETTE, args.flavor) accents = args.accents @@ -610,8 +161,11 @@ def main(): output_format = "zip" else: output_format = "dir" + ctx = BuildContext( - build_root=args.dest, + output_root=args.dest, + colloid_src_dir=src_dir, + git_root=git_root, theme_name=args.name, flavor=palette, accent=accent, @@ -619,18 +173,26 @@ def main(): tweaks=tweaks, output_format=output_format, ) + logger.info("Building temp tweaks file") - init_tweaks_temp() + init_tweaks_temp(src_dir) logger.info("Inserting gnome-shell imports") - gnome_shell_version() + gnome_shell_version(src_dir) logger.info("Building main theme") build_theme(ctx) logger.info(f"Completed {palette.identifier} with {accent.identifier}") + print() + shutil.rmtree(colloid_tmp_dir) logger.info("Done!") -try: - main() -except Exception as e: - logger.error("Something went wrong when building the theme:", exc_info=e) - sys.exit(1) +if __name__ == "__main__": + try: + start = time.time() + build() + end = time.time() - start + + logger.info('') + logger.info(f'Built in {round(end, 3)}s') + except Exception as e: + logger.error("Something went wrong when building the theme:", exc_info=e) diff --git a/main.py b/main.py deleted file mode 100644 index 1eb0a466..00000000 --- a/main.py +++ /dev/null @@ -1,5 +0,0 @@ -import os -from src.build import build - -if __name__ == "__main__": - build(os.path.dirname(os.path.realpath(__file__))) diff --git a/src/__init__.py b/scripts/__init__.py similarity index 100% rename from src/__init__.py rename to scripts/__init__.py diff --git a/src/context.py b/scripts/context.py similarity index 78% rename from src/context.py rename to scripts/context.py index af5ae8b2..5a1ac779 100644 --- a/src/context.py +++ b/scripts/context.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from typing import Any, Literal, List from catppuccin.models import Flavor, Color - +from .utils import subst_text @dataclass class Tweaks: @@ -23,8 +23,15 @@ class Suffix: @dataclass class BuildContext: + # The src dir of the Colloid copy to operate on colloid_src_dir: str + + # The root of the project + git_root: str + + # The root of the output dir (as specified by --dest if given) output_root: str + output_format: Literal["zip"] | Literal["dir"] theme_name: str @@ -45,6 +52,11 @@ def apply_suffix(self, suffix: Suffix) -> str: else: return suffix.false_value + def apply_tweak(self, key, default, value): + subst_text( + f"{self.colloid_src_dir}/sass/_tweaks-temp.scss", f"\\${key}: {default}", f"${key}: {value}" + ) + IS_DARK = Suffix(true_value="-Dark", test=lambda ctx: ctx.flavor.dark) IS_LIGHT = Suffix(true_value="-Light", test=lambda ctx: not ctx.flavor.dark) diff --git a/src/logger.py b/scripts/logger.py similarity index 99% rename from src/logger.py rename to scripts/logger.py index b6d1d2f8..99e1552e 100644 --- a/src/logger.py +++ b/scripts/logger.py @@ -1,6 +1,7 @@ import logging logger = logging.getLogger("catppuccin-gtk") + logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() formatter = logging.Formatter("[%(name)s] [%(levelname)s] - %(message)s") diff --git a/src/patches.py b/scripts/patches.py similarity index 85% rename from src/patches.py rename to scripts/patches.py index 6d676c95..3cdff4cd 100644 --- a/src/patches.py +++ b/scripts/patches.py @@ -1,12 +1,11 @@ import os import subprocess -from src.logger import logger - +from .logger import logger def apply_colloid_patches(colloid_dir): if os.path.isfile(colloid_dir + "/.patched"): logger.info( - 'Patches seem to be applied, remove "colloid/.patched" to force application (this may fail)' + f'Patches seem to be applied, remove "{colloid_dir}/.patched" to force application (this may fail)' ) return diff --git a/src/theme.py b/scripts/theme.py similarity index 73% rename from src/theme.py rename to scripts/theme.py index 3f2397e2..64319f5a 100644 --- a/src/theme.py +++ b/scripts/theme.py @@ -3,38 +3,39 @@ import subprocess import glob import zipfile -from src.logger import logger -from src.utils import subst_text, translate_accent, init_tweaks_temp, write_tweak -from src.context import BuildContext, IS_DARK, IS_LIGHT, IS_WINDOW_NORMAL, DARK_LIGHT - -SASSC_OPT = ["-M", "-t", "expanded"] -THIS_DIR = os.path.dirname(os.path.realpath(__file__)) - +from .logger import logger +from .utils import subst_text +from .context import BuildContext, IS_DARK, IS_LIGHT, IS_WINDOW_NORMAL, DARK_LIGHT def apply_tweaks(ctx: BuildContext, src_dir): - write_tweak(src_dir, "theme", "'default'", f"'{ctx.accent.identifier}'") + ctx.apply_tweak("theme", "'default'", f"'{ctx.accent.identifier}'") if ctx.size == "compact": - write_tweak(src_dir, "compact", "'false'", "'true'") + ctx.apply_tweak("compact", "'false'", "'true'") subst_text( f"{src_dir}/sass/_tweaks-temp.scss", "@import 'color-palette-default';", f"@import 'color-palette-catppuccin-{ctx.flavor.identifier}';", ) - write_tweak(src_dir, "colorscheme", "'default'", "'catppuccin'") + ctx.apply_tweak("colorscheme", "'default'", "'catppuccin'") if ctx.tweaks.has("black"): - write_tweak(src_dir, "blackness", "'false'", "'true'") + ctx.apply_tweak("blackness", "'false'", "'true'") if ctx.tweaks.has("rimless"): - write_tweak(src_dir, "rimless", "'false'", "'true'") + ctx.apply_tweak("rimless", "'false'", "'true'") if ctx.tweaks.has("normal"): - write_tweak(src_dir, "window_button", "'mac'", "'normal'") + ctx.apply_tweak("window_button", "'mac'", "'normal'") if ctx.tweaks.has("float"): - write_tweak(src_dir, "float", "'false'", "'true'") + ctx.apply_tweak("float", "'false'", "'true'") + + +SASSC_OPT = ["-M", "-t", "expanded"] +def compile_sass(src: str, dest: str) -> subprocess.Popen: + return subprocess.Popen(["sassc", *SASSC_OPT, src, dest]) def build(ctx: BuildContext, src_dir): @@ -58,66 +59,60 @@ def build(ctx: BuildContext, src_dir): file.write(f"CursorTheme={ctx.flavor.name}-cursors\n") file.write("ButtonLayout=close,minimize,maximize:menu\n") + sassc_tasks = [] + os.makedirs(f"{output_dir}/gnome-shell", exist_ok=True) shutil.copyfile( f"{src_dir}/main/gnome-shell/pad-osd.css", f"{output_dir}/gnome-shell/pad-osd.css", ) - subprocess.check_call( - [ - "sassc", - *SASSC_OPT, + + sassc_tasks.append( + compile_sass( f"{src_dir}/main/gnome-shell/gnome-shell{ctx.apply_suffix(DARK_LIGHT)}.scss", f"{output_dir}/gnome-shell/gnome-shell.css", - ] + ) ) os.makedirs(f"{output_dir}/gtk-3.0", exist_ok=True) - subprocess.check_call( - [ - "sassc", - *SASSC_OPT, + sassc_tasks.append( + compile_sass( f"{src_dir}/main/gtk-3.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss", f"{output_dir}/gtk-3.0/gtk.css", - ] + ) ) - subprocess.check_call( - [ - "sassc", - *SASSC_OPT, + sassc_tasks.append( + compile_sass( f"{src_dir}/main/gtk-3.0/gtk-Dark.scss", f"{output_dir}/gtk-3.0/gtk-dark.css", - ] + ) ) os.makedirs(f"{output_dir}/gtk-4.0", exist_ok=True) - subprocess.check_call( - [ - "sassc", - *SASSC_OPT, + sassc_tasks.append( + compile_sass( f"{src_dir}/main/gtk-4.0/gtk{ctx.apply_suffix(DARK_LIGHT)}.scss", f"{output_dir}/gtk-4.0/gtk.css", - ] + ) ) - subprocess.check_call( - [ - "sassc", - *SASSC_OPT, + sassc_tasks.append( + compile_sass( f"{src_dir}/main/gtk-4.0/gtk-Dark.scss", f"{output_dir}/gtk-4.0/gtk-dark.css", - ] + ) ) os.makedirs(f"{output_dir}/cinnamon", exist_ok=True) - subprocess.check_call( - [ - "sassc", - *SASSC_OPT, + sassc_tasks.append( + compile_sass( f"{src_dir}/main/cinnamon/cinnamon{ctx.apply_suffix(DARK_LIGHT)}.scss", f"{output_dir}/cinnamon/cinnamon.css", - ] + ) ) + for task in sassc_tasks: + task.wait() + os.makedirs(f"{output_dir}/metacity-1", exist_ok=True) shutil.copyfile( f"{src_dir}/main/metacity-1/metacity-theme-3{ctx.apply_suffix(IS_WINDOW_NORMAL)}.xml", @@ -135,8 +130,7 @@ def build(ctx: BuildContext, src_dir): f"{src_dir}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", f"{output_dir}-hdpi/xfwm4/themerc", ) - subst_text(f"{output_dir}-hdpi/xfwm4/themerc", - "button_offset=6", "button_offset=9") + subst_text(f"{output_dir}-hdpi/xfwm4/themerc", "button_offset=6", "button_offset=9") os.makedirs(f"{output_dir}-xhdpi/xfwm4", exist_ok=True) shutil.copyfile( @@ -149,16 +143,21 @@ def build(ctx: BuildContext, src_dir): if not ctx.flavor.dark: shutil.copytree( - f"{src_dir}/main/plank/theme-Light-Catppuccin/", f"{output_dir}/plank", dirs_exist_ok=True + f"{src_dir}/main/plank/theme-Light-Catppuccin/", + f"{output_dir}/plank", + dirs_exist_ok=True, ) else: shutil.copytree( - f"{src_dir}/main/plank/theme-Dark-Catppuccin/", f"{output_dir}/plank", dirs_exist_ok=True + f"{src_dir}/main/plank/theme-Dark-Catppuccin/", + f"{output_dir}/plank", + dirs_exist_ok=True, ) -def make_assets(ctx: BuildContext, src_dir): +def make_assets(ctx: BuildContext): output_dir = ctx.output_dir() + src_dir = ctx.colloid_src_dir os.makedirs(f"{output_dir}/cinnamon/assets", exist_ok=True) for file in glob.glob(f"{src_dir}/assets/cinnamon/theme/*.svg"): @@ -221,60 +220,58 @@ def make_assets(ctx: BuildContext, src_dir): subst_text(file, "#3c3c3c", background_alt) if ctx.flavor.dark: - subst_text(f"{output_dir}/cinnamon/thumbnail.png", - "#2c2c2c", background) - subst_text(f"{output_dir}/cinnamon/thumbnail.png", - "#5b9bf8", theme_color) - - subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", - "#2c2c2c", background) - subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", - "#2c2c2c", background) - - subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", - "#5b9bf8", theme_color) - subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", - "#5b9bf8", theme_color) + subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#2c2c2c", background) + subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#5b9bf8", theme_color) + + subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#2c2c2c", background) + subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#2c2c2c", background) + + subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#5b9bf8", theme_color) + subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#5b9bf8", theme_color) else: - subst_text(f"{output_dir}/cinnamon/thumbnail.png", - "#ffffff", background) + subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#ffffff", background) subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#f2f2f2", titlebar) - subst_text(f"{output_dir}/cinnamon/thumbnail.png", - "#3c84f7", theme_color) + subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#3c84f7", theme_color) subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#f2f2f2", titlebar) - subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", - "#3c84f7", theme_color) + subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#3c84f7", theme_color) subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#f2f2f2", titlebar) - subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", - "#3c84f7", theme_color) + subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#3c84f7", theme_color) for file in glob.glob(f"{src_dir}/assets/cinnamon/common-assets/*.svg"): shutil.copy(file, f"{output_dir}/cinnamon/assets") - for file in glob.glob(f"{src_dir}/assets/cinnamon/assets{ctx.apply_suffix(IS_DARK)}/*.svg"): + for file in glob.glob( + f"{src_dir}/assets/cinnamon/assets{ctx.apply_suffix(IS_DARK)}/*.svg" + ): shutil.copy(file, f"{output_dir}/cinnamon/assets") for file in glob.glob(f"{src_dir}/assets/gnome-shell/common-assets/*.svg"): shutil.copy(file, f"{output_dir}/gnome-shell/assets") - for file in glob.glob(f"{src_dir}/assets/gnome-shell/assets{ctx.apply_suffix(IS_DARK)}/*.svg"): + for file in glob.glob( + f"{src_dir}/assets/gnome-shell/assets{ctx.apply_suffix(IS_DARK)}/*.svg" + ): shutil.copy(file, f"{output_dir}/gnome-shell/assets") for file in glob.glob(f"{src_dir}/assets/gtk/symbolics/*.svg"): shutil.copy(file, f"{output_dir}/gtk-3.0/assets") shutil.copy(file, f"{output_dir}/gtk-4.0/assets") - for file in glob.glob(f"{src_dir}/assets/metacity-1/assets{ctx.apply_suffix(IS_WINDOW_NORMAL)}/*.svg"): + for file in glob.glob( + f"{src_dir}/assets/metacity-1/assets{ctx.apply_suffix(IS_WINDOW_NORMAL)}/*.svg" + ): shutil.copy(file, f"{output_dir}/metacity-1/assets") shutil.copy( f"{src_dir}/assets/metacity-1/thumbnail{ctx.apply_suffix(IS_DARK)}.png", f"{output_dir}/metacity-1/thumbnail.png", ) - xfwm4_assets = f"{THIS_DIR}/patches/xfwm4/generated/assets-catppuccin-{ctx.flavor.identifier}" - for file in glob.glob(xfwm4_assets + '/*'): + xfwm4_assets = ( + f"{ctx.git_root}/patches/xfwm4/generated/assets-catppuccin-{ctx.flavor.identifier}" + ) + for file in glob.glob(xfwm4_assets + "/*"): shutil.copy(file, f"{output_dir}/xfwm4") xfwm4_assets = xfwm4_assets + "-hdpi/*" @@ -291,8 +288,7 @@ def zip_dir(path, zip_file): for file in files: zip_file.write( os.path.join(root, file), - os.path.relpath(os.path.join(root, file), - os.path.join(path, "..")), + os.path.relpath(os.path.join(root, file), os.path.join(path, "..")), ) @@ -316,11 +312,12 @@ def build_theme(ctx: BuildContext): size: {ctx.size} tweaks: {ctx.tweaks}""" logger.info(build_info) + build(ctx, src_dir) logger.info("Main build complete") logger.info("Bundling assets...") - make_assets(ctx, src_dir) + make_assets(ctx) logger.info("Asset bundling done") if ctx.output_format == "zip": diff --git a/src/utils.py b/scripts/utils.py similarity index 74% rename from src/utils.py rename to scripts/utils.py index 3335275b..91ebc6e8 100644 --- a/src/utils.py +++ b/scripts/utils.py @@ -1,6 +1,7 @@ import re import shutil + def copy_dir(_from, to): shutil.copytree(_from, to) @@ -34,11 +35,4 @@ def translate_accent(ctp_accent): def init_tweaks_temp(src_dir): - shutil.copyfile(f"{src_dir}/sass/_tweaks.scss", - f"{src_dir}/sass/_tweaks-temp.scss") - - -def write_tweak(src_dir, key, default, value): - subst_text( - f"{src_dir}/sass/_tweaks-temp.scss", f"\\${key}: {default}", f"${key}: {value}" - ) + shutil.copyfile(f"{src_dir}/sass/_tweaks.scss", f"{src_dir}/sass/_tweaks-temp.scss") \ No newline at end of file diff --git a/src/build.py b/src/build.py deleted file mode 100644 index aaa1ebd5..00000000 --- a/src/build.py +++ /dev/null @@ -1,187 +0,0 @@ -import os -import sys -import argparse -import shutil -from src.patches import apply_colloid_patches -from src.theme import build_theme, gnome_shell_version -from src.utils import init_tweaks_temp, copy_dir -from src.context import Tweaks, BuildContext -from src.logger import logger -from catppuccin import PALETTE - -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument( - "flavor", - type=str, - choices=["mocha", "frappe", "macchiato", "latte"], - help="Flavor of the theme to apply.", - ) - - parser.add_argument( - "--name", - "-n", - type=str, - default="catppuccin", - dest="name", - help="Name of the theme to apply.", - ) - - parser.add_argument( - "--dest", - "-d", - type=str, - required=True, - dest="dest", - help="Destination of the files.", - ) - - parser.add_argument( - "--accent", - "-a", - type=str, - default="mauve", - nargs='+', - dest="accents", - choices=[ - "rosewater", - "flamingo", - "pink", - "mauve", - "red", - "maroon", - "peach", - "yellow", - "green", - "teal", - "sky", - "sapphire", - "blue", - "lavender", - ], - help="Accent of the theme.", - ) - - parser.add_argument( - "--all-accents", - help="Whether to build all accents", - dest="all_accents", - action="store_true", - ) - - parser.add_argument( - "--size", - "-s", - type=str, - default="standard", - dest="size", - choices=["standard", "compact"], - help="Size variant of the theme.", - ) - - parser.add_argument( - "--tweaks", - type=str, - default=[], - nargs="+", - dest="tweaks", - choices=["black", "rimless", "normal", "float"], - help="Tweaks to apply to the build.", - ) - - parser.add_argument( - "--zip", - help="Whether to bundle the theme into a zip", - type=bool, - default=False, - action=argparse.BooleanOptionalAction, - ) - - parser.add_argument( - "--patch", - help="Whether to patch the colloid submodule", - type=bool, - default=True, - action=argparse.BooleanOptionalAction, - ) - - return parser.parse_args() - - -def build(git_root: str): - args = parse_args() - - colloid_dir = f"{git_root}/colloid" - colloid_tmp_dir = f"{git_root}/colloid-tmp-{args.flavor}" - - copy_dir(colloid_dir, colloid_tmp_dir) - - src_dir = colloid_tmp_dir + "/src" - - if args.patch: - apply_colloid_patches(colloid_tmp_dir) - - if args.zip: - output_format = "zip" - else: - output_format = "dir" - - tweaks = Tweaks(tweaks=args.tweaks) - palette = getattr(PALETTE, args.flavor) - - accents = args.accents - if args.all_accents: - accents = [ - "rosewater", - "flamingo", - "pink", - "mauve", - "red", - "maroon", - "peach", - "yellow", - "green", - "teal", - "sky", - "sapphire", - "blue", - "lavender", - ] - - for accent in accents: - accent = getattr(palette.colors, accent) - - tweaks = Tweaks(tweaks=args.tweaks) - - if args.zip: - output_format = "zip" - else: - output_format = "dir" - ctx = BuildContext( - output_root=args.dest, - colloid_src_dir=src_dir, - theme_name=args.name, - flavor=palette, - accent=accent, - size=args.size, - tweaks=tweaks, - output_format=output_format, - ) - - logger.info("Building temp tweaks file") - init_tweaks_temp(src_dir) - logger.info("Inserting gnome-shell imports") - gnome_shell_version(src_dir) - logger.info("Building main theme") - build_theme(ctx) - logger.info(f"Completed {palette.identifier} with {accent.identifier}") - - shutil.rmtree(colloid_tmp_dir) - logger.info("Done!") - - -if __name__ == "__main__": - try: - build() - except Exception as e: - logger.error("Something went wrong when building the theme:", exc_info=e) From 313462e36642c1f9ddc444316d03c11523ce316d Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sat, 25 May 2024 13:42:55 +0100 Subject: [PATCH 07/31] refactor: rework text substitution --- build.py | 4 +- scripts/context.py | 16 +++--- scripts/theme.py | 120 ++++++++++++++++++++++++++++++--------------- scripts/utils.py | 17 ++++--- 4 files changed, 102 insertions(+), 55 deletions(-) diff --git a/build.py b/build.py index 7465b08f..73c4cf2e 100755 --- a/build.py +++ b/build.py @@ -7,7 +7,7 @@ from scripts.patches import apply_colloid_patches from scripts.theme import build_theme, gnome_shell_version -from scripts.utils import init_tweaks_temp, copy_dir +from scripts.utils import init_tweaks_temp from scripts.context import Tweaks, BuildContext from scripts.logger import logger from catppuccin import PALETTE @@ -118,7 +118,7 @@ def build(): colloid_dir = f"{git_root}/colloid" colloid_tmp_dir = f"{git_root}/colloid-tmp-{args.flavor}" - copy_dir(colloid_dir, colloid_tmp_dir) + shutil.copytree(colloid_dir, colloid_tmp_dir) src_dir = colloid_tmp_dir + "/src" diff --git a/scripts/context.py b/scripts/context.py index 5a1ac779..99d0433c 100644 --- a/scripts/context.py +++ b/scripts/context.py @@ -1,7 +1,7 @@ from dataclasses import dataclass from typing import Any, Literal, List from catppuccin.models import Flavor, Color -from .utils import subst_text +from .utils import find_and_replace, Subsitution @dataclass class Tweaks: @@ -20,7 +20,6 @@ class Suffix: test: Any false_value: str = "" - @dataclass class BuildContext: # The src dir of the Colloid copy to operate on @@ -53,12 +52,17 @@ def apply_suffix(self, suffix: Suffix) -> str: return suffix.false_value def apply_tweak(self, key, default, value): - subst_text( - f"{self.colloid_src_dir}/sass/_tweaks-temp.scss", f"\\${key}: {default}", f"${key}: {value}" + find_and_replace( + f"{self.colloid_src_dir}/sass/_tweaks-temp.scss", + Subsitution(find=f"\\${key}: {default}", replace=f"${key}: {value}"), ) IS_DARK = Suffix(true_value="-Dark", test=lambda ctx: ctx.flavor.dark) IS_LIGHT = Suffix(true_value="-Light", test=lambda ctx: not ctx.flavor.dark) -IS_WINDOW_NORMAL = Suffix(true_value="-Normal", test=lambda ctx: ctx.tweaks.has('normal')) -DARK_LIGHT = Suffix(true_value="-Dark", false_value="-Light", test=lambda ctx: ctx.flavor.dark) +IS_WINDOW_NORMAL = Suffix( + true_value="-Normal", test=lambda ctx: ctx.tweaks.has("normal") +) +DARK_LIGHT = Suffix( + true_value="-Dark", false_value="-Light", test=lambda ctx: ctx.flavor.dark +) diff --git a/scripts/theme.py b/scripts/theme.py index 64319f5a..2b2e709a 100644 --- a/scripts/theme.py +++ b/scripts/theme.py @@ -4,19 +4,22 @@ import glob import zipfile from .logger import logger -from .utils import subst_text +from .utils import find_and_replace, Subsitution from .context import BuildContext, IS_DARK, IS_LIGHT, IS_WINDOW_NORMAL, DARK_LIGHT + def apply_tweaks(ctx: BuildContext, src_dir): ctx.apply_tweak("theme", "'default'", f"'{ctx.accent.identifier}'") if ctx.size == "compact": ctx.apply_tweak("compact", "'false'", "'true'") - subst_text( + find_and_replace( f"{src_dir}/sass/_tweaks-temp.scss", - "@import 'color-palette-default';", - f"@import 'color-palette-catppuccin-{ctx.flavor.identifier}';", + Subsitution( + find="@import 'color-palette-default';", + replace=f"@import 'color-palette-catppuccin-{ctx.flavor.identifier}';", + ), ) ctx.apply_tweak("colorscheme", "'default'", "'catppuccin'") @@ -34,6 +37,8 @@ def apply_tweaks(ctx: BuildContext, src_dir): SASSC_OPT = ["-M", "-t", "expanded"] + + def compile_sass(src: str, dest: str) -> subprocess.Popen: return subprocess.Popen(["sassc", *SASSC_OPT, src, dest]) @@ -130,15 +135,20 @@ def build(ctx: BuildContext, src_dir): f"{src_dir}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", f"{output_dir}-hdpi/xfwm4/themerc", ) - subst_text(f"{output_dir}-hdpi/xfwm4/themerc", "button_offset=6", "button_offset=9") + find_and_replace( + f"{output_dir}-hdpi/xfwm4/themerc", + Subsitution(find="button_offset=6", replace="button_offset=9"), + ) os.makedirs(f"{output_dir}-xhdpi/xfwm4", exist_ok=True) shutil.copyfile( f"{src_dir}/main/xfwm4/themerc{ctx.apply_suffix(IS_LIGHT)}", f"{output_dir}-xhdpi/xfwm4/themerc", ) - subst_text( - f"{output_dir}-xhdpi/xfwm4/themerc", "button_offset=6", "button_offset=12" + + find_and_replace( + f"{output_dir}-xhdpi/xfwm4/themerc", + Subsitution(find="button_offset=6", replace="button_offset=12"), ) if not ctx.flavor.dark: @@ -198,46 +208,76 @@ def make_assets(ctx: BuildContext): titlebar = palette.overlay0.hex for file in glob.glob(f"{output_dir}/cinnamon/assets/*.svg"): - subst_text(file, "#5b9bf8", theme_color) - subst_text(file, "#3c84f7", theme_color) + find_and_replace( + file, + Subsitution(find="#5b9bf8", replace=theme_color), + Subsitution(find="#3c84f7", replace=theme_color), + ) for file in glob.glob(f"{output_dir}/gnome-shell/assets/*.svg"): - subst_text(file, "#5b9bf8", theme_color) - subst_text(file, "#3c84f7", theme_color) + find_and_replace( + file, + Subsitution(find="#5b9bf8", replace=theme_color), + Subsitution(find="#3c84f7", replace=theme_color), + ) for file in glob.glob(f"{output_dir}/gtk-3.0/assets/*.svg"): - subst_text(file, "#5b9bf8", theme_color) - subst_text(file, "#3c84f7", theme_color) - subst_text(file, "#ffffff", background) - subst_text(file, "#2c2c2c", background) - subst_text(file, "#3c3c3c", background_alt) + find_and_replace( + file, + Subsitution(find="#5b9bf8", replace=theme_color), + Subsitution(find="#3c84f7", replace=theme_color), + Subsitution(find="#ffffff", replace=background), + Subsitution(find="#2c2c2c", replace=background), + Subsitution(find="#3c3c3c", replace=background_alt), + ) for file in glob.glob(f"{output_dir}/gtk-4.0/assets/*.svg"): - subst_text(file, "#5b9bf8", theme_color) - subst_text(file, "#3c84f7", theme_color) - subst_text(file, "#ffffff", background) - subst_text(file, "#2c2c2c", background) - subst_text(file, "#3c3c3c", background_alt) + find_and_replace( + file, + Subsitution(find="#5b9bf8", replace=theme_color), + Subsitution(find="#3c84f7", replace=theme_color), + Subsitution(find="#ffffff", replace=background), + Subsitution(find="#2c2c2c", replace=background), + Subsitution(find="#3c3c3c", replace=background_alt), + ) if ctx.flavor.dark: - subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#2c2c2c", background) - subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#5b9bf8", theme_color) + find_and_replace( + f"{output_dir}/cinnamon/thumbnail.png", + Subsitution(find="#2c2c2c", replace=background), + Subsitution(find="#5b9bf8", replace=theme_color), + ) - subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#2c2c2c", background) - subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#2c2c2c", background) + find_and_replace( + f"{output_dir}/gtk-3.0/thumbnail.png", + Subsitution(find="#5b9bf8", replace=theme_color), + Subsitution(find="#2c2c2c", replace=background), + ) - subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#5b9bf8", theme_color) - subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#5b9bf8", theme_color) + find_and_replace( + f"{output_dir}/gtk-4.0/thumbnail.png", + Subsitution(find="#5b9bf8", replace=theme_color), + Subsitution(find="#2c2c2c", replace=background), + ) else: - subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#ffffff", background) - subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#f2f2f2", titlebar) - subst_text(f"{output_dir}/cinnamon/thumbnail.png", "#3c84f7", theme_color) + find_and_replace( + f"{output_dir}/cinnamon/thumbnail.png", + Subsitution(find="#ffffff", replace=background), + Subsitution(find="#f2f2f2", replace=titlebar), + Subsitution(find="#3c84f7", replace=theme_color), + ) - subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#f2f2f2", titlebar) - subst_text(f"{output_dir}/gtk-3.0/thumbnail.png", "#3c84f7", theme_color) + find_and_replace( + f"{output_dir}/gtk-3.0/thumbnail.png", + Subsitution(find="#f2f2f2", replace=titlebar), + Subsitution(find="#3c84f7", replace=theme_color), + ) - subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#f2f2f2", titlebar) - subst_text(f"{output_dir}/gtk-4.0/thumbnail.png", "#3c84f7", theme_color) + find_and_replace( + f"{output_dir}/gtk-4.0/thumbnail.png", + Subsitution(find="#f2f2f2", replace=titlebar), + Subsitution(find="#3c84f7", replace=theme_color), + ) for file in glob.glob(f"{src_dir}/assets/cinnamon/common-assets/*.svg"): shutil.copy(file, f"{output_dir}/cinnamon/assets") @@ -268,9 +308,7 @@ def make_assets(ctx: BuildContext): f"{output_dir}/metacity-1/thumbnail.png", ) - xfwm4_assets = ( - f"{ctx.git_root}/patches/xfwm4/generated/assets-catppuccin-{ctx.flavor.identifier}" - ) + xfwm4_assets = f"{ctx.git_root}/patches/xfwm4/generated/assets-catppuccin-{ctx.flavor.identifier}" for file in glob.glob(xfwm4_assets + "/*"): shutil.copy(file, f"{output_dir}/xfwm4") @@ -341,8 +379,10 @@ def gnome_shell_version(src_dir): f"{src_dir}/sass/gnome-shell/_common.scss", f"{src_dir}/sass/gnome-shell/_common-temp.scss", ) - subst_text( + find_and_replace( f"{src_dir}/sass/gnome-shell/_common-temp.scss", - "@import 'widgets-40-0';", - f"@import 'widgets-{gs_version}';", + Subsitution( + find="@import 'widgets-40-0';", + replace=f"@import 'widgets-{gs_version}';", + ), ) diff --git a/scripts/utils.py b/scripts/utils.py index 91ebc6e8..9cc04cf4 100644 --- a/scripts/utils.py +++ b/scripts/utils.py @@ -1,18 +1,21 @@ import re import shutil +from dataclasses import dataclass +from typing import List +@dataclass +class Subsitution: + find: str + replace: str -def copy_dir(_from, to): - shutil.copytree(_from, to) - - -def subst_text(path, _from, to): +def find_and_replace(path: str, *subs: Subsitution): with open(path, "r+") as f: content = f.read() f.seek(0) f.truncate() - f.write(re.sub(_from, to, content)) - + for sub in subs: + content = re.sub(sub.find, sub.replace, content) + f.write(content) def translate_accent(ctp_accent): ctp_to_colloid = { From 97a567d5296de934b7ac8501a445e2cc26092614 Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sat, 25 May 2024 14:30:30 +0100 Subject: [PATCH 08/31] ci: update workflows --- .github/workflows/build.yml | 8 ++++---- .github/workflows/release.yml | 16 +++++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8d31625f..22a79c07 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,10 +29,10 @@ jobs: run: | python patches/xfwm4/generate_assets.py - python ./main.py mocha --all-accents --zip -d $PWD/releases & - python ./main.py macchiato --all-accents --zip -d $PWD/releases & - python ./main.py frappe --all-accents --zip -d $PWD/releases & - python ./main.py latte --all-accents --zip -d $PWD/releases & + python ./build.py mocha --all-accents --zip -d $PWD/releases & + python ./build.py macchiato --all-accents --zip -d $PWD/releases & + python ./build.py frappe --all-accents --zip -d $PWD/releases & + python ./build.py latte --all-accents --zip -d $PWD/releases & wait - name: Upload artifacts diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d5504faa..3023d784 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,22 +28,28 @@ jobs: uses: actions/checkout@v4 with: submodules: true + - uses: actions/setup-python@v5 with: python-version: "3.11" cache: "pip" + - name: Install dependencies run: pip install -r requirements.txt + - name: Install colloid specific dependencies run: sudo apt update && sudo apt install -y sassc inkscape optipng + - name: Generate themes run: | python patches/xfwm4/generate_assets.py - - python ./build.py mocha --all-accents --zip -d $PWD/releases && - python ./build.py macchiato --all-accents --zip -d $PWD/releases && - python ./build.py frappe --all-accents --zip -d $PWD/releases && - python ./build.py latte --all-accents --zip -d $PWD/releases + + python ./build.py mocha --all-accents --zip -d $PWD/releases & + python ./build.py macchiato --all-accents --zip -d $PWD/releases & + python ./build.py frappe --all-accents --zip -d $PWD/releases & + python ./build.py latte --all-accents --zip -d $PWD/releases & + wait + - name: Add zips to release run: gh release upload ${{ needs.release-please.outputs.tag_name }} releases/*.zip env: From effd47b36eb9097689a555f1061db096db27982f Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sat, 25 May 2024 14:42:31 +0100 Subject: [PATCH 09/31] ci: organise logs --- .github/workflows/build.yml | 12 +++++++----- .github/workflows/release.yml | 10 ++++++---- .gitignore | 1 + 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 22a79c07..836c3c41 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -29,14 +29,16 @@ jobs: run: | python patches/xfwm4/generate_assets.py - python ./build.py mocha --all-accents --zip -d $PWD/releases & - python ./build.py macchiato --all-accents --zip -d $PWD/releases & - python ./build.py frappe --all-accents --zip -d $PWD/releases & - python ./build.py latte --all-accents --zip -d $PWD/releases & + python ./build.py mocha --all-accents --zip -d $PWD/releases > mocha.log 2>&1 & + python ./build.py macchiato --all-accents --zip -d $PWD/releases > macchiato.log 2>&1 & + python ./build.py frappe --all-accents --zip -d $PWD/releases > frappe.log 2>&1 & + python ./build.py latte --all-accents --zip -d $PWD/releases > latte.log 2>&1 & wait + cat *.log + - name: Upload artifacts uses: actions/upload-artifact@v4 with: name: '${{ github.sha }}-artifacts' - path: ./releases/*.zip + path: ./releases/*.zip \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3023d784..69372f1e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -44,12 +44,14 @@ jobs: run: | python patches/xfwm4/generate_assets.py - python ./build.py mocha --all-accents --zip -d $PWD/releases & - python ./build.py macchiato --all-accents --zip -d $PWD/releases & - python ./build.py frappe --all-accents --zip -d $PWD/releases & - python ./build.py latte --all-accents --zip -d $PWD/releases & + python ./build.py mocha --all-accents --zip -d $PWD/releases > mocha.log 2>&1 & + python ./build.py macchiato --all-accents --zip -d $PWD/releases > macchiato.log 2>&1 & + python ./build.py frappe --all-accents --zip -d $PWD/releases > frappe.log 2>&1 & + python ./build.py latte --all-accents --zip -d $PWD/releases > latte.log 2>&1 & wait + cat *.log + - name: Add zips to release run: gh release upload ${{ needs.release-please.outputs.tag_name }} releases/*.zip env: diff --git a/.gitignore b/.gitignore index cb11597c..e645bbb0 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ lib*/ *.cfg .direnv build/ +*.log # Releases folder releases From 4ddb572d6be7a0bc041004b91cff3684016f162e Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sat, 25 May 2024 14:52:33 +0100 Subject: [PATCH 10/31] refactor: clean up entrypoints --- build.py | 184 +------------------------------------------- scripts/__init__.py | 82 ++++++++++++++++++++ scripts/args.py | 99 ++++++++++++++++++++++++ 3 files changed, 185 insertions(+), 180 deletions(-) create mode 100644 scripts/args.py diff --git a/build.py b/build.py index 73c4cf2e..cc1379f1 100755 --- a/build.py +++ b/build.py @@ -1,195 +1,19 @@ import os import sys -import argparse -import shutil import time import os -from scripts.patches import apply_colloid_patches -from scripts.theme import build_theme, gnome_shell_version -from scripts.utils import init_tweaks_temp -from scripts.context import Tweaks, BuildContext +from scripts import build +from scripts.args import parse_args from scripts.logger import logger -from catppuccin import PALETTE -def parse_args(): - parser = argparse.ArgumentParser() - parser.add_argument( - "flavor", - type=str, - choices=["mocha", "frappe", "macchiato", "latte"], - help="Flavor of the theme to apply.", - ) - - parser.add_argument( - "--name", - "-n", - type=str, - default="catppuccin", - dest="name", - help="Name of the theme to apply.", - ) - - parser.add_argument( - "--dest", - "-d", - type=str, - required=True, - dest="dest", - help="Destination of the files.", - ) - - parser.add_argument( - "--accent", - "-a", - type=str, - default="mauve", - nargs='+', - dest="accents", - choices=[ - "rosewater", - "flamingo", - "pink", - "mauve", - "red", - "maroon", - "peach", - "yellow", - "green", - "teal", - "sky", - "sapphire", - "blue", - "lavender", - ], - help="Accent of the theme.", - ) - - parser.add_argument( - "--all-accents", - help="Whether to build all accents", - dest="all_accents", - action="store_true", - ) - - parser.add_argument( - "--size", - "-s", - type=str, - default="standard", - dest="size", - choices=["standard", "compact"], - help="Size variant of the theme.", - ) - - parser.add_argument( - "--tweaks", - type=str, - default=[], - nargs="+", - dest="tweaks", - choices=["black", "rimless", "normal", "float"], - help="Tweaks to apply to the build.", - ) - - parser.add_argument( - "--zip", - help="Whether to bundle the theme into a zip", - type=bool, - default=False, - action=argparse.BooleanOptionalAction, - ) - - parser.add_argument( - "--patch", - help="Whether to patch the colloid submodule", - type=bool, - default=True, - action=argparse.BooleanOptionalAction, - ) - - return parser.parse_args() - - -def build(): +if __name__ == "__main__": git_root = os.path.dirname(os.path.realpath(__file__)) args = parse_args() - colloid_dir = f"{git_root}/colloid" - colloid_tmp_dir = f"{git_root}/colloid-tmp-{args.flavor}" - - shutil.copytree(colloid_dir, colloid_tmp_dir) - - src_dir = colloid_tmp_dir + "/src" - - if args.patch: - apply_colloid_patches(colloid_tmp_dir) - - if args.zip: - output_format = "zip" - else: - output_format = "dir" - - tweaks = Tweaks(tweaks=args.tweaks) - palette = getattr(PALETTE, args.flavor) - - accents = args.accents - if args.all_accents: - accents = [ - "rosewater", - "flamingo", - "pink", - "mauve", - "red", - "maroon", - "peach", - "yellow", - "green", - "teal", - "sky", - "sapphire", - "blue", - "lavender", - ] - - for accent in accents: - accent = getattr(palette.colors, accent) - - tweaks = Tweaks(tweaks=args.tweaks) - - if args.zip: - output_format = "zip" - else: - output_format = "dir" - - ctx = BuildContext( - output_root=args.dest, - colloid_src_dir=src_dir, - git_root=git_root, - theme_name=args.name, - flavor=palette, - accent=accent, - size=args.size, - tweaks=tweaks, - output_format=output_format, - ) - - logger.info("Building temp tweaks file") - init_tweaks_temp(src_dir) - logger.info("Inserting gnome-shell imports") - gnome_shell_version(src_dir) - logger.info("Building main theme") - build_theme(ctx) - logger.info(f"Completed {palette.identifier} with {accent.identifier}") - print() - - shutil.rmtree(colloid_tmp_dir) - logger.info("Done!") - -if __name__ == "__main__": try: start = time.time() - build() + build(git_root, args) end = time.time() - start logger.info('') diff --git a/scripts/__init__.py b/scripts/__init__.py index e69de29b..56333c0f 100644 --- a/scripts/__init__.py +++ b/scripts/__init__.py @@ -0,0 +1,82 @@ +from argparse import Namespace +import shutil + +from .patches import apply_colloid_patches +from .theme import build_theme, gnome_shell_version +from .utils import init_tweaks_temp +from .context import Tweaks, BuildContext +from .logger import logger +from catppuccin import PALETTE + + +def build(git_root: str, args: Namespace): + colloid_dir = f"{git_root}/colloid" + colloid_tmp_dir = f"{git_root}/colloid-tmp-{args.flavor}" + + shutil.copytree(colloid_dir, colloid_tmp_dir) + + src_dir = colloid_tmp_dir + "/src" + + if args.patch: + apply_colloid_patches(colloid_tmp_dir) + + if args.zip: + output_format = "zip" + else: + output_format = "dir" + + tweaks = Tweaks(tweaks=args.tweaks) + palette = getattr(PALETTE, args.flavor) + + accents = args.accents + if args.all_accents: + accents = [ + "rosewater", + "flamingo", + "pink", + "mauve", + "red", + "maroon", + "peach", + "yellow", + "green", + "teal", + "sky", + "sapphire", + "blue", + "lavender", + ] + + for accent in accents: + accent = getattr(palette.colors, accent) + + tweaks = Tweaks(tweaks=args.tweaks) + + if args.zip: + output_format = "zip" + else: + output_format = "dir" + + ctx = BuildContext( + output_root=args.dest, + colloid_src_dir=src_dir, + git_root=git_root, + theme_name=args.name, + flavor=palette, + accent=accent, + size=args.size, + tweaks=tweaks, + output_format=output_format, + ) + + logger.info("Building temp tweaks file") + init_tweaks_temp(src_dir) + logger.info("Inserting gnome-shell imports") + gnome_shell_version(src_dir) + logger.info("Building main theme") + build_theme(ctx) + logger.info(f"Completed {palette.identifier} with {accent.identifier}") + print() + + shutil.rmtree(colloid_tmp_dir) + logger.info("Done!") diff --git a/scripts/args.py b/scripts/args.py new file mode 100644 index 00000000..46b5f940 --- /dev/null +++ b/scripts/args.py @@ -0,0 +1,99 @@ +import argparse + +def parse_args(): + parser = argparse.ArgumentParser() + parser.add_argument( + "flavor", + type=str, + choices=["mocha", "frappe", "macchiato", "latte"], + help="Flavor of the theme to apply.", + ) + + parser.add_argument( + "--name", + "-n", + type=str, + default="catppuccin", + dest="name", + help="Name of the theme to apply.", + ) + + parser.add_argument( + "--dest", + "-d", + type=str, + required=True, + dest="dest", + help="Destination of the files.", + ) + + parser.add_argument( + "--accent", + "-a", + type=str, + default="mauve", + nargs="+", + dest="accents", + choices=[ + "rosewater", + "flamingo", + "pink", + "mauve", + "red", + "maroon", + "peach", + "yellow", + "green", + "teal", + "sky", + "sapphire", + "blue", + "lavender", + ], + help="Accent of the theme.", + ) + + parser.add_argument( + "--all-accents", + help="Whether to build all accents", + dest="all_accents", + action="store_true", + ) + + parser.add_argument( + "--size", + "-s", + type=str, + default="standard", + dest="size", + choices=["standard", "compact"], + help="Size variant of the theme.", + ) + + parser.add_argument( + "--tweaks", + type=str, + default=[], + nargs="+", + dest="tweaks", + choices=["black", "rimless", "normal", "float"], + help="Tweaks to apply to the build.", + ) + + parser.add_argument( + "--zip", + help="Whether to bundle the theme into a zip", + type=bool, + default=False, + action=argparse.BooleanOptionalAction, + ) + + parser.add_argument( + "--patch", + help="Whether to patch the colloid submodule", + type=bool, + default=True, + action=argparse.BooleanOptionalAction, + ) + + return parser.parse_args() From c48ba5704e6ece633e5fd5eb30dd531a54c089a8 Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sat, 25 May 2024 15:00:45 +0100 Subject: [PATCH 11/31] style: fmt/fix with ruff; remove sketchy path manipulation --- .gitignore | 1 + build.py | 4 ++-- install.py | 10 ++++++++-- patches/xfwm4/generate_assets.py | 19 +++++++++++-------- scripts/__init__.py | 3 +++ scripts/args.py | 1 + scripts/context.py | 2 ++ scripts/patches.py | 2 +- scripts/utils.py | 24 +++--------------------- shell.nix | 1 + 10 files changed, 33 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index e645bbb0..3a16e708 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ lib*/ .direnv build/ *.log +.ruff-cache # Releases folder releases diff --git a/build.py b/build.py index cc1379f1..e464a2b5 100755 --- a/build.py +++ b/build.py @@ -16,7 +16,7 @@ build(git_root, args) end = time.time() - start - logger.info('') - logger.info(f'Built in {round(end, 3)}s') + logger.info("") + logger.info(f"Built in {round(end, 3)}s") except Exception as e: logger.error("Something went wrong when building the theme:", exc_info=e) diff --git a/install.py b/install.py index d642cd33..27be5640 100644 --- a/install.py +++ b/install.py @@ -1,11 +1,15 @@ #!/usr/bin/env python3 -import os, zipfile, argparse, logging, io +import os +import zipfile +import argparse +import logging +import io + from typing import Optional from pathlib import Path from dataclasses import dataclass from urllib.request import urlopen, Request -from urllib.parse import urlparse logger = logging.getLogger("catppuccin-gtk") logger.setLevel(logging.DEBUG) @@ -160,6 +164,7 @@ def install(ctx: InstallContext): if ctx.link: add_libadwaita_links(ctx) + def install_from_artifact(ctx: InstallContext, artifact_path: Path): # Working from a pull request, special case it logger.info(f"Extracting artifact from '{artifact_path}'") @@ -189,6 +194,7 @@ def install_from_artifact(ctx: InstallContext, artifact_path: Path): add_libadwaita_links(ctx, True) logger.info("Links added") + def main(): args = parse_args() diff --git a/patches/xfwm4/generate_assets.py b/patches/xfwm4/generate_assets.py index 82cc89a5..4aed8bf5 100644 --- a/patches/xfwm4/generate_assets.py +++ b/patches/xfwm4/generate_assets.py @@ -2,7 +2,11 @@ from catppuccin import PALETTE from catppuccin.models import Flavor -import re, os, shutil, subprocess, time +import re +import os +import shutil +import subprocess +import time from dataclasses import dataclass THIS_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -83,9 +87,9 @@ def generate_for_flavor(flavor: Flavor): # Setup the palette palette = flavor.colors - close_color=f'#{palette.red.hex}' - max_color=f'#{palette.green.hex}' - min_color=f'#{palette.yellow.hex}' + close_color = f"#{palette.red.hex}" + max_color = f"#{palette.green.hex}" + min_color = f"#{palette.yellow.hex}" # We expand the source assets into the 4 flavors, but need to map between # Their definition of dark and ours. This means that latte will get the -light assets @@ -187,8 +191,9 @@ class RenderState: "-xhdpi": "192", } + def render_for_screen(state: RenderState, flavor: Flavor, screen: str, ident: str): - # NOTE: We do not generate for the -normal variant currently, that would just be + # NOTE: We do not generate for the -normal variant currently, that would just be # a stupid amount of compute and time for little benefit src_file = f"{state.input_root}/assets-catppuccin-{flavor.identifier}.svg" @@ -215,9 +220,7 @@ def render_for_screen(state: RenderState, flavor: Flavor, screen: str, ident: st def render_for_flavor(flavor: Flavor, state: RenderState): - print( - f"Starting render tasks for {flavor.identifier}" - ) + print(f"Starting render tasks for {flavor.identifier}") for ident in INDEX: render_for_screen(state=state, flavor=flavor, screen="", ident=ident) render_for_screen(state=state, flavor=flavor, screen="-hdpi", ident=ident) diff --git a/scripts/__init__.py b/scripts/__init__.py index 56333c0f..4b18870b 100644 --- a/scripts/__init__.py +++ b/scripts/__init__.py @@ -71,10 +71,13 @@ def build(git_root: str, args: Namespace): logger.info("Building temp tweaks file") init_tweaks_temp(src_dir) + logger.info("Inserting gnome-shell imports") gnome_shell_version(src_dir) + logger.info("Building main theme") build_theme(ctx) + logger.info(f"Completed {palette.identifier} with {accent.identifier}") print() diff --git a/scripts/args.py b/scripts/args.py index 46b5f940..38a0a128 100644 --- a/scripts/args.py +++ b/scripts/args.py @@ -1,5 +1,6 @@ import argparse + def parse_args(): parser = argparse.ArgumentParser() parser.add_argument( diff --git a/scripts/context.py b/scripts/context.py index 99d0433c..259fcc77 100644 --- a/scripts/context.py +++ b/scripts/context.py @@ -3,6 +3,7 @@ from catppuccin.models import Flavor, Color from .utils import find_and_replace, Subsitution + @dataclass class Tweaks: tweaks: List[str] @@ -20,6 +21,7 @@ class Suffix: test: Any false_value: str = "" + @dataclass class BuildContext: # The src dir of the Colloid copy to operate on diff --git a/scripts/patches.py b/scripts/patches.py index 3cdff4cd..880ecc29 100644 --- a/scripts/patches.py +++ b/scripts/patches.py @@ -22,7 +22,7 @@ def apply_colloid_patches(colloid_dir): path = f"./patches/colloid/{patch}" logger.info(f"Applying patch '{patch}', located at '{path}'") subprocess.check_call( - ["git", "apply", path, "--directory", colloid_dir.split('/')[-1]]) + ["git", "apply", path, "--directory", os.path.basename(colloid_dir)]) with open(colloid_dir + "/.patched", "w") as f: f.write("true") diff --git a/scripts/utils.py b/scripts/utils.py index 9cc04cf4..76d78f41 100644 --- a/scripts/utils.py +++ b/scripts/utils.py @@ -1,13 +1,14 @@ import re import shutil from dataclasses import dataclass -from typing import List + @dataclass class Subsitution: find: str replace: str + def find_and_replace(path: str, *subs: Subsitution): with open(path, "r+") as f: content = f.read() @@ -17,25 +18,6 @@ def find_and_replace(path: str, *subs: Subsitution): content = re.sub(sub.find, sub.replace, content) f.write(content) -def translate_accent(ctp_accent): - ctp_to_colloid = { - "rosewater": "pink", - "flamingo": "pink", - "pink": "pink", - "mauve": "purple", - "red": "red", - "maroon": "red", - "peach": "orange", - "yellow": "yellow", - "green": "green", - "teal": "teal", - "sky": "teal", - "sapphire": "default", - "blue": "default", - "lavender": "default", - } - return ctp_to_colloid[ctp_accent.identifier] - def init_tweaks_temp(src_dir): - shutil.copyfile(f"{src_dir}/sass/_tweaks.scss", f"{src_dir}/sass/_tweaks-temp.scss") \ No newline at end of file + shutil.copyfile(f"{src_dir}/sass/_tweaks.scss", f"{src_dir}/sass/_tweaks-temp.scss") diff --git a/shell.nix b/shell.nix index 7305ad6d..7e3c743f 100644 --- a/shell.nix +++ b/shell.nix @@ -9,5 +9,6 @@ pkgs.mkShell { sassc inkscape optipng + ruff ]; } From 69e8889e1cbcd19f3c10247ce7301d127d077cac Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sat, 25 May 2024 17:39:03 +0100 Subject: [PATCH 12/31] refactor: rename sources --- .gitignore | 2 +- .gitmodules | 2 +- build.py | 8 ++++---- {scripts => sources/build}/__init__.py | 6 +++--- {scripts => sources/build}/args.py | 0 {scripts => sources/build}/context.py | 0 {scripts => sources/build}/logger.py | 0 {scripts => sources/build}/patches.py | 0 {scripts => sources/build}/theme.py | 15 ++++++++------- {scripts => sources/build}/utils.py | 0 colloid => sources/colloid | 0 {patches => sources/patches}/colloid/palette.tera | 0 .../patches}/colloid/plank-dark.patch | 0 .../patches}/colloid/plank-light.patch | 0 .../patches}/colloid/sass-palette-frappe.patch | 0 .../patches}/colloid/sass-palette-latte.patch | 0 .../patches}/colloid/sass-palette-macchiato.patch | 0 .../patches}/colloid/sass-palette-mocha.patch | 0 .../patches}/colloid/theme-func.patch | 0 {patches => sources/patches}/xfwm4/.gitignore | 0 .../patches}/xfwm4/assets-dark-normal.svg | 0 .../patches}/xfwm4/assets-dark.svg | 0 .../patches}/xfwm4/assets-light-normal.svg | 0 .../patches}/xfwm4/assets-light.svg | 0 .../patches}/xfwm4/generate_assets.py | 0 25 files changed, 17 insertions(+), 16 deletions(-) rename {scripts => sources/build}/__init__.py (93%) rename {scripts => sources/build}/args.py (100%) rename {scripts => sources/build}/context.py (100%) rename {scripts => sources/build}/logger.py (100%) rename {scripts => sources/build}/patches.py (100%) rename {scripts => sources/build}/theme.py (98%) rename {scripts => sources/build}/utils.py (100%) rename colloid => sources/colloid (100%) rename {patches => sources/patches}/colloid/palette.tera (100%) rename {patches => sources/patches}/colloid/plank-dark.patch (100%) rename {patches => sources/patches}/colloid/plank-light.patch (100%) rename {patches => sources/patches}/colloid/sass-palette-frappe.patch (100%) rename {patches => sources/patches}/colloid/sass-palette-latte.patch (100%) rename {patches => sources/patches}/colloid/sass-palette-macchiato.patch (100%) rename {patches => sources/patches}/colloid/sass-palette-mocha.patch (100%) rename {patches => sources/patches}/colloid/theme-func.patch (100%) rename {patches => sources/patches}/xfwm4/.gitignore (100%) rename {patches => sources/patches}/xfwm4/assets-dark-normal.svg (100%) rename {patches => sources/patches}/xfwm4/assets-dark.svg (100%) rename {patches => sources/patches}/xfwm4/assets-light-normal.svg (100%) rename {patches => sources/patches}/xfwm4/assets-light.svg (100%) rename {patches => sources/patches}/xfwm4/generate_assets.py (100%) diff --git a/.gitignore b/.gitignore index 3a16e708..3b5286ff 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ bin/ lib*/ *.cfg .direnv -build/ +./build/ *.log .ruff-cache diff --git a/.gitmodules b/.gitmodules index 02412092..e92575fa 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "colloid"] - path = colloid + path = sources/colloid url = https://github.com/vinceliuice/Colloid-gtk-theme.git diff --git a/build.py b/build.py index e464a2b5..3f16be70 100755 --- a/build.py +++ b/build.py @@ -3,9 +3,9 @@ import time import os -from scripts import build -from scripts.args import parse_args -from scripts.logger import logger +from sources.build import execute_build +from sources.build.args import parse_args +from sources.build.logger import logger if __name__ == "__main__": git_root = os.path.dirname(os.path.realpath(__file__)) @@ -13,7 +13,7 @@ try: start = time.time() - build(git_root, args) + execute_build(git_root, args) end = time.time() - start logger.info("") diff --git a/scripts/__init__.py b/sources/build/__init__.py similarity index 93% rename from scripts/__init__.py rename to sources/build/__init__.py index 4b18870b..86e16384 100644 --- a/scripts/__init__.py +++ b/sources/build/__init__.py @@ -2,14 +2,14 @@ import shutil from .patches import apply_colloid_patches -from .theme import build_theme, gnome_shell_version +from .theme import build_with_context, gnome_shell_version from .utils import init_tweaks_temp from .context import Tweaks, BuildContext from .logger import logger from catppuccin import PALETTE -def build(git_root: str, args: Namespace): +def execute_build(git_root: str, args: Namespace): colloid_dir = f"{git_root}/colloid" colloid_tmp_dir = f"{git_root}/colloid-tmp-{args.flavor}" @@ -76,7 +76,7 @@ def build(git_root: str, args: Namespace): gnome_shell_version(src_dir) logger.info("Building main theme") - build_theme(ctx) + build_with_context(ctx) logger.info(f"Completed {palette.identifier} with {accent.identifier}") print() diff --git a/scripts/args.py b/sources/build/args.py similarity index 100% rename from scripts/args.py rename to sources/build/args.py diff --git a/scripts/context.py b/sources/build/context.py similarity index 100% rename from scripts/context.py rename to sources/build/context.py diff --git a/scripts/logger.py b/sources/build/logger.py similarity index 100% rename from scripts/logger.py rename to sources/build/logger.py diff --git a/scripts/patches.py b/sources/build/patches.py similarity index 100% rename from scripts/patches.py rename to sources/build/patches.py diff --git a/scripts/theme.py b/sources/build/theme.py similarity index 98% rename from scripts/theme.py rename to sources/build/theme.py index 2b2e709a..eecd1db8 100644 --- a/scripts/theme.py +++ b/sources/build/theme.py @@ -8,14 +8,14 @@ from .context import BuildContext, IS_DARK, IS_LIGHT, IS_WINDOW_NORMAL, DARK_LIGHT -def apply_tweaks(ctx: BuildContext, src_dir): +def apply_tweaks(ctx: BuildContext): ctx.apply_tweak("theme", "'default'", f"'{ctx.accent.identifier}'") if ctx.size == "compact": ctx.apply_tweak("compact", "'false'", "'true'") find_and_replace( - f"{src_dir}/sass/_tweaks-temp.scss", + f"{ctx.src_dir}/sass/_tweaks-temp.scss", Subsitution( find="@import 'color-palette-default';", replace=f"@import 'color-palette-catppuccin-{ctx.flavor.identifier}';", @@ -43,11 +43,13 @@ def compile_sass(src: str, dest: str) -> subprocess.Popen: return subprocess.Popen(["sassc", *SASSC_OPT, src, dest]) -def build(ctx: BuildContext, src_dir): +def execute_build(ctx: BuildContext): + src_dir = ctx.colloid_src_dir output_dir = ctx.output_dir() + logger.info(f"Building into '{output_dir}'...") - apply_tweaks(ctx, src_dir) + apply_tweaks(ctx) os.makedirs(output_dir, exist_ok=True) with open(f"{output_dir}/index.theme", "w") as file: @@ -340,8 +342,7 @@ def zip_artifacts(dir_list, zip_name, remove=True): shutil.rmtree(dir) -def build_theme(ctx: BuildContext): - src_dir = ctx.colloid_src_dir +def build_with_context(ctx: BuildContext): build_info = f"""Build info: build_root: {ctx.output_root} theme_name: {ctx.theme_name} @@ -351,7 +352,7 @@ def build_theme(ctx: BuildContext): tweaks: {ctx.tweaks}""" logger.info(build_info) - build(ctx, src_dir) + execute_build(ctx) logger.info("Main build complete") logger.info("Bundling assets...") diff --git a/scripts/utils.py b/sources/build/utils.py similarity index 100% rename from scripts/utils.py rename to sources/build/utils.py diff --git a/colloid b/sources/colloid similarity index 100% rename from colloid rename to sources/colloid diff --git a/patches/colloid/palette.tera b/sources/patches/colloid/palette.tera similarity index 100% rename from patches/colloid/palette.tera rename to sources/patches/colloid/palette.tera diff --git a/patches/colloid/plank-dark.patch b/sources/patches/colloid/plank-dark.patch similarity index 100% rename from patches/colloid/plank-dark.patch rename to sources/patches/colloid/plank-dark.patch diff --git a/patches/colloid/plank-light.patch b/sources/patches/colloid/plank-light.patch similarity index 100% rename from patches/colloid/plank-light.patch rename to sources/patches/colloid/plank-light.patch diff --git a/patches/colloid/sass-palette-frappe.patch b/sources/patches/colloid/sass-palette-frappe.patch similarity index 100% rename from patches/colloid/sass-palette-frappe.patch rename to sources/patches/colloid/sass-palette-frappe.patch diff --git a/patches/colloid/sass-palette-latte.patch b/sources/patches/colloid/sass-palette-latte.patch similarity index 100% rename from patches/colloid/sass-palette-latte.patch rename to sources/patches/colloid/sass-palette-latte.patch diff --git a/patches/colloid/sass-palette-macchiato.patch b/sources/patches/colloid/sass-palette-macchiato.patch similarity index 100% rename from patches/colloid/sass-palette-macchiato.patch rename to sources/patches/colloid/sass-palette-macchiato.patch diff --git a/patches/colloid/sass-palette-mocha.patch b/sources/patches/colloid/sass-palette-mocha.patch similarity index 100% rename from patches/colloid/sass-palette-mocha.patch rename to sources/patches/colloid/sass-palette-mocha.patch diff --git a/patches/colloid/theme-func.patch b/sources/patches/colloid/theme-func.patch similarity index 100% rename from patches/colloid/theme-func.patch rename to sources/patches/colloid/theme-func.patch diff --git a/patches/xfwm4/.gitignore b/sources/patches/xfwm4/.gitignore similarity index 100% rename from patches/xfwm4/.gitignore rename to sources/patches/xfwm4/.gitignore diff --git a/patches/xfwm4/assets-dark-normal.svg b/sources/patches/xfwm4/assets-dark-normal.svg similarity index 100% rename from patches/xfwm4/assets-dark-normal.svg rename to sources/patches/xfwm4/assets-dark-normal.svg diff --git a/patches/xfwm4/assets-dark.svg b/sources/patches/xfwm4/assets-dark.svg similarity index 100% rename from patches/xfwm4/assets-dark.svg rename to sources/patches/xfwm4/assets-dark.svg diff --git a/patches/xfwm4/assets-light-normal.svg b/sources/patches/xfwm4/assets-light-normal.svg similarity index 100% rename from patches/xfwm4/assets-light-normal.svg rename to sources/patches/xfwm4/assets-light-normal.svg diff --git a/patches/xfwm4/assets-light.svg b/sources/patches/xfwm4/assets-light.svg similarity index 100% rename from patches/xfwm4/assets-light.svg rename to sources/patches/xfwm4/assets-light.svg diff --git a/patches/xfwm4/generate_assets.py b/sources/patches/xfwm4/generate_assets.py similarity index 100% rename from patches/xfwm4/generate_assets.py rename to sources/patches/xfwm4/generate_assets.py From 6ed92bdd725fc5151af1906162a9f5733deee372 Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sat, 25 May 2024 17:52:46 +0100 Subject: [PATCH 13/31] docs: project structure --- CONTRIBUTING.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 813da838..33d9db46 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,6 +6,18 @@ Information regarding the architecture of the project can be found [in the ARCHI - All the [requirements for building](#building) - `whiskers`, optionally, from [catppuccin/toolbox](https://github.com/catppuccin/toolbox/tree/main/whiskers#installation) +### Project structure + +`sources/` contains all of the source files needed for the project to build, including the Colloid submodule. +It also contains our patches for Colloid, alongside the core build system implemented by us to replace the one from Colloid. + +`build.py` is the entrypoint to the build system, placed at the root for convenience. The plumbing this utilizes is in +`sources/build`. + +`install.py` is our officially supported install script, which will automate the process of pulling the release, extracting it, +and optionally adding symlinks for GTK-4.0 support. This script intentionally has no dependencies other than Python 3 itself. +This keeps the end user experience simple and reproducible. Do not add external dependencies to this script. + ### Patching colloid > [!TIP] > If you need to change the patches, reset the submodule and rerun the build script. From fba6c15a93db68cdc672718da2f2c400bea74d84 Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sat, 25 May 2024 17:54:24 +0100 Subject: [PATCH 14/31] ci: update paths --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 836c3c41..56ec2527 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,7 +27,7 @@ jobs: - name: Generate themes run: | - python patches/xfwm4/generate_assets.py + python sources/patches/xfwm4/generate_assets.py python ./build.py mocha --all-accents --zip -d $PWD/releases > mocha.log 2>&1 & python ./build.py macchiato --all-accents --zip -d $PWD/releases > macchiato.log 2>&1 & diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 69372f1e..48279955 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,7 +42,7 @@ jobs: - name: Generate themes run: | - python patches/xfwm4/generate_assets.py + python sources/patches/xfwm4/generate_assets.py python ./build.py mocha --all-accents --zip -d $PWD/releases > mocha.log 2>&1 & python ./build.py macchiato --all-accents --zip -d $PWD/releases > macchiato.log 2>&1 & From c4e6c98e36d2ca94441aa604ec9728260922a4d0 Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sat, 25 May 2024 17:58:57 +0100 Subject: [PATCH 15/31] fix: build path --- sources/build/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sources/build/__init__.py b/sources/build/__init__.py index 86e16384..1a7bf22f 100644 --- a/sources/build/__init__.py +++ b/sources/build/__init__.py @@ -10,8 +10,8 @@ def execute_build(git_root: str, args: Namespace): - colloid_dir = f"{git_root}/colloid" - colloid_tmp_dir = f"{git_root}/colloid-tmp-{args.flavor}" + colloid_dir = f"{git_root}/sources/colloid" + colloid_tmp_dir = f"{git_root}/sources/colloid-tmp-{args.flavor}" shutil.copytree(colloid_dir, colloid_tmp_dir) From 883084503822e754768faaf6c6428ccffd8ca7ff Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sat, 25 May 2024 18:00:34 +0100 Subject: [PATCH 16/31] fix: patch paths --- sources/build/__init__.py | 3 ++- sources/build/patches.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sources/build/__init__.py b/sources/build/__init__.py index 1a7bf22f..45b1b863 100644 --- a/sources/build/__init__.py +++ b/sources/build/__init__.py @@ -18,7 +18,8 @@ def execute_build(git_root: str, args: Namespace): src_dir = colloid_tmp_dir + "/src" if args.patch: - apply_colloid_patches(colloid_tmp_dir) + patch_dir = git_root + "/sources//patches/colloid/" + apply_colloid_patches(colloid_tmp_dir, patch_dir) if args.zip: output_format = "zip" diff --git a/sources/build/patches.py b/sources/build/patches.py index 880ecc29..69c2fc4f 100644 --- a/sources/build/patches.py +++ b/sources/build/patches.py @@ -2,7 +2,7 @@ import subprocess from .logger import logger -def apply_colloid_patches(colloid_dir): +def apply_colloid_patches(colloid_dir, patch_dir): if os.path.isfile(colloid_dir + "/.patched"): logger.info( f'Patches seem to be applied, remove "{colloid_dir}/.patched" to force application (this may fail)' @@ -19,7 +19,7 @@ def apply_colloid_patches(colloid_dir): "sass-palette-latte.patch", "sass-palette-macchiato.patch", ]: - path = f"./patches/colloid/{patch}" + path = f"{patch_dir}/{patch}" logger.info(f"Applying patch '{patch}', located at '{path}'") subprocess.check_call( ["git", "apply", path, "--directory", os.path.basename(colloid_dir)]) From 5f2e3cce416d257f77233d34b55015e2beb39f7e Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sat, 25 May 2024 18:14:10 +0100 Subject: [PATCH 17/31] fix: small path issues --- .gitignore | 3 ++- sources/build/__init__.py | 4 ++-- sources/build/patches.py | 12 ++++++++---- sources/build/theme.py | 3 ++- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 3b5286ff..dc38c0d7 100644 --- a/.gitignore +++ b/.gitignore @@ -7,9 +7,10 @@ bin/ lib*/ *.cfg .direnv -./build/ +build/ *.log .ruff-cache +.tmp # Releases folder releases diff --git a/sources/build/__init__.py b/sources/build/__init__.py index 45b1b863..b78e18f9 100644 --- a/sources/build/__init__.py +++ b/sources/build/__init__.py @@ -11,14 +11,14 @@ def execute_build(git_root: str, args: Namespace): colloid_dir = f"{git_root}/sources/colloid" - colloid_tmp_dir = f"{git_root}/sources/colloid-tmp-{args.flavor}" + colloid_tmp_dir = f"{git_root}/.tmp/colloid-tmp-{args.flavor}" shutil.copytree(colloid_dir, colloid_tmp_dir) src_dir = colloid_tmp_dir + "/src" if args.patch: - patch_dir = git_root + "/sources//patches/colloid/" + patch_dir = git_root + "/sources/patches/colloid/" apply_colloid_patches(colloid_tmp_dir, patch_dir) if args.zip: diff --git a/sources/build/patches.py b/sources/build/patches.py index 69c2fc4f..31bc9a60 100644 --- a/sources/build/patches.py +++ b/sources/build/patches.py @@ -1,9 +1,12 @@ import os import subprocess +from pathlib import Path from .logger import logger + def apply_colloid_patches(colloid_dir, patch_dir): - if os.path.isfile(colloid_dir + "/.patched"): + colloid_dir = Path(colloid_dir).relative_to(os.getcwd()) + if os.path.isfile(colloid_dir / ".patched"): logger.info( f'Patches seem to be applied, remove "{colloid_dir}/.patched" to force application (this may fail)' ) @@ -19,12 +22,13 @@ def apply_colloid_patches(colloid_dir, patch_dir): "sass-palette-latte.patch", "sass-palette-macchiato.patch", ]: - path = f"{patch_dir}/{patch}" + path = (Path(patch_dir) / patch).relative_to(os.getcwd()) logger.info(f"Applying patch '{patch}', located at '{path}'") subprocess.check_call( - ["git", "apply", path, "--directory", os.path.basename(colloid_dir)]) + ["git", "apply", str(path), "--directory", str(colloid_dir)] + ) - with open(colloid_dir + "/.patched", "w") as f: + with open(colloid_dir / ".patched", "w") as f: f.write("true") logger.info("Patching finished.") diff --git a/sources/build/theme.py b/sources/build/theme.py index eecd1db8..2a635afb 100644 --- a/sources/build/theme.py +++ b/sources/build/theme.py @@ -15,7 +15,7 @@ def apply_tweaks(ctx: BuildContext): ctx.apply_tweak("compact", "'false'", "'true'") find_and_replace( - f"{ctx.src_dir}/sass/_tweaks-temp.scss", + f"{ctx.colloid_src_dir}/sass/_tweaks-temp.scss", Subsitution( find="@import 'color-palette-default';", replace=f"@import 'color-palette-catppuccin-{ctx.flavor.identifier}';", @@ -345,6 +345,7 @@ def zip_artifacts(dir_list, zip_name, remove=True): def build_with_context(ctx: BuildContext): build_info = f"""Build info: build_root: {ctx.output_root} + src_root: {ctx.colloid_src_dir} theme_name: {ctx.theme_name} flavor: {ctx.flavor.identifier} accent: {ctx.accent.identifier} From f73cab66015979052a63ece812445567e7005675 Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sun, 26 May 2024 01:29:26 +0100 Subject: [PATCH 18/31] ci: fail when build errors --- .github/workflows/build.yml | 12 +++++++++++- sources/build/context.py | 1 - 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 56ec2527..dcb79c00 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,7 +33,17 @@ jobs: python ./build.py macchiato --all-accents --zip -d $PWD/releases > macchiato.log 2>&1 & python ./build.py frappe --all-accents --zip -d $PWD/releases > frappe.log 2>&1 & python ./build.py latte --all-accents --zip -d $PWD/releases > latte.log 2>&1 & - wait + + set -e + declare -i err=0 werr=0 + while wait -fn || werr=$?; ((werr != 127)); do + err=$werr + if [[ $err -ne 0 ]]; then + echo "Build failure, abort" + cat *.log + exit 1 + fi + done cat *.log diff --git a/sources/build/context.py b/sources/build/context.py index 259fcc77..3d43c019 100644 --- a/sources/build/context.py +++ b/sources/build/context.py @@ -59,7 +59,6 @@ def apply_tweak(self, key, default, value): Subsitution(find=f"\\${key}: {default}", replace=f"${key}: {value}"), ) - IS_DARK = Suffix(true_value="-Dark", test=lambda ctx: ctx.flavor.dark) IS_LIGHT = Suffix(true_value="-Light", test=lambda ctx: not ctx.flavor.dark) IS_WINDOW_NORMAL = Suffix( From 4a52417f1098f37bea9c7c097ab7027c6059f37e Mon Sep 17 00:00:00 2001 From: nullishamy Date: Sun, 26 May 2024 01:36:15 +0100 Subject: [PATCH 19/31] ci: polish --- .github/workflows/build.yml | 3 ++- .github/workflows/release.yml | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dcb79c00..e58004ca 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -27,6 +27,8 @@ jobs: - name: Generate themes run: | + set -eu pipefile + python sources/patches/xfwm4/generate_assets.py python ./build.py mocha --all-accents --zip -d $PWD/releases > mocha.log 2>&1 & @@ -34,7 +36,6 @@ jobs: python ./build.py frappe --all-accents --zip -d $PWD/releases > frappe.log 2>&1 & python ./build.py latte --all-accents --zip -d $PWD/releases > latte.log 2>&1 & - set -e declare -i err=0 werr=0 while wait -fn || werr=$?; ((werr != 127)); do err=$werr diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 48279955..85292b39 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -42,13 +42,23 @@ jobs: - name: Generate themes run: | + set -eu pipefile + python sources/patches/xfwm4/generate_assets.py python ./build.py mocha --all-accents --zip -d $PWD/releases > mocha.log 2>&1 & python ./build.py macchiato --all-accents --zip -d $PWD/releases > macchiato.log 2>&1 & python ./build.py frappe --all-accents --zip -d $PWD/releases > frappe.log 2>&1 & python ./build.py latte --all-accents --zip -d $PWD/releases > latte.log 2>&1 & - wait + declare -i err=0 werr=0 + while wait -fn || werr=$?; ((werr != 127)); do + err=$werr + if [[ $err -ne 0 ]]; then + echo "Build failure, abort" + cat *.log + exit 1 + fi + done cat *.log From ac93f540dd3d4a3720c59cdbd2cf1382ca7d1267 Mon Sep 17 00:00:00 2001 From: ruzo Date: Mon, 27 May 2024 02:56:25 +0300 Subject: [PATCH 20/31] ci: merge into single stage the installation of dependencies --- .github/workflows/build.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e58004ca..b04684f0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,10 +20,9 @@ jobs: cache: "pip" - name: Install dependencies - run: pip install -r requirements.txt - - - name: Install colloid specific dependencies - run: sudo apt update && sudo apt install -y sassc inkscape optipng + run: | + sudo apt update && sudo apt install -y sassc inkscape optipng + pip install -r requirements.txt - name: Generate themes run: | From 6767f21638219e91527580e739efb51a5a2b7e1c Mon Sep 17 00:00:00 2001 From: ruzo Date: Mon, 27 May 2024 02:57:07 +0300 Subject: [PATCH 21/31] ref: removed duplicated code from execute_build on __init__.py --- sources/build/__init__.py | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/sources/build/__init__.py b/sources/build/__init__.py index b78e18f9..b050cf0a 100644 --- a/sources/build/__init__.py +++ b/sources/build/__init__.py @@ -10,25 +10,20 @@ def execute_build(git_root: str, args: Namespace): + colloid_dir = f"{git_root}/sources/colloid" colloid_tmp_dir = f"{git_root}/.tmp/colloid-tmp-{args.flavor}" - shutil.copytree(colloid_dir, colloid_tmp_dir) - src_dir = colloid_tmp_dir + "/src" + tweaks = Tweaks(tweaks=args.tweaks) + palette = getattr(PALETTE, args.flavor) + output_format = "zip" if args.zip else "dir" + if args.patch: patch_dir = git_root + "/sources/patches/colloid/" apply_colloid_patches(colloid_tmp_dir, patch_dir) - if args.zip: - output_format = "zip" - else: - output_format = "dir" - - tweaks = Tweaks(tweaks=args.tweaks) - palette = getattr(PALETTE, args.flavor) - accents = args.accents if args.all_accents: accents = [ @@ -51,13 +46,6 @@ def execute_build(git_root: str, args: Namespace): for accent in accents: accent = getattr(palette.colors, accent) - tweaks = Tweaks(tweaks=args.tweaks) - - if args.zip: - output_format = "zip" - else: - output_format = "dir" - ctx = BuildContext( output_root=args.dest, colloid_src_dir=src_dir, From edd9fe5d61eb180b521dcde26fccede1126722e2 Mon Sep 17 00:00:00 2001 From: ruzo Date: Tue, 28 May 2024 05:27:44 +0300 Subject: [PATCH 22/31] add: docker/ - build, push and dockerfile for ci --- docker/Dockerfile | 14 ++++++++ docker/build.sh | 83 +++++++++++++++++++++++++++++++++++++++++++++++ docker/push.sh | 66 +++++++++++++++++++++++++++++++++++++ 3 files changed, 163 insertions(+) create mode 100644 docker/Dockerfile create mode 100644 docker/build.sh create mode 100644 docker/push.sh diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 00000000..e768f4cc --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,14 @@ +# This dockerfile generates a container with the needed dependencies to build the theme + +FROM python:alpine + +RUN apk add sassc inkscape optipng + +WORKDIR /app + +COPY requirements.txt . + +RUN pip install --no-cache-dir -r requirements.txt && rm requirements.txt + +# The reason for this is to allow the GH Actions Workflow execute commands within the container +CMD ["sleep", "infinity"] diff --git a/docker/build.sh b/docker/build.sh new file mode 100644 index 00000000..26261cdd --- /dev/null +++ b/docker/build.sh @@ -0,0 +1,83 @@ +#!/bin/sh + +# Default value for custom_version +VERSION="no" + +while getopts v:h opt 2>/dev/null; do + case "$opt" in + v) + VERSION=$OPTARG + ;; + h) + echo "\ +Usage: $0 [-v ] + +Push script for Catppuccin's GTK docker build image + +-v Custom version to build the image (:) + If you only want to generate the image with tag 'latest' use '-v no' +-h Print this help text" >&2 + exit 0 + ;; + ?) + echo "Usage: $0 [-h]" >&2 + exit 1 + ;; + esac +done +if [ $# -eq 0 ] + then + echo "Usage: $0 [-h]" + exit 1 +fi + +# Resolve the absolute path of the script without readlink +SCRIPT_PATH="$0" + +# Check if SCRIPT_PATH is a symbolic link +while [ -h "$SCRIPT_PATH" ]; do + LS=$(ls -ld "$SCRIPT_PATH") + LINK=$(expr "$LS" : '.*-> \(.*\)$') + if expr "$LINK" : '/.*' > /dev/null; then + SCRIPT_PATH="$LINK" + else + SCRIPT_PATH=$(dirname "$SCRIPT_PATH")/"$LINK" + fi +done + +# Ensure we have an absolute path +case "$SCRIPT_PATH" in + /*) ;; + *) SCRIPT_PATH="$(pwd)/$SCRIPT_PATH" ;; +esac + +# Path to script' dir +SCRIPT_DIR=$(cd "$(dirname "$SCRIPT_PATH")" && pwd) + +# Path to the Dockerfile +DOCKERFILE_PATH="$SCRIPT_DIR/Dockerfile" + +# Docker variables +IMAGE_NAME="ghcr.io/catppuccin/gtk" + +# Detect podman +if command -v podman > /dev/null 2>&1; then + CONTAINER_TOOL="podman" +elif command -v docker > /dev/null 2>&1; then + CONTAINER_TOOL="docker" +else + echo "Error: Neither podman nor docker is installed." + exit 1 +fi + +# Clean previous generated images +$CONTAINER_TOOL image rm "$IMAGE_NAME:latest" 2> /dev/null +$CONTAINER_TOOL image rm "$IMAGE_NAME:$VERSION" 2> /dev/null + +# Build the Docker image with latest tag +$CONTAINER_TOOL build -t "$IMAGE_NAME:latest" -f "$DOCKERFILE_PATH" "$SCRIPT_DIR/.." + +# Execute docker tag command if VERSION is not "no" +if [ "$VERSION" != "no" ]; then + $CONTAINER_TOOL tag "$IMAGE_NAME:latest" "$IMAGE_NAME:$VERSION" +fi diff --git a/docker/push.sh b/docker/push.sh new file mode 100644 index 00000000..f5e4f50b --- /dev/null +++ b/docker/push.sh @@ -0,0 +1,66 @@ +#!/bin/sh + +# Default value for parameters +VERSION="no" +USERNAME="no" +PASSWORD="no" + +while getopts u:p:v:h opt 2>/dev/null; do + case "$opt" in + v) + VERSION=$OPTARG + ;; + u) + USERNAME=$OPTARG + ;; + p) + PASSWORD=$OPTARG + ;; + h) + echo "\ +Usage: $0 [-v | -u [your-github-username] | -p [your-github-password]] + +Push script for Catppuccin's GTK docker build image + +-v Custom version to push the image (:) +-u Your GitHub username that will be used to log into GHCR +-p Your GitHub password that will be used to log into GHCR +-h Print this help text" >&2 + exit 0 + ;; + ?) + echo "Usage: $0 [-h]" >&2 + exit 1 + ;; + esac +done +if [ $# -eq 0 ] + then + echo "Usage: $0 [-h]" + exit 1 +fi + + +# Detect podman +if command -v podman > /dev/null 2>&1; then + CONTAINER_TOOL="podman" +elif command -v docker > /dev/null 2>&1; then + CONTAINER_TOOL="docker" +else + echo "Error: Neither podman nor docker is installed." + exit 1 +fi + +# Docker variables +IMAGE_NAME="ghcr.io/catppuccin/gtk" + +# Log into ghcr +echo $GITHUB_TOKEN | docker login ghcr.io -u --password-stdin + +# Push docker image with latest tag +$CONTAINER_TOOL push "$IMAGE_NAME:latest" + +# Execute docker push for specific version if VERSION is not "no" +if [ "$VERSION" == "no" ]; then + $CONTAINER_TOOL push "$IMAGE_NAME:$VERSION" +fi From cb21ce8e80a911bd91be24112b14de30e4e6f7c2 Mon Sep 17 00:00:00 2001 From: ruzo Date: Tue, 28 May 2024 05:40:01 +0300 Subject: [PATCH 23/31] ci: push docker image to ghcr --- .github/workflows/docker.yml | 26 ++++++++++++++++++++++++++ docker/push.sh | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/docker.yml diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 00000000..43583da3 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,26 @@ +name: "Generate test artifacts" + +on: + workflow_dispatch: + pull_request: + # types: [opened, reopened, synchronize] + types: [synchronize] + +permissions: + contents: write + packages: write + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + submodules: true + + - name: Generate themes + run: | + sh docker/build.sh -v no + sh docker/push.sh --username "${{ github.actor }}" --password "${{ secrets.GITHUB_TOKEN }}" diff --git a/docker/push.sh b/docker/push.sh index f5e4f50b..90d1fcd2 100644 --- a/docker/push.sh +++ b/docker/push.sh @@ -55,7 +55,7 @@ fi IMAGE_NAME="ghcr.io/catppuccin/gtk" # Log into ghcr -echo $GITHUB_TOKEN | docker login ghcr.io -u --password-stdin +$CONTAINER_TOOL login ghcr.io -u $USERNAME --password $PASSWORD # Push docker image with latest tag $CONTAINER_TOOL push "$IMAGE_NAME:latest" From 4c8c35ccc866fd0610cf34a9d44cfe2fcc11757b Mon Sep 17 00:00:00 2001 From: ruzo Date: Tue, 28 May 2024 05:44:47 +0300 Subject: [PATCH 24/31] doc: .github/workflows/docker.yml --- .github/workflows/docker.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 43583da3..7b4aafe8 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -22,5 +22,8 @@ jobs: - name: Generate themes run: | + # build docker image for the ci sh docker/build.sh -v no + + # push the image to the registry sh docker/push.sh --username "${{ github.actor }}" --password "${{ secrets.GITHUB_TOKEN }}" From f1aeeb13effdded6112eaeee92f1829887f24774 Mon Sep 17 00:00:00 2001 From: nullishamy Date: Tue, 28 May 2024 13:31:00 +0100 Subject: [PATCH 25/31] chore: add back patches --- sources/build/patches.py | 1 + 1 file changed, 1 insertion(+) diff --git a/sources/build/patches.py b/sources/build/patches.py index 31bc9a60..86237b19 100644 --- a/sources/build/patches.py +++ b/sources/build/patches.py @@ -21,6 +21,7 @@ def apply_colloid_patches(colloid_dir, patch_dir): "sass-palette-mocha.patch", "sass-palette-latte.patch", "sass-palette-macchiato.patch", + "theme-func.patch", ]: path = (Path(patch_dir) / patch).relative_to(os.getcwd()) logger.info(f"Applying patch '{patch}', located at '{path}'") From ca2c85dbc68300862cc6d6037deac2c6412175c4 Mon Sep 17 00:00:00 2001 From: nullishamy Date: Tue, 28 May 2024 13:37:44 +0100 Subject: [PATCH 26/31] ci: use correct args; rename workflow --- .github/workflows/docker.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 7b4aafe8..4f432da1 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,4 +1,4 @@ -name: "Generate test artifacts" +name: "Publish containers for build" on: workflow_dispatch: @@ -26,4 +26,4 @@ jobs: sh docker/build.sh -v no # push the image to the registry - sh docker/push.sh --username "${{ github.actor }}" --password "${{ secrets.GITHUB_TOKEN }}" + sh docker/push.sh -u "${{ github.actor }}" -p "${{ secrets.GITHUB_TOKEN }}" From 68b020f6a79e8905b1b00e8896061380b285c4ff Mon Sep 17 00:00:00 2001 From: nullishamy Date: Tue, 28 May 2024 13:42:25 +0100 Subject: [PATCH 27/31] ci: try new permission --- .github/workflows/docker.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 4f432da1..55bad3ba 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -6,9 +6,7 @@ on: # types: [opened, reopened, synchronize] types: [synchronize] -permissions: - contents: write - packages: write +permissions: write-all jobs: build: From fe760dd57b603b92564007ee8d9c67a0841aed46 Mon Sep 17 00:00:00 2001 From: ruzo Date: Tue, 28 May 2024 15:58:38 +0300 Subject: [PATCH 28/31] fix: docker build ci --- .github/workflows/docker.yml | 4 ++-- docker/push.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 55bad3ba..60466c1e 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -18,10 +18,10 @@ jobs: with: submodules: true - - name: Generate themes + - name: Generate and push image to ghcr run: | # build docker image for the ci sh docker/build.sh -v no # push the image to the registry - sh docker/push.sh -u "${{ github.actor }}" -p "${{ secrets.GITHUB_TOKEN }}" + sh docker/push.sh -u "${{ github.actor }}" -p "${{ secrets.GITHUB_TOKEN }}" diff --git a/docker/push.sh b/docker/push.sh index 90d1fcd2..83a72b60 100644 --- a/docker/push.sh +++ b/docker/push.sh @@ -61,6 +61,6 @@ $CONTAINER_TOOL login ghcr.io -u $USERNAME --password $PASSWORD $CONTAINER_TOOL push "$IMAGE_NAME:latest" # Execute docker push for specific version if VERSION is not "no" -if [ "$VERSION" == "no" ]; then +if [ "$VERSION" != "no" ]; then $CONTAINER_TOOL push "$IMAGE_NAME:$VERSION" fi From 78f6fe44b7cc3d4642cf65e81623b8a20a088bb2 Mon Sep 17 00:00:00 2001 From: ruzo Date: Wed, 29 May 2024 01:47:03 +0300 Subject: [PATCH 29/31] add: use of container in ci (commented) --- .github/workflows/build.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b04684f0..661758c7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,9 +4,21 @@ on: pull_request: types: [opened, reopened, synchronize] +# env: +# TAG: latest + jobs: build: runs-on: ubuntu-latest + + # container: + # image: ghcr.io/${{ github.repository_owner }}/${{ github.repository }}:${{ env.TAG }} + # + # # is this really necessary? + # credentials: + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + steps: - name: Checkout From 65a2cd60279d43cba1824b434a6aafcebfc7e24f Mon Sep 17 00:00:00 2001 From: ruzo Date: Wed, 29 May 2024 02:22:58 +0300 Subject: [PATCH 30/31] ref: moved missed patch to sources/patches/colloid --- .../patches/colloid}/alt-tab-background-color.patch | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {patches/colloid/fixes => sources/patches/colloid}/alt-tab-background-color.patch (100%) diff --git a/patches/colloid/fixes/alt-tab-background-color.patch b/sources/patches/colloid/alt-tab-background-color.patch similarity index 100% rename from patches/colloid/fixes/alt-tab-background-color.patch rename to sources/patches/colloid/alt-tab-background-color.patch From 4fadf584c912d98173d030f662bac33a7f1a2d61 Mon Sep 17 00:00:00 2001 From: ruzo Date: Wed, 29 May 2024 02:31:03 +0300 Subject: [PATCH 31/31] docs: moved documentation from root dir to docs/ --- ARCHITECTURE.md => docs/ARCHITECTURE.md | 0 CHANGELOG.md => docs/CHANGELOG.md | 0 CONTRIBUTING.md => docs/CONTRIBUTING.md | 16 ++++++++-------- 3 files changed, 8 insertions(+), 8 deletions(-) rename ARCHITECTURE.md => docs/ARCHITECTURE.md (100%) rename CHANGELOG.md => docs/CHANGELOG.md (100%) rename CONTRIBUTING.md => docs/CONTRIBUTING.md (94%) diff --git a/ARCHITECTURE.md b/docs/ARCHITECTURE.md similarity index 100% rename from ARCHITECTURE.md rename to docs/ARCHITECTURE.md diff --git a/CHANGELOG.md b/docs/CHANGELOG.md similarity index 100% rename from CHANGELOG.md rename to docs/CHANGELOG.md diff --git a/CONTRIBUTING.md b/docs/CONTRIBUTING.md similarity index 94% rename from CONTRIBUTING.md rename to docs/CONTRIBUTING.md index 33d9db46..018557ce 100644 --- a/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -8,7 +8,7 @@ Information regarding the architecture of the project can be found [in the ARCHI ### Project structure -`sources/` contains all of the source files needed for the project to build, including the Colloid submodule. +`sources/` contains all of the source files needed for the project to build, including the Colloid submodule. It also contains our patches for Colloid, alongside the core build system implemented by us to replace the one from Colloid. `build.py` is the entrypoint to the build system, placed at the root for convenience. The plumbing this utilizes is in @@ -23,7 +23,7 @@ This keeps the end user experience simple and reproducible. Do not add external > If you need to change the patches, reset the submodule and rerun the build script. We patch upstream colloid through a series of `.patch` files, applied through `git apply` once when the build begins. -The patches are located in `./patches/colloid/`. +The patches are located in `./patches/colloid/`. Once the build script patches the submodule, it will write a file into `colloid/.patched`, to signal to future invocations that the patches have already been applied. @@ -39,12 +39,12 @@ Now and again, Colloid will have bugs upstream that impacts our theme. With our but we still want to contribute the fixes upstream to benefit all users & forks of Colloid. To avoid stalling unnecessarily, our procedure for the above is as follows: -1) Open a PR to fix the issue, by adding a patch file to our theme, add `upstream:intended` +1) Open a PR to fix the issue, by adding a patch file to our theme, add `upstream:intended` to signal these changes are to be sent to Colloid eventually. 2) Merge the PR & close the issue in our theme pertaining to the issue, once reviewed and approved 3) Open a PR in Colloid with the patch 4) Open a new issue in our theme, with these details: - - The initial issue in our theme + - The initial issue in our theme - The PR in Colloid that fixes the issue there - The PR that fixed the issue in our theme @@ -55,7 +55,7 @@ to signal these changes are to be sent to Colloid eventually. - The tracking issue - The commit that fixed the issue in Colloid 3) Close the tracking issue & merge the PR to remove the patch file - + ### Running test builds We support building and publishing test builds from PRs. When you open PRs, the CI will automatically build with your changes and push an artifact @@ -67,10 +67,10 @@ pass the path into `install.py` under the `--from-artifact` option: python3 install.py mocha blue --dest ./build --from-artifact ~/downloads/7bff2448a81e36bf3b0e03bfbd649bebe6973ec7-artifacts.zip ``` -This will take the target flavor / accent out of the zip, and install it using the regular install process. +This will take the target flavor / accent out of the zip, and install it using the regular install process. It is advised to pass a `--dest` when running in this mode, because the released zips follow the exact same naming scheme as regular builds. -This wil cause conflicts when you install, if you already had that theme installed. Passing a different destination allows you to move the +This wil cause conflicts when you install, if you already had that theme installed. Passing a different destination allows you to move the extracted folders to `~/.local/share/themes` yourself, adding a suffix as appropriate to avoid conflicts. > [!WARNING] @@ -79,4 +79,4 @@ extracted folders to `~/.local/share/themes` yourself, adding a suffix as approp ### Useful resources - GNOME-shell sources: https://gitlab.gnome.org/GNOME/gnome-shell/-/tree/gnome-46/data/theme -- GTK inspector guide: https://developer.gnome.org/documentation/tools/inspector.html \ No newline at end of file +- GTK inspector guide: https://developer.gnome.org/documentation/tools/inspector.html