import os import hashlib import zipfile from pathlib import Path import shutil import subprocess def get_font_files(font_folder): """Find all .ttf and .otf files in the given folder.""" font_files = [] for root, _, files in os.walk(font_folder): for file in files: if file.lower().endswith(('.ttf', '.otf')): font_files.append(os.path.join(root, file)) return font_files def generate_sha256(file_path): """Generate the sha256 hash of the given file.""" 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) return sha256_hash.hexdigest() def create_zip(font_files, font_folder, zip_path): """Create a zip file from the font files.""" print(f"Creating zip file at {zip_path} with the following font files:") for font_file in font_files: print(f" - {font_file}") with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf: for file in font_files: # Add the font file with its relative path arcname = os.path.relpath(file, font_folder) zipf.write(file, arcname) print(f"Added {file} to the zip as {arcname}") def create_ruby_file(font_name, zip_path, sha256_hash): """Generate a Ruby formula file for the font.""" formula_content = f"""class {font_name} < Formula desc "Font for {font_name}" homepage "https://github.com/{font_name}" url "{zip_path}" sha256 "{sha256_hash}" version "latest" def install (share/"fonts").install Dir["*.ttf", "*.otf"] end test do assert_predicate share/"fonts/{font_name}-Regular.ttf", :exist? end end """ formula_path = f"./{font_name}/{font_name.lower()}.rb" with open(formula_path, 'w') as formula_file: formula_file.write(formula_content) print(f"Ruby file created at {formula_path}") return formula_path def move_formula_to_formula_folder(formula_path): """Move the formula file to the Formula directory in the tap.""" formula_folder = "./Formula" if not os.path.exists(formula_folder): os.makedirs(formula_folder) shutil.move(formula_path, os.path.join(formula_folder, os.path.basename(formula_path))) print(f"Moved {formula_path} to {formula_folder}/") def font_exists(font_name): """Check if the formula already exists in the Formula folder.""" formula_path = f"./Formula/font-{font_name.lower()}.rb" return os.path.exists(formula_path) def stage_and_commit_changes(font_name, font_folder_path, formula_path): """Stage only the new font zip file and the formula file, then commit.""" try: # Stage the new font zip file zip_file_path = font_folder_path / f"{font_name.lower()}.zip" subprocess.run(["git", "add", str(zip_file_path)], check=True) # Stage the formula file from the Formula folder formula_in_formula_folder = f"./Formula/{font_name.lower()}.rb" subprocess.run(["git", "add", formula_in_formula_folder], check=True) # Commit with a default message commit_message = f"Add {font_name} font" subprocess.run(["git", "commit", "-m", commit_message], check=True) print(f"Changes staged and committed with message: '{commit_message}'") except subprocess.CalledProcessError as e: print(f"Error while staging or committing: {e}") def main(): font_folder = input("Enter the location of the font folder: ").strip() if not os.path.isdir(font_folder): print("The folder does not exist. Please provide a valid path.") return font_files = get_font_files(font_folder) if not font_files: print("No .ttf or .otf font files found in the specified folder.") return font_name = input("Enter the name of the font (e.g., FiraCode): ").strip() # Add the "font-" prefix to the font name font_package_name = f"font-{font_name.lower()}" # Check if the font already exists in the Formula folder if font_exists(font_name): update = input( f"The font '{font_package_name}' already exists. Do you want to update it? (y/n): ").strip().lower() if update != 'y': print("Font update canceled.") return # Create the folder for the font font_folder_path = Path(f"./{font_package_name}") font_folder_path.mkdir(exist_ok=True) zip_path = f"./{font_package_name}/{font_package_name}.zip" create_zip(font_files, font_folder, zip_path) sha256_hash = generate_sha256(zip_path) print(f"SHA256 hash generated: {sha256_hash}") formula_path = create_ruby_file(font_package_name, zip_path, sha256_hash) # Move the formula to the Formula directory move_formula_to_formula_folder(formula_path) # Stage and commit the changes (only the font and its formula) stage_and_commit_changes(font_package_name, font_folder_path, formula_path) print(f"Font {font_package_name} has been added successfully.") print("Remember to push your changes to GitHub manually.") if __name__ == "__main__": main()