mct-cli 0.2.5__tar.gz → 0.2.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mct_cli-0.2.5 → mct_cli-0.2.6}/.github/workflows/release.yml +13 -40
- {mct_cli-0.2.5 → mct_cli-0.2.6}/PKG-INFO +1 -1
- {mct_cli-0.2.5 → mct_cli-0.2.6}/pyproject.toml +1 -1
- mct_cli-0.2.6/scripts/update_homebrew_formula.py +90 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/uv.lock +1 -1
- {mct_cli-0.2.5 → mct_cli-0.2.6}/.gitignore +0 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/.python-version +0 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/CLAUDE.md +0 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/LICENSE +0 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/README.md +0 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/src/mct/__init__.py +0 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/src/mct/cli.py +0 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/src/mct/commands/dock.py +0 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/src/mct/commands/finder.py +0 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/src/mct/commands/keyboard.py +0 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/src/mct/commands/screenshot.py +0 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/src/mct/commands/system.py +0 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/src/mct/config.py +0 -0
- {mct_cli-0.2.5 → mct_cli-0.2.6}/src/mct/defaults.py +0 -0
|
@@ -114,54 +114,27 @@ jobs:
|
|
|
114
114
|
done
|
|
115
115
|
echo "Warning: Timed out waiting for PyPI, continuing anyway..."
|
|
116
116
|
|
|
117
|
-
- name:
|
|
118
|
-
uses:
|
|
117
|
+
- name: Checkout
|
|
118
|
+
uses: actions/checkout@v6
|
|
119
119
|
|
|
120
|
-
- name:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
# Fetch package info from PyPI
|
|
125
|
-
PYPI_JSON=$(curl -s "https://pypi.org/pypi/mct-cli/$VERSION/json")
|
|
120
|
+
- name: Set up Python
|
|
121
|
+
uses: actions/setup-python@v6
|
|
122
|
+
with:
|
|
123
|
+
python-version: "3.12"
|
|
126
124
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
SHA256=$(echo "$PYPI_JSON" | python3 -c "import sys, json; urls = json.load(sys.stdin)['urls']; sdist = next(u for u in urls if u['packagetype'] == 'sdist'); print(sdist['digests']['sha256'])")
|
|
125
|
+
- name: Set up Homebrew
|
|
126
|
+
uses: Homebrew/actions/setup-homebrew@main
|
|
130
127
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
echo "Package URL: $URL"
|
|
134
|
-
echo "SHA256: $SHA256"
|
|
128
|
+
- name: Tap formula repo
|
|
129
|
+
run: brew tap ocolunga/mct-cli
|
|
135
130
|
|
|
136
|
-
- name:
|
|
131
|
+
- name: Update formula
|
|
137
132
|
run: |
|
|
138
133
|
VERSION="${{ steps.version.outputs.version }}"
|
|
139
|
-
SHA256="${{ steps.pypi.outputs.sha256 }}"
|
|
140
|
-
URL="${{ steps.pypi.outputs.url }}"
|
|
141
|
-
|
|
142
|
-
# Tap the repo (installs to proper Homebrew location)
|
|
143
|
-
brew tap ocolunga/mct-cli
|
|
144
|
-
|
|
145
|
-
# Get the tap directory
|
|
146
134
|
TAP_DIR="$(brew --prefix)/Library/Taps/ocolunga/homebrew-mct-cli"
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
# Update URL and SHA256
|
|
150
|
-
sed -i '' "s|url \".*\"|url \"${URL}\"|" "$FORMULA"
|
|
151
|
-
sed -i '' "s|sha256 \".*\"|sha256 \"${SHA256}\"|" "$FORMULA"
|
|
152
|
-
|
|
135
|
+
python scripts/update_homebrew_formula.py "$VERSION" "$TAP_DIR/Formula/mct-cli.rb"
|
|
153
136
|
echo "Updated formula:"
|
|
154
|
-
cat "$
|
|
155
|
-
|
|
156
|
-
- name: Update Python resource dependencies
|
|
157
|
-
run: |
|
|
158
|
-
echo "Updating Python resources..."
|
|
159
|
-
for i in {1..6}; do
|
|
160
|
-
brew update-python-resources ocolunga/mct-cli/mct-cli && break
|
|
161
|
-
echo "Attempt $i/6 failed, waiting 30s for PyPI to propagate..."
|
|
162
|
-
sleep 30
|
|
163
|
-
done
|
|
164
|
-
echo "Resources updated successfully"
|
|
137
|
+
cat "$TAP_DIR/Formula/mct-cli.rb"
|
|
165
138
|
|
|
166
139
|
- name: Commit and push
|
|
167
140
|
env:
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Update Homebrew formula: main url/sha256 + all resource blocks."""
|
|
3
|
+
import json
|
|
4
|
+
import re
|
|
5
|
+
import subprocess
|
|
6
|
+
import sys
|
|
7
|
+
import urllib.request
|
|
8
|
+
|
|
9
|
+
PACKAGE = "mct-cli"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def pypi_json(name, version):
|
|
13
|
+
url = f"https://pypi.org/pypi/{name}/{version}/json"
|
|
14
|
+
with urllib.request.urlopen(url) as f:
|
|
15
|
+
return json.loads(f.read())
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def sdist_url_sha256(name, version):
|
|
19
|
+
data = pypi_json(name, version)
|
|
20
|
+
for u in data["urls"]:
|
|
21
|
+
if u["packagetype"] == "sdist":
|
|
22
|
+
return u["url"], u["digests"]["sha256"]
|
|
23
|
+
raise RuntimeError(f"No sdist for {name}=={version}")
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_deps(package, version):
|
|
27
|
+
"""Return {name: version} for all transitive pip deps (excluding the package itself)."""
|
|
28
|
+
result = subprocess.run(
|
|
29
|
+
[sys.executable, "-m", "pip", "install",
|
|
30
|
+
"--dry-run", "--ignore-installed", "--quiet",
|
|
31
|
+
"--report", "-", f"{package}=={version}"],
|
|
32
|
+
capture_output=True, text=True, check=True,
|
|
33
|
+
)
|
|
34
|
+
report = json.loads(result.stdout)
|
|
35
|
+
pkg_names = {package.lower(), package.replace("-", "_").lower()}
|
|
36
|
+
return {
|
|
37
|
+
pkg["metadata"]["name"]: pkg["metadata"]["version"]
|
|
38
|
+
for pkg in report["install"]
|
|
39
|
+
if pkg["metadata"]["name"].lower() not in pkg_names
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def update_formula(formula_path, main_url, main_sha256, resources):
|
|
44
|
+
with open(formula_path) as f:
|
|
45
|
+
content = f.read()
|
|
46
|
+
|
|
47
|
+
# Only replace the top-level url/sha256 (2-space indent, not inside resource blocks)
|
|
48
|
+
content = re.sub(r'^ url ".*"', f' url "{main_url}"', content, flags=re.MULTILINE)
|
|
49
|
+
content = re.sub(r'^ sha256 ".*"', f' sha256 "{main_sha256}"', content, flags=re.MULTILINE)
|
|
50
|
+
|
|
51
|
+
# Rebuild resource blocks
|
|
52
|
+
blocks = ""
|
|
53
|
+
for name in sorted(resources):
|
|
54
|
+
url, sha256 = resources[name]
|
|
55
|
+
rb_name = name.lower().replace("_", "-")
|
|
56
|
+
blocks += f'\n resource "{rb_name}" do\n url "{url}"\n sha256 "{sha256}"\n end\n'
|
|
57
|
+
|
|
58
|
+
# Replace all existing resource blocks, insert before `def install`
|
|
59
|
+
content = re.sub(r'\n resource ".*?" do.*?end\n', "", content, flags=re.DOTALL)
|
|
60
|
+
content = content.replace("\n def install", blocks + "\n def install")
|
|
61
|
+
|
|
62
|
+
with open(formula_path, "w") as f:
|
|
63
|
+
f.write(content)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
if __name__ == "__main__":
|
|
67
|
+
if len(sys.argv) != 3:
|
|
68
|
+
print(f"Usage: {sys.argv[0]} <version> <formula_path>", file=sys.stderr)
|
|
69
|
+
sys.exit(1)
|
|
70
|
+
|
|
71
|
+
version = sys.argv[1]
|
|
72
|
+
formula_path = sys.argv[2]
|
|
73
|
+
|
|
74
|
+
print(f"Fetching {PACKAGE}=={version} from PyPI...")
|
|
75
|
+
main_url, main_sha256 = sdist_url_sha256(PACKAGE, version)
|
|
76
|
+
print(f"URL: {main_url}")
|
|
77
|
+
print(f"SHA256: {main_sha256}")
|
|
78
|
+
|
|
79
|
+
print("Resolving dependencies...")
|
|
80
|
+
deps = get_deps(PACKAGE, version)
|
|
81
|
+
for name, ver in deps.items():
|
|
82
|
+
print(f" {name}=={ver}")
|
|
83
|
+
|
|
84
|
+
resources = {}
|
|
85
|
+
for name, ver in deps.items():
|
|
86
|
+
url, sha256 = sdist_url_sha256(name, ver)
|
|
87
|
+
resources[name] = (url, sha256)
|
|
88
|
+
|
|
89
|
+
update_formula(formula_path, main_url, main_sha256, resources)
|
|
90
|
+
print("Formula updated successfully.")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|