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
  • Loading branch information
srl295 committed Sep 24, 2021
1 parent 72ddf0c commit 3ea0c1b
Show file tree
Hide file tree
Showing 13 changed files with 251 additions and 4 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": "eslint:recommended",
"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) {
var icupkg = fullIcu.icupkg;
var 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');
var path = require('path');
var 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;
14 changes: 13 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
"version": "1.3.5-0",
"description": "install 'full-icu' data for your current node",
"scripts": {
<<<<<<< HEAD
"lint": "standard",
"postinstall": "node postinstall.js"
=======
"postinstall": "node postinstall.js",
"test": "tap test/*.js",
"lint": "eslint *.js test/*.js"
>>>>>>> 652cffa (some lint)
},
"keywords": [
"icu4c"
Expand All @@ -22,7 +28,13 @@
"bugs": {
"url": "https://github.com/unicode-org/full-icu-npm/issues"
},
"dependencies": {
"yauzl": "^2.10.0"
},
"devDependencies": {
"standard": "^16.0.3"
"standard": "^16.0.3",
"eslint": "^6.8.0",
"eslint-plugin-header": "^3.0.0",
"tap": "^14.10.6"
}
}
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
var 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.done();
});
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.done();
});
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.done();
});
t.test('cleanup', t => {
try {
fs.unlinkSync('test/tmp/needle.txt');
} catch(e) { /* ignore */ }
t.done();
});
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 3ea0c1b

Please sign in to comment.