Created
April 30, 2025 14:17
-
-
Save ParaN3xus/939134a9c817c6d13745d7e6da54db71 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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