1
- import { statOrNull , spawn , debug } from "./util"
2
- import { emptyDir , move , remove } from "fs-extra-p"
1
+ import { statOrNull , spawn , debug , debug7z } from "./util"
2
+ import { readdir , mkdirs , move , remove } from "fs-extra-p"
3
3
import { download } from "./httpRequest"
4
4
import { path7za } from "7zip-bin"
5
5
import * as path from "path"
6
- import { tmpdir } from "os"
6
+ import { homedir } from "os"
7
7
import { Promise as BluebirdPromise } from "bluebird"
8
8
9
9
//noinspection JSUnusedLocalSymbols
@@ -18,42 +18,77 @@ function getTempName(prefix?: string | n): string {
18
18
const versionToPromise = new Map < string , BluebirdPromise < string > > ( )
19
19
20
20
// can be called in parallel, all calls for the same version will get the same promise - will be downloaded only once
21
- export function downloadFpm ( version : string ) : Promise < string > {
21
+ export function downloadFpm ( version : string , osAndArch : string ) : Promise < string > {
22
22
let promise = versionToPromise . get ( version )
23
23
// if rejected, we will try to download again
24
24
if ( < any > promise != null && ! promise ! . isRejected ( ) ) {
25
25
return promise !
26
26
}
27
27
28
- promise = < BluebirdPromise < string > > doDownloadFpm ( version )
28
+ promise = < BluebirdPromise < string > > doDownloadFpm ( version , osAndArch )
29
29
versionToPromise . set ( version , promise )
30
30
return promise
31
31
}
32
32
33
- async function doDownloadFpm ( version : string ) : Promise < string > {
34
- const dirName = `fpm-${ version } -osx `
33
+ async function doDownloadFpm ( version : string , osAndArch : string ) : Promise < string > {
34
+ const dirName = `fpm-${ version } -${ osAndArch } `
35
35
const url = `https://github.com/develar/fpm-self-contained/releases/download/v${ version } /${ dirName } .7z`
36
- const cache = path . join ( __dirname , ".." , "node_modules" , ".fpm" )
37
- const fpmDir = path . join ( cache , dirName )
36
+
37
+ // we cache in the global location - in the home dir, not in the node_modules/.cache (https://www.npmjs.com/package/find-cache-dir) because
38
+ // * don't need to find node_modules
39
+ // * don't pollute user project dir (important in case of 1-package.json project structure)
40
+ // * simplify/speed-up tests (don't download fpm for each test project)
41
+ const cacheDir = path . join ( homedir ( ) , ".cache" , "fpm" )
42
+ const fpmDir = path . join ( cacheDir , dirName )
38
43
39
44
const stat = await statOrNull ( fpmDir )
40
45
if ( stat != null && stat . isDirectory ( ) ) {
46
+ debug ( `Found existing fpm ${ fpmDir } ` )
41
47
return path . join ( fpmDir , "fpm" )
42
48
}
43
49
44
50
// the only version currently supported (i.e. all clients are consumed the same version
45
- await emptyDir ( cache )
51
+ await emptyDir ( cacheDir , dirName )
46
52
47
- const archiveName = path . join ( tmpdir ( ) , getTempName ( "fpm-download" ) + ".7z" )
53
+ // 7z cannot be extracted from the input stream, temp file is required
54
+ const tempName = getTempName ( )
55
+ const archiveName = path . join ( cacheDir , tempName + ".7z" )
56
+ debug ( `Download fpm from ${ url } to ${ archiveName } ` )
48
57
await download ( url , archiveName )
49
- const tempUnpackDir = path . join ( cache , getTempName ( ) )
50
- await spawn ( path7za , [ "x" , archiveName , "-o" + tempUnpackDir , "-bb" + ( debug . enabled ? "3" : "0" ) , "-bd" ] , {
51
- cwd : cache ,
52
- stdio : [ "ignore" , "inherit" , "inherit" ] ,
58
+ const tempUnpackDir = path . join ( cacheDir , tempName )
59
+ const args = [ "x" , archiveName , "-o" + tempName , "-bd" ]
60
+ if ( debug7z . enabled ) {
61
+ args . push ( "-bb3" )
62
+ }
63
+ else if ( ! debug . enabled ) {
64
+ args . push ( "-bb0" )
65
+ }
66
+ await spawn ( path7za , args , {
67
+ cwd : cacheDir ,
68
+ stdio : [ "ignore" , debug . enabled ? "inherit" : "ignore" , "inherit" ] ,
53
69
} )
54
70
55
- await move ( path . join ( tempUnpackDir , dirName ) , fpmDir , { clobber : true } )
56
- await BluebirdPromise . all ( [ remove ( tempUnpackDir ) , remove ( archiveName ) ] )
71
+ await BluebirdPromise . all ( [ move ( path . join ( tempUnpackDir , dirName ) , fpmDir , { clobber : true } ) , remove ( archiveName ) ] )
72
+ await remove ( tempUnpackDir )
57
73
74
+ debug ( `fpm downloaded to ${ fpmDir } ` )
58
75
return path . join ( fpmDir , "fpm" )
76
+ }
77
+
78
+ // prefix to not delete dir or archived dir (.7z)
79
+ async function emptyDir ( dir : string , excludeNamePrefix : string ) {
80
+ let items : string [ ] | null = null
81
+ try {
82
+ items = await readdir ( dir )
83
+ }
84
+ catch ( e ) {
85
+ await mkdirs ( dir )
86
+ return
87
+ }
88
+
89
+ items = items !
90
+ . filter ( it => ! it . startsWith ( excludeNamePrefix ) )
91
+ . map ( it => path . join ( dir , it ) )
92
+
93
+ await BluebirdPromise . map ( items , remove )
59
94
}
0 commit comments