diff gui_ze/gui_ze.bzl @ 58:ccb42d5bf8fd

[PostDog] Somewhat working copy. That would use for testing.
author June Park <parkjune1995@gmail.com>
date Sat, 20 Dec 2025 09:33:15 -0800
parents 342726584be2
children a30944e5719e
line wrap: on
line diff
--- a/gui_ze/gui_ze.bzl	Fri Dec 19 18:00:30 2025 -0800
+++ b/gui_ze/gui_ze.bzl	Sat Dec 20 09:33:15 2025 -0800
@@ -10,7 +10,6 @@
   implementation = _foo_impl,
 )
 
-
 def _bundle_impl(ctx):
   """
   bundle binary target into a folder which can later be used to make a post to github easily.
@@ -183,3 +182,169 @@
     "dest": attr.string(),
   },
 )
+
+
+def _macos_app_impl(ctx):
+    """Implementation for creating a macOS .app bundle from a binary."""
+    binary = ctx.file.binary
+    app_name = ctx.attr.app_name
+    bundle_id = ctx.attr.bundle_id
+
+    # Declare the .app directory as output
+    app_dir = ctx.actions.declare_directory(app_name + ".app")
+
+    ctx.actions.run_shell(
+        inputs = [binary],
+        outputs = [app_dir],
+        command = """
+        set -e
+
+        APPDIR="{app_dir}"
+
+        rm -rf "$APPDIR"
+        mkdir -p "$APPDIR/Contents/MacOS"
+        mkdir -p "$APPDIR/Contents/Resources"
+
+        cp {binary} "$APPDIR/Contents/MacOS/{app_name}"
+        chmod +x "$APPDIR/Contents/MacOS/{app_name}"
+
+        cat > "$APPDIR/Contents/Info.plist" <<EOF
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+  <key>CFBundleExecutable</key>
+  <string>{app_name}</string>
+  <key>CFBundleIdentifier</key>
+  <string>{bundle_id}</string>
+  <key>CFBundleName</key>
+  <string>{app_name}</string>
+  <key>CFBundleVersion</key>
+  <string>1.0</string>
+</dict>
+</plist>
+EOF
+        """.format(
+            app_dir = app_dir.path,
+            binary = binary.path,
+            app_name = app_name,
+            bundle_id = bundle_id,
+        ),
+        progress_message = "Creating macOS app bundle for {}".format(app_name),
+    )
+
+    return [DefaultInfo(files = depset([app_dir]))]
+
+_macos_app = rule(
+    implementation = _macos_app_impl,
+    attrs = {
+        "binary": attr.label(
+            allow_single_file = True,
+            mandatory = True,
+            doc = "The binary to bundle into a .app",
+        ),
+        "app_name": attr.string(
+            mandatory = True,
+            doc = "Name of the application",
+        ),
+        "bundle_id": attr.string(
+            mandatory = True,
+            doc = "Bundle identifier (e.g., com.example.app)",
+        ),
+    },
+)
+
+def _macos_signed_app_impl(ctx):
+    """Implementation for signing a macOS .app bundle."""
+    app_dir = ctx.file.app
+    app_name = ctx.attr.app_name
+
+    # Declare the signed .app directory as output
+    signed_app_dir = ctx.actions.declare_directory(app_name + "_signed.app")
+
+    ctx.actions.run_shell(
+        inputs = [app_dir],
+        outputs = [signed_app_dir],
+        command = """
+        set -e
+
+        APPDIR="{app_dir}"
+        SIGNEDDIR="{signed_dir}"
+
+        rm -rf "$SIGNEDDIR"
+        # Use -L to dereference symlinks, as codesign doesn't work with symlinks
+        cp -RL "$APPDIR" "$SIGNEDDIR"
+
+        codesign --deep --force --sign - "$SIGNEDDIR"
+        """.format(
+            app_dir = app_dir.path,
+            signed_dir = signed_app_dir.path,
+        ),
+        progress_message = "Signing macOS app bundle {}".format(app_name),
+    )
+
+    return [DefaultInfo(files = depset([signed_app_dir]))]
+
+_macos_signed_app = rule(
+    implementation = _macos_signed_app_impl,
+    attrs = {
+        "app": attr.label(
+            allow_single_file = True,
+            mandatory = True,
+            doc = "The .app directory to sign",
+        ),
+        "app_name": attr.string(
+            mandatory = True,
+            doc = "Name of the application",
+        ),
+    },
+)
+
+def macos_app_and_dmg(name, binary, bundle_id = "com.example.app"):
+    """
+    Creates a macOS .app bundle, signs it, and packages it into a DMG.
+
+    Args:
+        name: Base name for the generated targets
+        binary: Label of the binary target to bundle
+        bundle_id: Bundle identifier for the app (default: com.example.app)
+
+    Generates:
+        {name}_app: The .app bundle
+        {name}_signed_app: The signed .app bundle
+        {name}_dmg: The final DMG file
+    """
+    # 1. Build the .app bundle
+    _macos_app(
+        name = name + "_app",
+        binary = binary,
+        app_name = name,
+        bundle_id = bundle_id,
+    )
+
+    # 2. Sign the .app
+    _macos_signed_app(
+        name = name + "_signed_app",
+        app = ":" + name + "_app",
+        app_name = name,
+    )
+
+    # 3. Create the DMG
+    native.genrule(
+        name = name + "_dmg",
+        srcs = [":" + name + "_signed_app"],
+        outs = [name + ".dmg"],
+        cmd = """
+        set -e
+
+        SIGNEDDIR="$(location :{name}_signed_app)"
+
+        hdiutil create \
+            -volname {name} \
+            -srcfolder "$$SIGNEDDIR" \
+            -ov -format UDZO "$@"
+        """.format(name = name),
+        local = 1,  # Disable sandboxing for hdiutil
+        tags = ["no-sandbox"],
+    )