36
36
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37
37
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38
38
# SOFTWARE.
39
-
39
+ import re
40
40
from pathlib import Path
41
41
import argparse
42
42
import json
46
46
import subprocess
47
47
import tempfile
48
48
import importlib
49
- import sys
50
49
50
+ import sys
51
51
52
52
WARNING = '\033 [93m'
53
53
FAIL = '\033 [91m'
@@ -365,7 +365,7 @@ def xit(msg, status=-1):
365
365
exit (- 1 )
366
366
367
367
368
- def _install_from_url (url , package , extra_opts = [], add_cflags = "" , ignore_errors = False , env = {}):
368
+ def _install_from_url (url , package , extra_opts = [], add_cflags = "" , ignore_errors = False , env = {}, version = None ):
369
369
name = url [url .rfind ("/" )+ 1 :]
370
370
tempdir = tempfile .mkdtemp ()
371
371
@@ -407,11 +407,25 @@ def _install_from_url(url, package, extra_opts=[], add_cflags="", ignore_errors=
407
407
else :
408
408
xit ("Unknown file type: %s" % name )
409
409
410
- patch_file_path = get_patch (package )
410
+ file_realpath = os .path .dirname (os .path .realpath (__file__ ))
411
+ patches_dir = os .path .join (Path (file_realpath ).parent , 'patches' , package )
412
+ # empty match group to have the same groups range as in pip_hook
413
+ # unlike with pip, the version number may not be available at all
414
+ versions = re .search ("()(\\ d+)?(.\\ d+)?(.\\ d+)?" , "" if version is None else version )
415
+
416
+ patch_file_path = first_existing (package , versions , os .path .join (patches_dir , "sdist" ), ".patch" )
411
417
if patch_file_path :
412
418
system ("patch -d %s/%s/ -p1 < %s" %
413
419
(tempdir , bare_name , patch_file_path ))
414
420
421
+ whl_patches_dir = os .path .join (patches_dir , "whl" )
422
+ patch_file_path = first_existing (package , versions , whl_patches_dir , ".patch" )
423
+ subdir = read_first_existing (package , versions , whl_patches_dir , ".dir" )
424
+ subdir = "" if subdir is None else "/" + subdir
425
+ if patch_file_path :
426
+ system ("patch -d %s/%s%s -p1 < %s" %
427
+ (tempdir , bare_name , subdir , patch_file_path ))
428
+
415
429
if "--prefix" not in extra_opts and site .ENABLE_USER_SITE :
416
430
user_arg = "--user"
417
431
else :
@@ -420,19 +434,41 @@ def _install_from_url(url, package, extra_opts=[], add_cflags="", ignore_errors=
420
434
if status != 0 and not ignore_errors :
421
435
xit ("An error occurred trying to run `setup.py install %s %s'" % (user_arg , " " .join (extra_opts )))
422
436
423
- def get_patch (package ):
424
- dir_path = os .path .dirname (os .path .realpath (__file__ ))
425
- parent_folder = Path (dir_path ).parent
426
- patch_file_path = os .path .join (
427
- parent_folder , 'patches' , "%s.patch" % package
428
- )
429
- if os .path .exists (patch_file_path ):
430
- return patch_file_path
437
+ # NOTE: Following 3 functions are duplicated in pip_hook.py:
438
+ # creates a search list of a versioned file:
439
+ # {name}-X.Y.Z.{suffix}, {name}-X.Y.{suffix}, {name}-X.{suffix}, {name}.{suffix}
440
+ # 'versions' is a result of re.search
441
+ def list_versioned (pkg_name , versions , dir , suffix ):
442
+ acc = ""
443
+ res = []
444
+ for i in range (2 ,5 ):
445
+ v = versions .group (i )
446
+ if v is not None :
447
+ acc = acc + v
448
+ res .append (acc )
449
+ res .reverse ()
450
+ res = [os .path .join (dir , pkg_name + "-" + ver + suffix ) for ver in res ]
451
+ res .append (os .path .join (dir , pkg_name + suffix ))
452
+ return res
453
+
454
+ def first_existing (pkg_name , versions , dir , suffix ):
455
+ for filename in list_versioned (pkg_name , versions , dir , suffix ):
456
+ if os .path .exists (filename ):
457
+ return filename
458
+
459
+ def read_first_existing (pkg_name , versions , dir , suffix ):
460
+ filename = first_existing (pkg_name , versions , dir , suffix )
461
+ if filename :
462
+ with open (filename , "r" ) as f :
463
+ return f .read ()
464
+
465
+ # end of code duplicated in pip_hook.py
431
466
432
467
def install_from_pypi (package , extra_opts = [], add_cflags = "" , ignore_errors = True , env = {}):
433
468
package_pattern = os .environ .get ("GINSTALL_PACKAGE_PATTERN" , "https://pypi.org/pypi/%s/json" )
434
469
package_version_pattern = os .environ .get ("GINSTALL_PACKAGE_VERSION_PATTERN" , "https://pypi.org/pypi/%s/%s/json" )
435
470
471
+ version = None
436
472
if "==" in package :
437
473
package , _ , version = package .rpartition ("==" )
438
474
url = package_version_pattern % (package , version )
@@ -456,7 +492,8 @@ def install_from_pypi(package, extra_opts=[], add_cflags="", ignore_errors=True,
456
492
break
457
493
458
494
if url :
459
- _install_from_url (url , package = package , extra_opts = extra_opts , add_cflags = add_cflags , ignore_errors = ignore_errors , env = env )
495
+ _install_from_url (url , package = package , extra_opts = extra_opts , add_cflags = add_cflags ,
496
+ ignore_errors = ignore_errors , env = env , version = version )
460
497
else :
461
498
xit ("Package not found: '%s'" % package )
462
499
0 commit comments