Skip to content

Commit

Permalink
feat: Pull from GitHub instead of npm
Browse files Browse the repository at this point in the history
- fetch from ICU’s GitHub release instead of npm (ICU v50+)
- set env FULL_ICU_PREFER_NPM to prefer npm instead
- add .eslint

Fixes: #36
  • Loading branch information
srl295 committed Sep 24, 2021
1 parent 72ddf0c commit dcf0d5b
Show file tree
Hide file tree
Showing 13 changed files with 252 additions and 6 deletions.
17 changes: 17 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module.exports = {
"env": {
"commonjs": true,
"es6": true,
"node": true
},
"extends": "standard",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018
},
"rules": {
}
};
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ node_modules
*.dat
npm-debug.log
/yarn.lock
package-lock.json
/.nyc_output
3 changes: 2 additions & 1 deletion .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
node_modules
.svn
.git
npm-debug.log
npm-debug.log
/test
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package-lock=false
14 changes: 14 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
language: node_js
node_js:
- '8'
- '10'
- '11'
- '12'
script:
- npm install
- npm t
cache:
directories:
- node_modules
- ".nvm"
# this is a comment
62 changes: 62 additions & 0 deletions install-gh.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (C) 2015-2016 IBM Corporation and Others. All Rights Reserved.

// Install by using spawn

// var fs = require('fs');
const { URL } = require('url')
const process = require('process')
const myFetch = require('./myFetch')
// const yauzl = require('yauzl');

// var isglobal = process.env.npm_config_global === 'true';

module.exports = async function installFromGithub (fullIcu, advice) {
const icupkg = fullIcu.icupkg
const icudat = fullIcu.icudat

// var cmdPath = nodePath = process.env.npm_node_execpath;

// var npmPath = process.env.npm_execpath;

// var args;
// https://github.com/unicode-org/icu/releases/download/release-51-3/icu4c-51_3-src.zip
const _baseUrl = process.env.FULL_ICU_BASEURL || 'https://github.com/unicode-org/icu/releases/'
const baseUrl = new URL(_baseUrl)
const versionsAsHyphen = fullIcu.icuver.replace(/\./g, '-')
const versionsAsUnderscore = fullIcu.icuver.replace(/\./g, '_')
const tag = `release-${versionsAsHyphen}`
const file = `icu4c-${versionsAsUnderscore}-src.zip`
const fullUrl = new URL(`./download/${tag}/${file}`, baseUrl)
console.log(fullUrl.toString())
const [srcZip, tmpd] = await myFetch(fullUrl)

console.log(srcZip, tmpd)
// now, unpack it

/*
if(spawned.error) {
throw(spawned.error);
} else if(spawned.status !== 0) {
throw(Error(cmdPath + ' ' + args.join(' ') + ' --> status ' + spawned.status));
} else {
var datPath;
if(fs.existsSync(icudat)) {
console.log(' √ ' + icudat + " (existing link?)");
} else if(!fs.existsSync(datPath)) {
console.log(' • ' + ' (no ' + icudat + ' at ‘' + datPath+'’)');
} else {
try {
fs.linkSync(datPath, icudat);
console.log(' √ ' + icudat + " (link)");
} catch(e) {
fs.symlinkSync(datPath, icudat);
console.log(' √ ' + icudat + " (symlink)");
}
}
if(!fullIcu.haveDat()) {
throw Error('Somehow failed to install ' + icudat);
} else {
advice();
}
} */
}
58 changes: 58 additions & 0 deletions myFetch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright (C) 2015-2016 IBM Corporation and Others. All Rights Reserved.

const os = require('os')
const path = require('path')
const fs = require('fs')

function getFetcher (u) {
if (u.protocol === 'https:') return require('https')
if (u.protocol === 'http:') return require('http')
return null
}

/**
* @param {URL} fullUrl url to fetch
* @returns {Promse<String[]>} filename, tmpdir
*/
function myFetch (fullUrl) {
return new Promise((resolve, reject) => {
const fetcher = getFetcher(fullUrl)
console.log('Fetch:', fullUrl.toString())
if (!fetcher) {
return reject(Error(`Unknown URL protocol ${fullUrl.protocol} in ${fullUrl.toString()}`))
}

fetcher.get(fullUrl, res => {
const length = res.headers['content-length']
if (res.statusCode === 302 && res.headers.location) {
return resolve(myFetch(new URL(res.headers.location)))
} else if (res.statusCode !== 200) {
return reject(Error(`Bad status code ${res.statusCode}`))
}
const tmpd = fs.mkdtempSync(os.tmpdir())
const tmpf = path.join(tmpd, 'icu-download.zip')
let gotSoFar = 0
console.dir(tmpd)

res.on('data', data => {
gotSoFar += data.length
fs.appendFileSync(tmpf, data)
// console.dir(res.headers);
process.stdout.write(`${gotSoFar}/${length}\r`)
// console.log(`chunk: ${data.length}`);
})
res.on('end', () => {
resolve([tmpf, tmpd])
console.log(`${gotSoFar}/${length}\n`)
})
res.on('error', error => {
fs.unlinkSync(tmpf)
fs.rmdirSync(tmpd)
console.error(error)
return reject(error)
})
})
})
}

