scripts: Add more options to hs-client generator.

This commit is contained in:
Nodari Chkuaselidze 2023-05-29 19:07:53 +04:00
parent a349a44507
commit b0661265f1
No known key found for this signature in database
GPG key ID: B018A7BB437D1F05
3 changed files with 117 additions and 68 deletions

View file

@ -11,3 +11,4 @@ bin/hsw-cli
etc/genesis etc/genesis
lib/ lib/
test/ test/
scripts/

View file

@ -123,7 +123,7 @@ and create PR with the relevant updates to the `download/index.html` and
- Create PR to the main repository. - Create PR to the main repository.
# hs-client # hs-client
Since hsd v5 `hs-client` is part of the `hsd`. Original [hs-client repo][hsclient] is now used to Since hsd v6 `hs-client` is part of the `hsd`. Original [hs-client repo][hsclient] is now used to
publish generated content. `hs-client` version will now be strictly tied to publish generated content. `hs-client` version will now be strictly tied to
the `hsd` version. It is then generated from `hsd` code to release separately on the `hsd` version. It is then generated from `hsd` code to release separately on
`git` and `npm`. Most of the process is done by the introduced helper script `git` and `npm`. Most of the process is done by the introduced helper script
@ -132,12 +132,12 @@ publishing on `git` and `npm`. It also gives instructions how to do both.
After `hsd` has been released we can also release `hs-client` from the same After `hsd` has been released we can also release `hs-client` from the same
commit/tag, just run: `./scripts/gen-hsclient.js` which will generate `hs-client` commit/tag, just run: `./scripts/gen-hsclient.js` which will generate `hs-client`
package with `git` setup in `tmp` directory. You can alternatively pass package with `git` setup in `tmp` directory. You can alternatively pass
`HS_CLIENT_DIR` env variable for custom place. If generating git failed for some `DIRECTORY` as argument for custom path. If generating git failed for some
reason, it will list commands that needs executing and you can proceed manually reason, it will list commands that needs executing and you can proceed manually
or fix the issues and rerun the script. NOTE, that the script will never try to or fix the issues and rerun the script. NOTE, that the script will never try to
publish by itself, only generate files to review locally. publish by itself, only generate files to review locally.
- `./scripts/gen-hsclient.js` - script will also list left commands that are - `./scripts/gen-hsclient.js /tmp/hs-client` - script will also list the commands,
necessary for publishing. that needs running for publishing to the git and npm.
- `cd /tmp/hs-client` - `cd /tmp/hs-client`
- `git push -f origin master` - rewrite whole `hs-client` repo with the new content. - `git push -f origin master` - rewrite whole `hs-client` repo with the new content.
- `git push -f origin vVersion` - push newly generated tag to the `hs-client`. - `git push -f origin vVersion` - push newly generated tag to the `hs-client`.

View file

