From c544d8a100c50e0713512e331f204f4d4e708d50 Mon Sep 17 00:00:00 2001 From: Cliffano Subagio Date: Sat, 18 May 2024 15:21:49 +1000 Subject: [PATCH] Add HCL placeholder. Need a library that can support dot notation. --- lib/resource-types/hcl.js | 59 +++++++++++++++++++++ lib/rtk.js | 2 + package.json | 2 + test/resource-types/hcl.js | 106 +++++++++++++++++++++++++++++++++++++ 4 files changed, 169 insertions(+) create mode 100644 lib/resource-types/hcl.js create mode 100644 test/resource-types/hcl.js diff --git a/lib/resource-types/hcl.js b/lib/resource-types/hcl.js new file mode 100644 index 00000000..6a0a4715 --- /dev/null +++ b/lib/resource-types/hcl.js @@ -0,0 +1,59 @@ +"use strict" +import {getProperty, setProperty} from 'dot-prop'; +import fs from 'fs'; +import hcl2 from 'hcl2-json-parser'; +import hcl from 'js-hcl-parser'; + +/** + * Set version value in the HCL resource's property (defined in dot-notation). + * + * @param {String} version: version value to set + * @param {Object} resource: resource configuration which contains type, path, and params + * @param {Object} opts: optional settings + * - dryRun: when true, HCL file won't be modified + * @param {Function} cb: standard cb(err, result) callback + */ +function setVersion(version, resource, opts, cb) { + const property = resource.params.property; + let data = hcl.parse(fs.readFileSync(resource.path, 'UTF-8')); + console.dir("OBJECTIFY"); + console.dir(data); + setProperty(data, property, version); + if (!opts.dryRun) { + console.dir("STRINGIFY") + console.dir(hcl.stringify(data)) + fs.writeFile(resource.path, hcl.stringify(data), cb); + } else { + cb(); + } +} + +/** + * Get version value from the HCL resource's property (defined in dot-notation). + * + * @param {Object} resource: resource configuration which contains type, path, and params + * @param {Function} cb: standard cb(err, result) callback + */ +function getVersion(resource, cb) { + const property = resource.params.property; + + function readCb(err, result) { + let version; + if (!err) { + const data = hcl2.parseToObject(result); + version = getProperty(data, property); + } + cb(err, version); + } + fs.readFile(resource.path, 'UTF-8', readCb); +} + +const exports = { + setReleaseVersion: setVersion, + setPostReleaseVersion: setVersion, + getVersion: getVersion +}; + +export { + exports as default +}; diff --git a/lib/rtk.js b/lib/rtk.js index 70ed85b9..f2a6ca35 100644 --- a/lib/rtk.js +++ b/lib/rtk.js @@ -1,6 +1,7 @@ "use strict" import async from 'async'; import rtkReleaseScheme from './release-schemes/rtk.js'; +import hclResourceType from './resource-types/hcl.js'; import jsonResourceType from './resource-types/json.js'; import keepAChangelogResourceType from './resource-types/keep-a-changelog.js'; import makefileResourceType from './resource-types/makefile.js'; @@ -27,6 +28,7 @@ class RTK { rtk: rtkReleaseScheme }; this.resourceTypes = { + hcl: hclResourceType, json: jsonResourceType, makefile: makefileResourceType, text: textResourceType, diff --git a/package.json b/package.json index 8fdcb581..d1beb594 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,8 @@ "bagofcli": "^2.4.1", "chalk": "^5.3.0", "dot-prop": "^8.0.2", + "hcl2-json-parser": "^1.0.1", + "js-hcl-parser": "^1.0.1", "js-yaml": "^4.1.0", "keep-a-changelog": "^0.10.4", "lodash": "^4.17.21", diff --git a/test/resource-types/hcl.js b/test/resource-types/hcl.js new file mode 100644 index 00000000..1180e367 --- /dev/null +++ b/test/resource-types/hcl.js @@ -0,0 +1,106 @@ +"use strict" +/* eslint no-unused-vars: 0 */ +import assert from 'assert'; +import fs from 'fs'; +import resourceType from '../../lib/resource-types/hcl.js'; +import sinon from 'sinon'; + +describe('hcl', function() { + + beforeEach(function (done) { + this.mockFs = sinon.mock(fs); + done(); + }); + afterEach(function (done) { + this.mockFs.verify(); + sinon.restore(); + done(); + }); + + describe('setVersion', function() { + it('should only set version but not modify hcl file when dry run is enabled', function(done) { + let resource = { + path: 'variables.tf', + type: 'hcl', + params: { + property: 'version' + } + }; + this.mockFs.expects('readFileSync').once().withExactArgs('variables.tf', 'UTF-8').returns('variable "tags" { default = { version = "0.0.0" }}'); + this.mockFs.expects('writeFile').never(); + function cb(err, result) { + assert.equal(err, null); + done(); + } + resourceType.setReleaseVersion('1.2.3', resource, { dryRun: true }, cb); + }); + it('should set version and modify hcl file when dry run is disabled', function(done) { + let resource = { + path: 'variables.tf', + type: 'hcl', + params: { + property: 'variable.tags.default.version' + } + }; + this.mockFs.expects('readFileSync').once().withExactArgs('variables.tf', 'UTF-8').returns('variable "tags" { default = { version = "0.0.0" }}'); + this.mockFs.expects('writeFile').once().withExactArgs('variables.tf', 'variable "tags" { default = { version = "1.2.3" }}\n', sinon.match.func).callsArgWith(2, null); + function cb(err, result) { + assert.equal(err, null); + done(); + } + resourceType.setReleaseVersion('1.2.3', resource, { dryRun: false }, cb); + }); + // it('should set array property under a section', function(done) { + // let resource = { + // path: 'variables.tf', + // type: 'hcl', + // params: { + // property: 'package.versions[1]' + // } + // }; + // this.mockFs.expects('readFileSync').once().withExactArgs('variables.tf', 'UTF-8').returns('[package]\nversions = ["9.9.9", "0.0.0", "8.8.8"]'); + // this.mockFs.expects('writeFile').once().withExactArgs('variables.tf', '[package]\nversions = [ "9.9.9", "1.2.3", "8.8.8" ]\n', sinon.match.func).callsArgWith(2, null); + // function cb(err, result) { + // assert.equal(err, null); + // done(); + // } + // resourceType.setReleaseVersion('1.2.3', resource, { dryRun: false }, cb); + // }); + }); + + // describe('getVersion', function() { + // it('should get version from resource property', function(done) { + // let resource = { + // path: 'variables.tf', + // type: 'hcl', + // params: { + // property: 'version' + // } + // }; + // this.mockFs.expects('readFile').once().withExactArgs('variables.tf', 'UTF-8', sinon.match.func).callsArgWith(2, null, 'version = "0.0.0"'); + // function cb(err, result) { + // assert.equal(err, null); + // assert.equal(result, '0.0.0'); + // done(); + // } + // resourceType.getVersion(resource, cb); + // }); + // it('should get array property under a section', function(done) { + // let resource = { + // path: 'variables.tf', + // type: 'hcl', + // params: { + // property: 'package.versions[1]' + // } + // }; + // this.mockFs.expects('readFile').once().withExactArgs('variables.tf', 'UTF-8', sinon.match.func).callsArgWith(2, null, '[package]\nversions = ["9.9.9", "0.0.0", "8.8.8"]'); + // function cb(err, result) { + // assert.equal(err, null); + // assert.equal(result, '0.0.0'); + // done(); + // } + // resourceType.getVersion(resource, cb); + // }); + // }); + +});