-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathhexbrew.py
More file actions
116 lines (99 loc) · 3.83 KB
/
hexbrew.py
File metadata and controls
116 lines (99 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import yaml
import os
import hashlib
import tarfile
from pathlib import Path
class BrewPackager:
def __init__(self, config_path):
with open(config_path) as f:
self.config = yaml.safe_load(f)
self.name = self.config['name']
self.version = self.config['version']
self.files_dir = Path(self.config['files_dir'])
self.output_dir = Path(self.config['output_dir'])
self.codesign = self.config.get('codesign', False)
self.download_url = self.config['download_url']
self.commands = self.config.get('commands', [])
def create_tarball(self):
"""Create tar.gz archive of files"""
tarball_path = self.output_dir / f"{self.name}-{self.version}.tar.gz"
with tarfile.open(tarball_path, "w:gz") as tar:
tar.add(self.files_dir, arcname=self.name)
return tarball_path
def calculate_sha256(self, file_path):
"""Calculate SHA256 checksum of 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 generate_formula(self, tarball_path, sha256):
"""Generate Ruby formula file for brew tap with embedded commands"""
formula = f"""class {self.name.capitalize()} < Formula
desc "{self.config['description']}"
homepage "{self.config['homepage']}"
"""
#Add custom download URL if enabled
if self.download_url:
formula += f"""url "{self.download_url}"
"""
else:
formula += f"""url "https://github.com/{self.config['github_repo']}/releases/download/v{self.version}/{tarball_path.name}"
"""
formula += f"""sha256 "{sha256}"
version "{self.version}"
def install
bin.install Dir["*"]
"""
# Add codesigning if enabled
if self.codesign:
formula += """ Dir["#{bin}/*"].each do |f|
system "codesign", "--force", "--sign", "-", f if File.file?(f)
end
"""
# Add commands
if self.commands:
formula += "\n".join(f' system "{cmd}"' for cmd in self.commands)
formula += "\n"
formula += " end\n"
# Add caveats
caveat = self.config.get("caveat")
if caveat:
formula += f"""
def caveats
<<~EOS
{caveat.strip()}
EOS
end
"""
formula += "end\n"
formula_path = self.output_dir / "Formula" / f"{self.name}.rb"
os.makedirs(formula_path.parent, exist_ok=True)
with open(formula_path, "w") as f:
f.write(formula)
return formula_path
def print_github_commands(self):
"""Print commands for GitHub setup"""
repo = self.config['github_repo']
print(f"\nCreated release v{self.version} and upload {self.name}-{self.version}.tar.gz\n\n")
print("To push to GitHub, run:")
print(" cd", self.output_dir)
print(" git init")
print(" git add .")
print(' git commit -m "Initial brew tap commit"')
print(" git branch -M main")
print(f" git remote add origin https://github.com/{repo}.git")
print(" git push -u origin main\n\n")
print("To install with brew:")
print(f" brew tap {repo}")
print(f" brew install {self.name}")
def build(self):
"""Build complete brew tap package"""
os.makedirs(self.output_dir, exist_ok=True)
tarball_path = self.create_tarball()
sha256 = self.calculate_sha256(tarball_path)
formula_path = self.generate_formula(tarball_path, sha256)
self.print_github_commands()
if __name__ == "__main__":
packager = BrewPackager("config.yaml")
result = packager.build()