Skip to content

Commit ddf7583

Browse files
committed
[GR-17116] Allow setting environment variables to override where packages are loaded from in ginstall
PullRequest: graalpython/581
2 parents ea72413 + d41c95d commit ddf7583

File tree

1 file changed

+99
-105
lines changed

1 file changed

+99
-105
lines changed

graalpython/lib-graalpython/modules/ginstall.py

Lines changed: 99 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -47,81 +47,82 @@
4747
import tempfile
4848

4949
def system(cmd, msg=""):
50+
print("+", cmd)
5051
status = os.system(cmd)
5152
if status != 0:
5253
xit(msg, status=status)
5354

5455

5556
def known_packages():
56-
def PyYAML(*args):
57-
install_from_pypi("PyYAML==3.13", args)
57+
def PyYAML(**kwargs):
58+
install_from_pypi("PyYAML==3.13", **kwargs)
5859

59-
def six(*args):
60-
install_from_pypi("six==1.12.0", args)
60+
def six(**kwargs):
61+
install_from_pypi("six==1.12.0", **kwargs)
6162

62-
def Cython(*args):
63-
install_from_pypi("Cython==0.29.2", ('--no-cython-compile',) + args)
63+
def Cython(extra_opts=[], **kwargs):
64+
install_from_pypi("Cython==0.29.2", extra_opts=(['--no-cython-compile'] + extra_opts), **kwargs)
6465

65-
def setuptools(*args):
66-
install_from_pypi("setuptools==41.0.1", args)
66+
def setuptools(**kwargs):
67+
install_from_pypi("setuptools==41.0.1", **kwargs)
6768

68-
def pkgconfig(*args):
69-
install_from_pypi("pkgconfig==1.5.1", args)
69+
def pkgconfig(**kwargs):
70+
install_from_pypi("pkgconfig==1.5.1", **kwargs)
7071

71-
def wheel(*args):
72-
install_from_pypi("wheel==0.33.4", args)
72+
def wheel(**kwargs):
73+
install_from_pypi("wheel==0.33.4", **kwargs)
7374

74-
def protobuf(*args):
75-
install_from_pypi("protobuf==3.8.0", args)
75+
def protobuf(**kwargs):
76+
install_from_pypi("protobuf==3.8.0", **kwargs)
7677

77-
def Keras_preprocessing(*args):
78-
install_from_pypi("Keras-Preprocessing==1.0.5", args)
78+
def Keras_preprocessing(**kwargs):
79+
install_from_pypi("Keras-Preprocessing==1.0.5", **kwargs)
7980

80-
def gast(*args):
81-
install_from_pypi("gast==0.2.2", args)
81+
def gast(**kwargs):
82+
install_from_pypi("gast==0.2.2", **kwargs)
8283

83-
def astor(*args):
84-
install_from_pypi("astor==0.8.0", args)
84+
def astor(**kwargs):
85+
install_from_pypi("astor==0.8.0", **kwargs)
8586

86-
def absl_py(*args):
87-
install_from_pypi("absl-py==0.7.1", args)
87+
def absl_py(**kwargs):
88+
install_from_pypi("absl-py==0.7.1", **kwargs)
8889

89-
def mock(*args):
90-
install_from_pypi("mock==3.0.5", args)
90+
def mock(**kwargs):
91+
install_from_pypi("mock==3.0.5", **kwargs)
9192

92-
def Markdown(*args):
93-
install_from_pypi("Markdown==3.1.1", args)
93+
def Markdown(**kwargs):
94+
install_from_pypi("Markdown==3.1.1", **kwargs)
9495

95-
def Werkzeug(*args):
96-
install_from_pypi("Werkzeug==0.15.4", args)
96+
def Werkzeug(**kwargs):
97+
install_from_pypi("Werkzeug==0.15.4", **kwargs)
9798

9899
# Does not yet work
99-
# def h5py(*args):
100+
# def h5py(**kwargs):
100101
# try:
101102
# import pkgconfig
102103
# except ImportError:
103104
# print("Installing required dependency: pkgconfig")
104-
# pkgconfig(*args)
105-
# install_from_pypi("h5py==2.9.0", args)
105+
# pkgconfig(**kwargs)
106+
# install_from_pypi("h5py==2.9.0", **kwargs)
106107

