@@ -4,24 +4,29 @@ import fs from 'node:fs/promises';
4
4
import child_process from 'node:child_process' ;
5
5
import events from 'node:events' ;
6
6
import path from 'node:path' ;
7
+ import https from 'node:https' ;
8
+ import { pipeline } from 'node:stream/promises' ;
7
9
8
10
async function parseArguments ( ) {
9
- const jsonImport = { [ process . version . split ( '.' ) . at ( 0 ) === 'v16' ? 'assert' : 'with' ] : { type : 'json' } } ;
11
+ const jsonImport = {
12
+ [ process . version . split ( '.' ) . at ( 0 ) === 'v16' ? 'assert' : 'with' ] : { type : 'json' }
13
+ } ;
10
14
const pkg = ( await import ( '../../package.json' , jsonImport ) ) . default ;
11
15
const libmongocryptVersion = pkg [ 'mongodb:libmongocrypt' ] ;
12
16
13
17
const options = {
14
- url : { short : 'u' , type : 'string' , default : 'https://github.com/mongodb/libmongocrypt.git' } ,
15
- libversion : { short : 'l' , type : 'string' , default : libmongocryptVersion } ,
16
- clean : { short : 'c' , type : 'boolean' } ,
17
- help : { short : 'h' , type : 'boolean' }
18
+ gitURL : { short : 'u' , type : 'string' , default : 'https://github.com/mongodb/libmongocrypt.git' } ,
19
+ libVersion : { short : 'l' , type : 'string' , default : libmongocryptVersion } ,
20
+ clean : { short : 'c' , type : 'boolean' , default : false } ,
21
+ build : { short : 'b' , type : 'boolean' , default : false } ,
22
+ help : { short : 'h' , type : 'boolean' , default : false }
18
23
} ;
19
24
20
25
const args = util . parseArgs ( { args : process . argv . slice ( 2 ) , options, allowPositionals : false } ) ;
21
26
22
27
if ( args . values . help ) {
23
28
console . log (
24
- `${ process . argv [ 1 ] } ${ [ ...Object . keys ( options ) ]
29
+ `${ path . basename ( process . argv [ 1 ] ) } ${ [ ...Object . keys ( options ) ]
25
30
. filter ( k => k !== 'help' )
26
31
. map ( k => `[--${ k } =${ options [ k ] . type } ]` )
27
32
. join ( ' ' ) } `
@@ -30,8 +35,9 @@ async function parseArguments() {
30
35
}
31
36
32
37
return {
33
- libmongocrypt : { url : args . values . url , ref : args . values . libversion } ,
34
- clean : args . values . clean
38
+ libmongocrypt : { url : args . values . gitURL , ref : args . values . libVersion } ,
39
+ clean : args . values . clean ,
40
+ build : args . values . build
35
41
} ;
36
42
}
37
43
@@ -49,24 +55,30 @@ function toFlags(object) {
49
55
const args = await parseArguments ( ) ;
50
56
const libmongocryptRoot = path . resolve ( '_libmongocrypt' ) ;
51
57
52
- const currentLibMongoCryptBranch = await fs . readFile ( path . join ( libmongocryptRoot , '.git' , 'HEAD' ) , 'utf8' ) . catch ( ( ) => '' )
53
- const libmongocryptAlreadyClonedAndCheckedOut = currentLibMongoCryptBranch . trim ( ) . endsWith ( `r-${ args . libmongocrypt . ref } ` ) ;
58
+ const currentLibMongoCryptBranch = await fs
59
+ . readFile ( path . join ( libmongocryptRoot , '.git' , 'HEAD' ) , 'utf8' )
60
+ . catch ( ( ) => '' ) ;
61
+ const libmongocryptAlreadyClonedAndCheckedOut = currentLibMongoCryptBranch
62
+ . trim ( )
63
+ . endsWith ( `r-${ args . libmongocrypt . ref } ` ) ;
54
64
55
- if ( args . clean || ! libmongocryptAlreadyClonedAndCheckedOut ) {
65
+ if ( args . build && ( args . clean || ! libmongocryptAlreadyClonedAndCheckedOut ) ) {
56
66
console . error ( 'fetching libmongocrypt...' , args . libmongocrypt ) ;
57
67
await fs . rm ( libmongocryptRoot , { recursive : true , force : true } ) ;
58
68
await run ( 'git' , [ 'clone' , args . libmongocrypt . url , libmongocryptRoot ] ) ;
59
69
await run ( 'git' , [ 'fetch' , '--tags' ] , { cwd : libmongocryptRoot } ) ;
60
- await run ( 'git' , [ 'checkout' , args . libmongocrypt . ref , '-b' , `r-${ args . libmongocrypt . ref } ` ] , { cwd : libmongocryptRoot } ) ;
61
- } else {
62
- console . error ( 'libmongocrypt already up to date...' , args . libmongocrypt ) ;
70
+ await run ( 'git' , [ 'checkout' , args . libmongocrypt . ref , '-b' , `r-${ args . libmongocrypt . ref } ` ] , {
71
+ cwd : libmongocryptRoot
72
+ } ) ;
63
73
}
64
74
65
- const libmongocryptBuiltVersion = await fs . readFile ( path . join ( libmongocryptRoot , 'VERSION_CURRENT' ) , 'utf8' ) . catch ( ( ) => '' ) ;
75
+ const libmongocryptBuiltVersion = await fs
76
+ . readFile ( path . join ( libmongocryptRoot , 'VERSION_CURRENT' ) , 'utf8' )
77
+ . catch ( ( ) => '' ) ;
66
78
const libmongocryptAlreadyBuilt = libmongocryptBuiltVersion . trim ( ) === args . libmongocrypt . ref ;
67
79
68
- if ( args . clean || ! libmongocryptAlreadyBuilt ) {
69
- console . error ( 'building libmongocrypt...\n' , args ) ;
80
+ if ( args . build && ( args . clean || ! libmongocryptAlreadyBuilt ) ) {
81
+ console . error ( 'building libmongocrypt...\n' , args . libmongocrypt ) ;
70
82
71
83
const nodeDepsRoot = path . resolve ( 'deps' ) ;
72
84
const nodeBuildRoot = path . resolve ( nodeDepsRoot , 'tmp' , 'libmongocrypt-build' ) ;
@@ -115,10 +127,55 @@ if (args.clean || !libmongocryptAlreadyBuilt) {
115
127
? toFlags ( { DCMAKE_OSX_DEPLOYMENT_TARGET : '10.12' } )
116
128
: [ ] ;
117
129
118
- await run ( 'cmake' , [ ...CMAKE_FLAGS , ...WINDOWS_CMAKE_FLAGS , ...MACOS_CMAKE_FLAGS , libmongocryptRoot ] , { cwd : nodeBuildRoot } ) ;
119
- await run ( 'cmake' , [ '--build' , '.' , '--target' , 'install' , '--config' , 'RelWithDebInfo' ] , { cwd : nodeBuildRoot } ) ;
120
- } else {
121
- console . error ( 'libmongocrypt already built...' ) ;
130
+ await run (
131
+ 'cmake' ,
132
+ [ ...CMAKE_FLAGS , ...WINDOWS_CMAKE_FLAGS , ...MACOS_CMAKE_FLAGS , libmongocryptRoot ] ,
133
+ { cwd : nodeBuildRoot }
134
+ ) ;
135
+ await run ( 'cmake' , [ '--build' , '.' , '--target' , 'install' , '--config' , 'RelWithDebInfo' ] , {
136
+ cwd : nodeBuildRoot
137
+ } ) ;
138
+ }
139
+
140
+ if ( ! args . build ) {
141
+ const downloadURL =
142
+ args . libmongocrypt . ref === 'latest'
143
+ ? 'https://mciuploads.s3.amazonaws.com/libmongocrypt/all/master/latest/libmongocrypt-all.tar.gz'
144
+ : `https://mciuploads.s3.amazonaws.com/libmongocrypt/all/${ args . libmongocrypt . ref } /libmongocrypt-all.tar.gz` ;
145
+
146
+ console . error ( 'downloading libmongocrypt...' , downloadURL ) ;
147
+ const destination = `_libmongocrypt-${ args . libmongocrypt . ref } ` ;
148
+
149
+ await fs . rm ( destination , { recursive : true , force : true } ) ;
150
+ await fs . mkdir ( destination ) ;
151
+
152
+ const platformMatrix = {
153
+ [ 'darwin-arm64' ] : 'macos' ,
154
+ [ 'darwin-x64' ] : 'macos' ,
155
+ [ 'linux-ppc64' ] : 'rhel-71-ppc64el' ,
156
+ [ 'linux-s390x' ] : 'rhel72-zseries-test' ,
157
+ [ 'linux-arm64' ] : 'ubuntu1804-arm64' ,
158
+ [ 'linux-x64' ] : 'rhel-70-64-bit' ,
159
+ [ 'win32-x64' ] : 'windows-test'
160
+ } ;
161
+
162
+ const platform = platformMatrix [ `${ process . platform } -${ process . arch } ` ] ;
163
+ if ( platform == null ) throw new Error ( `${ process . platform } -${ process . arch } ` ) ;
164
+
165
+ const unzip = child_process . spawn ( 'tar' , [ '-xz' , '-C' , destination , ...new Set ( Object . values ( platformMatrix ) ) ] , {
166
+ stdio : [ 'pipe' ]
167
+ } ) ;
168
+
169
+ const [ response ] = await events . once ( https . get ( downloadURL ) , 'response' ) ;
170
+
171
+ const start = performance . now ( ) ;
172
+ await pipeline ( response , unzip . stdin ) ;
173
+ const end = performance . now ( ) ;
174
+
175
+ console . error ( `downloaded libmongocrypt in ${ ( end - start ) / 1000 } secs...` ) ;
176
+
177
+ await fs . rm ( 'deps' , { recursive : true , force : true } ) ;
178
+ await fs . cp ( path . join ( destination , platform , 'nocrypto' ) , 'deps' , { recursive : true } ) ;
122
179
}
123
180
124
181
await run ( 'npm' , [ 'install' , '--ignore-scripts' ] ) ;
0 commit comments