Skip to content

Commit 2c84342

Browse files
committed
Added generate-all-sources.py
1 parent 975e91b commit 2c84342

7 files changed

Lines changed: 21624 additions & 2746 deletions

.claude/settings.local.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"permissions": {
3+
"allow": [
4+
"Bash(grep -r \"\\\\.FLATPAK\\\\|Flatpak\\\\|flatpak\" D:/development/Github-Store --include=*.kt)"
5+
]
6+
}
7+
}

packaging/flatpak/disable-android-for-flatpak.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,55 @@ set -euo pipefail
99

1010
echo "=== Disabling Android targets for Flatpak build ==="
1111

12+
CONVENTION_DIR="build-logic/convention/src/main/kotlin"
13+
1214
# Note: Step 0 (offline repo) removed — using --share=network instead
1315

1416
# ─────────────────────────────────────────────────────────────────────
1517
# 1. Root build.gradle.kts — comment out Android plugin declarations
1618
# ─────────────────────────────────────────────────────────────────────
19+
echo "[0/7] Removing Android & non-essential dependencies from build-logic/convention/build.gradle.kts"
20+
sed -i \
21+
-e '/compileOnly(libs.android.gradlePlugin)/d' \
22+
-e '/compileOnly(libs.android.tools.common)/d' \
23+
-e '/alias(libs.plugins.flatpak.gradle.generator)/d' \
24+
-e '/flatpakGradleGenerator/,/^}/d' \
25+
build-logic/convention/build.gradle.kts
26+
27+
# Stub out Android utility files that reference Android SDK
28+
cat > "$CONVENTION_DIR/zed/rainxch/githubstore/convention/AndroidCompose.kt" << 'KOTLIN'
29+
package zed.rainxch.githubstore.convention
30+
31+
import org.gradle.api.Project
32+
33+
// Stubbed out for Flatpak build — no Android SDK available
34+
internal fun Project.configureAndroidCompose() {}
35+
KOTLIN
36+
37+
cat > "$CONVENTION_DIR/zed/rainxch/githubstore/convention/KotlinAndroid.kt" << 'KOTLIN'
38+
package zed.rainxch.githubstore.convention
39+
40+
import org.gradle.api.Project
41+
42+
// Stubbed out for Flatpak build — no Android SDK available
43+
internal fun Project.configureKotlinAndroid(project: Project) {}
44+
KOTLIN
45+
1746
echo "[1/7] Patching root build.gradle.kts"
1847
sed -i \
1948
-e 's|alias(libs.plugins.android.application)|// alias(libs.plugins.android.application)|' \
2049
-e 's|alias(libs.plugins.android.library)|// alias(libs.plugins.android.library)|' \
2150
-e 's|alias(libs.plugins.android.kotlin.multiplatform.library)|// alias(libs.plugins.android.kotlin.multiplatform.library)|' \
51+
-e '/alias(libs.plugins.flatpak.gradle.generator)/d' \
52+
-e '/flatpakGradleGenerator/,/^}/d' \
53+
-e '/alias(libs.plugins.compose.hot.reload)/d' \
2254
build.gradle.kts
2355

56+
# Also remove hot-reload from composeApp/build.gradle.kts
57+
sed -i \
58+
-e '/alias(libs.plugins.compose.hot.reload)/d' \
59+
composeApp/build.gradle.kts
60+
2461
# ─────────────────────────────────────────────────────────────────────
2562
# 2. Convention plugins — replace Android plugin applies with no-ops
2663
# ─────────────────────────────────────────────────────────────────────
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]

packaging/flatpak/flatpak-sources.json

Lines changed: 21311 additions & 2740 deletions
Large diffs are not rendered by default.
Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Generate comprehensive flatpak-sources.json by scanning Gradle cache.
4+
5+
FAST approach:
6+
1. Scan ~/.gradle/caches/modules-2/files-2.1/ for all cached artifacts
7+
2. Compute SHA512 from local files (no network needed)
8+
3. Determine Maven repo URL based on group name heuristics
9+
4. For POMs not in local cache, download from repos (tries multiple)
10+
5. Skip files with non-standard names (AAR/klib with internal cache names)
11+
6. Output flatpak-sources.json
12+
13+
Files that Gradle stores under internal names (e.g., "animation.aar" instead of
14+
"animation-android-1.10.0.aar") are SKIPPED — they are Android/iOS platform
15+
artifacts that are not needed for the Desktop/Flatpak build.
16+
"""
17+
18+
import hashlib
19+
import json
20+
import os
21+
import sys
22+
import urllib.request
23+
import ssl
24+
from pathlib import Path
25+
from collections import defaultdict
26+
27+
GRADLE_CACHE = Path(os.path.expanduser("~")) / ".gradle" / "caches" / "modules-2" / "files-2.1"
28+
OUTPUT_DIR = Path(__file__).parent
29+
SSL_CTX = ssl.create_default_context()
30+
31+
# All repos
32+
ALL_REPOS = [
33+
"https://repo1.maven.org/maven2",
34+
"https://dl.google.com/dl/android/maven2",
35+
"https://maven.pkg.jetbrains.space/public/p/compose/dev",
36+
"https://plugins.gradle.org/m2",
37+
]
38+
39+
40+
def get_repos_for_group(group):
41+
"""Get ordered list of repos to try for a given group."""
42+
g = group.lower()
43+
if any(g.startswith(p) for p in ["androidx.", "com.android.", "com.google.android.",
44+
"com.google.firebase", "com.google.gms", "com.google.testing."]):
45+
return ["https://dl.google.com/dl/android/maven2", "https://repo1.maven.org/maven2",
46+
"https://maven.pkg.jetbrains.space/public/p/compose/dev"]
47+
if g.startswith("org.jetbrains.compose"):
48+
return ["https://maven.pkg.jetbrains.space/public/p/compose/dev",
49+
"https://repo1.maven.org/maven2", "https://plugins.gradle.org/m2"]
50+
if g.startswith("org.gradle.") or g.startswith("gradle.plugin."):
51+
return ["https://plugins.gradle.org/m2", "https://repo1.maven.org/maven2"]
52+
return ["https://repo1.maven.org/maven2", "https://dl.google.com/dl/android/maven2",
53+
"https://maven.pkg.jetbrains.space/public/p/compose/dev", "https://plugins.gradle.org/m2"]
54+
55+
56+
def sha512_file(filepath):
57+
h = hashlib.sha512()
58+
with open(filepath, "rb") as f:
59+
for chunk in iter(lambda: f.read(65536), b""):
60+
h.update(chunk)
61+
return h.hexdigest()
62+
63+
64+
def download_and_hash(url):
65+
"""Download file, return SHA512 or None."""
66+
try:
67+
req = urllib.request.Request(url)
68+
req.add_header("User-Agent", "flatpak-gen/1.0")
69+
with urllib.request.urlopen(req, timeout=20, context=SSL_CTX) as resp:
70+
if resp.status == 200:
71+
data = resp.read()
72+
if len(data) < 500 and b'<html' in data[:100].lower():
73+
return None
74+
return hashlib.sha512(data).hexdigest()
75+
except:
76+
pass
77+
return None
78+
79+
80+
def is_standard_filename(artifact, version, filename):
81+
"""Check if filename follows Maven naming convention (artifact-version.ext)."""
82+
base = f"{artifact}-{version}"
83+
# Standard: artifact-version.ext or artifact-version-classifier.ext
84+
if filename.startswith(base):
85+
return True
86+
return False
87+
88+
89+
def scan_gradle_cache():
90+
artifacts = defaultdict(dict)
91+
if not GRADLE_CACHE.exists():
92+
print(f"ERROR: Gradle cache not found at {GRADLE_CACHE}", file=sys.stderr)
93+
sys.exit(1)
94+
for group_dir in GRADLE_CACHE.iterdir():
95+
if not group_dir.is_dir(): continue
96+
for artifact_dir in group_dir.iterdir():
97+
if not artifact_dir.is_dir(): continue
98+
for version_dir in artifact_dir.iterdir():
99+
if not version_dir.is_dir(): continue
100+
for hash_dir in version_dir.iterdir():
101+
if not hash_dir.is_dir(): continue
102+
for f in hash_dir.iterdir():
103+
if f.is_file():
104+
artifacts[(group_dir.name, artifact_dir.name, version_dir.name)][f.name] = str(f)
105+
return artifacts
106+
107+
108+
def main():
109+
print("=" * 60)
110+
print("Flatpak Sources Generator (fast, skip non-standard names)")
111+
print("=" * 60)
112+
113+
print("\nScanning Gradle cache...")
114+
artifacts = scan_gradle_cache()
115+
print(f"Found {len(artifacts)} unique artifacts")
116+
117+
all_entries = []
118+
seen = set()
119+
stats = {"local": 0, "downloaded": 0, "skipped": 0, "failed_pom": 0}
120+
total = len(artifacts)
121+
122+
for idx, ((group, artifact, version), files) in enumerate(sorted(artifacts.items())):
123+
if (idx + 1) % 200 == 0:
124+
print(f" [{idx+1}/{total}] {stats}")
125+
126+
group_path = group.replace(".", "/")
127+
base_name = f"{artifact}-{version}"
128+
repos = get_repos_for_group(group)
129+
130+
needed = set()
131+
has_jar_or_aar = False
132+
133+
for fname in files:
134+
if fname.endswith("-sources.jar") or fname.endswith("-javadoc.jar"):
135+
continue
136+
if not fname.endswith((".jar", ".pom", ".module", ".klib", ".aar")):
137+
continue
138+
# SKIP files with non-standard names (Gradle internal cache names)
139+
if not is_standard_filename(artifact, version, fname):
140+
stats["skipped"] += 1
141+
continue
142+
needed.add(fname)
143+
if fname.endswith((".jar", ".aar")):
144+
has_jar_or_aar = True
145+
146+
# Ensure POM if we have JAR/AAR
147+
pom_name = f"{base_name}.pom"
148+
if has_jar_or_aar and pom_name not in needed:
149+
needed.add(pom_name)
150+
151+
for fname in sorted(needed):
152+
key = f"{group_path}/{artifact}/{version}/{fname}"
153+
if key in seen: continue
154+
seen.add(key)
155+
156+
local_path = files.get(fname)
157+
if local_path and os.path.exists(local_path):
158+
sha = sha512_file(local_path)
159+
url = f"{repos[0]}/{group_path}/{artifact}/{version}/{fname}"
160+
all_entries.append({
161+
"type": "file", "url": url, "sha512": sha,
162+
"dest": f"offline-repository/{group_path}/{artifact}/{version}",
163+
"dest-filename": fname
164+
})
165+
stats["local"] += 1
166+
else:
167+
# Download (missing POMs mostly)
168+
found = False
169+
for repo in repos:
170+
url = f"{repo}/{group_path}/{artifact}/{version}/{fname}"
171+
sha = download_and_hash(url)
172+
if sha:
173+
all_entries.append({
174+
"type": "file", "url": url, "sha512": sha,
175+
"dest": f"offline-repository/{group_path}/{artifact}/{version}",
176+
"dest-filename": fname
177+
})
178+
stats["downloaded"] += 1
179+
found = True
180+
break
181+
if not found:
182+
stats["failed_pom"] += 1
183+
184+
# Plugin markers
185+
print("\nAdding plugin marker POMs...")
186+
mc = add_plugin_markers(artifacts, all_entries, seen)
187+
188+
all_entries.sort(key=lambda e: (e["dest"], e["dest-filename"]))
189+
190+
output = OUTPUT_DIR / "flatpak-sources.json"
191+
with open(output, "w") as f:
192+
json.dump(all_entries, f, indent=4)
193+
194+
print(f"\n{'='*60}")
195+
print(f" Local: {stats['local']}")
196+
print(f" Downloaded: {stats['downloaded']}")
197+
print(f" Markers: {mc}")
198+
print(f" Skipped: {stats['skipped']} (non-standard filenames)")
199+
print(f" Failed: {stats['failed_pom']}")
200+
print(f" TOTAL: {len(all_entries)}")
201+
print(f"\nWritten to {output}")
202+
203+
204+
def add_plugin_markers(artifacts, entries, seen):
205+
count = 0
206+
pv = {}
207+
for (g, a, v), _ in artifacts.items():
208+
if g == "org.jetbrains.kotlin" and a == "kotlin-gradle-plugin": pv["kotlin"] = v
209+
if g == "org.jetbrains.compose" and a == "compose-gradle-plugin": pv["compose"] = v
210+
if g == "com.google.devtools.ksp" and a == "symbol-processing-gradle-plugin": pv["ksp"] = v
211+
if g == "com.android.tools.build" and a == "gradle": pv["agp"] = v
212+
if g == "org.jlleitschuh.gradle" and a == "ktlint-gradle": pv["ktlint"] = v
213+
if g == "com.codingfeline.buildkonfig" and a == "buildkonfig-gradle-plugin": pv["buildkonfig"] = v
214+
if g == "androidx.room" and a == "room-gradle-plugin": pv["room"] = v
215+
if g == "org.gradle.kotlin" and a == "gradle-kotlin-dsl-plugins": pv["kotlin-dsl"] = v
216+
217+
print(f" Versions: {pv}")
218+
219+
markers = []
220+
if "kotlin" in pv:
221+
for pid in ["org.jetbrains.kotlin.multiplatform", "org.jetbrains.kotlin.plugin.serialization",
222+
"org.jetbrains.kotlin.plugin.compose", "org.jetbrains.kotlin.jvm", "org.jetbrains.kotlin.android"]:
223+
markers.append((pid, pv["kotlin"]))
224+
if "compose" in pv:
225+
markers.append(("org.jetbrains.compose", pv["compose"]))
226+
if "ksp" in pv:
227+
markers.append(("com.google.devtools.ksp", pv["ksp"]))
228+
if "agp" in pv:
229+
for pid in ["com.android.application", "com.android.library", "com.android.kotlin.multiplatform.library"]:
230+
markers.append((pid, pv["agp"]))
231+
if "ktlint" in pv:
232+
markers.append(("org.jlleitschuh.gradle.ktlint", pv["ktlint"]))
233+
if "buildkonfig" in pv:
234+
markers.append(("com.codingfeline.buildkonfig", pv["buildkonfig"]))
235+
if "room" in pv:
236+
markers.append(("androidx.room", pv["room"]))
237+
if "kotlin-dsl" in pv:
238+
markers.append(("org.gradle.kotlin.kotlin-dsl", pv["kotlin-dsl"]))
239+
markers.append(("io.github.jwharm.flatpak-gradle-generator", "1.7.0"))
240+
241+
repos = ["https://plugins.gradle.org/m2", "https://dl.google.com/dl/android/maven2",
242+
"https://maven.pkg.jetbrains.space/public/p/compose/dev", "https://repo1.maven.org/maven2"]
243+
244+
for pid, ver in markers:
245+
gp = pid.replace(".", "/")
246+
art = f"{pid}.gradle.plugin"
247+
fn = f"{art}-{ver}.pom"
248+
key = f"{gp}/{art}/{ver}/{fn}"
249+
if key in seen: continue
250+
seen.add(key)
251+
for repo in repos:
252+
url = f"{repo}/{gp}/{art}/{ver}/{fn}"
253+
sha = download_and_hash(url)
254+
if sha:
255+
entries.append({"type": "file", "url": url, "sha512": sha,
256+
"dest": f"offline-repository/{gp}/{art}/{ver}", "dest-filename": fn})
257+
count += 1
258+
print(f" + {pid}:{ver}")
259+
break
260+
return count
261+
262+
263+
if __name__ == "__main__":
264+
main()

packaging/flatpak/zed.rainxch.githubstore.yml

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,15 @@ modules:
6464
f.write(' includeBuild(\"build-logic\")\n')
6565
f.write(' repositories {\n')
6666
f.write(' maven { url = uri(\"/run/build/githubstore/offline-repository\") }\n')
67-
f.write(' gradlePluginPortal()\n')
6867
f.write(' }\n')
6968
f.write('}\n\n')
7069
f.write('dependencyResolutionManagement {\n')
7170
f.write(' repositories {\n')
7271
f.write(' maven { url = uri(\"/run/build/githubstore/offline-repository\") }\n')
7372
f.write(' }\n')
7473
f.write('}\n\n')
75-
f.write('plugins {\n')
76-
f.write(' id(\"org.gradle.toolchains.foojay-resolver-convention\") version \"1.0.0\"\n')
77-
f.write('}\n\n')
74+
# foojay-resolver-convention plugin removed — not needed in Flatpak
75+
# (JAVA_HOME is set explicitly, no toolchain auto-download)
7876
for inc in includes:
7977
f.write(inc)
8078
print('Rewrote root settings.gradle.kts for offline build')
@@ -86,13 +84,11 @@ modules:
8684
f.write('pluginManagement {\n')
8785
f.write(' repositories {\n')
8886
f.write(' maven { url = uri(\"/run/build/githubstore/offline-repository\") }\n')
89-
f.write(' gradlePluginPortal()\n')
9087
f.write(' }\n')
9188
f.write('}\n\n')
9289
f.write('dependencyResolutionManagement {\n')
9390
f.write(' repositories {\n')
9491
f.write(' maven { url = uri(\"/run/build/githubstore/offline-repository\") }\n')
95-
f.write(' gradlePluginPortal()\n')
9692
f.write(' }\n\n')
9793
f.write(' versionCatalogs {\n')
9894
f.write(' create(\"libs\") {\n')
@@ -142,3 +138,4 @@ modules:
142138
# Pre-downloaded Gradle/Maven dependencies for offline build
143139
- flatpak-sources.json
144140
- flatpak-sources-convention.json
141+
- flatpak-sources-manual.json

0 commit comments

Comments
 (0)