107108
# Does not yet work
108-
# def keras_applications(*args):
109+
# def keras_applications(**kwargs):
109110
# try:
110111
# import h5py
111112
# except ImportError:
112113
# print("Installing required dependency: h5py")
113-
# h5py(*args)
114-
# install_from_pypi("Keras-Applications==1.0.6", args)
114+
# h5py(**kwargs)
115+
# install_from_pypi("Keras-Applications==1.0.6", **kwargs)
115116

116-
def setuptools_scm(*args):
117-
install_from_url("https://files.pythonhosted.org/packages/70/bc/f34b06274c1260c5e4842f789fb933a09b89f23549f282b36a15bdf63614/setuptools_scm-1.15.0rc1.tar.gz", extra_opts=args)
117+
def setuptools_scm(**kwargs):
118+
install_from_pypi("setuptools_scm==1.15.0rc1", **kwargs)
118119

119-
def numpy(*args):
120+
def numpy(**kwargs):
120121
try:
121122
import setuptools as st
122123
except ImportError:
123124
print("Installing required dependency: setuptools")
124-
setuptools(*args)
125+
setuptools(**kwargs)
125126

126127
patch = """
127128
diff --git a/setup.py 2018-02-28 17:03:26.000000000 +0100
@@ -369,47 +370,46 @@ def get_lapack_lite_sources(ext, build_dir):
369370
2.14.1
370371
371372
"""
372-
install_from_url("https://files.pythonhosted.org/packages/b0/2b/497c2bb7c660b2606d4a96e2035e92554429e139c6c71cdff67af66b58d2/numpy-1.14.3.zip", patch=patch, extra_opts=args)
373+
install_from_pypi("numpy==1.14.3", patch=patch, **kwargs)
373374

374375

375-
def dateutil(*args):
376+
def dateutil(**kwargs):
376377
try:
377378
import setuptools_scm as st_scm
378379
except ImportError:
379380
print("Installing required dependency: setuptools_scm")
380-
setuptools_scm(*args)
381-
install_from_url("https://files.pythonhosted.org/packages/0e/01/68747933e8d12263d41ce08119620d9a7e5eb72c876a3442257f74490da0/python-dateutil-2.7.5.tar.gz", extra_opts=args)
381+
setuptools_scm(**kwargs)
382+
install_from_pypi("python-dateutil==2.7.5", **kwargs)
382383

383384

384-
def pytz(*args):
385-
install_from_url("https://files.pythonhosted.org/packages/cd/71/ae99fc3df1b1c5267d37ef2c51b7d79c44ba8a5e37b48e3ca93b4d74d98b/pytz-2018.7.tar.gz", extra_opts=args)
386-
387-
388-
def pandas(*args):
389-
try:
390-
import numpy as np
391-
except ImportError:
392-
print("Installing required dependency: numpy")
393-
numpy(*args)
385+
def pytz(**kwargs):
386+
install_from_pypi("pytz==2018.7", **kwargs)
394387

395388

389+
def pandas(**kwargs):
396390
try:
397391
import pytz as _dummy_pytz
398392
except ImportError:
399393
print("Installing required dependency: pytz")
400-
pytz(*args)
394+
pytz(**kwargs)
401395

402396
try:
403397
import six as _dummy_six
404398
except ImportError:
405399
print("Installing required dependency: six")
406-
six(*args)
400+
six(**kwargs)
407401

408402
try:
409403
import dateutil as __dummy_dateutil
410404
except ImportError:
411405
print("Installing required dependency: dateutil")
412-
dateutil(*args)
406+
dateutil(**kwargs)
407+
408+
try:
409+
import numpy as np
410+
except ImportError:
411+
print("Installing required dependency: numpy")
412+
numpy(**kwargs)
413413

