Skip to content

Instantly share code, notes, and snippets.

@ParaN3xus
Created April 30, 2025 14:17
Show Gist options
  • Save ParaN3xus/939134a9c817c6d13745d7e6da54db71 to your computer and use it in GitHub Desktop.
Save ParaN3xus/939134a9c817c6d13745d7e6da54db71 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import requests
import json
import re
import os
import subprocess
from datetime import datetime
import tempfile
def get_latest_tag_info():
tags_url = "https://api.github.com/repos/hyprwm/Hyprland/tags"
response = requests.get(tags_url)
tags = response.json()
if not tags:
raise Exception("No tags found")
latest_tag = tags[0]
tag_name = latest_tag["name"]
commit_url = latest_tag["commit"]["url"]
commit_response = requests.get(commit_url)
commit_info = commit_response.json()
tag_date = commit_info["commit"]["committer"]["date"]
tag_date_obj = datetime.strptime(tag_date, "%Y-%m-%dT%H:%M:%SZ")
print(f"Latest tag: {tag_name}")
print(f"Created on: {tag_date}")
return tag_name, tag_date_obj
def get_hidpi_patch_url():
url = "https://github.com/moetayuko/Hyprland/activity?ref=hidpi-xprop"
response = requests.get(url)
content = response.text
pattern = r'<script type="application/json" data-target="react-app.embeddedData">(.*?)</script>'
match = re.search(pattern, content, re.DOTALL)
if not match:
raise Exception("Could not find JSON data in the activity page")
json_data = match.group(1).strip()
activity_data = json.loads(json_data)
tag_name, tag_date_obj = get_latest_tag_info()
force_pushes = []
items = activity_data["payload"]["activityList"]["items"]
for item in items:
if item["pushType"] == "force_push":
pushed_at = item["pushedAt"]
try:
if "Z" in pushed_at:
pushed_at = pushed_at.replace("Z", "+00:00")
date_part = pushed_at.split("+")[0].split(".")[0]
pushed_at_obj = datetime.strptime(
date_part, "%Y-%m-%dT%H:%M:%S")
except ValueError as e:
print(f"warning: can't parse time '{pushed_at}': {e}")
continue
force_pushes.append({
"after": item["after"],
"date": pushed_at_obj
})
last_valid_push = None
for push in force_pushes:
if push["date"] < tag_date_obj:
last_valid_push = push
break
if not last_valid_push:
raise Exception(
"No suitable force push found before the latest tag date")
commit_hash = last_valid_push["after"]
patch_url = f"https://github.com/moetayuko/Hyprland/commit/{commit_hash}.patch"
print(f"Found suitable commit: {commit_hash}")
print(f"Patch URL: {patch_url}")
return patch_url, tag_name
def generate_pkgbuild(tag, patch_url):
pkg_ver = tag.lstrip('v')
pkgbuild_content = f"""# Maintainer: q234 rty <q23456yuiop at gmail dot com>
# Maintainer: moetayuko <loli at yuko dot moe>
# Contributor: FabioLolix
# Contributor: éclairevoyant
# Contributor: ThatOneCalculator <kainoa at t1c dot dev>
# Contributor: Aleksana QwQ <[email protected]>
# Contributor: lilydjwg <[email protected]>
_pkgname=hyprland
pkgname=$_pkgname-hidpi-xprop
pkgver={pkg_ver}
pkgrel=1
pkgdesc="Hyprland is an independent, highly customizable, dynamic tiling Wayland compositor that doesn't sacrifice on its looks."
arch=("i686" "x86_64" "arm" "armv6h" "armv7h" "aarch64")
url="https://github.com/hyprwm/Hyprland"
license=('BSD-3-Clause')
depends=(
aquamarine
cairo
gcc-libs
glib2
glibc
glslang
hyprutils
hyprcursor
hyprlang
libdisplay-info
libdrm
libglvnd
libinput
libliftoff
libx11
libxcb
libxcomposite
libxcursor
libxfixes
libxkbcommon
libxrender
mesa
opengl-driver
pango
pixman
polkit
seatd
systemd-libs
tomlplusplus
util-linux-libs
wayland
wayland-protocols
xcb-proto
xcb-util
xcb-util-errors
xcb-util-image
xcb-util-keysyms
xcb-util-renderutil
xcb-util-wm
xorg-xwayland-hidpi-xprop
)
makedepends=(
cmake
git
hyprwayland-scanner
meson
ninja
xorgproto
)
optdepends=(
'cmake: to build and install plugins using hyprpm'
'cpio: to build and install plugins using hyprpm'
'meson: to build and install plugins using hyprpm'
)
provides=("hyprland=${{pkgver%%.r*}}")
conflicts=(hyprland)
source=(
"git+https://github.com/hyprwm/Hyprland.git"
"git+https://github.com/hyprwm/hyprland-protocols.git"
"git+https://github.com/canihavesomecoffee/udis86.git"
"hidpi-xprop.patch::{patch_url}"
)
b2sums=(
'SKIP'
'SKIP'
'SKIP'
'SKIP'
)
options=(debug)
prepare() {{
cd Hyprland
git submodule init
git config submodule.subprojects/hyprland-protocols.url "$srcdir/hyprland-protocols"
git config submodule.subprojects/udis86.url "$srcdir/udis86"
git config submodule.subprojects/tracy.update none
git -c protocol.file.allow=always submodule update
if [[ -z "$(git config --get user.name)" ]]; then
git config user.name local && git config user.email '<>' && git config commit.gpgsign false
fi
git checkout {tag}
patch -p1 -i "$srcdir/hidpi-xprop.patch"
}}
pkgver() {{
git -C Hyprland describe --long --tags | sed 's/^v//;s/\\([^-]*-\\)g/r\\1/;s/-/./g'
}}
build() {{
cd Hyprland
mkdir -p build && cd build
cmake -G Ninja -DCMAKE_BUILD_TYPE=None -DCMAKE_SKIP_RPATH=ON -DCMAKE_INSTALL_PREFIX=/usr ..
cmake --build .
}}
package() {{
cd Hyprland
DESTDIR="$pkgdir" cmake --install build
pushd "$pkgdir/usr/bin"
ln -sf Hyprland hyprland
popd
# Avoid conflict w/ extra/xdg-desktop-portal-hyprland
rm -rf "$pkgdir/usr/share/xdg-desktop-portal"
for cmd in hyprctl hyprpm; do
install -Dm0644 "$cmd/$cmd.bash" "$pkgdir/usr/share/bash-completion/completions/$cmd"
install -Dm0644 "$cmd/$cmd.zsh" "$pkgdir/usr/share/zsh/site-functions/_$cmd"
install -Dm0644 -t "$pkgdir/usr/share/fish/vendor_completions.d/" "$cmd/$cmd.fish"
done
install -Dm0644 -t "$pkgdir/usr/share/licenses/$pkgname/" LICENSE
install -Dm0644 subprojects/udis86/LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE-udis86"
}}
# vi: et ts=2 sw=2
"""
return pkgbuild_content
def main():
with tempfile.TemporaryDirectory() as temp_dir:
os.chdir(temp_dir)
print(f"Working in temporary directory: {temp_dir}")
patch_url, tag = get_hidpi_patch_url()
pkgbuild_content = generate_pkgbuild(tag, patch_url)
with open("PKGBUILD", "w") as f:
f.write(pkgbuild_content)
print("Generated PKGBUILD file")
print("Running makepkg -si...")
try:
subprocess.run(["makepkg", "-si"], check=True)
print("Package built and installed successfully")
except subprocess.CalledProcessError as e:
print(f"Error building package: {e}")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment