Skip to content

Commit 89834d3

Browse files
authored
Merge pull request #77 from TheTripleV/master
Add tool to detect supported platforms
2 parents 02169a1 + 54bbe83 commit 89834d3

File tree

1 file changed

+172
-0
lines changed

1 file changed

+172
-0
lines changed

robotpy_build/tool.py

+172
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
import pprint
77
import subprocess
88
import sys
9+
import re
10+
from urllib.request import Request, urlopen
11+
from urllib.error import HTTPError
12+
from collections import defaultdict
13+
import toml
14+
from contextlib import suppress
915

1016
from .setup import Setup
1117
from .generator_data import MissingReporter
@@ -256,6 +262,171 @@ def run(self, args):
256262
pprint.pprint(platforms.get_platform_override_keys(p))
257263

258264

265+
class MavenParser:
266+
267+
after_archs = [
268+
"static",
269+
"debug",
270+
"staticdebug",
271+
]
272+
273+
@classmethod
274+
def add_subparser(cls, parent_parser, subparsers):
275+
parser = subparsers.add_parser(
276+
"parse-maven",
277+
help="Find supported platforms from a pyproject.toml",
278+
parents=[parent_parser],
279+
)
280+
parser.add_argument(
281+
"toml_link", help="Ex: pyproject.toml",
282+
)
283+
parser.add_argument(
284+
"-b",
285+
"--brute_force",
286+
action="store_true",
287+
help="Try known os and arch combinations instead of parsing html (needed for rev)",
288+
)
289+
return parser
290+
291+
def check_url_exists(self, file_url):
292+
with suppress(Exception):
293+
if urlopen(Request(file_url)).code == 200:
294+
return True
295+
return False
296+
297+
def run(self, args):
298+
299+
self.os_names = set()
300+
self.arch_names = set()
301+
for plat in platforms._platforms.values():
302+
self.os_names.add(plat.os)
303+
self.arch_names.add(plat.arch)
304+
305+
with open(args.toml_link) as fp:
306+
config = toml.load(fp)["tool"]["robotpy-build"]
307+
308+
wrappers = {}
309+
if "wrappers" in config:
310+
wrappers = {
311+
k: v
312+
for (k, v) in config["wrappers"].items()
313+
if "maven_lib_download" in v
314+
}
315+
316+
static_libs = {}
317+
if "static_libs" in config:
318+
static_libs = {
319+
k: v
320+
for (k, v) in config["static_libs"].items()
321+
if "maven_lib_download" in v
322+
}
323+
324+
if wrappers == {} and static_libs == {}:
325+
print("No maven_lib_downloads in pyproject.toml")
326+
exit()
327+
328+
for w_name, wrapper in {**wrappers, **static_libs}.items():
329+
330+
if "maven_lib_download" not in wrapper:
331+
continue
332+
333+
mvl = wrapper["maven_lib_download"]
334+
335+
repo_url = mvl["repo_url"]
336+
grp = mvl["group_id"].replace(".", "/")
337+
art = mvl["artifact_id"]
338+
ver = mvl["version"]
339+
340+
dir_url = f"{repo_url}/{grp}/{art}/{ver}/"
341+
342+
plats = defaultdict(set)
343+
344+
found_source = False
345+
source_name = None
346+
347+
if args.brute_force:
348+
349+
for os in self.os_names:
350+
for arch in self.arch_names:
351+
for after_arch in self.after_archs + [""]:
352+
classifier = os + arch + after_arch
353+
file_url = f"{dir_url}{art}-{ver}-{classifier}.zip"
354+
355+
if self.check_url_exists(file_url):
356+
plats[os].add(arch)
357+
358+
if self.check_url_exists(f"{dir_url}{art}-{ver}-source.zip"):
359+
found_source = True
360+
source_name = "source"
361+
362+
if self.check_url_exists(f"{dir_url}{art}-{ver}-sources.zip"):
363+
found_source = True
364+
source_name = "sources"
365+
366+
else:
367+
try:
368+
html = str(urlopen(Request(dir_url)).read())
369+
except HTTPError as e:
370+
if e.code != 404:
371+
raise e
372+
else:
373+
print(
374+
"The repo url returned a 404 error. Try using the brute_force flag."
375+
)
376+
exit()
377+
378+
found_source = False
379+
source_name = None
380+
381+
if "source.zip" in html:
382+
found_source = True
383+
source_name = "source"
384+
385+
if "sources.zip" in html:
386+
found_source = True
387+
source_name = "sources"
388+
389+
# matches = re.findall('\.zip">(.*?)\.zip</a>', html, re.I) # match on text
390+
matches = re.findall('href="(.*?)">', html, re.I) # match on links
391+
matches = [
392+
m[:-4] for m in matches if m[-4:] == ".zip"
393+
] # match on zip files and remove extension
394+
395+
for m in matches:
396+
for os in self.os_names:
397+
idx = m.find(os)
398+
399+
if idx != -1:
400+
arch = m[idx + len(os) :]
401+
402+
for after_arch in self.after_archs:
403+
arch = arch.replace(after_arch, "")
404+
405+
plats[os].add(arch)
406+
break
407+
408+
# Formatting
409+
print()
410+
print(f"Wrapper / static_lib :: {w_name}")
411+
print(f"Artifact ID :: {art}")
412+
print()
413+
414+
if found_source:
415+
print("This repo appears to provide sources.")
416+
print("The name of the source file is:", source_name)
417+
print()
418+
419+
plat_str = "supported_platforms = [\n"
420+
for os in plats:
421+
for arch in plats[os]:
422+
plat_str += ' {{ os = "{}", arch = "{}" }},\n'.format(
423+
os, arch
424+
)
425+
plat_str += "]"
426+
427+
print(plat_str)
428+
429+
259430
def main():
260431

261432
parser = argparse.ArgumentParser(prog="robotpy-build")
@@ -270,6 +441,7 @@ def main():
270441
ImportCreator,
271442
LibraryRelinker,
272443
PlatformInfo,
444+
MavenParser,
273445
):
274446
cls.add_subparser(parent_parser, subparsers).set_defaults(cls=cls)
275447

0 commit comments

Comments
 (0)