414414
# download pandas-0.20.3
415415
patch = """diff --git a/pandas/_libs/src/period_helper.c b/pandas/_libs/src/period_helper.c
@@ -473,7 +473,7 @@ def pandas(*args):
473473
474474
"""
475475
cflags = "-allowcpp" if sys.implementation.name == "graalpython" else ""
476-
install_from_url("https://files.pythonhosted.org/packages/ee/aa/90c06f249cf4408fa75135ad0df7d64c09cf74c9870733862491ed5f3a50/pandas-0.20.3.tar.gz", patch=patch, extra_opts=args, add_cflags=cflags)
476+
install_from_pypi("pandas==0.20.3", patch=patch, add_cflags=cflags, **kwargs)
477477

478478
return locals()
479479

@@ -486,29 +486,35 @@ def xit(msg, status=-1):
486486
exit(-1)
487487

488488

489-
def install_from_url(url, patch=None, extra_opts=[], add_cflags=""):
489+
def _install_from_url(url, patch=None, extra_opts=[], add_cflags="", ignore_errors=False):
490490
name = url[url.rfind("/")+1:]
491491
tempdir = tempfile.mkdtemp()
492492

493-
# honor env var 'HTTP_PROXY' and 'HTTPS_PROXY'
494-
env = os.environ
495-
curl_opts = []
496-
if url.startswith("http://") and "HTTP_PROXY" in env:
497-
curl_opts += ["--proxy", env["HTTP_PROXY"]]
498-
elif url.startswith("https://") and "HTTPS_PROXY" in env:
499-
curl_opts += ["--proxy", env["HTTPS_PROXY"]]
500-
501493
# honor env var 'CFLAGS' and 'CPPFLAGS'
502494
cppflags = os.environ.get("CPPFLAGS", "")
503495
cflags = "-v " + os.environ.get("CFLAGS", "") + ((" " + add_cflags) if add_cflags else "")
504496

505-
system("curl %s -o %s/%s %s" % (" ".join(curl_opts), tempdir, name, url))
497+
if os.system("curl -L -o %s/%s %s" % (tempdir, name, url)) != 0:
498+
# honor env var 'HTTP_PROXY' and 'HTTPS_PROXY'
499+
env = os.environ
500+
curl_opts = []
501+
if url.startswith("http://") and "HTTP_PROXY" in env:
502+
curl_opts += ["--proxy", env["HTTP_PROXY"]]
503+
elif url.startswith("https://") and "HTTPS_PROXY" in env:
504+
curl_opts += ["--proxy", env["HTTPS_PROXY"]]
505+
system("curl -L %s -o %s/%s %s" % (" ".join(curl_opts), tempdir, name, url), msg="Download error")
506+
506507
if name.endswith(".tar.gz"):
507-
system("tar xzf %s/%s -C %s" % (tempdir, name, tempdir))
508+
system("tar xzf %s/%s -C %s" % (tempdir, name, tempdir), msg="Error extracting tar.gz")
508509
bare_name = name[:-len(".tar.gz")]
510+
elif name.endswith(".tar.bz2"):
511+
system("tar xjf %s/%s -C %s" % (tempdir, name, tempdir), msg="Error extracting tar.bz2")
512+
bare_name = name[:-len(".tar.bz2")]
509513
elif name.endswith(".zip"):
510-
system("unzip -u %s/%s -d %s" % (tempdir, name, tempdir))
514+
system("unzip -u %s/%s -d %s" % (tempdir, name, tempdir), msg="Error extracting zip")
511515
bare_name = name[:-len(".zip")]
516+
else:
517+
xit("Unknown file type: %s" % name)
512518

513519
if patch:
514520
with open("%s/%s.patch" % (tempdir, bare_name), "w") as f:
@@ -519,51 +525,39 @@ def install_from_url(url, patch=None, extra_opts=[], add_cflags=""):
519525
user_arg = "--user"
520526
else:
521527
user_arg = ""
522-
system("cd %s/%s; %s %s %s setup.py install %s %s" % (tempdir, bare_name, 'CFLAGS="%s"' % cflags if cflags else "", 'CPPFLAGS="%s"' % cppflags if cppflags else "", sys.executable, user_arg, " ".join(extra_opts)))
528+
status = system("cd %s/%s; %s %s %s setup.py install %s %s" % (tempdir, bare_name, 'CFLAGS="%s"' % cflags if cflags else "", 'CPPFLAGS="%s"' % cppflags if cppflags else "", sys.executable, user_arg, " ".join(extra_opts)))
529+
if status != 0 and not ignore_errors:
530+
xit("An error occurred trying to run `setup.py install %s %s'" % (user_arg, " ".join(extra_opts)))
523531

