From 44ef0665e9e8e5fdf7c6bfcd61f95fe8b6990a4b Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Mon, 3 Apr 2017 22:39:34 +1000 Subject: [PATCH 01/18] Release itself --- README.md | 15 +++++++++++++++ package.json | 4 +++- release.js | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 README.md create mode 100644 release.js diff --git a/README.md b/README.md new file mode 100644 index 0000000..5827aed --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +## Operations + +#### `Promise bumpJSONFiles(String bumpSpec, Array filePaths)` + +Bumps the "version" property from a list of file paths that matches the [JSON](http://json.org/) spec. +Returns a `Promise` that will resolve once all files have been bumped. + +#### `Promise gitCommit(String message, NodeGitRepository gitRepository)` + +Adds all the changes to the staging area and create a commit to the given repository. +Returns a `Promise` that will resolve once the commit has been created. + +## Release Steps + +* Run `npm run release `, where `bumpSpec` is either `patch`, `minor` or `major` diff --git a/package.json b/package.json index 33c01f4..1285375 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,9 @@ "license": "MIT", "scripts": { "test": "eslint \"src/**/*.js\" \"test/**/*.js\" && mocha --trace-warnings", - "test:watch": "eslint \"src/**/*.js\" \"test/**/*.js\" && mocha -w" + "test:watch": "eslint \"src/**/*.js\" \"test/**/*.js\" && mocha -w", + "release:test": "node release.js fake patch", + "release": "node release.js fake patch" }, "devDependencies": { "chai": "4.1.2", diff --git a/release.js b/release.js new file mode 100644 index 0000000..19ceccf --- /dev/null +++ b/release.js @@ -0,0 +1,50 @@ +const Promise = require("bluebird"); +const Git = require("nodegit"); + +const bumpJSONFiles = require("./src/file/bump-json-files"); +const gitCommit = require("./src/git/git-commit"); + +let targetBumpSpec; +if (process.argv.includes("patch")) { + targetBumpSpec = "patch"; +} +if (process.argv.includes("minor")) { + targetBumpSpec = "minor"; +} +if (process.argv.includes("major")) { + targetBumpSpec = "major"; +} +if (!targetBumpSpec) { + console.log("Invalid bump spec, use 'patch', 'minor' or 'major'"); + return; +} + +const isFakeRun = process.argv.includes("fake"); + +let localRepo; + +Promise.try(() => { + console.log("Bumping package.json..."); + if (!isFakeRun) { + return bumpJSONFiles(targetBumpSpec, ["package.json"]); + } +}).then(() => { + return Git.Repository.discover(".", 0, "."); +}).then((_localRepo) => { + localRepo = _localRepo + console.log("Found repository:", localRepo); + console.log("Creating release commit..."); + if (!isFakeRun) { + return gitCommit("Release new version", localRepo); + } +}).then((commitObjectId) => { + const tagName = commitObjectId && commitObjectId.substring(0, 8) + const tagReferenceCommit = commitObjectId + console.log("Creating tag:", tagName); + if (!isFakeRun) { + return gitTag(tagName, tagReferenceCommit, localRepo); + } +}); + +// TODO Push the tag to the remote +// TODO Publish on NPM From 23aa1291d1c59aa4ac73485475dc1640f8405a5f Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Thu, 19 Oct 2017 21:41:26 +1100 Subject: [PATCH 02/18] Create a default commit hash for fake runs --- release.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/release.js b/release.js index 19ceccf..7b34dff 100644 --- a/release.js +++ b/release.js @@ -34,9 +34,10 @@ Promise.try(() => { localRepo = _localRepo console.log("Found repository:", localRepo); console.log("Creating release commit..."); - if (!isFakeRun) { - return gitCommit("Release new version", localRepo); + if (isFakeRun) { + return 'fake44ef0665e9e8e5fdf7c6bfcd61f95fe8b699'; } + return gitCommit("Release new version", localRepo); }).then((commitObjectId) => { const tagName = commitObjectId && commitObjectId.substring(0, 8) const tagReferenceCommit = commitObjectId From 7c1e220033a0eac4903b9693836f8e0489ce4d95 Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Thu, 19 Oct 2017 22:48:20 +1100 Subject: [PATCH 03/18] Create push tag function --- release.js | 22 +++++++-- src/git/{git-push.js => git-push-master.js} | 0 src/git/git-push-tag.js | 5 ++ test/git/git-push.spec.js | 55 ++++++++++++++------- 4 files changed, 60 insertions(+), 22 deletions(-) rename src/git/{git-push.js => git-push-master.js} (100%) create mode 100644 src/git/git-push-tag.js diff --git a/release.js b/release.js index 7b34dff..225d6a5 100644 --- a/release.js +++ b/release.js @@ -3,6 +3,8 @@ const Git = require("nodegit"); const bumpJSONFiles = require("./src/file/bump-json-files"); const gitCommit = require("./src/git/git-commit"); +const gitTag = require("./src/git/git-tag"); +const gitPushTag = require("./src/git/git-push-tag"); let targetBumpSpec; if (process.argv.includes("patch")) { @@ -30,14 +32,17 @@ Promise.try(() => { } }).then(() => { return Git.Repository.discover(".", 0, "."); +}).then((foundRepositoryPath) => { + console.log("Found repository on:", foundRepositoryPath); + return Git.Repository.open(foundRepositoryPath); }).then((_localRepo) => { localRepo = _localRepo - console.log("Found repository:", localRepo); +}).then(() => { console.log("Creating release commit..."); - if (isFakeRun) { - return 'fake44ef0665e9e8e5fdf7c6bfcd61f95fe8b699'; + if (!isFakeRun) { + return gitCommit("Release new version", localRepo); } - return gitCommit("Release new version", localRepo); + return 'fake44ef0665e9e8e5fdf7c6bfcd61f95fe8b699'; }).then((commitObjectId) => { const tagName = commitObjectId && commitObjectId.substring(0, 8) const tagReferenceCommit = commitObjectId @@ -45,7 +50,14 @@ Promise.try(() => { if (!isFakeRun) { return gitTag(tagName, tagReferenceCommit, localRepo); } + return /* FakeTag */ { tag_name: 'fake_tag_name' }; +}).then((tag) => { + return localRepo.getRemotes().then((localRemotes) => { + if (!isFakeRun) { + return gitPushTag(tag.name(), localRemotes[0], localRepo); + } + }); }); -// TODO Push the tag to the remote +// TODO eslint in this file // TODO Publish on NPM diff --git a/src/git/git-push.js b/src/git/git-push-master.js similarity index 100% rename from src/git/git-push.js rename to src/git/git-push-master.js diff --git a/src/git/git-push-tag.js b/src/git/git-push-tag.js new file mode 100644 index 0000000..fd80b50 --- /dev/null +++ b/src/git/git-push-tag.js @@ -0,0 +1,5 @@ +module.exports = function(tagName, remoteName, repository) { + return repository.getRemote(remoteName).then(function(remote) { + return remote.push([`refs/tags/${tagName}:refs/tags/${tagName}`]); + }); +}; diff --git a/test/git/git-push.spec.js b/test/git/git-push.spec.js index e462f40..c66e3ad 100644 --- a/test/git/git-push.spec.js +++ b/test/git/git-push.spec.js @@ -2,35 +2,36 @@ const root = require("app-root-path"); const expect = require("chai").expect; const startGitRepoWithServer = require(root + "/test/dummy-data/start-git-repo-with-server"); -const gitPush = require(root + "/src/git/git-push"); +const gitPushMaster = require(root + "/src/git/git-push-master"); +const gitPushTag = require(root + "/src/git/git-push-tag"); const gitCommit = require(root + "/src/git/git-commit"); +const gitTag = require(root + "/src/git/git-tag"); const cloneToLocalDir = require(root + "/test/dummy-data/clone-repo-to-local-dir"); -describe("git-push", function() { +describe("Given a dummy server with git enabled cloned to local dir", function() { let defaultTestRepository; let clonedTestRepository; - describe("Given a dummy server with git enabled cloned to local dir", function() { - - beforeEach(function() { - return startGitRepoWithServer().then(function(defaultTestRepositoryResult) { - defaultTestRepository = defaultTestRepositoryResult; - return cloneToLocalDir(defaultTestRepository.gitHttpUrl); - }).then(function(clonedTestRepositoryResult) { - clonedTestRepository = clonedTestRepositoryResult; - }); + beforeEach(function() { + return startGitRepoWithServer().then(function(defaultTestRepositoryResult) { + defaultTestRepository = defaultTestRepositoryResult; + return cloneToLocalDir(defaultTestRepository.gitHttpUrl); + }).then(function(clonedTestRepositoryResult) { + clonedTestRepository = clonedTestRepositoryResult; }); + }); - afterEach(function() { - defaultTestRepository.destroy(); - clonedTestRepository.remove(); - }); + afterEach(function() { + defaultTestRepository.destroy(); + clonedTestRepository.remove(); + }); + describe("Git Push Master To Remote", function() { it("should commit and push the repository sucessfully to the remote", function() { let dummyCommitId; return gitCommit("Dummy commit", clonedTestRepository.repository).then(function(oid) { dummyCommitId = oid; - return gitPush(defaultTestRepository.remotes[0].name, clonedTestRepository.repository); + return gitPushMaster(defaultTestRepository.remotes[0].name, clonedTestRepository.repository); }).then(function() { return defaultTestRepository.remotes[0].repository.getCommit(dummyCommitId); }).then(function(commit) { @@ -38,4 +39,24 @@ describe("git-push", function() { }); }); }); -}); \ No newline at end of file + + describe("Git Push Tag To Remote", function() { + it("should commit, create a tag and push successfully to the remote", function() { + return gitCommit("Dummy commit", clonedTestRepository.repository).then(function(dummyCommitId) { + return gitTag("dummy_tag_name", dummyCommitId, clonedTestRepository.repository); + }).then(function() { + return gitPushTag("dummy_tag_name", defaultTestRepository.remotes[0].name, clonedTestRepository.repository); + }).then(function deleteLocalTag() { + return require("nodegit").Tag.delete(clonedTestRepository.repository, "dummy_tag_name"); + }).then(function fetchRemoteTag() { + return clonedTestRepository.repository.getRemote(defaultTestRepository.remotes[0].name).then(function(remote) { + return remote.fetch(["refs/tags/dummy_tag_name"]); + }); + }).then(function() { + return clonedTestRepository.repository.getTagByName("dummy_tag_name").then(function(tag) { + expect(tag.name()).to.equal("dummy_tag_name"); + }); + }); + }); + }); +}); From ba92bb47c31e38024fdd8f17c3a8a3a9a4380568 Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Thu, 19 Oct 2017 22:50:37 +1100 Subject: [PATCH 04/18] Run eslint on release.js file --- package.json | 2 +- release.js | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 1285375..b972777 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "author": "Fagner Brack", "license": "MIT", "scripts": { - "test": "eslint \"src/**/*.js\" \"test/**/*.js\" && mocha --trace-warnings", + "test": "eslint *.js \"src/**/*.js\" \"test/**/*.js\" && mocha --trace-warnings", "test:watch": "eslint \"src/**/*.js\" \"test/**/*.js\" && mocha -w", "release:test": "node release.js fake patch", "release": "node release.js fake patch" diff --git a/release.js b/release.js index 225d6a5..dde1921 100644 --- a/release.js +++ b/release.js @@ -17,7 +17,7 @@ if (process.argv.includes("major")) { targetBumpSpec = "major"; } if (!targetBumpSpec) { - console.log("Invalid bump spec, use 'patch', 'minor' or 'major'"); + console.log("Invalid bump spec, use \"patch\", \"minor\" or \"major\""); return; } @@ -36,21 +36,21 @@ Promise.try(() => { console.log("Found repository on:", foundRepositoryPath); return Git.Repository.open(foundRepositoryPath); }).then((_localRepo) => { - localRepo = _localRepo + localRepo = _localRepo; }).then(() => { console.log("Creating release commit..."); if (!isFakeRun) { return gitCommit("Release new version", localRepo); } - return 'fake44ef0665e9e8e5fdf7c6bfcd61f95fe8b699'; + return "fake44ef0665e9e8e5fdf7c6bfcd61f95fe8b699"; }).then((commitObjectId) => { - const tagName = commitObjectId && commitObjectId.substring(0, 8) - const tagReferenceCommit = commitObjectId + const tagName = commitObjectId && commitObjectId.substring(0, 8); + const tagReferenceCommit = commitObjectId; console.log("Creating tag:", tagName); if (!isFakeRun) { return gitTag(tagName, tagReferenceCommit, localRepo); } - return /* FakeTag */ { tag_name: 'fake_tag_name' }; + return /* FakeTag */ { tag_name: "fake_tag_name" }; }).then((tag) => { return localRepo.getRemotes().then((localRemotes) => { if (!isFakeRun) { @@ -59,5 +59,4 @@ Promise.try(() => { }); }); -// TODO eslint in this file // TODO Publish on NPM From c0d6a0f5d5f659b826b91753a56a97883ffb02e9 Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Thu, 19 Oct 2017 22:55:16 +1100 Subject: [PATCH 05/18] Create const ffor git push tag spec to avoid typos and false positive testing --- test/git/git-push.spec.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/test/git/git-push.spec.js b/test/git/git-push.spec.js index c66e3ad..cfb8ece 100644 --- a/test/git/git-push.spec.js +++ b/test/git/git-push.spec.js @@ -42,19 +42,20 @@ describe("Given a dummy server with git enabled cloned to local dir", function() describe("Git Push Tag To Remote", function() { it("should commit, create a tag and push successfully to the remote", function() { + const DUMMY_TAG_NAME = "dummy_tag_name"; return gitCommit("Dummy commit", clonedTestRepository.repository).then(function(dummyCommitId) { - return gitTag("dummy_tag_name", dummyCommitId, clonedTestRepository.repository); + return gitTag(DUMMY_TAG_NAME, dummyCommitId, clonedTestRepository.repository); }).then(function() { - return gitPushTag("dummy_tag_name", defaultTestRepository.remotes[0].name, clonedTestRepository.repository); + return gitPushTag(DUMMY_TAG_NAME, defaultTestRepository.remotes[0].name, clonedTestRepository.repository); }).then(function deleteLocalTag() { - return require("nodegit").Tag.delete(clonedTestRepository.repository, "dummy_tag_name"); + return require("nodegit").Tag.delete(clonedTestRepository.repository, DUMMY_TAG_NAME); }).then(function fetchRemoteTag() { return clonedTestRepository.repository.getRemote(defaultTestRepository.remotes[0].name).then(function(remote) { - return remote.fetch(["refs/tags/dummy_tag_name"]); + return remote.fetch([`refs/tags/${DUMMY_TAG_NAME}`]); }); }).then(function() { - return clonedTestRepository.repository.getTagByName("dummy_tag_name").then(function(tag) { - expect(tag.name()).to.equal("dummy_tag_name"); + return clonedTestRepository.repository.getTagByName(DUMMY_TAG_NAME).then(function(tag) { + expect(tag.name()).to.equal(DUMMY_TAG_NAME); }); }); }); From e3687e6226a0e0cddaae7ac697b57d8322cf0239 Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Thu, 19 Oct 2017 22:56:14 +1100 Subject: [PATCH 06/18] Rename 'operations' to 'functions' in the API Docs (README) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5827aed..f57adc5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## Operations +## Functions #### `Promise bumpJSONFiles(String bumpSpec, Array filePaths)` From cec978699e2e7f83187d32c1a4293e0f3f0624de Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Thu, 19 Oct 2017 22:57:11 +1100 Subject: [PATCH 07/18] Let's manually publish on npm for now --- README.md | 1 + release.js | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index f57adc5..c085add 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,4 @@ Returns a `Promise` that will resolve once the commit has been created. ## Release Steps * Run `npm run release `, where `bumpSpec` is either `patch`, `minor` or `major` +* Run `npm publish ./` diff --git a/release.js b/release.js index dde1921..2e81e43 100644 --- a/release.js +++ b/release.js @@ -58,5 +58,3 @@ Promise.try(() => { } }); }); - -// TODO Publish on NPM From e49944ce960fed437e370e73efc284b1426edb56 Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Thu, 19 Oct 2017 22:59:53 +1100 Subject: [PATCH 08/18] Add project description in the README --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index c085add..ae4d176 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +# JS Cookie Release API + +Release routines for JavaScript Cookie library + ## Functions #### `Promise bumpJSONFiles(String bumpSpec, Array filePaths)` From 0d73d12254bb36093108775a762f75686c152f74 Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Thu, 19 Oct 2017 23:04:34 +1100 Subject: [PATCH 09/18] Release new version From 82631cd372fb0727987fd0d2e5bc1bff6c57d572 Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Thu, 19 Oct 2017 23:06:30 +1100 Subject: [PATCH 10/18] Prepare release commands to do the real thing --- package.json | 2 +- release.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b972777..81b1fb4 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "test": "eslint *.js \"src/**/*.js\" \"test/**/*.js\" && mocha --trace-warnings", "test:watch": "eslint \"src/**/*.js\" \"test/**/*.js\" && mocha -w", "release:test": "node release.js fake patch", - "release": "node release.js fake patch" + "release": "node release.js patch" }, "devDependencies": { "chai": "4.1.2", diff --git a/release.js b/release.js index 2e81e43..485c25f 100644 --- a/release.js +++ b/release.js @@ -50,8 +50,9 @@ Promise.try(() => { if (!isFakeRun) { return gitTag(tagName, tagReferenceCommit, localRepo); } - return /* FakeTag */ { tag_name: "fake_tag_name" }; + return /* FakeTag */ { name: () => "fake_tag_name" }; }).then((tag) => { + console.log("Created tag '" + tag.name() + "'"); return localRepo.getRemotes().then((localRemotes) => { if (!isFakeRun) { return gitPushTag(tag.name(), localRemotes[0], localRepo); From 3b3c3abc2750581e9cb3baa0ff6d3eaa5fdc6513 Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Sat, 21 Oct 2017 17:15:03 +1100 Subject: [PATCH 11/18] Release new version From 30d8f59b06e2ab1f5c4e7bd4731e292fc68a84ff Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Sat, 21 Oct 2017 20:05:06 +1100 Subject: [PATCH 12/18] Add TODOs --- release.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/release.js b/release.js index 485c25f..d8b41e1 100644 --- a/release.js +++ b/release.js @@ -59,3 +59,6 @@ Promise.try(() => { } }); }); + +// TODO Allow the input of password? +// TODO Keep identation for package.json From be3fbab880fb9e21d0b8ba00487911b8560266f2 Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Sat, 21 Oct 2017 21:48:58 +1100 Subject: [PATCH 13/18] Release new version From ca54934d012e1abf270eb52ecc1f0342b64c1256 Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Sun, 22 Oct 2017 00:55:20 +1100 Subject: [PATCH 14/18] Rewrite package json bumper --- .eslintrc.json | 2 +- package.json | 6 ++-- release.js | 4 +-- src/file/bump-json-files.js | 18 ------------ src/file/bump-package-json.js | 11 +++++++ test/file/bump-json-files.spec.js | 49 +++++++++++++++---------------- 6 files changed, 41 insertions(+), 49 deletions(-) delete mode 100644 src/file/bump-json-files.js create mode 100644 src/file/bump-package-json.js diff --git a/.eslintrc.json b/.eslintrc.json index a14b4ed..36c42e7 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -5,7 +5,7 @@ }, "extends": "eslint:recommended", "parserOptions": { - "ecmaVersion": 6, + "ecmaVersion": 2017, "ecmaFeatures": { "impliedStrict": true } diff --git a/package.json b/package.json index 81b1fb4..5525080 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,9 @@ "author": "Fagner Brack", "license": "MIT", "scripts": { - "test": "eslint *.js \"src/**/*.js\" \"test/**/*.js\" && mocha --trace-warnings", - "test:watch": "eslint \"src/**/*.js\" \"test/**/*.js\" && mocha -w", + "lint": "eslint *.js \"src/**/*.js\" \"test/**/*.js\"", + "test": "mocha --trace-warnings", + "test:watch": "mocha -w", "release:test": "node release.js fake patch", "release": "node release.js patch" }, @@ -27,7 +28,6 @@ "dependencies": { "app-root-path": "2.0.1", "bluebird": "3.5.1", - "json-update": "3.0.0", "nodegit": "0.20.2" }, "engines": { diff --git a/release.js b/release.js index d8b41e1..64d0443 100644 --- a/release.js +++ b/release.js @@ -1,7 +1,7 @@ const Promise = require("bluebird"); const Git = require("nodegit"); -const bumpJSONFiles = require("./src/file/bump-json-files"); +const bumpPackageJSON = require("./src/file/bump-package-json"); const gitCommit = require("./src/git/git-commit"); const gitTag = require("./src/git/git-tag"); const gitPushTag = require("./src/git/git-push-tag"); @@ -28,7 +28,7 @@ let localRepo; Promise.try(() => { console.log("Bumping package.json..."); if (!isFakeRun) { - return bumpJSONFiles(targetBumpSpec, ["package.json"]); + return bumpPackageJSON(targetBumpSpec, "package.json"); } }).then(() => { return Git.Repository.discover(".", 0, "."); diff --git a/src/file/bump-json-files.js b/src/file/bump-json-files.js deleted file mode 100644 index bf53beb..0000000 --- a/src/file/bump-json-files.js +++ /dev/null @@ -1,18 +0,0 @@ -const root = require("app-root-path"); -const Promise = require("bluebird"); -const updateJSON = Promise.promisify(require("json-update").update); -const loadJSON = Promise.promisify(require("json-update").load); - -const bumpVersion = require(root + "/src/bump-version"); - -module.exports = function(bumpSpec, fileNames) { - const promisesToBumpFiles = fileNames.map(function(fileName) { - return loadJSON(fileName) - .then(function(fileContent) { - return updateJSON(fileName, { - version: bumpVersion(fileContent.version, bumpSpec) - }); - }); - }); - return Promise.join(promisesToBumpFiles); -}; diff --git a/src/file/bump-package-json.js b/src/file/bump-package-json.js new file mode 100644 index 0000000..c6da565 --- /dev/null +++ b/src/file/bump-package-json.js @@ -0,0 +1,11 @@ +const root = require("app-root-path"); +const writeFile = require("util").promisify(require("fs").writeFile); +const readFile = require("util").promisify(require("fs").readFile); + +const bumpVersion = require(root + "/src/bump-version"); + +module.exports = async (bumpSpec, filePath) => { + const fileContentAsJSON = JSON.parse(await readFile(filePath, "UTF-8")); + fileContentAsJSON.version = bumpVersion(fileContentAsJSON.version, bumpSpec); + await writeFile(filePath, JSON.stringify(fileContentAsJSON)); +}; diff --git a/test/file/bump-json-files.spec.js b/test/file/bump-json-files.spec.js index 15b6fc5..ee132c9 100644 --- a/test/file/bump-json-files.spec.js +++ b/test/file/bump-json-files.spec.js @@ -1,33 +1,32 @@ -const root = require("app-root-path"); const expect = require("chai").expect; -const Promise = require("bluebird"); -const loadJSON = Promise.promisify(require("json-update").load); +const readFile = require("util").promisify(require("fs").readFile); +const writeFile = require("util").promisify(require("fs").writeFile); +const unlink = require("util").promisify(require("fs").unlink); -const bumpJSONFiles = require(root + "/src/file/bump-json-files"); -const createFileSync = require(root + "/test/dummy-data/create-file-sync"); +const bumpPackageJSON = require(require("app-root-path") + "/src/file/bump-package-json"); -describe("bump-json-files", function() { +describe("Bump Package JSON", () => { - describe("Given a dummy file in JSON format", function() { - const targetFilename = "bump-minor.json"; - let removeDummyJSONFileSync; + it("bumps the patch version in the package.json", async () => { + await writeFile("target-package.json", "{\"version\":\"0.0.0\"}"); + await bumpPackageJSON("patch", "target-package.json"); + const targetFileContent = await readFile("target-package.json", "UTF-8"); + expect(targetFileContent).to.equal("{\"version\":\"0.0.1\"}"); + await unlink("target-package.json"); - beforeEach(function() { - removeDummyJSONFileSync = createFileSync(targetFilename, JSON.stringify({ - version: "0.0.0" - })); - }); - - afterEach(function() { - removeDummyJSONFileSync(); - }); + await writeFile("another-target-package.json", "{\"version\":\"0.0.0\"}"); + await bumpPackageJSON("patch", "another-target-package.json"); + const anotherTargetFileContent = await readFile("another-target-package.json", "UTF-8"); + expect(anotherTargetFileContent).to.equal("{\"version\":\"0.0.1\"}"); + await unlink("another-target-package.json"); + }); - it("should bump the 'minor' version attribute", function() { - return bumpJSONFiles("minor", [targetFilename]).then(function() { - return loadJSON(targetFilename); - }).then(function(targetFile) { - expect(targetFile).to.have.property("version", "0.1.0"); - }); - }); + it("keeps existing properties intact", async () => { + await writeFile("target-package.json", "{\"existing\":1,\"version\":\"0.0.0\"}"); + await bumpPackageJSON("patch", "target-package.json"); + const bumpedFile = await readFile("target-package.json", "UTF-8"); + expect(bumpedFile).to.equal("{\"existing\":1,\"version\":\"0.0.1\"}"); + await unlink("target-package.json"); }); + }); From 76db9d29033fb7f0a60c271e4623f695113932bf Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Tue, 24 Oct 2017 23:05:21 +1100 Subject: [PATCH 15/18] keep package.json identation after bump --- release.js | 1 - src/file/bump-package-json.js | 18 +++++++++++++++--- test/file/bump-json-files.spec.js | 16 ++++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/release.js b/release.js index 64d0443..38596bc 100644 --- a/release.js +++ b/release.js @@ -61,4 +61,3 @@ Promise.try(() => { }); // TODO Allow the input of password? -// TODO Keep identation for package.json diff --git a/src/file/bump-package-json.js b/src/file/bump-package-json.js index c6da565..5088b39 100644 --- a/src/file/bump-package-json.js +++ b/src/file/bump-package-json.js @@ -5,7 +5,19 @@ const readFile = require("util").promisify(require("fs").readFile); const bumpVersion = require(root + "/src/bump-version"); module.exports = async (bumpSpec, filePath) => { - const fileContentAsJSON = JSON.parse(await readFile(filePath, "UTF-8")); - fileContentAsJSON.version = bumpVersion(fileContentAsJSON.version, bumpSpec); - await writeFile(filePath, JSON.stringify(fileContentAsJSON)); + const VERSION_KEY_VALUE_REGEX = /"version":( +)?"(.+)"/; + const fileContent = await readFile(filePath, "UTF-8"); + const matchedVersion = fileContent.match(VERSION_KEY_VALUE_REGEX); + if (matchedVersion === null) { + throw new Error( + "Could not find 'version' property in package.json to bump" + ); + } + const version = matchedVersion[2]; + const bumpedVersion = bumpVersion(version, bumpSpec); + const replacedFileContent = fileContent.replace( + VERSION_KEY_VALUE_REGEX, + `"version":$1"${bumpedVersion}"` + ); + await writeFile(filePath, replacedFileContent); }; diff --git a/test/file/bump-json-files.spec.js b/test/file/bump-json-files.spec.js index ee132c9..5adff0e 100644 --- a/test/file/bump-json-files.spec.js +++ b/test/file/bump-json-files.spec.js @@ -29,4 +29,20 @@ describe("Bump Package JSON", () => { await unlink("target-package.json"); }); + it("keeps existing spacing intact", async () => { + await writeFile("target-package.json", "{ \"version\": \"0.0.0\" }"); + await bumpPackageJSON("patch", "target-package.json"); + const bumpedFile = await readFile("target-package.json", "UTF-8"); + expect(bumpedFile).to.equal("{ \"version\": \"0.0.1\" }"); + await unlink("target-package.json"); + }); + + it("keep existing multiple spacing intact", async () => { + await writeFile("target-package.json", "{ \"version\": \"0.0.0\" }"); + await bumpPackageJSON("patch", "target-package.json"); + const bumpedFile = await readFile("target-package.json", "UTF-8"); + expect(bumpedFile).to.equal("{ \"version\": \"0.0.1\" }"); + await unlink("target-package.json"); + }); + }); From 057f9b56dd172dc3c7017cd4663e78f4cdceb3ac Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Tue, 24 Oct 2017 23:07:38 +1100 Subject: [PATCH 16/18] Release new version From 6adeab2c41a3c0c1a1c38e8e83ef216b26e77f61 Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Tue, 24 Oct 2017 23:17:27 +1100 Subject: [PATCH 17/18] Review README docs --- README.md | 8 +++----- package.json | 2 +- release.js | 1 + 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ae4d176..402bb1a 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,13 @@ Release routines for JavaScript Cookie library ## Functions -#### `Promise bumpJSONFiles(String bumpSpec, Array filePaths)` +#### `Promise bumpPackageJSON(String bumpSpec, String filePath)` -Bumps the "version" property from a list of file paths that matches the [JSON](http://json.org/) spec. -Returns a `Promise` that will resolve once all files have been bumped. +Bumps the "version" property from a list of file paths that matches the [JSON](http://json.org/) spec. #### `Promise gitCommit(String message, NodeGitRepository gitRepository)` -Adds all the changes to the staging area and create a commit to the given repository. -Returns a `Promise` that will resolve once the commit has been created. +Add all the changes to the staging area and create a commit to the given repository. ## Release Steps diff --git a/package.json b/package.json index 5525080..681b060 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "test": "mocha --trace-warnings", "test:watch": "mocha -w", "release:test": "node release.js fake patch", - "release": "node release.js patch" + "release": "node release.js" }, "devDependencies": { "chai": "4.1.2", diff --git a/release.js b/release.js index 38596bc..6e6f4f8 100644 --- a/release.js +++ b/release.js @@ -60,4 +60,5 @@ Promise.try(() => { }); }); +// TODO Don't leak NodeGitRepository to gitCommit // TODO Allow the input of password? From 53048c2c99b1b74834e5ff4a013f3bdd753d6c3f Mon Sep 17 00:00:00 2001 From: Fagner Brack Date: Tue, 24 Oct 2017 23:17:43 +1100 Subject: [PATCH 18/18] Release new version