From 89246be45088f5d7e16e54bf2685d22f7c66e9f5 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Fri, 17 Aug 2018 09:54:23 +0200 Subject: [PATCH 01/21] version bot fetch , parse and sort tags --- updater.js | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 updater.js diff --git a/updater.js b/updater.js new file mode 100644 index 0000000..363a626 --- /dev/null +++ b/updater.js @@ -0,0 +1,58 @@ +const { exec } = require("child_process"); +const versionNumberRegexp = /v([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{1,2})(?:\.([0-9]{1,2})){0,1}/g; + + +listRemoteTags("https://github.com/dashpay/dash").then(stdout => { + const versions = parseVersionsTags(stdout); + versions.sort(versionsSorter); + console.log(versions[versions.length - 1].toString()); +}).catch(err => { + console.log(err); +}); + +function versionsSorter(a, b) { + if (a.major > b.major + || (a.major >= b.major && a.minor > b.minor) + || (a.major >= b.major && a.minor >= b.minor && a.patch > b.patch) + || (a.major >= b.major && a.minor >= b.minor && a.patch >= b.patch) && a.fourth > b.fourth) { + return 1; + } else { + return -1; + } +} + +function parseVersionsTags(tagLists) { + const versions = []; + let version = {}; + while (version = versionNumberRegexp.exec(tagLists)) { + versions.push(new Version(version)); + } + return versions; +} + +function listRemoteTags(remote) { + return new Promise((resolve, reject) => { + exec("git ls-remote --tags " + remote, (err, stdout, stderr) => { + if (typeof stdout === "string") { + resolve(stdout); + } else if (typeof stderr === "string") { + reject(stderr); + } else { + reject(err); + } + }); + }); +} + +class Version { + constructor(versionRegexpResult) { + this.major = parseInt(versionRegexpResult[1]); + this.minor = parseInt(versionRegexpResult[2]); + this.patch = parseInt(versionRegexpResult[3]); + this.fourth = versionRegexpResult[4] ? parseInt(versionRegexpResult[4]) : null; + } + + toString() { + return "v" + this.major + "." + this.minor + "." + this.patch + "." + this.fourth; + } +} From ea1dacaef34d37212ad1f77a51aabc69f217167f Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Fri, 17 Aug 2018 11:06:28 +0200 Subject: [PATCH 02/21] promisify and leverage async / await syntax. --- updater.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/updater.js b/updater.js index 363a626..76515da 100644 --- a/updater.js +++ b/updater.js @@ -1,4 +1,5 @@ -const { exec } = require("child_process"); +const util = require("util"); +const exec = util.promisify(require("child_process").exec); const versionNumberRegexp = /v([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{1,2})(?:\.([0-9]{1,2})){0,1}/g; @@ -10,6 +11,12 @@ listRemoteTags("https://github.com/dashpay/dash").then(stdout => { console.log(err); }); +function majorFilter(major) { + return (o) => { + return (o.major === major); + }; +} + function versionsSorter(a, b) { if (a.major > b.major || (a.major >= b.major && a.minor > b.minor) @@ -30,18 +37,13 @@ function parseVersionsTags(tagLists) { return versions; } -function listRemoteTags(remote) { - return new Promise((resolve, reject) => { - exec("git ls-remote --tags " + remote, (err, stdout, stderr) => { - if (typeof stdout === "string") { - resolve(stdout); - } else if (typeof stderr === "string") { - reject(stderr); - } else { - reject(err); - } - }); - }); +async function listRemoteTags(remote) { + const {stdout, stderr} = await exec("git ls-remote --tags " + remote); + if (typeof stdout === "string") { + return stdout; + } else if (typeof stderr === "string") { + return Promise.reject(stderr); + } } class Version { From bbf7f81adc3b7aedd5e903d0f67f4a7f1d37b808 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Fri, 17 Aug 2018 11:12:12 +0200 Subject: [PATCH 03/21] prepare update class. --- updater.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/updater.js b/updater.js index 76515da..95118c1 100644 --- a/updater.js +++ b/updater.js @@ -58,3 +58,15 @@ class Version { return "v" + this.major + "." + this.minor + "." + this.patch + "." + this.fourth; } } + +class Update { + constructor(wallet,from,to) { + this.wallet = wallet; + this.from = from; + this.to = to; + } + + toString() { + return 'updated ' + this.wallet + 'from ' + this.from + 'to ' + this.to; + } +} From f00e9e506ec2ba61141cda5b9090b3a4460338e9 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Fri, 17 Aug 2018 12:20:22 +0200 Subject: [PATCH 04/21] add function to check for updates. --- updater.js | 62 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/updater.js b/updater.js index 95118c1..2620a7d 100644 --- a/updater.js +++ b/updater.js @@ -1,22 +1,66 @@ const util = require("util"); const exec = util.promisify(require("child_process").exec); const versionNumberRegexp = /v([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{1,2})(?:\.([0-9]{1,2})){0,1}/g; +const wallets = require('./wallets'); +const updates = []; +wallets.Zerocoin.identifier = 'Zerocoin'; -listRemoteTags("https://github.com/dashpay/dash").then(stdout => { - const versions = parseVersionsTags(stdout); - versions.sort(versionsSorter); - console.log(versions[versions.length - 1].toString()); -}).catch(err => { - console.log(err); +checkForUpdates(wallets.Zerocoin).then(() => { + console.log(updates[0].toString()); }); +async function checkForUpdates(wallet) { + const tags = await listRemoteTags(wallet.repository); + let versions = parseVersionsTags(tags); + const currentVersion = findCurrentVersion(wallet); + + versions = versions.filter(superiorVersionsFilter(currentVersion)); + versions = versions.sort(versionsSorter); + + if(versions.length > 0) { + const targetVersion = versions[versions.length - 1]; + updates.push(new Update(wallet.identifier,currentVersion,targetVersion)); + } + return true; +} + +function findCurrentVersion(wallet) { + if(wallet.tag) { + let regexpResult = versionNumberRegexp.exec(wallet.tag); + if (regexpResult) { + return new Version(regexpResult); + } + } + + throw new Error("Can't determined current version for wallet : " + wallet.name); +} + function majorFilter(major) { return (o) => { return (o.major === major); }; } +function superiorVersionsFilter(currentVersion) { + return (version) => { + if(version.major === currentVersion.major) { + if(version.minor > currentVersion.minor) { + return 1; + } else if(version.minor === currentVersion.minor) { + if(version.patch > currentVersion.patch) { + return 1; + } else if(version.patch === currentVersion.patch) { + if(version.fourth > currentVersion.fourth) { + return 1; + } + } + } + } + return 0; + } +} + function versionsSorter(a, b) { if (a.major > b.major || (a.major >= b.major && a.minor > b.minor) @@ -60,13 +104,13 @@ class Version { } class Update { - constructor(wallet,from,to) { - this.wallet = wallet; + constructor(walletIdentifier,from,to) { + this.walletIdentifier = walletIdentifier; this.from = from; this.to = to; } toString() { - return 'updated ' + this.wallet + 'from ' + this.from + 'to ' + this.to; + return 'updated ' + this.walletIdentifier + ' from ' + this.from.toString() + ' to ' + this.to.toString(); } } From 89c3764b4960dd24b743519059451f40f1950b42 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Fri, 17 Aug 2018 12:20:50 +0200 Subject: [PATCH 05/21] removed unused filter --- updater.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/updater.js b/updater.js index 2620a7d..d5b1edb 100644 --- a/updater.js +++ b/updater.js @@ -36,12 +36,6 @@ function findCurrentVersion(wallet) { throw new Error("Can't determined current version for wallet : " + wallet.name); } -function majorFilter(major) { - return (o) => { - return (o.major === major); - }; -} - function superiorVersionsFilter(currentVersion) { return (version) => { if(version.major === currentVersion.major) { From 3d5a9e94bf62623839e5ec9958ed05f9d4afdc83 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Fri, 17 Aug 2018 13:22:21 +0200 Subject: [PATCH 06/21] trigger all updates. --- updater.js | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/updater.js b/updater.js index d5b1edb..05e314b 100644 --- a/updater.js +++ b/updater.js @@ -4,11 +4,23 @@ const versionNumberRegexp = /v([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{1,2})(?:\.([0-9 const wallets = require('./wallets'); const updates = []; -wallets.Zerocoin.identifier = 'Zerocoin'; +const pendingUpdates = []; +for (let property in wallets) { + if(wallets.hasOwnProperty(property)) { + let wallet = wallets[property]; + wallet.identifier = property; + + pendingUpdates.push(checkForUpdates(wallet).catch(err => { + console.log(err); + })); + } +} + +Promise.all(pendingUpdates).then((updates) => { + console.log(updates); + } +); -checkForUpdates(wallets.Zerocoin).then(() => { - console.log(updates[0].toString()); -}); async function checkForUpdates(wallet) { const tags = await listRemoteTags(wallet.repository); @@ -20,9 +32,9 @@ async function checkForUpdates(wallet) { if(versions.length > 0) { const targetVersion = versions[versions.length - 1]; - updates.push(new Update(wallet.identifier,currentVersion,targetVersion)); + return new Update(wallet.identifier,currentVersion,targetVersion); } - return true; + return null; } function findCurrentVersion(wallet) { @@ -33,7 +45,7 @@ function findCurrentVersion(wallet) { } } - throw new Error("Can't determined current version for wallet : " + wallet.name); + throw new Error("Can't determined current version for wallet : " + wallet.identifier); } function superiorVersionsFilter(currentVersion) { From 801de02da365f49686fffff16ef0a492f653b551 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Fri, 17 Aug 2018 13:52:10 +0200 Subject: [PATCH 07/21] update version regexp to match all existing conventions in wallets.json --- updater.js | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/updater.js b/updater.js index 05e314b..25f53ad 100644 --- a/updater.js +++ b/updater.js @@ -1,6 +1,6 @@ const util = require("util"); const exec = util.promisify(require("child_process").exec); -const versionNumberRegexp = /v([0-9]{1,2})\.([0-9]{1,2})\.([0-9]{1,2})(?:\.([0-9]{1,2})){0,1}/g; +const versionNumberRegexp = /([vV])?([0-9]{1,2})\.([0-9]{1,2})(?:\.([0-9]{1,2}))?(?:\.([0-9]{1,2}))?[\n|\s]?/g; const wallets = require('./wallets'); const updates = []; @@ -10,14 +10,20 @@ for (let property in wallets) { let wallet = wallets[property]; wallet.identifier = property; - pendingUpdates.push(checkForUpdates(wallet).catch(err => { - console.log(err); + pendingUpdates + .push(checkForUpdates(wallet).catch(err => { + console.error(err.message); })); } } Promise.all(pendingUpdates).then((updates) => { console.log(updates); + updates.forEach(update => { + if(update) { + console.log(update.toString()); + } + }) } ); @@ -98,14 +104,18 @@ async function listRemoteTags(remote) { class Version { constructor(versionRegexpResult) { - this.major = parseInt(versionRegexpResult[1]); - this.minor = parseInt(versionRegexpResult[2]); - this.patch = parseInt(versionRegexpResult[3]); - this.fourth = versionRegexpResult[4] ? parseInt(versionRegexpResult[4]) : null; + this.prefix = versionRegexpResult[1] || ''; + this.major = parseInt(versionRegexpResult[2]); + this.minor = parseInt(versionRegexpResult[3]); + this.patch = versionRegexpResult[4] ? parseInt(versionRegexpResult[4]) : null; + this.fourth = versionRegexpResult[5] ? parseInt(versionRegexpResult[5]) : null; } toString() { - return "v" + this.major + "." + this.minor + "." + this.patch + "." + this.fourth; + let string = this.prefix + this.major + '.' + this.minor; + string += ((this.patch !== null ) ? '.' + this.patch : ''); + string += ((this.fourth !== null) ? '.' + this.fourth : ''); + return string; } } From d47b6c22e642c67c0bc893c6dcd2bc0471b2a965 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Fri, 17 Aug 2018 13:52:35 +0200 Subject: [PATCH 08/21] remove unused variable. --- updater.js | 1 - 1 file changed, 1 deletion(-) diff --git a/updater.js b/updater.js index 25f53ad..97a10c7 100644 --- a/updater.js +++ b/updater.js @@ -2,7 +2,6 @@ const util = require("util"); const exec = util.promisify(require("child_process").exec); const versionNumberRegexp = /([vV])?([0-9]{1,2})\.([0-9]{1,2})(?:\.([0-9]{1,2}))?(?:\.([0-9]{1,2}))?[\n|\s]?/g; const wallets = require('./wallets'); -const updates = []; const pendingUpdates = []; for (let property in wallets) { From e1072eba2b907793608035cff2a652d285b3e6da Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Fri, 17 Aug 2018 15:38:07 +0200 Subject: [PATCH 09/21] write changes to wallets.json --- updater.js | 51 +++++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/updater.js b/updater.js index 97a10c7..860fd05 100644 --- a/updater.js +++ b/updater.js @@ -2,32 +2,39 @@ const util = require("util"); const exec = util.promisify(require("child_process").exec); const versionNumberRegexp = /([vV])?([0-9]{1,2})\.([0-9]{1,2})(?:\.([0-9]{1,2}))?(?:\.([0-9]{1,2}))?[\n|\s]?/g; const wallets = require('./wallets'); - -const pendingUpdates = []; -for (let property in wallets) { - if(wallets.hasOwnProperty(property)) { - let wallet = wallets[property]; - wallet.identifier = property; - - pendingUpdates - .push(checkForUpdates(wallet).catch(err => { - console.error(err.message); - })); - } +const writeFile = util.promisify(require('fs').writeFile); + + (async function() { + let updates = await checkAllForUpdates(); + await updateFile(updates); + })().catch(err => { + console.error(err); + }); + +async function updateFile(updates) { + updates.forEach(update => { + if(update) { + wallets[update.walletIdentifier].tag = update.to.toString(); + } + }); + return writeFile('./wallets.json', JSON.stringify(wallets,null, ' ')); } -Promise.all(pendingUpdates).then((updates) => { - console.log(updates); - updates.forEach(update => { - if(update) { - console.log(update.toString()); - } - }) +async function checkAllForUpdates() { + const pendingUpdates = []; + for (let property in wallets) { + if(wallets.hasOwnProperty(property)) { + pendingUpdates + .push(checkForUpdates(wallets[property], property).catch(err => { + console.error(err.message); + })); + } } -); + return Promise.all(pendingUpdates); +} -async function checkForUpdates(wallet) { +async function checkForUpdates(wallet, identifier) { const tags = await listRemoteTags(wallet.repository); let versions = parseVersionsTags(tags); const currentVersion = findCurrentVersion(wallet); @@ -37,7 +44,7 @@ async function checkForUpdates(wallet) { if(versions.length > 0) { const targetVersion = versions[versions.length - 1]; - return new Update(wallet.identifier,currentVersion,targetVersion); + return new Update(identifier,currentVersion,targetVersion); } return null; } From aa3a8f4ab06ca804159e2fac94a3f08304fb72c4 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Fri, 17 Aug 2018 15:39:32 +0200 Subject: [PATCH 10/21] add function to build commit message --- updater.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/updater.js b/updater.js index 860fd05..be33740 100644 --- a/updater.js +++ b/updater.js @@ -7,10 +7,21 @@ const writeFile = util.promisify(require('fs').writeFile); (async function() { let updates = await checkAllForUpdates(); await updateFile(updates); + console.log(buildCommitMessage(updates)); })().catch(err => { console.error(err); }); +function buildCommitMessage(updates) { + let commitMessage = 'Update wallet.json\n\n'; + updates.forEach((update) => { + if(update) { + commitMessage += update.toString() + '\n'; + } + }); + return commitMessage; +} + async function updateFile(updates) { updates.forEach(update => { if(update) { From 2158dcc458307eee935b84150417bf99379b6b70 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Fri, 17 Aug 2018 17:29:39 +0200 Subject: [PATCH 11/21] install dotenv --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index db9aae2..beaffa9 100644 --- a/package.json +++ b/package.json @@ -39,5 +39,8 @@ "bugs": { "url": "https://github.com/LePetitBloc/wallets/issues" }, - "homepage": "https://github.com/LePetitBloc/wallets#readme" + "homepage": "https://github.com/LePetitBloc/wallets#readme", + "dependencies": { + "dotenv": "^6.0.0" + } } From 76ecc8a0dff3e12502a594ad2a137f1affa01fa5 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Mon, 20 Aug 2018 12:05:27 +0200 Subject: [PATCH 12/21] add commit and push functions. --- updater.js | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/updater.js b/updater.js index be33740..1c842b2 100644 --- a/updater.js +++ b/updater.js @@ -1,3 +1,4 @@ +require('dotenv').config(); const util = require("util"); const exec = util.promisify(require("child_process").exec); const versionNumberRegexp = /([vV])?([0-9]{1,2})\.([0-9]{1,2})(?:\.([0-9]{1,2}))?(?:\.([0-9]{1,2}))?[\n|\s]?/g; @@ -7,11 +8,37 @@ const writeFile = util.promisify(require('fs').writeFile); (async function() { let updates = await checkAllForUpdates(); await updateFile(updates); - console.log(buildCommitMessage(updates)); + await addDeployKey(); + await commit(buildCommitMessage(updates)); + await push() })().catch(err => { console.error(err); }); +async function addDeployKey() { + const {stdout, stderr} = await exec('eval "$(ssh-agent -s)" && echo $deploy_key | ssh-add -'); + console.log(stdout); + console.log(stderr); +} + +async function commit(message) { + const {stdout, stderr} = await exec('git commit -m "' + message +'"'); + console.log(stdout); + if(stderr) { + throw new Error(stderr); + } +} + +async function push() { + const {stdout, stderr} = await exec('git push origin HEAD'); + if(stderr) { + throw new Error(stderr); + } else { + console.log(stdout); + console.log('Updated wallet.json successfully') + } +} + function buildCommitMessage(updates) { let commitMessage = 'Update wallet.json\n\n'; updates.forEach((update) => { @@ -44,7 +71,6 @@ async function checkAllForUpdates() { return Promise.all(pendingUpdates); } - async function checkForUpdates(wallet, identifier) { const tags = await listRemoteTags(wallet.repository); let versions = parseVersionsTags(tags); From e2749f8c54c65918e9bdb62b9b555e82a08d1878 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Mon, 20 Aug 2018 12:09:18 +0200 Subject: [PATCH 13/21] throw an error when no deploy key is provided --- updater.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/updater.js b/updater.js index 1c842b2..6c66db1 100644 --- a/updater.js +++ b/updater.js @@ -16,6 +16,9 @@ const writeFile = util.promisify(require('fs').writeFile); }); async function addDeployKey() { + if(!process.env.deploy_key) { + throw new Error('Environment variable deploy_key is not set - cannot send modifications to server.'); + } const {stdout, stderr} = await exec('eval "$(ssh-agent -s)" && echo $deploy_key | ssh-add -'); console.log(stdout); console.log(stderr); From db5ec48ee947646dcd4a9e9dbf0ede0004ed049b Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Mon, 20 Aug 2018 12:15:23 +0200 Subject: [PATCH 14/21] add changes to commit before commit --- updater.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/updater.js b/updater.js index 6c66db1..eeb46dc 100644 --- a/updater.js +++ b/updater.js @@ -9,6 +9,7 @@ const writeFile = util.promisify(require('fs').writeFile); let updates = await checkAllForUpdates(); await updateFile(updates); await addDeployKey(); + await addChanges(); await commit(buildCommitMessage(updates)); await push() })().catch(err => { @@ -24,6 +25,14 @@ async function addDeployKey() { console.log(stderr); } +async function addChanges() { + const {stdout, stderr} = await exec('git add wallets.json'); + console.log(stdout); + if(stderr) { + throw new Error(stderr); + } +} + async function commit(message) { const {stdout, stderr} = await exec('git commit -m "' + message +'"'); console.log(stdout); From 9ba5a48e8a7fec8df243232525ca7e98c7d770fa Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Mon, 20 Aug 2018 12:47:51 +0200 Subject: [PATCH 15/21] improve error handling and log output. --- updater.js | 49 ++++++++++++++++++------------------------------- 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/updater.js b/updater.js index eeb46dc..15d88e3 100644 --- a/updater.js +++ b/updater.js @@ -5,16 +5,19 @@ const versionNumberRegexp = /([vV])?([0-9]{1,2})\.([0-9]{1,2})(?:\.([0-9]{1,2})) const wallets = require('./wallets'); const writeFile = util.promisify(require('fs').writeFile); - (async function() { +(async function() { + try { + console.log("--- Wallet updater launched at " + new Date() + "--"); let updates = await checkAllForUpdates(); await updateFile(updates); await addDeployKey(); await addChanges(); await commit(buildCommitMessage(updates)); await push() - })().catch(err => { - console.error(err); - }); + } catch (e) { + console.error(e); + } +})(); async function addDeployKey() { if(!process.env.deploy_key) { @@ -26,29 +29,20 @@ async function addDeployKey() { } async function addChanges() { - const {stdout, stderr} = await exec('git add wallets.json'); + const { stdout } = await exec('git add wallets.json'); console.log(stdout); - if(stderr) { - throw new Error(stderr); - } } async function commit(message) { - const {stdout, stderr} = await exec('git commit -m "' + message +'"'); + const { stdout } = await exec('git commit -m "' + message +'"'); console.log(stdout); - if(stderr) { - throw new Error(stderr); - } } async function push() { - const {stdout, stderr} = await exec('git push origin HEAD'); - if(stderr) { - throw new Error(stderr); - } else { - console.log(stdout); - console.log('Updated wallet.json successfully') - } + const { stderr } = await exec('git push origin HEAD'); + console.log(stderr); + console.log('Updated wallet.json successfully') + } function buildCommitMessage(updates) { @@ -58,7 +52,7 @@ function buildCommitMessage(updates) { commitMessage += update.toString() + '\n'; } }); - return commitMessage; + return commitMessage; } async function updateFile(updates) { @@ -74,10 +68,7 @@ async function checkAllForUpdates() { const pendingUpdates = []; for (let property in wallets) { if(wallets.hasOwnProperty(property)) { - pendingUpdates - .push(checkForUpdates(wallets[property], property).catch(err => { - console.error(err.message); - })); + pendingUpdates.push(checkForUpdates(wallets[property], property)); } } return Promise.all(pendingUpdates); @@ -106,7 +97,7 @@ function findCurrentVersion(wallet) { } } - throw new Error("Can't determined current version for wallet : " + wallet.identifier); + console.warn("Can't determined current version for wallet : " + wallet.identifier); } function superiorVersionsFilter(currentVersion) { @@ -149,12 +140,8 @@ function parseVersionsTags(tagLists) { } async function listRemoteTags(remote) { - const {stdout, stderr} = await exec("git ls-remote --tags " + remote); - if (typeof stdout === "string") { - return stdout; - } else if (typeof stderr === "string") { - return Promise.reject(stderr); - } + const {stdout} = await exec("git ls-remote --tags " + remote); + return stdout; } class Version { From 103d92312db47f7b2fc34c228e49c3777d362687 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Mon, 20 Aug 2018 13:12:53 +0200 Subject: [PATCH 16/21] improve error handling and log output. --- updater.js | 92 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/updater.js b/updater.js index 15d88e3..a8d5fc6 100644 --- a/updater.js +++ b/updater.js @@ -1,29 +1,30 @@ require('dotenv').config(); -const util = require("util"); -const exec = util.promisify(require("child_process").exec); +const util = require('util'); +const exec = util.promisify(require('child_process').exec); const versionNumberRegexp = /([vV])?([0-9]{1,2})\.([0-9]{1,2})(?:\.([0-9]{1,2}))?(?:\.([0-9]{1,2}))?[\n|\s]?/g; const wallets = require('./wallets'); const writeFile = util.promisify(require('fs').writeFile); (async function() { try { - console.log("--- Wallet updater launched at " + new Date() + "--"); + console.log('--- Wallet updater launched at ' + new Date() + '--'); let updates = await checkAllForUpdates(); await updateFile(updates); await addDeployKey(); await addChanges(); await commit(buildCommitMessage(updates)); - await push() + await push(); + console.log('--- Wallet updater ended at ' + new Date() + '--'); } catch (e) { console.error(e); } })(); async function addDeployKey() { - if(!process.env.deploy_key) { + if (!process.env.deploy_key) { throw new Error('Environment variable deploy_key is not set - cannot send modifications to server.'); } - const {stdout, stderr} = await exec('eval "$(ssh-agent -s)" && echo $deploy_key | ssh-add -'); + const { stdout, stderr } = await exec('eval "$(ssh-agent -s)" && echo $deploy_key | ssh-add -'); console.log(stdout); console.log(stderr); } @@ -34,21 +35,20 @@ async function addChanges() { } async function commit(message) { - const { stdout } = await exec('git commit -m "' + message +'"'); + const { stdout } = await exec('git commit -m "' + message + '"'); console.log(stdout); } async function push() { const { stderr } = await exec('git push origin HEAD'); console.log(stderr); - console.log('Updated wallet.json successfully') - + console.log('Updated wallet.json successfully'); } function buildCommitMessage(updates) { let commitMessage = 'Update wallet.json\n\n'; - updates.forEach((update) => { - if(update) { + updates.forEach(update => { + if (update) { commitMessage += update.toString() + '\n'; } }); @@ -57,17 +57,17 @@ function buildCommitMessage(updates) { async function updateFile(updates) { updates.forEach(update => { - if(update) { + if (update) { wallets[update.walletIdentifier].tag = update.to.toString(); } }); - return writeFile('./wallets.json', JSON.stringify(wallets,null, ' ')); + return writeFile('./wallets.json', JSON.stringify(wallets, null, ' ')); } async function checkAllForUpdates() { const pendingUpdates = []; for (let property in wallets) { - if(wallets.hasOwnProperty(property)) { + if (wallets.hasOwnProperty(property)) { pendingUpdates.push(checkForUpdates(wallets[property], property)); } } @@ -77,53 +77,57 @@ async function checkAllForUpdates() { async function checkForUpdates(wallet, identifier) { const tags = await listRemoteTags(wallet.repository); let versions = parseVersionsTags(tags); - const currentVersion = findCurrentVersion(wallet); - - versions = versions.filter(superiorVersionsFilter(currentVersion)); - versions = versions.sort(versionsSorter); - - if(versions.length > 0) { - const targetVersion = versions[versions.length - 1]; - return new Update(identifier,currentVersion,targetVersion); + const currentVersion = findCurrentVersion(wallet, identifier); + if(currentVersion) { + versions = versions.filter(superiorVersionsFilter(currentVersion)); + versions = versions.sort(versionsSorter); + + if (versions.length > 0) { + const targetVersion = versions[versions.length - 1]; + return new Update(identifier, currentVersion, targetVersion); + } } return null; } -function findCurrentVersion(wallet) { - if(wallet.tag) { +function findCurrentVersion(wallet, identifier) { + if (wallet.tag) { let regexpResult = versionNumberRegexp.exec(wallet.tag); if (regexpResult) { return new Version(regexpResult); } } - console.warn("Can't determined current version for wallet : " + wallet.identifier); + console.warn("Can't determined current version for wallet : " + identifier + ' missing tag'); + return null; } function superiorVersionsFilter(currentVersion) { - return (version) => { - if(version.major === currentVersion.major) { - if(version.minor > currentVersion.minor) { - return 1; - } else if(version.minor === currentVersion.minor) { - if(version.patch > currentVersion.patch) { + return version => { + if (version.major === currentVersion.major) { + if (version.minor > currentVersion.minor) { + return 1; + } else if (version.minor === currentVersion.minor) { + if (version.patch > currentVersion.patch) { return 1; - } else if(version.patch === currentVersion.patch) { - if(version.fourth > currentVersion.fourth) { + } else if (version.patch === currentVersion.patch) { + if (version.fourth > currentVersion.fourth) { return 1; } } } } return 0; - } + }; } function versionsSorter(a, b) { - if (a.major > b.major - || (a.major >= b.major && a.minor > b.minor) - || (a.major >= b.major && a.minor >= b.minor && a.patch > b.patch) - || (a.major >= b.major && a.minor >= b.minor && a.patch >= b.patch) && a.fourth > b.fourth) { + if ( + a.major > b.major || + (a.major >= b.major && a.minor > b.minor) || + (a.major >= b.major && a.minor >= b.minor && a.patch > b.patch) || + (a.major >= b.major && a.minor >= b.minor && a.patch >= b.patch && a.fourth > b.fourth) + ) { return 1; } else { return -1; @@ -133,14 +137,14 @@ function versionsSorter(a, b) { function parseVersionsTags(tagLists) { const versions = []; let version = {}; - while (version = versionNumberRegexp.exec(tagLists)) { + while ((version = versionNumberRegexp.exec(tagLists))) { versions.push(new Version(version)); } return versions; } async function listRemoteTags(remote) { - const {stdout} = await exec("git ls-remote --tags " + remote); + const { stdout } = await exec('git ls-remote --tags ' + remote); return stdout; } @@ -154,15 +158,15 @@ class Version { } toString() { - let string = this.prefix + this.major + '.' + this.minor; - string += ((this.patch !== null ) ? '.' + this.patch : ''); - string += ((this.fourth !== null) ? '.' + this.fourth : ''); + let string = this.prefix + this.major + '.' + this.minor; + string += this.patch !== null ? '.' + this.patch : ''; + string += this.fourth !== null ? '.' + this.fourth : ''; return string; } } class Update { - constructor(walletIdentifier,from,to) { + constructor(walletIdentifier, from, to) { this.walletIdentifier = walletIdentifier; this.from = from; this.to = to; From 2c79e325c96b2f463112acdcb713e8f4ec2c5a31 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Wed, 22 Aug 2018 08:29:17 +0200 Subject: [PATCH 17/21] add .npmrc for npmjs authentication. --- .npmrc | 1 + 1 file changed, 1 insertion(+) create mode 100644 .npmrc diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..ae64359 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +//registry.npmjs.org/:_authToken=${NPM_TOKEN} From 02c2d105ea7e2e90635e639b7267a886dbafcb70 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Wed, 22 Aug 2018 08:41:28 +0200 Subject: [PATCH 18/21] add utilities to update version patch, tag commit and publish. --- updater.js | 158 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 107 insertions(+), 51 deletions(-) diff --git a/updater.js b/updater.js index a8d5fc6..8c071df 100644 --- a/updater.js +++ b/updater.js @@ -1,55 +1,114 @@ -require('dotenv').config(); -const util = require('util'); -const exec = util.promisify(require('child_process').exec); +require("dotenv").config(); +const util = require("util"); +const exec = util.promisify(require("child_process").exec); const versionNumberRegexp = /([vV])?([0-9]{1,2})\.([0-9]{1,2})(?:\.([0-9]{1,2}))?(?:\.([0-9]{1,2}))?[\n|\s]?/g; -const wallets = require('./wallets'); -const writeFile = util.promisify(require('fs').writeFile); +const wallets = require("./wallets"); +const writeFile = util.promisify(require("fs").writeFile); +const manifest = require("./package"); + +class Version { + constructor(versionRegexpResult) { + this.prefix = versionRegexpResult[1] || ""; + this.major = parseInt(versionRegexpResult[2]); + this.minor = parseInt(versionRegexpResult[3]); + this.patch = versionRegexpResult[4] ? parseInt(versionRegexpResult[4]) : null; + this.fourth = versionRegexpResult[5] ? parseInt(versionRegexpResult[5]) : null; + } + + static fromVersionString(versionString) { + if (typeof versionString === "string") { + let regexpResult = versionNumberRegexp.exec(versionString); + if (regexpResult) { + return new Version(regexpResult); + } + } + + throw new Error("Can't parse version string : syntax error"); + } + + toString() { + let string = this.prefix + this.major + "." + this.minor; + string += this.patch !== null ? "." + this.patch : ""; + string += this.fourth !== null ? "." + this.fourth : ""; + return string; + } +} + +class Update { + constructor(walletIdentifier, from, to) { + this.walletIdentifier = walletIdentifier; + this.from = from; + this.to = to; + } + + toString() { + return "updated " + this.walletIdentifier + " from " + this.from.toString() + " to " + this.to.toString(); + } +} (async function() { try { - console.log('--- Wallet updater launched at ' + new Date() + '--'); + console.log("--- Wallet updater launched at " + new Date() + "--"); let updates = await checkAllForUpdates(); - await updateFile(updates); - await addDeployKey(); - await addChanges(); - await commit(buildCommitMessage(updates)); - await push(); - console.log('--- Wallet updater ended at ' + new Date() + '--'); + + if (updates.filter(o => { return o !== null; }).length > 0) { + await updateFile(updates); + await updatePatchNumber(); + + const commitMessage = buildCommitMessage(updates); + + await addDeployKey(); + await addChanges(); + await commit(commitMessage); + await tag(commitMessage); + await push(); + await publish(); + } else { + console.log("Wallets are up to date"); + } + + console.log("--- Wallet updater ended at " + new Date() + "--"); } catch (e) { console.error(e); } })(); + async function addDeployKey() { if (!process.env.deploy_key) { - throw new Error('Environment variable deploy_key is not set - cannot send modifications to server.'); + throw new Error("Environment variable deploy_key is not set - cannot send modifications to server."); } - const { stdout, stderr } = await exec('eval "$(ssh-agent -s)" && echo $deploy_key | ssh-add -'); + const { stdout, stderr } = await exec("eval \"$(ssh-agent -s)\" && echo $deploy_key | ssh-add -"); console.log(stdout); console.log(stderr); } async function addChanges() { - const { stdout } = await exec('git add wallets.json'); + const { stdout } = await exec("git add wallets.json"); console.log(stdout); } async function commit(message) { - const { stdout } = await exec('git commit -m "' + message + '"'); + const { stdout } = await exec("git commit -m \"" + message + "\""); + console.log(stdout); +} + +async function tag(message) { + const { stdout } = await exex("git tag " + manifest.version + "-m " + message); console.log(stdout); } async function push() { - const { stderr } = await exec('git push origin HEAD'); + const { stderr } = await exec("git push --follow-tags origin HEAD"); console.log(stderr); - console.log('Updated wallet.json successfully'); + console.log("Updated wallet.json successfully"); } function buildCommitMessage(updates) { - let commitMessage = 'Update wallet.json\n\n'; + let commitMessage = "Update wallet.json\n\n"; updates.forEach(update => { if (update) { - commitMessage += update.toString() + '\n'; + commitMessage += update.toString() + "\n"; } }); return commitMessage; @@ -61,7 +120,7 @@ async function updateFile(updates) { wallets[update.walletIdentifier].tag = update.to.toString(); } }); - return writeFile('./wallets.json', JSON.stringify(wallets, null, ' ')); + return writeFile("./wallets.json", JSON.stringify(wallets, null, " ")); } async function checkAllForUpdates() { @@ -78,7 +137,7 @@ async function checkForUpdates(wallet, identifier) { const tags = await listRemoteTags(wallet.repository); let versions = parseVersionsTags(tags); const currentVersion = findCurrentVersion(wallet, identifier); - if(currentVersion) { + if (currentVersion) { versions = versions.filter(superiorVersionsFilter(currentVersion)); versions = versions.sort(versionsSorter); @@ -98,10 +157,34 @@ function findCurrentVersion(wallet, identifier) { } } - console.warn("Can't determined current version for wallet : " + identifier + ' missing tag'); + console.warn("Can't determined current version for wallet : " + identifier + " missing tag"); return null; } +async function publish() { + if (!process.env.NPM_TOKEN) { + throw new Error("Environment variable NPM_TOKEN is not set - cannot publish package."); + } + try { + await exec("npm whoami"); + } catch (e) { + throw new Error("Something went wrong authenticating you on npm - Check your NPM_TOKEN validity"); + } + + const { stdout, stderr } = exec("npm publish"); + console.log(stdout); + return stdout; +} + +async function updatePatchNumber() { + const currentVersion = Version.fromVersionString(manifest.version); + currentVersion.patch += 1; + + manifest.version = currentVersion.toString(); + return writeFile("./package.json", JSON.stringify(manifest, null, " ")); +} + + function superiorVersionsFilter(currentVersion) { return version => { if (version.major === currentVersion.major) { @@ -144,35 +227,8 @@ function parseVersionsTags(tagLists) { } async function listRemoteTags(remote) { - const { stdout } = await exec('git ls-remote --tags ' + remote); + const { stdout } = await exec("git ls-remote --tags " + remote); return stdout; } -class Version { - constructor(versionRegexpResult) { - this.prefix = versionRegexpResult[1] || ''; - this.major = parseInt(versionRegexpResult[2]); - this.minor = parseInt(versionRegexpResult[3]); - this.patch = versionRegexpResult[4] ? parseInt(versionRegexpResult[4]) : null; - this.fourth = versionRegexpResult[5] ? parseInt(versionRegexpResult[5]) : null; - } - - toString() { - let string = this.prefix + this.major + '.' + this.minor; - string += this.patch !== null ? '.' + this.patch : ''; - string += this.fourth !== null ? '.' + this.fourth : ''; - return string; - } -} - -class Update { - constructor(walletIdentifier, from, to) { - this.walletIdentifier = walletIdentifier; - this.from = from; - this.to = to; - } - toString() { - return 'updated ' + this.walletIdentifier + ' from ' + this.from.toString() + ' to ' + this.to.toString(); - } -} From 5af4cf661d9205e4070dba5c019c396d240d4522 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Wed, 22 Aug 2018 09:51:01 +0200 Subject: [PATCH 19/21] reset regexp lastIndex before matching. --- updater.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/updater.js b/updater.js index 8c071df..465ab5b 100644 --- a/updater.js +++ b/updater.js @@ -17,6 +17,7 @@ class Version { static fromVersionString(versionString) { if (typeof versionString === "string") { + versionNumberRegexp.lastIndex = 0; let regexpResult = versionNumberRegexp.exec(versionString); if (regexpResult) { return new Version(regexpResult); @@ -64,7 +65,7 @@ class Update { await push(); await publish(); } else { - console.log("Wallets are up to date"); + console.log("Wallets are up to date."); } console.log("--- Wallet updater ended at " + new Date() + "--"); @@ -94,7 +95,7 @@ async function commit(message) { } async function tag(message) { - const { stdout } = await exex("git tag " + manifest.version + "-m " + message); + const { stdout } = await exec("git tag " + manifest.version + "-m " + message); console.log(stdout); } @@ -150,15 +151,12 @@ async function checkForUpdates(wallet, identifier) { } function findCurrentVersion(wallet, identifier) { - if (wallet.tag) { - let regexpResult = versionNumberRegexp.exec(wallet.tag); - if (regexpResult) { - return new Version(regexpResult); - } + try { + return Version.fromVersionString(wallet.tag); + }catch (e) { + console.warn("Can't determined current version for wallet : " + identifier + " missing tag"); + return null; } - - console.warn("Can't determined current version for wallet : " + identifier + " missing tag"); - return null; } async function publish() { @@ -220,6 +218,7 @@ function versionsSorter(a, b) { function parseVersionsTags(tagLists) { const versions = []; let version = {}; + versionNumberRegexp.lastIndex = 0; while ((version = versionNumberRegexp.exec(tagLists))) { versions.push(new Version(version)); } From 3867cddbdfe97e166c3ce34ae72b97c563169fd8 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Wed, 22 Aug 2018 10:06:26 +0200 Subject: [PATCH 20/21] fix syntax of git tag command --- updater.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/updater.js b/updater.js index 465ab5b..4297f5a 100644 --- a/updater.js +++ b/updater.js @@ -95,7 +95,7 @@ async function commit(message) { } async function tag(message) { - const { stdout } = await exec("git tag " + manifest.version + "-m " + message); + const { stdout } = await exec("git tag " + manifest.version + " -m \" " + message + "\""); console.log(stdout); } From f8cef0ab4179ea3b4e7b7296c95bce68020068d9 Mon Sep 17 00:00:00 2001 From: Jules LAURENT Date: Wed, 22 Aug 2018 10:51:38 +0200 Subject: [PATCH 21/21] fix publish log output - add package.json to changes. --- updater.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/updater.js b/updater.js index 4297f5a..5602e69 100644 --- a/updater.js +++ b/updater.js @@ -85,7 +85,7 @@ async function addDeployKey() { } async function addChanges() { - const { stdout } = await exec("git add wallets.json"); + const { stdout } = await exec("git add wallets.json package.json"); console.log(stdout); } @@ -169,7 +169,7 @@ async function publish() { throw new Error("Something went wrong authenticating you on npm - Check your NPM_TOKEN validity"); } - const { stdout, stderr } = exec("npm publish"); + const { stdout } = await exec("npm publish"); console.log(stdout); return stdout; }