8
8
NamedTuple ,
9
9
Optional ,
10
10
Set ,
11
+ Tuple ,
11
12
Type ,
12
13
)
13
14
@@ -79,11 +80,17 @@ def _process_packages_v1(
79
80
elif version_url .scheme == 'file' :
80
81
source = LocalSource (path = version_url .path )
81
82
else :
82
- integrity = Integrity .parse (info ['integrity' ])
83
+ integrity = None
84
+ if 'integrity' in info :
85
+ integrity = Integrity .parse (info ['integrity' ])
86
+
83
87
if 'resolved' in info :
84
- source = ResolvedSource (
85
- resolved = info ['resolved' ], integrity = integrity
86
- )
88
+ if info ['resolved' ].startswith ('git+' ):
89
+ source = self .parse_git_source (info ['resolved' ])
90
+ else :
91
+ source = ResolvedSource (
92
+ resolved = info ['resolved' ], integrity = integrity
93
+ )
87
94
elif version_url .scheme in {'http' , 'https' }:
88
95
source = PackageURLSource (resolved = version , integrity = integrity )
89
96
else :
@@ -104,20 +111,15 @@ def _process_packages_v2(
104
111
# NOTE We're not interested in symlinks, NPM will create them at install time
105
112
# but we still could collect package symlinks anyway just for completeness
106
113
continue
114
+ if install_path == '' :
115
+ # The root project is typically listed with a key of ''
116
+ continue
107
117
108
118
name = info .get ('name' )
109
119
110
120
source : PackageSource
111
- package_json_path = lockfile .parent / install_path / 'package.json'
112
- if (
113
- 'node_modules' not in install_path .split ('/' )
114
- and package_json_path .exists ()
115
- ):
116
- source = LocalSource (path = install_path )
117
- if name is None :
118
- with package_json_path .open ('rb' ) as fp :
119
- name = json .load (fp )['name' ]
120
- elif 'resolved' in info :
121
+
122
+ if 'resolved' in info :
121
123
resolved_url = urllib .parse .urlparse (info ['resolved' ])
122
124
if resolved_url .scheme == 'file' :
123
125
source = LocalSource (path = resolved_url .path )
@@ -130,14 +132,10 @@ def _process_packages_v2(
130
132
integrity = integrity , resolved = info ['resolved' ]
131
133
)
132
134
elif resolved_url .scheme .startswith ('git+' ):
133
- raise NotImplementedError (
134
- 'Git sources in lockfile v2 format are not supported yet'
135
- f' (package { install_path } in { lockfile } )'
136
- )
135
+ source = self .parse_git_source (info ['resolved' ])
137
136
else :
138
- raise NotImplementedError (
139
- f"Don't know how to handle package { install_path } in { lockfile } "
140
- )
137
+ source = LocalSource (path = install_path )
138
+ name = install_path
141
139
142
140
# NOTE We can't reliably determine the package name from the lockfile v2 syntax,
143
141
# but we need it for registry queries and special source processing;
@@ -208,7 +206,7 @@ def __init__(
208
206
self .all_lockfiles : Set [Path ] = set ()
209
207
# Mapping of lockfiles to a dict of the Git source target paths and GitSource objects.
210
208
self .git_sources : DefaultDict [
211
- Path , Dict [Path , GitSource ]
209
+ Path , Dict [Path , Tuple [ str , GitSource ] ]
212
210
] = collections .defaultdict (lambda : {})
213
211
# FIXME better pass the same provider object we created in main
214
212
self .rcfile_provider = NpmRCFileProvider ()
@@ -369,9 +367,49 @@ async def generate_package(self, package: Package) -> None:
369
367
# Get a unique name to use for the Git repository folder.
370
368
name = f'{ package .name } -{ source .commit } '
371
369
path = self .gen .data_root / 'git-packages' / name
372
- self .git_sources [package .lockfile ][path ] = source
370
+ self .git_sources [package .lockfile ][path ] = ( package . name , source )
373
371
self .gen .add_git_source (source .url , source .commit , path )
374
372
373
+ url = urllib .parse .urlparse (source .url )
374
+ if url .
netloc == '[email protected] ' or url .
netloc == 'github.com' :
375
+ url = url ._replace (
376
+ netloc = 'codeload.github.com' , path = re .sub ('.git$' , '' , url .path )
377
+ )
378
+ tarball_url = url ._replace (
379
+ path = re .sub ('$' , f'/tar.gz/{ source .commit } ' , url .path )
380
+ )
381
+ index_url = tarball_url .geturl ()
382
+ elif url .
netloc == '[email protected] ' or url .
netloc == 'gitlab.com' :
383
+ url = url ._replace (
384
+ netloc = 'gitlab.com' , path = re .sub ('.git$' , '' , url .path )
385
+ )
386
+ tarball_url = url ._replace (
387
+ path = re .sub (
388
+ '$' ,
389
+ f'/-/archive/{ source .commit } /{ package .name } -{ source .commit } .tar.gz' ,
390
+ url .path ,
391
+ )
392
+ )
393
+ index_url = url ._replace (
394
+ path = re .sub (
395
+ '$' , f'/repository/archive.tar.gz?ref={ source .commit } ' , url .path
396
+ )
397
+ ).geturl ()
398
+ metadata = await RemoteUrlMetadata .get (
399
+ tarball_url .geturl (), cachable = True , integrity_algorithm = 'sha512'
400
+ )
401
+
402
+ self .gen .add_url_source (
403
+ url = tarball_url .geturl (),
404
+ integrity = metadata .integrity ,
405
+ destination = self .get_cacache_content_path (metadata .integrity ),
406
+ )
407
+
408
+ self .add_index_entry (
409
+ url = index_url ,
410
+ metadata = metadata ,
411
+ )
412
+
375
413
elif isinstance (source , LocalSource ):
376
414
pass
377
415
@@ -432,8 +470,8 @@ def _finalize(self) -> None:
432
470
if type == "object"
433
471
then
434
472
to_entries | map(
435
- if (.value | type == "string") and $data[.value ]
436
- then .value = "git+file:\($buildroot)/\($data[.value ])"
473
+ if (.key | type == "string") and $data[.key ]
474
+ then .value = "git+file:// \($buildroot)/\($data[.key ])"
437
475
else .
438
476
end
439
477
) | from_entries
@@ -445,7 +483,7 @@ def _finalize(self) -> None:
445
483
walk(
446
484
if type == "object" and (.version | type == "string") and $data[.version]
447
485
then
448
- .version = "git+file:\($buildroot)/\($data[.version])"
486
+ .resolved = "git+file:\($buildroot)/\($data[.version])"
449
487
else .
450
488
end
451
489
)
@@ -459,56 +497,57 @@ def _finalize(self) -> None:
459
497
'package-lock.json' : {},
460
498
}
461
499
462
- for path , source in sources .items ():
463
- GIT_URL_PREFIX = 'git+'
464
-
465
- new_version = f'{ path } #{ source .commit } '
466
- assert source .from_ is not None
467
- data ['package.json' ][source .from_ ] = new_version
468
- data ['package-lock.json' ][source .original ] = new_version
469
-
470
- if source .from_ .startswith (GIT_URL_PREFIX ):
471
- data ['package.json' ][
472
- source .from_ [len (GIT_URL_PREFIX ) :]
473
- ] = new_version
474
-
475
- if source .original .startswith (GIT_URL_PREFIX ):
476
- data ['package-lock.json' ][
477
- source .original [len (GIT_URL_PREFIX ) :]
478
- ] = new_version
479
-
480
- for filename , script in scripts .items ():
481
- target = Path ('$FLATPAK_BUILDER_BUILDDIR' ) / prefix / filename
482
- script = (
483
- textwrap .dedent (script .lstrip ('\n ' )).strip ().replace ('\n ' , '' )
484
- )
485
- json_data = json .dumps (data [filename ])
486
- patch_commands [lockfile ].append (
487
- 'jq'
488
- ' --arg buildroot "$FLATPAK_BUILDER_BUILDDIR"'
489
- f' --argjson data { shlex .quote (json_data )} '
490
- f' { shlex .quote (script )} { target } '
491
- f' > { target } .new'
492
- )
493
- patch_commands [lockfile ].append (f'mv { target } {{.new,}}' )
494
-
495
- patch_all_commands : List [str ] = []
496
- for lockfile in self .all_lockfiles :
497
- patch_dest = (
498
- self .gen .data_root / 'patch' / self .relative_lockfile_dir (lockfile )
499
- )
500
- # Don't use with_extension to avoid problems if the package has a . in its name.
501
- patch_dest = patch_dest .with_name (patch_dest .name + '.sh' )
500
+ with open (lockfile ) as fp :
501
+ lockfile_v1 = json .load (fp )['lockfileVersion' ] == 1
502
+
503
+ if lockfile_v1 :
504
+ for path , name_source in sources .items ():
505
+ GIT_URL_PREFIX = 'git+'
506
+ name , source = name_source
507
+ new_version = f'{ path } #{ source .commit } '
508
+ data ['package.json' ][name ] = new_version
509
+ data ['package-lock.json' ][source .original ] = new_version
510
+
511
+ if source .original .startswith (GIT_URL_PREFIX ):
512
+ data ['package-lock.json' ][
513
+ source .original [len (GIT_URL_PREFIX ) :]
514
+ ] = new_version
515
+
516
+ for filename , script in scripts .items ():
517
+ target = Path ('$FLATPAK_BUILDER_BUILDDIR' ) / prefix / filename
518
+ script = (
519
+ textwrap .dedent (script .lstrip ('\n ' ))
520
+ .strip ()
521
+ .replace ('\n ' , '' )
522
+ )
523
+ json_data = json .dumps (data [filename ])
524
+ patch_commands [lockfile ].append (
525
+ 'jq'
526
+ ' --arg buildroot "$FLATPAK_BUILDER_BUILDDIR"'
527
+ f' --argjson data { shlex .quote (json_data )} '
528
+ f' { shlex .quote (script )} { target } '
529
+ f' > { target } .new'
530
+ )
531
+ patch_commands [lockfile ].append (f'mv { target } {{.new,}}' )
532
+
533
+ if len (patch_commands ) > 0 :
534
+ patch_all_commands : List [str ] = []
535
+ for lockfile in self .all_lockfiles :
536
+ patch_dest = (
537
+ self .gen .data_root / 'patch' / self .relative_lockfile_dir (lockfile )
538
+ )
539
+ # Don't use with_extension to avoid problems if the package has a . in its name.
540
+ patch_dest = patch_dest .with_name (patch_dest .name + '.sh' )
502
541
503
- self .gen .add_script_source (patch_commands [lockfile ], patch_dest )
504
- patch_all_commands .append (f'" $FLATPAK_BUILDER_BUILDDIR" /{ patch_dest } ' )
542
+ self .gen .add_script_source (patch_commands [lockfile ], patch_dest )
543
+ patch_all_commands .append (f'$FLATPAK_BUILDER_BUILDDIR/{ patch_dest } ' )
505
544
506
- patch_all_dest = self .gen .data_root / 'patch-all.sh'
507
- self .gen .add_script_source (patch_all_commands , patch_all_dest )
545
+ patch_all_dest = self .gen .data_root / 'patch-all.sh'
546
+ self .gen .add_script_source (patch_all_commands , patch_all_dest )
508
547
509
- if not self .no_autopatch :
510
- # FLATPAK_BUILDER_BUILDDIR isn't defined yet for script sources.
511
- self .gen .add_command (f'FLATPAK_BUILDER_BUILDDIR=" $PWD" { patch_all_dest } ' )
548
+ if not self .no_autopatch :
549
+ # FLATPAK_BUILDER_BUILDDIR isn't defined yet for script sources.
550
+ self .gen .add_command (f'FLATPAK_BUILDER_BUILDDIR=$PWD { patch_all_dest } ' )
512
551
513
552
if self .index_entries :
514
553
for path , entry in self .index_entries .items ():
0 commit comments