269 lines
No EOL
9.9 KiB
Python
Executable file
269 lines
No EOL
9.9 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
import os
|
|
import sys
|
|
import shutil
|
|
import subprocess
|
|
import hashlib
|
|
import zipfile
|
|
import tempfile
|
|
import json
|
|
import requests
|
|
from pathlib import Path
|
|
from dotenv import load_dotenv
|
|
|
|
# Load environment variables from .env file
|
|
load_dotenv()
|
|
|
|
def create_gitea_repo(gitea_url, gitea_username, gitea_token, repo_name, description):
|
|
"""Create a new repository on Gitea using the API."""
|
|
api_url = f"{gitea_url}/api/v1/user/repos"
|
|
headers = {
|
|
"Authorization": f"token {gitea_token}",
|
|
"Content-Type": "application/json"
|
|
}
|
|
data = {
|
|
"name": repo_name,
|
|
"description": description,
|
|
"private": False,
|
|
"auto_init": False
|
|
}
|
|
|
|
print(f"Creating repository {repo_name} on Gitea...")
|
|
response = requests.post(api_url, headers=headers, json=data)
|
|
|
|
if response.status_code == 201:
|
|
print(f"Repository {repo_name} created successfully.")
|
|
return response.json()
|
|
else:
|
|
print(f"Error creating repository: {response.status_code} - {response.text}")
|
|
return None
|
|
|
|
def create_zip(font_files, zip_path):
|
|
"""Create a zip file with the font files."""
|
|
print(f"Creating zip file at {zip_path} with the following font files:")
|
|
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
|
for font_file in font_files:
|
|
print(f" - {font_file}")
|
|
# Add each font file to the zip with its original name (no path)
|
|
arcname = os.path.basename(font_file)
|
|
zipf.write(font_file, arcname=arcname)
|
|
print(f"Zip file created at {zip_path}")
|
|
|
|
def generate_sha256(zip_path):
|
|
"""Generate SHA256 hash for the zip file."""
|
|
sha256_hash = hashlib.sha256()
|
|
with open(zip_path, "rb") as f:
|
|
# Read in 4k chunks to hash
|
|
for byte_block in iter(lambda: f.read(4096), b""):
|
|
sha256_hash.update(byte_block)
|
|
return sha256_hash.hexdigest()
|
|
|
|
def create_font_repo(font_name, font_files, gitea_url, gitea_username, gitea_token):
|
|
"""Create a new repository for the font and set it up with the necessary files."""
|
|
# Create a temporary directory for the font repository
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
# Create the zip file
|
|
zip_filename = f"{font_name}.zip"
|
|
zip_path = os.path.join(temp_dir, zip_filename)
|
|
create_zip(font_files, zip_path)
|
|
|
|
# Generate SHA256 hash for the zip file
|
|
sha256_hash = generate_sha256(zip_path)
|
|
print(f"SHA256 hash generated: {sha256_hash}")
|
|
|
|
# Create the repository on Gitea
|
|
repo_name = f"font-{font_name}"
|
|
description = f"Font files for {font_name}"
|
|
repo_data = create_gitea_repo(gitea_url, gitea_username, gitea_token, repo_name, description)
|
|
|
|
if not repo_data:
|
|
print("Failed to create repository on Gitea.")
|
|
return None, None, None
|
|
|
|
# Clone the repository
|
|
repo_url = repo_data["clone_url"]
|
|
repo_path = os.path.join(temp_dir, repo_name)
|
|
subprocess.run(["git", "clone", repo_url, repo_path], check=True)
|
|
|
|
# Copy the zip file to the repository
|
|
shutil.copy(zip_path, os.path.join(repo_path, zip_filename))
|
|
|
|
# Create a README.md file
|
|
with open(os.path.join(repo_path, "README.md"), "w") as f:
|
|
f.write(f"# {font_name} Font\n\n")
|
|
f.write(f"This repository contains the font files for {font_name}.\n\n")
|
|
f.write(f"SHA256: {sha256_hash}\n")
|
|
|
|
# Commit and push the changes
|
|
subprocess.run(["git", "-C", repo_path, "add", "."], check=True)
|
|
subprocess.run(["git", "-C", repo_path, "commit", "-m", f"Add {font_name} font files"], check=True)
|
|
subprocess.run(["git", "-C", repo_path, "push"], check=True)
|
|
|
|
# Create a local copy of the zip file for the formula
|
|
local_zip_path = os.path.join(os.getcwd(), zip_filename)
|
|
shutil.copy(zip_path, local_zip_path)
|
|
|
|
return repo_path, sha256_hash, zip_filename
|
|
|
|
def create_formula(font_name, sha256_hash, gitea_url, gitea_username, zip_filename):
|
|
"""Create the Homebrew formula for the font."""
|
|
# Get the font filename without extension (assuming it's a valid font file in the zip)
|
|
font_file = os.path.basename(font_files[0]) # Assumes the first font file is the primary font file
|
|
|
|
# Convert font_name to CamelCase for the class name
|
|
class_name = ''.join(word.capitalize() for word in font_name.split('-'))
|
|
|
|
# Create the formula content
|
|
formula_content = f"""class {class_name} < Formula
|
|
desc "A custom font"
|
|
homepage "{gitea_url}/{gitea_username}/font-{font_name}"
|
|
url "{gitea_url}/{gitea_username}/font-{font_name}/raw/branch/master/{zip_filename}"
|
|
sha256 "{sha256_hash}"
|
|
version "1.0.0"
|
|
|
|
def install
|
|
(share/"fonts").install "{font_file}"
|
|
end
|
|
|
|
test do
|
|
# Test installation by checking that the font exists
|
|
system "fc-list | grep '{font_file.split('.')[0]}'"
|
|
end
|
|
end
|
|
"""
|
|
|
|
# Create the formula directory if it doesn't exist
|
|
formula_dir = os.path.join(os.getcwd(), "Formula")
|
|
os.makedirs(formula_dir, exist_ok=True)
|
|
|
|
# Write the formula to a file
|
|
formula_path = os.path.join(formula_dir, f"font-{font_name}.rb")
|
|
with open(formula_path, "w") as f:
|
|
f.write(formula_content)
|
|
|
|
print(f"Formula created at {formula_path}")
|
|
return formula_path
|
|
|
|
def add_submodule(font_name, gitea_url, gitea_username):
|
|
"""Add the font repository as a submodule."""
|
|
# Create the fonts directory if it doesn't exist
|
|
fonts_dir = os.path.join(os.getcwd(), "fonts")
|
|
os.makedirs(fonts_dir, exist_ok=True)
|
|
|
|
# Add the submodule
|
|
submodule_path = os.path.join(fonts_dir, font_name)
|
|
repo_url = f"{gitea_url}/{gitea_username}/font-{font_name}.git"
|
|
|
|
# Check if the submodule already exists
|
|
if os.path.exists(submodule_path):
|
|
print(f"Submodule {submodule_path} already exists. Removing it first.")
|
|
subprocess.run(["git", "submodule", "deinit", "-f", submodule_path], check=True)
|
|
subprocess.run(["git", "rm", "-f", submodule_path], check=True)
|
|
subprocess.run(["rm", "-rf", f".git/modules/{submodule_path}"], check=True)
|
|
|
|
# Add the submodule
|
|
print(f"Adding submodule {submodule_path}...")
|
|
subprocess.run(["git", "submodule", "add", repo_url, submodule_path], check=True)
|
|
|
|
return submodule_path
|
|
|
|
def update_submodule_index(font_name, submodule_path):
|
|
"""Update the submodule index file."""
|
|
# Create the index file if it doesn't exist
|
|
index_path = os.path.join(os.getcwd(), "fonts", "index.json")
|
|
if not os.path.exists(index_path):
|
|
with open(index_path, "w") as f:
|
|
json.dump({"fonts": []}, f, indent=2)
|
|
|
|
# Read the index file
|
|
with open(index_path, "r") as f:
|
|
index = json.load(f)
|
|
|
|
# Add the font to the index
|
|
font_info = {
|
|
"name": font_name,
|
|
"path": submodule_path,
|
|
"formula": f"font-{font_name}"
|
|
}
|
|
|
|
# Check if the font is already in the index
|
|
for i, font in enumerate(index.get("fonts", [])):
|
|
if font["name"] == font_name:
|
|
index["fonts"][i] = font_info
|
|
break
|
|
else:
|
|
# Add the font to the index
|
|
if "fonts" not in index:
|
|
index["fonts"] = []
|
|
index["fonts"].append(font_info)
|
|
|
|
# Write the updated index back to the file
|
|
with open(index_path, "w") as f:
|
|
json.dump(index, f, indent=2)
|
|
|
|
print(f"Index updated at {index_path}")
|
|
|
|
def main():
|
|
# Get the Gitea URL from environment variable or prompt
|
|
gitea_url = os.getenv("GITEA_URL")
|
|
if not gitea_url:
|
|
gitea_url = input("Enter your Gitea URL (e.g., http://clancy.genet-godzilla.ts.net:3002): ")
|
|
|
|
# Get the Gitea username from environment variable or prompt
|
|
gitea_username = os.getenv("GITEA_USERNAME")
|
|
if not gitea_username:
|
|
gitea_username = input("Enter your Gitea username: ")
|
|
|
|
# Get the Gitea token from environment variable or prompt
|
|
gitea_token = os.getenv("GITEA_API_TOKEN")
|
|
if not gitea_token:
|
|
gitea_token = input("Enter your Gitea API token: ")
|
|
|
|
# Get the font name
|
|
font_name = input("Enter the name of the font (e.g., FiraCode): ").lower()
|
|
|
|
# Get the font files
|
|
font_folder = input("Enter the location of the font folder: ").strip("'\"") # Strip quotes from the input
|
|
print(f"Looking for font files in: {font_folder}")
|
|
|
|
# Check if the folder exists
|
|
if not os.path.exists(font_folder):
|
|
print(f"Error: The folder '{font_folder}' does not exist.")
|
|
return
|
|
|
|
# Find all the font files in the provided folder
|
|
font_files = [os.path.join(font_folder, f) for f in os.listdir(font_folder) if f.endswith(('ttf', 'otf'))]
|
|
|
|
if not font_files:
|
|
print("No font files found in the provided folder.")
|
|
return
|
|
|
|
print(f"Found {len(font_files)} font files:")
|
|
for font_file in font_files:
|
|
print(f" - {os.path.basename(font_file)}")
|
|
|
|
# Create the font repository
|
|
font_repo_path, sha256_hash, zip_filename = create_font_repo(font_name, font_files, gitea_url, gitea_username, gitea_token)
|
|
|
|
if not font_repo_path:
|
|
print("Failed to create font repository. Exiting.")
|
|
return
|
|
|
|
# Create the formula
|
|
formula_path = create_formula(font_name, sha256_hash, gitea_url, gitea_username, zip_filename)
|
|
|
|
# Add the submodule
|
|
submodule_path = add_submodule(font_name, gitea_url, gitea_username)
|
|
|
|
# Update the submodule index
|
|
update_submodule_index(font_name, submodule_path)
|
|
|
|
# Stage and commit the changes
|
|
subprocess.run(["git", "add", formula_path, "fonts/index.json", submodule_path], check=True)
|
|
subprocess.run(["git", "commit", "-m", f"Add {font_name} font as submodule"], check=True)
|
|
|
|
print(f"Font {font_name} has been added successfully as a submodule.")
|
|
print("Remember to push your changes to Gitea manually.")
|
|
|
|
if __name__ == "__main__":
|
|
main() |