@ -2,65 +2,67 @@
'use strict'; 'use strict';
const assert = require('assert'); const assert = require('bsert');
const path = require('path'); const path = require('path');
const fs = require('bfile');
const os = require('os'); const os = require('os');
const util = require('util'); const util = require('util');
const cp = require('child_process'); const cp = require('child_process');
const exec = util.promisify(cp.exec); const exec = util.promisify(cp.exec);
const fs = require('bfile');
const Config = require('bcfg');
const ROOT = path.dirname(__dirname); const ROOT = path.dirname(__dirname);
const NAME = 'hs-client';
const HSD_PKG = require(path.join(ROOT, 'package.json')); const HSD_PKG = require(path.join(ROOT, 'package.json'));
const REMOTE = 'git@github.com:handshake-org/hs-client.git'; const REMOTE = 'git@github.com:handshake-org/hs-client.git';
const INIT_HS_CLIENT_PKG = { const INIT_HS_CLIENT_PKG = {
name: "hs-client", name: 'hs-client',
description: "HSD node and wallet client", description: 'HSD node and wallet client',
keywords: [ keywords: [
"http", 'http',
"request", 'request',
"socket.io", 'socket.io',
"websockets" 'websockets'
], ],
main: "./lib/client/index.js", main: './lib/client/index.js',
bin: { bin: {
"hsd-cli": "./bin/hsd-cli", 'hsd-cli': './bin/hsd-cli',
"hsd-rpc": "./bin/hsd-rpc", 'hsd-rpc': './bin/hsd-rpc',
"hsw-cli": "./bin/hsw-cli", 'hsw-cli': './bin/hsw-cli',
"hsw-rpc": "./bin/hsw-rpc" 'hsw-rpc': './bin/hsw-rpc'
}, },
engines: { engines: {
node: ">=8.0.0" node: '>=8.0.0'
} }
} };
const INHERIT_PROPERTIES = [ const INHERIT_PROPERTIES = [
"version", 'version',
"license", 'license',
"repository", 'repository',
"homepage", 'homepage',
"bugs", 'bugs',
"author" 'author'
]; ];
const DEPENDENCIES = [ const DEPENDENCIES = [
"bcfg", 'bcfg',
"bcurl", 'bcurl',
"bsert" 'bsert'
]; ];
const COPY_FILES = [ const COPY_FILES = [
".npmignore", '.npmignore',
".gitignore", '.gitignore',
"bin/hsd-cli", 'bin/hsd-cli',
"bin/hsw-cli", 'bin/hsw-cli',
"bin/hsd-rpc", 'bin/hsd-rpc',
"bin/hsw-rpc", 'bin/hsw-rpc',
"lib/client/index.js", 'lib/client/index.js',
"lib/client/wallet.js", 'lib/client/wallet.js',
"lib/client/node.js", 'lib/client/node.js'
]; ];
const README = ` const README = `
@ -78,33 +80,30 @@ const {NodeClient, WalletClient} = require('hs-client');
\`\`\` \`\`\`
`; `;
async function ensureDir() { const HELP = `Usage: gen-hsclient [DIRECTORY] [OPTIONS]...
if (!await fs.exists(ROOT)) Generate hs-client package in DIRECTORY.
throw new Error(`${ROOT} does not exist.`);
const {HS_CLIENT_DIR} = process.env; OPTIONS:
--no-git - Don't setup git.
--verbose - Verbose output.
--no-steps - Don't print next steps.
`;
let HS_PKG = HS_CLIENT_DIR ? path.resolve(HS_CLIENT_DIR) : null; async function ensureDir(dir) {
dir = path.resolve(dir);
if (!HS_PKG) if (dir.startsWith(ROOT))
HS_PKG = path.join(os.tmpdir(), `hs-client`); throw new Error(`${NAME} needs to be outside of the hsd. ${dir}`);
if (await fs.exists(dir)) {
if (HS_PKG.startsWith(ROOT))
throw new Error(`hs-client needs to be outside of the hsd. ${HS_PKG}`);
console.log('hs-client directory: ', HS_PKG);
if (await fs.exists(HS_PKG)) {
throw new Error( throw new Error(
`Directory ${HS_PKG} already exists.` `Directory ${dir} already exists.`
+ ' Please remove to proceed or choose different directory.' + ' Please remove to proceed or choose different directory.'
); );
} }
await fs.mkdir(HS_PKG); await fs.mkdir(dir);
return dir;
return HS_PKG;
} }
async function setupPackageContent(dir) { async function setupPackageContent(dir) {
@ -120,7 +119,7 @@ async function setupPackageContent(dir) {
} }
const hsClientPkg = { const hsClientPkg = {
...INIT_HS_CLIENT_PKG, ...INIT_HS_CLIENT_PKG
}; };
for (const name of INHERIT_PROPERTIES) { for (const name of INHERIT_PROPERTIES) {
@ -140,8 +139,7 @@ async function setupPackageContent(dir) {
return hsClientPkg; return hsClientPkg;
} }
async function setupGit(dir, version) { async function setupGit(dir, version, log) {
console.log('Setting up git: ', dir);
const commands = [ const commands = [
'git init -b master', 'git init -b master',
`git remote add origin ${REMOTE}`, `git remote add origin ${REMOTE}`,
@ -155,36 +153,86 @@ async function setupGit(dir, version) {
`git push -f origin v${version}` `git push -f origin v${version}`
]; ];
log('Setting up git: ', dir);
for (const cmd of [...commands]) { for (const cmd of [...commands]) {
console.log(`executing: ${cmd} in ${dir}.`); log(` > ${cmd} in ${dir}.`);
try { try {
console.log(await execCmd(cmd, dir)); log(await execCmd(cmd, dir));
} catch (e) { } catch (e) {
console.log(`Failed to execute: ${cmd}.`); console.log(`Failed to execute: ${cmd}.`);
console.log(e.message); console.log(e.message);
console.log(' You can proceed manually'); console.log('You need to proceed manually.');
break; break;
} }
commands.shift(); commands.shift();
} }
for (const command of [...commands, ...manualCommands]) return [...commands, ...manualCommands];
console.log(`Needs exec: ${command}`);
} }
(async () => { (async () => {
const HS_PKG = await ensureDir(); const config = new Config('hsd', {
const pkg = await setupPackageContent(HS_PKG); alias: {
'v': 'verbose'
}
});
await setupGit(HS_PKG, pkg.version); config.load({
console.log('Needs: npm publish'); argv: true,
env: true
});
if (config.bool('help')) {
console.log(HELP);
process.exit(0);
}
const dir = config.str(0, tmpdir());
const verbose = config.bool('verbose', false);
const noGit = config.bool('no-git', false);
const noSteps = config.bool('no-steps', false);
const log = verbose ? console.log : () => {};
const pkgDir = await ensureDir(dir);
log(`Copying files to ${pkgDir}...`);
const pkg = await setupPackageContent(pkgDir);
let gitNext = null;
if (!noGit)
gitNext = await setupGit(pkgDir, pkg.version, log);
if (noSteps)
return;
console.log(`Generated ${pkgDir}.`);
console.log('Next steps:');
console.log(` $ cd ${pkgDir}`);
if (!noGit) {
assert(gitNext);
console.log('Git Next:');
for (const cmd of gitNext)
console.log(` $ ${cmd}`);
}
console.log('NPM Next:');
console.log(' $ npm publish --dry-run # check if everything is ok');
console.log(' $ npm publish');
})().catch((err) => { })().catch((err) => {
console.log('Try passing --help for help.');
console.error(err.stack); console.error(err.stack);
process.exit(1); process.exit(1);
}); });
function tmpdir() {
return path.join(os.tmpdir(), NAME + '-' + Date.now());
}
async function execCmd(cmd, cwd, timeout = 2000) { async function execCmd(cmd, cwd, timeout = 2000) {
assert(cwd, 'CWD is required.'); assert(cwd, 'CWD is required.');
@ -193,7 +241,7 @@ async function execCmd(cmd, cwd, timeout = 2000) {
timeout timeout
}); });
if (stderr.length != 0) if (stderr.length !== 0)
throw new Error(stderr); throw new Error(stderr);
return stdout; return stdout;