1818
1919import { ArchiveFileAsset , Downloadable , Downloader , GitHubReleaseAsset , GitHubWorkflowAsset , WebFileAsset } from '@open-cmsis-pack/vsce-helper' ;
2020import { PackageJson } from 'type-fest' ;
21+ import process from 'node:process' ;
2122import fs from 'node:fs/promises' ;
2223import path from 'node:path' ;
23- import process from 'node:process' ;
24- // Temporary solution until we have fixed vsce-helper
25- import extract from 'extract-zip' ;
26- import { fileURLToPath } from 'node:url' ;
27- import { dirname } from 'node:path' ;
24+ import { execFile as execFileCallback } from 'node:child_process' ;
25+ import { promisify } from 'node:util' ;
2826
29- const __filename = fileURLToPath ( import . meta. url ) ;
30- const __dirname = dirname ( __filename ) ;
27+ const execFile = promisify ( execFileCallback ) ;
3128
3229type CmsisPackageJson = PackageJson & {
3330 cmsis : {
@@ -48,15 +45,6 @@ function splitGitReference(reference: string, owner: string, repo: string) {
4845 return { repo, owner, reference } ;
4946}
5047
51- // Temporary solution until we have fixed vsce-helper
52- class ExtractZipArchiveFileAsset extends ArchiveFileAsset {
53- protected async extractArchive ( archiveFile : string , dest ?: string ) : Promise < string > {
54- const effDest = dest ?? path . join ( __dirname , 'tools' , 'pyocd' ) ;
55- await extract ( archiveFile , { dir : effDest } ) ;
56- return effDest ;
57- }
58- }
59-
6048const pyocd : Downloadable = new Downloadable (
6149 'pyOCD' , 'pyocd' ,
6250 async ( target ) => {
@@ -80,20 +68,11 @@ const pyocd : Downloadable = new Downloadable(
8068 owner , repo , reference ,
8169 `pyocd-${ os } ${ arch } -${ reference } .zip` ,
8270 { token : process . env . GITHUB_TOKEN } ) ;
83- const asset = new ExtractZipArchiveFileAsset ( releaseAsset ) ;
71+ const asset = new ArchiveFileAsset ( releaseAsset ) ;
8472 return asset ;
8573 } ,
8674)
8775
88- // Temporary solution until we have fixed vsce-helper
89- class ExtractZipGitHubWorkflowAsset extends GitHubWorkflowAsset {
90- protected async extractArchive ( archiveFile : string , dest ?: string ) : Promise < string > {
91- const effDest = dest ?? path . join ( __dirname , 'tools' , 'pyocd' ) ;
92- await extract ( archiveFile , { dir : effDest } ) ;
93- return effDest ;
94- }
95- }
96-
9776
9877const pyocdNightly : Downloadable = new Downloadable (
9978 'pyOCD' , 'pyocd' ,
@@ -115,7 +94,7 @@ const pyocdNightly : Downloadable = new Downloadable(
11594 // Here, reference is expected to be the name of the workflow yaml file without file ending
11695 const { repo, owner, reference } = splitGitReference ( workflow , 'pyocd' , 'pyOCD' ) ;
11796 const assetPattern = ( `pyocd-${ os } ${ arch } -\\d+\\.\\d+\\.\\d+.*` ) ;
118- const asset = new ExtractZipGitHubWorkflowAsset (
97+ const asset = new GitHubWorkflowAsset (
11998 owner , repo , `${ reference } .yaml` ,
12099 assetPattern ,
121100 { token : process . env . GITHUB_TOKEN } ) ;
@@ -124,10 +103,32 @@ const pyocdNightly : Downloadable = new Downloadable(
124103)
125104
126105class GDBArchiveFileAsset extends ArchiveFileAsset {
106+ protected async extractArchive ( archiveFile : string , dest ?: string , options : { strip ?: number ; force ?: boolean } = { } ) : Promise < string > {
107+ if ( ! archiveFile . toLowerCase ( ) . endsWith ( '.tar.xz' ) ) {
108+ return super . extractArchive ( archiveFile , dest , options ) ;
109+ }
110+
111+ const effDest = await this . mkDest ( dest ) ;
112+ const strip = options . strip ?? this . strip ;
113+ const args = [ '-xJf' , archiveFile , '-C' , effDest ] ;
114+ if ( strip > 0 ) {
115+ args . push ( `--strip-components=${ strip } ` ) ;
116+ }
117+
118+ try {
119+ // Some GNU Arm tarballs include large numeric headers the JS tar parser rejects.
120+ await execFile ( 'tar' , args ) ;
121+ return effDest ;
122+ } catch {
123+ console . warn ( 'System tar extraction failed, falling back to built-in archive extractor.' ) ;
124+ return super . extractArchive ( archiveFile , effDest , options ) ;
125+ }
126+ }
127+
127128 public async copyTo ( dest ?: string ) {
128129 dest = await super . copyTo ( dest ) ;
129130 // Remove doc directory as it contains duplicate files (names differ only in case)
130- // which are not supported by ZIP (VSIX) archives
131+ // which are not supported by ZIP (VSIX) archives.
131132 await fs . rm ( path . join ( dest , 'share' , 'doc' ) , { recursive : true , force : true } ) ;
132133 return dest ;
133134 }
0 commit comments