@@ -5,7 +5,10 @@ const fs = require('fs')
55const fetch = require ( 'node-fetch' )
66const path = require ( 'path' )
77const process = require ( 'process' )
8+ const stream = require ( 'stream' )
9+ const tar = require ( 'tar-fs' )
810const URL = require ( 'url' ) . URL
11+ const util = require ( 'util' )
912
1013// This could have been a ten-line shell script, but no, we are full-stack async now...
1114// Though, it does look pretty in the Web console.
@@ -75,47 +78,47 @@ async function main() {
7578 }
7679
7780 async function buildFromSource ( ) {
78- const url = new URL ( `https://www.nasm.us/pub/nasm/releasebuilds/${ version } /nasm-${ version } .zip ` )
81+ const url = new URL ( `https://www.nasm.us/pub/nasm/releasebuilds/${ version } /nasm-${ version } .tar.gz ` )
7982 const buffer = await fetchBuffer ( url )
80- const zip = new AdmZip ( buffer )
83+ // node-fetch returns already ungzipped tarball.
84+ await extractTar ( buffer , absNasmDir )
8185
82- zip . extractAllTo ( absNasmDir )
86+ // The tarball has all content in a versioned subdirectory: "nasm-2.15.05".
87+ const sourceDir = path . join ( absNasmDir , `nasm-${ version } ` )
88+ core . debug ( `extracted NASM to '${ sourceDir } '` )
8389
84- // NASM uses the usual "./configure && make" but ZIP makes it harder.
85- // First of all, configure shell script usually ends up with Windows
86- // line endings which breaks the shebang line on non-Windows machines.
87- const configurePath = path . join ( absNasmDir , 'configure' )
90+ // NASM uses the usual "./configure && make", but make sure we extracted
91+ // everything correctly before jumping in.
92+ const configurePath = path . join ( sourceDir , 'configure' )
8893 if ( ! fs . existsSync ( configurePath ) ) {
8994 core . debug ( `configure script missing: ${ configurePath } ` )
90- throw new Error ( `failed to extract to '${ absNasmDir } '` )
95+ throw new Error ( `failed to extract to '${ sourceDir } '` )
9196 }
92- dos2unix ( configurePath )
93- fs . chmodSync ( configurePath , '755' )
9497
9598 // Now we can run "./configure". Node.js does not allow to change current
9699 // working directory for the current process, so we use absolute paths.
97- execute ( [ configurePath ] , { cwd : absNasmDir } )
100+ execute ( [ configurePath ] , { cwd : sourceDir } )
98101
99102 // Now comes the fun part! Somehow, despite smoking Autocrack, NASM manages
100103 // to botch up platform detection. Or that's Apple thinking different again,
101104 // I don't know. Whatever it is, here are magic patches to make things work.
102105 if ( platform == 'linux' || platform == 'macosx' ) {
103106 if ( version . match ( / 2 .1 4 / ) ) {
104- appendFile ( path . join ( absNasmDir , 'include/compiler.h' ) , [
107+ appendFile ( path . join ( sourceDir , 'include/compiler.h' ) , [
105108 '#include <time.h>'
106109 ] )
107110 }
108111 }
109112 if ( platform == 'macosx' ) {
110113 if ( version . match ( / 2 .1 4 / ) ) {
111- appendFile ( path . join ( absNasmDir , 'config/config.h' ) , [
114+ appendFile ( path . join ( sourceDir , 'config/config.h' ) , [
112115 '#define HAVE_SNPRINTF 1' ,
113116 '#define HAVE_VSNPRINTF 1' ,
114117 '#define HAVE_INTTYPES_H 1'
115118 ] )
116119 }
117120 if ( version . match ( / 2 .1 3 / ) ) {
118- appendFile ( path . join ( absNasmDir , 'config/config.h' ) , [
121+ appendFile ( path . join ( sourceDir , 'config/config.h' ) , [
119122 '#define HAVE_STRLCPY 1' ,
120123 '#define HAVE_DECL_STRLCPY 1' ,
121124 '#define HAVE_SNPRINTF 1' ,
@@ -124,7 +127,7 @@ async function main() {
124127 ] )
125128 }
126129 if ( version . match ( / 2 .1 2 / ) ) {
127- appendFile ( path . join ( absNasmDir , 'config.h' ) , [
130+ appendFile ( path . join ( sourceDir , 'config.h' ) , [
128131 '#define HAVE_STRLCPY 1' ,
129132 '#define HAVE_DECL_STRLCPY 1' ,
130133 '#define HAVE_SNPRINTF 1' ,
@@ -134,9 +137,12 @@ async function main() {
134137 }
135138
136139 // Finally, build the damn binary.
137- execute ( [ 'make' , 'nasm' ] , { cwd : absNasmDir } )
140+ execute ( [ 'make' , 'nasm' ] , { cwd : sourceDir } )
138141
139- core . debug ( `compiled NASM in '${ absNasmDir } '` )
142+ core . debug ( `compiled NASM in '${ sourceDir } '` )
143+
144+ // The binary is expected at a slightly different place...
145+ fs . renameSync ( path . join ( sourceDir , nasm ) , absNasmFile )
140146 }
141147
142148 var made_it = false
@@ -187,14 +193,6 @@ function execute(cmdline, extra_options) {
187193 return result
188194}
189195
190- function dos2unix ( path ) {
191- const converted = path + '.unix'
192- const content = fs . readFileSync ( path , { encoding : 'utf8' } )
193- const unixified = content . replace ( / \r \n / g, '\n' )
194- fs . writeFileSync ( converted , unixified , { encoding : 'utf8' } )
195- fs . renameSync ( converted , path )
196- }
197-
198196function appendFile ( path , strings ) {
199197 fs . appendFileSync ( path , '\n' + strings . join ( '\n' ) + '\n' )
200198}
@@ -212,4 +210,15 @@ async function fetchBuffer(url) {
212210 return buffer
213211}
214212
213+ async function extractTar ( buffer , directory ) {
214+ core . info ( 'Extracting source code...' )
215+ // Yes, I love async programming very much. So straightforward!
216+ async function * data ( ) { yield buffer ; }
217+ const tarball = stream . Readable . from ( data ( ) )
218+ . pipe ( tar . extract ( directory ) )
219+ // Stream promise API is not available on GitHub Actions. Drain manually.
220+ const finished = util . promisify ( stream . finished )
221+ return finished ( tarball )
222+ }
223+
215224main ( ) . catch ( ( e ) => core . setFailed ( `could not install NASM: ${ e } ` ) )
0 commit comments