524532

525-
def install_from_pypi(package, extra_opts=[]):
533+
def install_from_pypi(package, patch=None, extra_opts=[], add_cflags="", ignore_errors=True):
534+
package_pattern = os.environ.get("GINSTALL_PACKAGE_PATTERN", "https://pypi.org/pypi/%s/json")
535+
package_version_pattern = os.environ.get("GINSTALL_PACKAGE_VERSION_PATTERN", "https://pypi.org/pypi/%s/%s/json")
536+
526537
if "==" in package:
527538
package, _, version = package.rpartition("==")
528-
url = "https://pypi.org/pypi/%s/%s/json" % (package, version)
539+
url = package_version_pattern % (package, version)
529540
else:
530-
url = "https://pypi.org/pypi/%s/json" % package
541+
url = package_pattern % package
531542

532-
r = subprocess.check_output("curl %s" % url, shell=True).decode("utf8")
533-
try:
534-
urls = json.loads(r)["urls"]
535-
except:
543+
if any(url.endswith(ending) for ending in [".zip", ".tar.bz2", ".tar.gz"]):
544+
# this is already the url to the actual package
536545
pass
537546
else:
538-
for url_info in urls:
539-
if url_info["python_version"] == "source":
540-
url = url_info["url"]
541-
break
542-
543-
if url:
544-
tempdir = tempfile.mkdtemp()
545-
filename = url.rpartition("/")[2]
546-
system("curl -L -o %s/%s %s" % (tempdir, filename, url), msg="Download error")
547-
dirname = None
548-
if filename.endswith(".zip"):
549-
system("unzip -u %s/%s -d %s" % (tempdir, filename, tempdir))
550-
dirname = filename[:-4]
551-
elif filename.endswith(".tar.gz"):
552-
system("tar -C %s -xzf %s/%s" % (tempdir, tempdir, filename), msg="Error during extraction")
553-
dirname = filename[:-7]
554-
elif filename.endswith(".tar.bz2"):
555-
system("tar -C %s -xjf %s/%s" % (tempdir, tempdir, filename), msg="Error during extraction")
556-
dirname = filename[:-7]
547+
r = subprocess.check_output("curl -L %s" % url, shell=True).decode("utf8")
548+
url = None
549+
try:
550+
urls = json.loads(r)["urls"]
551+
except:
552+
pass
557553
else:
558-
xit("Unknown file type: %s" % filename)
554+
for url_info in urls:
555+
if url_info["python_version"] == "source":
556+
url = url_info["url"]
557+
break
559558

560-
if "--prefix" not in extra_opts and site.ENABLE_USER_SITE:
561-
user_arg = "--user"
562-
else:
563-
user_arg = ""
564-
status = os.system("cd %s/%s; %s setup.py install %s %s" % (tempdir, dirname, sys.executable, user_arg, " ".join(extra_opts)))
565-
if status != 0:
566-
xit("An error occurred trying to run `setup.py install %s %s'" % (user_arg, " ".join(extra_opts)))
559+
if url:
560+
_install_from_url(url, patch=patch, extra_opts=extra_opts, add_cflags=add_cflags, ignore_errors=ignore_errors)
567561
else:
568562
xit("Package not found: '%s'" % package)
569563

@@ -649,12 +643,12 @@ def main(argv):
649643
xit("Unknown package: '%s'" % pkg)
650644
else:
651645
if args.prefix:
652-
KNOWN_PACKAGES[pkg]("--prefix", args.prefix)
646+
KNOWN_PACKAGES[pkg](extra_opts=["--prefix", args.prefix])
653647
else:
654648
KNOWN_PACKAGES[pkg]()
655649
elif args.command == "pypi":
656650
for pkg in args.package.split(","):
657-
install_from_pypi(pkg)
651+
install_from_pypi(pkg, ignore_errors=False)
658652

659653

660654

0 commit comments

Comments
 (0)