module.exports = myFetch
17 changes: 14 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
"version": "1.3.5-0",
"description": "install 'full-icu' data for your current node",
"scripts": {
"lint": "standard",
"postinstall": "node postinstall.js"
"lint": "standard && eslint *.js test/*.js",
"postinstall": "node postinstall.js",
"test": "tap test/*.js"
},
"keywords": [
"icu4c"
Expand All @@ -22,7 +23,17 @@
"bugs": {
"url": "https://github.com/unicode-org/full-icu-npm/issues"
},
"dependencies": {
"yauzl": "^2.10.0"
},
"devDependencies": {
"standard": "^16.0.3"
"eslint": "^7.7.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-header": "^3.0.0",
"eslint-plugin-import": "^2.24.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"standard": "^16.0.3",
"tap": "^15.0.10"
}
}
12 changes: 10 additions & 2 deletions postinstall.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,16 @@ function advice () {
console.log("... will show “enero”. If it shows “January” you don't have full data.")
}

// install by using spawn
const npmInstall = require('./install-spawn')
// Choose install method
let npmInstall

// GitHub has v50+ as releases
// Experimentally, pull from GitHub for little endian
if (fullIcu.icuend === 'l' && !process.env.FULL_ICU_PREFER_NPM) {
npmInstall = require('./install-gh')
} else {
npmInstall = require('./install-spawn')
}

if (fs.existsSync(fullIcu.icudat)) {
console.log('√ ' + fullIcu.icudat + ' Already there (for Node ' + fullIcu.nodever + ' and small-icu ' + fullIcu.icuver + ')')
Expand Down
Binary file added test/data/haystack.zip
Binary file not shown.
32 changes: 32 additions & 0 deletions test/test-unzipOne.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const tap = require('tap')
const fs = require('fs')
const unzipOne = require('../unzipOne')

tap.test('unzipOne', async t => {
t.test('setup', t => {
try {
fs.unlinkSync('test/tmp/needle.txt')
} catch (e) { /* ignore */ }
t.end()
})
t.test('no easteregg in haystack.zip', async t => {
const ee = await unzipOne('./test/data/haystack.zip', 'easteregg.txt', './test/tmp/')
t.notOk(ee, 'Did not expect to find easteregg in haystack: ' + ee)
t.end()
})
t.test('get needle.txt in haystack.zip', async t => {
const ee = await unzipOne('./test/data/haystack.zip', 'needle.txt', './test/tmp/')
t.ok(ee, 'Did expect to find needle.txt in haystack: ' + ee)
const truism = fs.readFileSync('./test/tmp/needle.txt', 'utf-8')
t.ok(truism)
t.equal(truism.trim(), 'true')
t.end()
})
t.test('cleanup', t => {
try {
fs.unlinkSync('test/tmp/needle.txt')
} catch (e) { /* ignore */ }
t.end()
})
t.end()
})
Empty file added test/tmp/.keep
Empty file.
40 changes: 40 additions & 0 deletions unzipOne.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const yauzl = require('yauzl')
const { basename, join } = require('path')
const fs = require('fs')

/**
* unzip and write file 'fn' to 'dstDir'
* @param {String} srcZip source zipfile
* @param {String} fn to unzip
* @param {String} dstDir destination dir
* @returns {Promise<String>} to output filename if successful, or falsy if the file was not found.
*/
function unzipOne (srcZip, fn, dstDir) {
const outFile = join(dstDir, fn)
return new Promise((resolve, reject) => {
yauzl.open(srcZip, { lazyEntries: true },
(err, zipfile) => {
if (err) return reject(err)
zipfile.readEntry()
zipfile.on('entry', entry => {
if (basename(entry.fileName) === fn) {
zipfile.openReadStream(entry, (err, readStream) => {
if (err) return reject(err)
readStream.on('end', () => {
zipfile.close()
resolve(entry.fileName)
})
readStream.pipe(fs.createWriteStream(outFile))
})
} else {
zipfile.readEntry()
}
})
zipfile.on('end', () => {
resolve() // not found
})
})
})
}

module.exports = unzipOne

0 comments on commit dcf0d5b

Please sign in to comment.