Swap lmstudio -> lmstudio-bin
This commit is contained in:
15 files changed
+594
-93
No files matched your search
@@ -13,7 +13,7 @@ dropbox
|
||||
dropbox-cli
|
||||
github-copilot-cli
|
||||
hyprshade
|
||||
lmstudio
|
||||
lmstudio-bin
|
||||
localsend
|
||||
localsend-bin
|
||||
minecraft-launcher
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
pkgbase = lmstudio-bin
|
||||
pkgdesc = LM Studio - A desktop app for exploring and running large language models locally
|
||||
pkgver = 0.4.2
|
||||
pkgrel = 2
|
||||
url = https://lmstudio.ai
|
||||
install = lmstudio-bin.install
|
||||
arch = x86_64
|
||||
license = EULA
|
||||
depends = fuse2
|
||||
depends = zlib
|
||||
depends = hicolor-icon-theme
|
||||
depends = gtk3
|
||||
depends = nss
|
||||
depends = libxcrypt-compat
|
||||
options = !strip
|
||||
source = https://installers.lmstudio.ai/linux/x64/0.4.2-2/LM-Studio-0.4.2-2-x64.AppImage
|
||||
source = lmstudio.png
|
||||
source = lmstudio.desktop
|
||||
sha256sums = 2711a5aa0b2e2dc5bcd66388727b551521efd7dcd2168b880a1833fde81cf89d
|
||||
sha256sums = 9f791789c959a11316328692807737a5f1bc1c170ae99ec04c56bfd8ee8263e5
|
||||
sha256sums = d5ac11aae025cd1cc0f9aa0713ee427dc6f46e4d1adac2a5948f93d8bbca705f
|
||||
|
||||
pkgname = lmstudio-bin
|
||||
@@ -0,0 +1,9 @@
|
||||
pkg/
|
||||
src/
|
||||
*.AppImage
|
||||
*.tar.gz
|
||||
*.tar.xz
|
||||
*.log
|
||||
squashfs-root/
|
||||
__pycache__/
|
||||
*.pkg.tar.zst
|
||||
@@ -0,0 +1,102 @@
|
||||
PROJECT BLUEPRINT: lmstudio-bin Maintenance Framework
|
||||
|
||||
1. Executive Summary
|
||||
|
||||
Project Name: lmstudio-bin
|
||||
|
||||
Target Platform: Arch Linux (AUR)
|
||||
|
||||
Upstream Software: LM Studio (Proprietary AppImage)
|
||||
|
||||
This project provides an Arch User Repository (AUR) package for LM Studio. It employs a "Maintenance Bridge" architecture to convert dynamic upstream releases into deterministic, security-verified Arch Linux packages while adhering strictly to Arch Linux packaging standards for binary software.
|
||||
|
||||
2. Core Objectives
|
||||
|
||||
Correct Naming Convention: Utilize the -bin suffix as mandated by AUR guidelines for software distributed as pre-compiled binaries.
|
||||
|
||||
Replacement of Legacy Packages: Explicitly provide and conflict with the abandoned lmstudio package to ensure a clean migration path for the community.
|
||||
|
||||
Security & Determinism: Implement strict SHA256 checksum verification for every release, preventing "moving target" build failures.
|
||||
|
||||
Full Desktop Integration: Ensure high-resolution icon support, XDG-compliant desktop entries, and taskbar grouping (StartupWMClass).
|
||||
|
||||
3. Technical Architecture
|
||||
|
||||
A. The Maintenance Engine (update_package.py)
|
||||
|
||||
The heart of the project is a Python-based automation script that manages the lifecycle of a release.
|
||||
|
||||
URL Resolution: Follows the latest redirect to identify the specific build version.
|
||||
|
||||
Verification: Downloads the AppImage and calculates the SHA256 hash.
|
||||
|
||||
Template Rendering: Injects metadata into PKGBUILD.template to produce a valid PKGBUILD.
|
||||
|
||||
Metadata Generation: Automatically updates .SRCINFO for AUR indexing.
|
||||
|
||||
B. Packaging Logic (PKGBUILD)
|
||||
|
||||
The build process follows a specific lifecycle to ensure stability:
|
||||
|
||||
Extraction Stage: Uses --appimage-extract within a temporary sandbox to access internal assets.
|
||||
|
||||
Icon Strategy (Static Vendoring):
|
||||
* Static Icon: The high-resolution (512x512) icon is vendored as `lmstudio.png` in the base repository.
|
||||
* Optimization: Icons must be optimized to stay under the 500KB AUR repository blob limit.
|
||||
* Rationale: Static vendoring prevents build-time extraction failures and ensures consistent visual presentation across versions without relying on internal AppImage layout stability.
|
||||
|
||||
Binary Placement: Installs the AppImage to /opt/lm-studio/ and provides a symbolic link at /usr/bin/lm-studio.
|
||||
|
||||
C. Lifecycle Management (.install)
|
||||
|
||||
The .install script ensures the host system recognizes changes immediately upon installation, upgrade, or removal by triggering:
|
||||
|
||||
update-desktop-database (Applications menu)
|
||||
|
||||
gtk-update-icon-cache (Visual assets)
|
||||
|
||||
4. Automation Workflow (For Orchestrator Reference)
|
||||
|
||||
When updating to a new version, the orchestrator should follow this sequence:
|
||||
|
||||
Sync: Pull latest changes from the AUR remote.
|
||||
|
||||
Execute: Run ./update_package.py to fetch upstream changes and regenerate files.
|
||||
|
||||
Validate: * Verify PKGBUILD version matches upstream.
|
||||
|
||||
Run makepkg -f to test the build locally.
|
||||
|
||||
Inspect pkg/ directory to ensure icon assets are present at /usr/share/icons/hicolor/512x512/apps/lmstudio-bin.png.
|
||||
|
||||
Publish: * Refresh .SRCINFO (makepkg --printsrcinfo > .SRCINFO).
|
||||
|
||||
Commit PKGBUILD, .SRCINFO, lmstudio.desktop, lmstudio.png, and lmstudio-bin.install.
|
||||
|
||||
Push to origin master.
|
||||
|
||||
5. Git Hygiene & AUR Constraints
|
||||
|
||||
* Blob Limit: The AUR imposes a strict 512KB limit on individual file blobs. All vendored assets (like `lmstudio.png`) must be optimized to comply.
|
||||
* Tracking Restrictions: Only source-of-truth files and metadata are permitted in the repository. Tracking of `src/` or `pkg/` directories is strictly prohibited.
|
||||
* Verification: Use `verify_git_hygiene.sh` to audit the repository state before pushing to the AUR remote.
|
||||
|
||||
6. Directory Structure
|
||||
|
||||
.
|
||||
├── PKGBUILD # Generated Arch Linux build script
|
||||
├── PKGBUILD.template # Blueprint for the maintenance engine
|
||||
├── .SRCINFO # AUR metadata index (auto-generated)
|
||||
├── lmstudio.desktop # Desktop integration file
|
||||
├── lmstudio.png # Static vendored icon (512x512)
|
||||
├── lmstudio-bin.install # Post-install hooks for cache clearing
|
||||
├── update_package.py # The Maintenance Engine script
|
||||
├── verify_git_hygiene.sh # Hygiene enforcement script
|
||||
└── LMStudio-bin Blueprint.md # This reference document
|
||||
|
||||
|
||||
7. Maintenance Contacts & Authority
|
||||
|
||||
Maintainer: madgoat (AUR)
|
||||
|
||||
Package URL: https://aur.archlinux.org/packages/lmstudio-bin
|
||||
@@ -0,0 +1,41 @@
|
||||
# Maintainer: noureddinex
|
||||
pkgname=lmstudio-bin
|
||||
pkgver=0.4.2
|
||||
pkgrel=2
|
||||
_pkgver=${pkgver}-${pkgrel}
|
||||
pkgdesc="LM Studio - A desktop app for exploring and running large language models locally"
|
||||
arch=('x86_64')
|
||||
url="https://lmstudio.ai"
|
||||
license=('EULA')
|
||||
depends=('fuse2' 'zlib' 'hicolor-icon-theme' 'gtk3' 'nss' 'libxcrypt-compat')
|
||||
options=('!strip')
|
||||
install=lmstudio-bin.install
|
||||
source=("https://installers.lmstudio.ai/linux/x64/${_pkgver}/LM-Studio-${_pkgver}-x64.AppImage"
|
||||
"lmstudio.png"
|
||||
"lmstudio.desktop")
|
||||
sha256sums=('2711a5aa0b2e2dc5bcd66388727b551521efd7dcd2168b880a1833fde81cf89d'
|
||||
'9f791789c959a11316328692807737a5f1bc1c170ae99ec04c56bfd8ee8263e5'
|
||||
'd5ac11aae025cd1cc0f9aa0713ee427dc6f46e4d1adac2a5948f93d8bbca705f')
|
||||
|
||||
prepare() {
|
||||
chmod +x "${srcdir}/${source[0]##*/}"
|
||||
}
|
||||
|
||||
package() {
|
||||
# Create installation directory
|
||||
install -dm755 "$pkgdir/opt/lm-studio"
|
||||
|
||||
# Install AppImage
|
||||
install -Dm755 "${srcdir}/${source[0]##*/}" "$pkgdir/opt/lm-studio/lm-studio.AppImage"
|
||||
|
||||
# Install static icon
|
||||
install -Dm644 "${srcdir}/lmstudio.png" "${pkgdir}/usr/share/icons/hicolor/512x512/apps/lmstudio-bin.png"
|
||||
install -Dm644 "${srcdir}/lmstudio.png" "${pkgdir}/usr/share/pixmaps/lmstudio-bin.png"
|
||||
|
||||
# Desktop entry
|
||||
install -Dm644 "$srcdir/lmstudio.desktop" "$pkgdir/usr/share/applications/lmstudio.desktop"
|
||||
|
||||
# Symlink to binary
|
||||
install -dm755 "$pkgdir/usr/bin"
|
||||
ln -s /opt/lm-studio/lm-studio.AppImage "$pkgdir/usr/bin/lm-studio"
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
pkgname=lmstudio-bin
|
||||
pkgver={{version}}
|
||||
pkgrel=1
|
||||
pkgdesc="LM Studio - A desktop app for exploring and running large language models locally"
|
||||
arch=('x86_64')
|
||||
url="https://lmstudio.ai"
|
||||
license=('EULA')
|
||||
depends=('fuse2' 'zlib' 'hicolor-icon-theme' 'gtk3' 'nss' 'libxcrypt-compat')
|
||||
options=('!strip')
|
||||
install=lmstudio-bin.install
|
||||
source=("{{url}}"
|
||||
"lmstudio.png"
|
||||
"lmstudio.desktop")
|
||||
sha256sums=('{{sha256}}'
|
||||
'{{icon_sha256}}'
|
||||
'SKIP')
|
||||
|
||||
prepare() {
|
||||
chmod +x "${srcdir}/${source[0]##*/}"
|
||||
}
|
||||
|
||||
package() {
|
||||
# Create installation directory
|
||||
install -dm755 "$pkgdir/opt/lm-studio"
|
||||
|
||||
# Install AppImage
|
||||
install -Dm755 "${srcdir}/${source[0]##*/}" "$pkgdir/opt/lm-studio/lm-studio.AppImage"
|
||||
|
||||
# Install static icon
|
||||
install -Dm644 "${srcdir}/lmstudio.png" "${pkgdir}/usr/share/icons/hicolor/512x512/apps/lmstudio-bin.png"
|
||||
install -Dm644 "${srcdir}/lmstudio.png" "${pkgdir}/usr/share/pixmaps/lmstudio-bin.png"
|
||||
|
||||
# Desktop entry
|
||||
install -Dm644 "$srcdir/lmstudio.desktop" "$pkgdir/usr/share/applications/lmstudio.desktop"
|
||||
|
||||
# Symlink to binary
|
||||
install -dm755 "$pkgdir/usr/bin"
|
||||
ln -s /opt/lm-studio/lm-studio.AppImage "$pkgdir/usr/bin/lm-studio"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
post_install() {
|
||||
update-desktop-database -q
|
||||
gtk-update-icon-cache -ftq /usr/share/icons/hicolor
|
||||
}
|
||||
|
||||
post_upgrade() {
|
||||
update-desktop-database -q
|
||||
gtk-update-icon-cache -ftq /usr/share/icons/hicolor
|
||||
}
|
||||
|
||||
post_remove() {
|
||||
update-desktop-database -q
|
||||
gtk-update-icon-cache -ftq /usr/share/icons/hicolor
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
[Desktop Entry]
|
||||
Name=LM Studio
|
||||
GenericName=Large Language Model Studio
|
||||
Comment=A desktop app for exploring and running large language models locally
|
||||
Exec=lm-studio %U
|
||||
Icon=lmstudio-bin
|
||||
Type=Application
|
||||
Categories=Development;ArtificialIntelligence;
|
||||
Terminal=false
|
||||
StartupNotify=true
|
||||
StartupWMClass=LM Studio
|
||||
MimeType=text/plain;
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
@@ -0,0 +1,204 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
LM Studio PKGBUILD Maintenance Engine
|
||||
|
||||
Resolves dynamic upstream link, extracts version, calculates SHA256,
|
||||
and generates PKGBUILD from template.
|
||||
|
||||
Updated to handle:
|
||||
- AppImage file with calculated sha256
|
||||
- .desktop file with 'SKIP' (locally managed)
|
||||
- Static icon (lmstudio.png) with calculated sha256
|
||||
- .install file staging and template rendering
|
||||
"""
|
||||
|
||||
import re
|
||||
import hashlib
|
||||
import requests
|
||||
import subprocess
|
||||
import tarfile
|
||||
from pathlib import Path
|
||||
from typing import Tuple, List
|
||||
|
||||
|
||||
def resolve_download_url(redirect_url: str = "https://lmstudio.ai/download/latest/linux/x64") -> str:
|
||||
"""
|
||||
Follow redirects to resolve the final download URL.
|
||||
Uses HEAD request to avoid downloading the full file.
|
||||
"""
|
||||
print(f"Resolving download URL: {redirect_url}")
|
||||
|
||||
session = requests.Session()
|
||||
response = session.head(redirect_url, allow_redirects=True)
|
||||
response.raise_for_status()
|
||||
|
||||
final_url = response.url
|
||||
print(f"Resolved URL: {final_url}")
|
||||
return final_url
|
||||
|
||||
|
||||
def extract_version(filename: str) -> str:
|
||||
"""
|
||||
Extract semantic version from filename using regex.
|
||||
Expected format: LM-Studio-X.Y.Z-x64.AppImage or LM-Studio-X.Y.Z-R-x64.AppImage
|
||||
Extracts only X.Y.Z portion (pkgrel handled separately in PKGBUILD).
|
||||
"""
|
||||
match = re.search(r'LM-Studio-([\d.]+)-(?:\d+-)?x64\.AppImage', filename)
|
||||
if match:
|
||||
return match.group(1)
|
||||
raise ValueError(f"Could not extract version from filename: {filename}")
|
||||
|
||||
|
||||
def calculate_sha256(file_path: str) -> str:
|
||||
"""
|
||||
Calculate SHA256 checksum of a file.
|
||||
Handles both AppImage and icon files with identical hashing logic.
|
||||
"""
|
||||
print(f"Calculating SHA256 for: {file_path}")
|
||||
|
||||
sha256_hash = hashlib.sha256()
|
||||
with open(file_path, "rb") as f:
|
||||
for byte_block in iter(lambda: f.read(4096), b""):
|
||||
sha256_hash.update(byte_block)
|
||||
|
||||
checksum = sha256_hash.hexdigest()
|
||||
print(f"SHA256: {checksum}")
|
||||
return checksum
|
||||
|
||||
|
||||
def download_file(url: str, file_path: str) -> None:
|
||||
"""
|
||||
Download file from URL if it doesn't already exist.
|
||||
"""
|
||||
path = Path(file_path)
|
||||
if path.exists():
|
||||
print(f"File already exists: {file_path}")
|
||||
return
|
||||
|
||||
print(f"Downloading: {url}")
|
||||
response = requests.get(url, stream=True)
|
||||
response.raise_for_status()
|
||||
|
||||
with open(file_path, "wb") as f:
|
||||
for chunk in response.iter_content(chunk_size=8192):
|
||||
if chunk:
|
||||
f.write(chunk)
|
||||
|
||||
print(f"Downloaded: {file_path}")
|
||||
|
||||
|
||||
def stage_install_file() -> None:
|
||||
"""
|
||||
Ensure lmstudio-bin.install file exists and is staged.
|
||||
"""
|
||||
install_path = Path("/home/madgoat/Documents/LMStudio-bin Aur/lmstudio-bin.install")
|
||||
|
||||
if install_path.exists():
|
||||
print(f"✓ Install file present: {install_path}")
|
||||
else:
|
||||
print(f"Warning: Install file not found at {install_path}")
|
||||
|
||||
|
||||
def render_template(template_path: str, output_path: str, version: str, url: str, sha256: str, icon_sha256: str) -> None:
|
||||
"""
|
||||
Render PKGBUILD from template by replacing placeholders.
|
||||
|
||||
Placeholders:
|
||||
- {{version}}: Semantic version extracted from filename
|
||||
- {{url}}: Resolved download URL
|
||||
- {{sha256}}: SHA256 checksum of the AppImage
|
||||
- {{icon_sha256}}: SHA256 checksum of the static icon (lmstudio.png)
|
||||
|
||||
The template includes sha256sums array with appimage hash, icon hash, and SKIP for .desktop file.
|
||||
"""
|
||||
print(f"Rendering template: {template_path} -> {output_path}")
|
||||
|
||||
with open(template_path, "r") as f:
|
||||
content = f.read()
|
||||
|
||||
content = content.replace("{{version}}", version)
|
||||
content = content.replace("{{url}}", url)
|
||||
content = content.replace("{{sha256}}", sha256)
|
||||
content = content.replace("{{icon_sha256}}", icon_sha256)
|
||||
|
||||
with open(output_path, "w") as f:
|
||||
f.write(content)
|
||||
|
||||
print(f"Generated: {output_path}")
|
||||
|
||||
|
||||
def generate_srcinfo() -> None:
|
||||
"""
|
||||
Generate .SRCINFO using makepkg --printsrcinfo.
|
||||
"""
|
||||
print("Generating .SRCINFO...")
|
||||
|
||||
result = subprocess.run(
|
||||
["makepkg", "--printsrcinfo"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
cwd="/home/madgoat/Documents/LMStudio-bin Aur"
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError(f"makepkg failed: {result.stderr}")
|
||||
|
||||
with open("/home/madgoat/Documents/LMStudio-bin Aur/.SRCINFO", "w") as f:
|
||||
f.write(result.stdout)
|
||||
|
||||
print("Generated: .SRCINFO")
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Main maintenance engine workflow.
|
||||
"""
|
||||
print("=== LM Studio PKGBUILD Maintenance Engine ===\n")
|
||||
|
||||
# Change to workspace directory
|
||||
import os
|
||||
os.chdir("/home/madgoat/Documents/LMStudio-bin Aur")
|
||||
|
||||
# Step 1: Resolve download URL
|
||||
final_url = resolve_download_url()
|
||||
|
||||
# Step 2: Extract filename and version
|
||||
filename = final_url.split("/")[-1]
|
||||
version = extract_version(filename)
|
||||
print(f"Detected version: {version}\n")
|
||||
|
||||
# Step 3: Download file if missing
|
||||
download_file(final_url, filename)
|
||||
|
||||
# Step 4: Calculate SHA256 for AppImage
|
||||
sha256 = calculate_sha256(filename)
|
||||
print()
|
||||
|
||||
# Step 5: Calculate SHA256 for static icon (lmstudio.png)
|
||||
# Uses identical hashing logic as AppImage
|
||||
icon_hash = calculate_sha256("lmstudio.png")
|
||||
print()
|
||||
|
||||
# Step 6: Stage install file
|
||||
stage_install_file()
|
||||
print()
|
||||
|
||||
# Step 7: Render PKGBUILD from template
|
||||
# The template uses {{sha256}} for the AppImage hash and {{icon_sha256}} for icon hash
|
||||
# and the sha256sums array in the template includes both hashes plus 'SKIP' for .desktop file
|
||||
render_template("PKGBUILD.template", "PKGBUILD", version, final_url, sha256, icon_hash)
|
||||
print()
|
||||
|
||||
# Step 8: Generate .SRCINFO
|
||||
generate_srcinfo()
|
||||
|
||||
print("\n=== Maintenance Engine Complete ===")
|
||||
print(f"Version: {version}")
|
||||
print(f"URL: {final_url}")
|
||||
print(f"AppImage SHA256: {sha256}")
|
||||
print(f"Icon SHA256: {icon_hash}")
|
||||
print(f"SHA256sums: ('{sha256}' '{icon_hash}' 'SKIP')")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
#!/bin/bash
|
||||
# Git Hygiene Verification Guard
|
||||
# Updated: Explicitly allows lmstudio.png, verifies exclusion of src/ and pkg/ from history and staged index
|
||||
|
||||
echo "=== Git Hygiene Verification Guard ==="
|
||||
echo ""
|
||||
|
||||
# Color codes
|
||||
RED="\033[0;31m"
|
||||
GREEN="\033[0;32m"
|
||||
YELLOW="\033[1;33m"
|
||||
NC="\033[0m"
|
||||
|
||||
FAIL=0
|
||||
|
||||
# Check 1: Verify lmstudio.png is NOT ignored (explicitly allowed)
|
||||
echo "Check 1: Verifying lmstudio.png is tracked/allowed..."
|
||||
if git ls-files lmstudio.png 2>/dev/null | grep -q "lmstudio.png"; then
|
||||
echo -e "${GREEN}✓ PASSED: lmstudio.png is tracked${NC}"
|
||||
elif ! git check-ignore lmstudio.png 2>/dev/null; then
|
||||
echo -e "${GREEN}✓ PASSED: lmstudio.png is not ignored${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠ WARNING: lmstudio.png appears to be in .gitignore${NC}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check 2: Verify src/ folder is NOT in git history
|
||||
echo "Check 2: Verifying src/ folder is NOT in git history..."
|
||||
SRC_IN_HISTORY=$(git log --all --full-history --name-only --format="" -- 'src/' 2>/dev/null | wc -l)
|
||||
if [ "$SRC_IN_HISTORY" -gt 0 ]; then
|
||||
echo -e "${RED}✗ FAILED: src/ folder found in git history${NC}"
|
||||
FAIL=1
|
||||
else
|
||||
echo -e "${GREEN}✓ PASSED: src/ folder is clean from history${NC}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check 3: Verify pkg/ folder is NOT in git history
|
||||
echo "Check 3: Verifying pkg/ folder is NOT in git history..."
|
||||
PKG_IN_HISTORY=$(git log --all --full-history --name-only --format="" -- 'pkg/' 2>/dev/null | wc -l)
|
||||
if [ "$PKG_IN_HISTORY" -gt 0 ]; then
|
||||
echo -e "${RED}✗ FAILED: pkg/ folder found in git history${NC}"
|
||||
FAIL=1
|
||||
else
|
||||
echo -e "${GREEN}✓ PASSED: pkg/ folder is clean from history${NC}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check 4: Verify src/ folder is NOT in staged index
|
||||
echo "Check 4: Verifying src/ folder is NOT in staged index..."
|
||||
SRC_STAGED=$(git diff --cached --name-only -- 'src/' 2>/dev/null | wc -l)
|
||||
if [ "$SRC_STAGED" -gt 0 ]; then
|
||||
echo -e "${RED}✗ FAILED: src/ folder has staged files${NC}"
|
||||
git diff --cached --name-only -- 'src/'
|
||||
FAIL=1
|
||||
else
|
||||
echo -e "${GREEN}✓ PASSED: src/ folder is clean from staged index${NC}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check 5: Verify pkg/ folder is NOT in staged index
|
||||
echo "Check 5: Verifying pkg/ folder is NOT in staged index..."
|
||||
PKG_STAGED=$(git diff --cached --name-only -- 'pkg/' 2>/dev/null | wc -l)
|
||||
if [ "$PKG_STAGED" -gt 0 ]; then
|
||||
echo -e "${RED}✗ FAILED: pkg/ folder has staged files${NC}"
|
||||
git diff --cached --name-only -- 'pkg/'
|
||||
FAIL=1
|
||||
else
|
||||
echo -e "${GREEN}✓ PASSED: pkg/ folder is clean from staged index${NC}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check 6: Verify no AppImages or packages are staged
|
||||
echo "Check 6: Verifying NO binary extensions are staged..."
|
||||
BINARY_STAGED=$(git diff --cached --name-only | grep -E "\.(AppImage|zst|tar\.gz)$" | wc -l)
|
||||
if [ "$BINARY_STAGED" -gt 0 ]; then
|
||||
echo -e "${RED}✗ FAILED: Binary files are staged!${NC}"
|
||||
git diff --cached --name-only | grep -E "\.(AppImage|zst|tar\.gz)$"
|
||||
FAIL=1
|
||||
else
|
||||
echo -e "${GREEN}✓ PASSED: No binary extensions staged${NC}"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# Check 7: Review staged changes
|
||||
echo "Check 7: Reviewing staged changes summary..."
|
||||
git diff --cached --stat
|
||||
echo ""
|
||||
|
||||
# Final result
|
||||
echo "=== Verification Summary ==="
|
||||
if [ "$FAIL" -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ All hygiene checks PASSED${NC}"
|
||||
echo "Repository is ready for commit."
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}✗ Some hygiene checks FAILED${NC}"
|
||||
echo "Please fix the issues before committing."
|
||||
exit 1
|
||||
fi
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
#!/bin/bash
|
||||
# LM Studio AUR Package Verification Script
|
||||
# Updated: Checks for vendored lmstudio.png in root, makes /usr/share checks informative in dev environments
|
||||
|
||||
echo "=== LM Studio AUR Verification ==="
|
||||
echo ""
|
||||
|
||||
# 1. Vendored Icon Existence Check (Primary)
|
||||
echo "[1/4] Checking Vendored Icon..."
|
||||
if [ -f "./lmstudio.png" ]; then
|
||||
echo "✓ Found vendored lmstudio.png in root"
|
||||
else
|
||||
echo "✗ MISSING: vendored lmstudio.png in root"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 2. System Icon Installation Check (Informative)
|
||||
echo "[2/4] Checking System Icon Installation..."
|
||||
if [ -f "/usr/share/pixmaps/lmstudio-bin.png" ]; then
|
||||
echo "✓ Found lmstudio-bin pixmap icon in /usr/share"
|
||||
else
|
||||
echo "ℹ INFO: lmstudio-bin pixmap not in /usr/share (expected in non-installed dev environment)"
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 3. Desktop File Verification
|
||||
echo "[3/4] Verifying Desktop Entry..."
|
||||
ICON_NAME=$(grep "^Icon=" lmstudio.desktop | cut -d'=' -f2)
|
||||
if [ "$ICON_NAME" == "lmstudio-bin" ]; then
|
||||
echo "✓ Desktop Icon name matches: $ICON_NAME"
|
||||
else
|
||||
echo "✗ Desktop Icon mismatch: $ICON_NAME (expected lmstudio-bin)"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
# 4. PKGBUILD Consistency
|
||||
echo "[4/4] Verifying PKGBUILD Icon Mapping..."
|
||||
grep -q "lmstudio.png" PKGBUILD
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ PKGBUILD contains lmstudio.png mapping"
|
||||
else
|
||||
echo "✗ PKGBUILD missing icon installation logic"
|
||||
exit 1
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== SYSTEM GREEN ==="
|
||||
@@ -1,20 +0,0 @@
|
||||
pkgbase = lmstudio
|
||||
pkgdesc = Discover, download, and run local LLMs
|
||||
pkgver = 0.3.35.1
|
||||
pkgrel = 1
|
||||
url = https://lmstudio.ai/
|
||||
arch = x86_64
|
||||
license = LicenseRef-EULA
|
||||
makedepends = squashfs-tools
|
||||
makedepends = graphicsmagick
|
||||
depends = zlib
|
||||
depends = hicolor-icon-theme
|
||||
depends = fuse2
|
||||
depends = clblast
|
||||
noextract = lmstudio-0.3.35.1.AppImage
|
||||
options = !strip
|
||||
options = !debug
|
||||
source = lmstudio-0.3.35.1.AppImage::https://installers.lmstudio.ai/linux/x64/0.3.35-1/LM-Studio-0.3.35-1-x64.AppImage
|
||||
sha256sums = ad9bf98e91ff13b5eea1d26f1457c8d7c4bed24bbb419551d5cbff4840380953
|
||||
|
||||
pkgname = lmstudio
|
||||
@@ -1,3 +0,0 @@
|
||||
[lmstudio]
|
||||
source = "cmd"
|
||||
cmd = "curl -sIL -o /dev/null -w '%{url_effective}\\n' https://lmstudio.ai/download/latest/linux/x64 | sed -E 's|.*x64/([0-9]+\\.[0-9]+\\.[0-9]+)-([0-9]+).*|\\1.\\2|'"
|
||||
@@ -1,69 +0,0 @@
|
||||
# Maintainer: envolution
|
||||
# Contributor: SoleSoul
|
||||
# shellcheck shell=bash disable=SC2034,SC2154
|
||||
|
||||
pkgname=lmstudio
|
||||
_appname=lm-studio
|
||||
pkgver=0.3.35.1
|
||||
_pkgver="${pkgver%.*}-${pkgver##*.}"
|
||||
pkgrel=1
|
||||
pkgdesc="Discover, download, and run local LLMs"
|
||||
arch=('x86_64')
|
||||
url="https://lmstudio.ai/"
|
||||
license=('LicenseRef-EULA')
|
||||
depends=('zlib' 'hicolor-icon-theme' 'fuse2' 'clblast')
|
||||
makedepends=('squashfs-tools' 'graphicsmagick')
|
||||
options=(!strip !debug)
|
||||
_appimage="${pkgname}-${pkgver}.AppImage"
|
||||
source=("${_appimage}::https://installers.lmstudio.ai/linux/x64/${_pkgver}/LM-Studio-${_pkgver}-x64.AppImage")
|
||||
sha256sums=('ad9bf98e91ff13b5eea1d26f1457c8d7c4bed24bbb419551d5cbff4840380953')
|
||||
noextract=("${_appimage}")
|
||||
|
||||
prepare() {
|
||||
rm -rf squashfs-root
|
||||
chmod +x "${_appimage}"
|
||||
# get the files we need for packaging
|
||||
offset=$(./"${_appimage}" --appimage-offset)
|
||||
unset PAGER # unsquashfs is very picky about pager settings
|
||||
unsquashfs -q -o "$offset" -d squashfs-root "${_appimage}" \
|
||||
"${_appname}.desktop" \
|
||||
"usr/share/icons/hicolor/0x0/apps/lm-studio.png" \
|
||||
"LICENSE.electron.txt" \
|
||||
"LICENSES.chromium.html"
|
||||
# unsquashfs -o "$offset" -l "${_appimage}" | grep -i license
|
||||
}
|
||||
|
||||
build() {
|
||||
# Adjust .desktop so it will work outside of AppImage container
|
||||
sed -i -E "s|Exec=AppRun|Exec=env DESKTOPINTEGRATION=false /usr/bin/${pkgname}|" \
|
||||
"squashfs-root/${_appname}.desktop"
|
||||
sed -i -E "s|Icon=.*|Icon=${pkgname}|" \
|
||||
"squashfs-root/${_appname}.desktop"
|
||||
}
|
||||
|
||||
package() {
|
||||
# AppImage
|
||||
install -Dm755 "${srcdir}/${_appimage}" "${pkgdir}/opt/${pkgname}/${_appname}.AppImage"
|
||||
install -Dm644 "${srcdir}/squashfs-root/LICENSE"* -t "${pkgdir}/usr/share/licenses/${pkgname}"
|
||||
install -Dm644 /dev/stdin "$pkgdir/usr/share/licenses/$pkgname/EULA" <<< "https://lmstudio.ai/app-terms"
|
||||
|
||||
|
||||
# Desktop file
|
||||
install -Dm644 "${srcdir}/squashfs-root/${_appname}.desktop" \
|
||||
"${pkgdir}/usr/share/applications/${pkgname}.desktop"
|
||||
|
||||
#source icon from squashfs
|
||||
src_icon="$srcdir/squashfs-root/usr/share/icons/hicolor/0x0/apps/lm-studio.png"
|
||||
sizes=("16x16" "32x32" "48x48" "64x64" "128x128" "256x256")
|
||||
|
||||
# Loop through each size and create resized icons
|
||||
for size in "${sizes[@]}"; do
|
||||
install -dm755 "${pkgdir}/usr/share/icons/hicolor/$size/apps"
|
||||
gm convert "$src_icon" -resize "$size" "$pkgdir/usr/share/icons/hicolor/$size/apps/${pkgname}.png"
|
||||
done
|
||||
|
||||
# Symlink executable
|
||||
install -dm755 "${pkgdir}/usr/bin"
|
||||
ln -s "/opt/${pkgname}/${_appname}.AppImage" "${pkgdir}/usr/bin/${pkgname}"
|
||||
}
|
||||
# vim:set ts=2 sw=2 et:
|
||||
Reference in new issue
Block a user