From 6466bebf849bbdcdaebf493a1ccce9670c469fde Mon Sep 17 00:00:00 2001 From: Taylor Hoffmann Date: Mon, 15 Jan 2024 19:34:58 -0300 Subject: [PATCH] feat(updater): add maven pom.xml file support (#33, #109) (#123) * feat: added maven support * fix: correct updater for pom.xml files --- README.md | 17 +- lib/updaters/index.js | 4 + lib/updaters/types/maven.js | 44 ++++ package-lock.json | 429 +++++++++++++++++++++++++++++++++- package.json | 2 + test/core.spec.js | 76 +++++- test/mocks/pom-6.3.1-crlf.xml | 30 +++ test/mocks/pom-6.3.1-lf.xml | 30 +++ test/mocks/pom-6.4.0-crlf.xml | 30 +++ test/mocks/pom-6.4.0-lf.xml | 30 +++ 10 files changed, 681 insertions(+), 11 deletions(-) create mode 100644 lib/updaters/types/maven.js create mode 100644 test/mocks/pom-6.3.1-crlf.xml create mode 100644 test/mocks/pom-6.3.1-lf.xml create mode 100644 test/mocks/pom-6.4.0-crlf.xml create mode 100644 test/mocks/pom-6.4.0-lf.xml diff --git a/README.md b/README.md index a5d58b8ae..233001c77 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,6 @@ > **`Why was it renamed commit-and-tag-version?`**. I didn't want to scope the package or name it `standard-version-fork`, and it was a good opportunity to make the purpose of the tool clearer. I also wanted to distinguish it from the other tool in this organisation, [`absolute-version`](https://github.com/absolute-version/absolute-version-js), which just prints version information for pre-releases. - A utility for versioning using [semver](https://semver.org/) and CHANGELOG generation powered by [Conventional Commits](https://conventionalcommits.org). ![ci](https://github.com/absolute-version/commit-and-tag-version/workflows/ci/badge.svg) @@ -20,6 +19,7 @@ _Having problems? Want to contribute? Join us on the [node-tooling community Sla - [Commit and Tag Version](#commit-and-tag-version) - [How It Works:](#how-it-works) - [`bumpFiles`, `packageFiles` and `updaters`](#bumpfiles-packagefiles-and-updaters) + - [Maven Support (Java/Kotlin)](#maven-support-javakotlin) - [Gradle Support (Java/Kotlin)](#gradle-support-javakotlin) - [.NET Support](#net-support) - [Installing `commit-and-tag-version`](#installing-commit-and-tag-version) @@ -55,7 +55,7 @@ _Having problems? Want to contribute? Join us on the [node-tooling community Sla - [License](#license) -### How It Works: +### How It Works 1. Follow the [Conventional Commits Specification](https://conventionalcommits.org) in your repository. 2. When you're ready to release, run `commit-and-tag-version`. @@ -83,6 +83,14 @@ By default, `commit-and-tag-version` assumes you're working in a NodeJS based pr That said, if you find your self asking [How can I use commit-and-tag-version for additional metadata files, languages or version files?](#can-i-use-commit-and-tag-version-for-additional-metadata-files-languages-or-version-files) – these configuration options will help! +### Maven Support (Java/Kotlin) + +If you are using Maven, then just point to your `pom.xml` file. + +```sh +commit-and-tag-version --packageFiles pom.xml --bumpFiles pom.xml +``` + ### Gradle Support (Java/Kotlin) If you are using Gradle, then just point to your `build.gradle` file (or `build.gradle.kts` if using Kotlin DSL). @@ -95,6 +103,7 @@ commit-and-tag-version --packageFiles build.gradle --bumpFiles build.gradle If you are using .NET with `.csproj` files. This is going to read and update only the `` tag in the file. + ```sh commit-and-tag-version --packageFiles .csproj --bumpFiles .csproj ``` @@ -148,7 +157,7 @@ You can configure `commit-and-tag-version` either by: 1. Placing a `commit-and-tag-version` stanza in your `package.json` (assuming your project is JavaScript). - > Note for users who have migrated to + > Note for users who have migrated to `commit-and-tag-version` from `standard-version`: the previous package.json configuration key of `standard-version` will still work. 2. Creating a `.versionrc`, `.versionrc.json` or `.versionrc.js`. @@ -312,7 +321,7 @@ Simply add the following to your package.json to configure lifecycle scripts: ``` As an example to change from using GitHub to track your items to using your projects Jira use a -`postchangelog` script to replace the url fragment containing 'https://github.com/`myproject`/issues/' +`postchangelog` script to replace the url fragment containing '' with a link to your Jira - assuming you have already installed [replace](https://www.npmjs.com/package/replace) ```json diff --git a/lib/updaters/index.js b/lib/updaters/index.js index 44c711ff6..3698045dc 100644 --- a/lib/updaters/index.js +++ b/lib/updaters/index.js @@ -3,6 +3,7 @@ const JSON_BUMP_FILES = require('../../defaults').bumpFiles; const updatersByType = { json: require('./types/json'), 'plain-text': require('./types/plain-text'), + maven: require('./types/maven'), gradle: require('./types/gradle'), csproj: require('./types/csproj'), }; @@ -23,6 +24,9 @@ function getUpdaterByFilename(filename) { if (PLAIN_TEXT_BUMP_FILES.includes(filename)) { return getUpdaterByType('plain-text'); } + if (/pom.xml/.test(filename)) { + return getUpdaterByType('maven'); + } if (/build.gradle/.test(filename)) { return getUpdaterByType('gradle'); } diff --git a/lib/updaters/types/maven.js b/lib/updaters/types/maven.js new file mode 100644 index 000000000..37d81c5be --- /dev/null +++ b/lib/updaters/types/maven.js @@ -0,0 +1,44 @@ +const jsdom = require('jsdom'); +const serialize = require('w3c-xmlserializer'); +const detectNewline = require('detect-newline'); +const CRLF = '\r\n'; +const LF = '\n'; + +function pomDocument(contents) { + const dom = new jsdom.JSDOM(''); + const parser = new dom.window.DOMParser(); + return parser.parseFromString(contents, 'application/xml'); +} + +function pomVersionElement(document) { + const versionElement = document.querySelector('project > version'); + + if (!versionElement) { + throw new Error( + 'Failed to read the version field in your pom file - is it present?', + ); + } + + return versionElement; +} + +module.exports.readVersion = function (contents) { + const document = pomDocument(contents); + return pomVersionElement(document).textContent; +}; + +module.exports.writeVersion = function (contents, version) { + const newline = detectNewline(contents); + const document = pomDocument(contents); + const versionElement = pomVersionElement(document); + + versionElement.textContent = version; + + const xml = serialize(document); + + if (newline === CRLF) { + return xml.replace(/\n/g, CRLF) + CRLF; + } + + return xml + LF; +}; diff --git a/package-lock.json b/package-lock.json index 3eeb6c0da..bdfddb86e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,7 +20,9 @@ "figures": "^3.1.0", "find-up": "^5.0.0", "git-semver-tags": "^5.0.0", + "jsdom": "^23.2.0", "semver": "^7.5.4", + "w3c-xmlserializer": "^5.0.0", "yargs": "^17.7.2" }, "bin": { @@ -63,6 +65,16 @@ "node": ">=6.0.0" } }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-2.0.2.tgz", + "integrity": "sha512-x1KXOatwofR6ZAYzXRBL5wrdV0vwNxlTCK9NCuLqAzQYARqGcvFwiJA6A1ERuh+dgeA4Dxm3JBYictIes+SqUQ==", + "dependencies": { + "bidi-js": "^1.0.3", + "css-tree": "^2.3.1", + "is-potential-custom-element-name": "^1.0.1" + } + }, "node_modules/@babel/code-frame": { "version": "7.22.13", "license": "MIT", @@ -1695,6 +1707,17 @@ "version": "1.0.0", "license": "MIT" }, + "node_modules/agent-base": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", + "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", + "dependencies": { + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/ajv": { "version": "6.12.6", "dev": true, @@ -1893,6 +1916,11 @@ "node": ">=0.10.0" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "dev": true, @@ -2081,6 +2109,14 @@ "version": "1.0.2", "license": "MIT" }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "license": "MIT", @@ -2279,6 +2315,17 @@ "version": "1.1.3", "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/compare-func": { "version": "2.0.0", "license": "MIT", @@ -2717,6 +2764,29 @@ "node": ">= 8" } }, + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssstyle": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", + "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", + "dependencies": { + "rrweb-cssom": "^0.6.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/dargs": { "version": "7.0.0", "license": "MIT", @@ -2724,6 +2794,18 @@ "node": ">=8" } }, + "node_modules/data-urls": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/dateformat": { "version": "3.0.3", "license": "MIT", @@ -2733,7 +2815,6 @@ }, "node_modules/debug": { "version": "4.3.4", - "dev": true, "license": "MIT", "dependencies": { "ms": "2.1.2" @@ -2772,6 +2853,11 @@ "node": ">=0.10.0" } }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==" + }, "node_modules/dedent": { "version": "1.5.1", "dev": true, @@ -2827,6 +2913,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-indent": { "version": "6.1.0", "license": "MIT", @@ -2971,6 +3065,17 @@ "version": "8.0.0", "license": "MIT" }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/error-ex": { "version": "1.3.2", "license": "MIT", @@ -3735,6 +3840,19 @@ "is-callable": "^1.1.3" } }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "dev": true, @@ -4168,11 +4286,46 @@ "node": ">=10" } }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "dev": true, "license": "MIT" }, + "node_modules/http-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", + "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", + "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", + "dependencies": { + "agent-base": "^7.0.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/human-signals": { "version": "2.1.0", "dev": true, @@ -4181,6 +4334,17 @@ "node": ">=10.17.0" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.2.0", "dev": true, @@ -4442,6 +4606,11 @@ "node": ">=0.10.0" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==" + }, "node_modules/is-regex": { "version": "1.1.4", "dev": true, @@ -6089,6 +6258,45 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdom": { + "version": "23.2.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-23.2.0.tgz", + "integrity": "sha512-L88oL7D/8ufIES+Zjz7v0aes+oBMh2Xnh3ygWvL0OaICOomKEPKuPnIfBJekiXr+BHbbMjrWn/xqrDQuxFTeyA==", + "dependencies": { + "@asamuzakjp/dom-selector": "^2.0.1", + "cssstyle": "^4.0.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.6.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.3", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.16.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "canvas": "^2.11.2" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, "node_modules/jsesc": { "version": "2.5.2", "dev": true, @@ -6296,6 +6504,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, "node_modules/meow": { "version": "8.1.2", "license": "MIT", @@ -6477,6 +6690,25 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mimic-fn": { "version": "2.1.0", "dev": true, @@ -6527,7 +6759,6 @@ }, "node_modules/ms": { "version": "2.1.2", - "dev": true, "license": "MIT" }, "node_modules/natural-compare": { @@ -6750,6 +6981,17 @@ "node": ">=4" } }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "license": "MIT", @@ -6946,9 +7188,13 @@ "node": ">= 6" } }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, "node_modules/punycode": { "version": "2.3.1", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -6977,6 +7223,11 @@ "teleport": ">=0.2.0" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "node_modules/queue-microtask": { "version": "1.2.3", "dev": true, @@ -7174,6 +7425,19 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "node_modules/resolve": { "version": "1.22.8", "license": "MIT", @@ -7247,6 +7511,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==" + }, "node_modules/run-parallel": { "version": "1.2.0", "dev": true, @@ -7308,6 +7577,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/semver": { "version": "7.5.4", "license": "ISC", @@ -7421,6 +7706,14 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.13", "dev": true, @@ -7653,6 +7946,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" + }, "node_modules/test-exclude": { "version": "6.0.0", "dev": true, @@ -7713,6 +8011,31 @@ "node": ">=8.0" } }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/trim-newlines": { "version": "3.0.1", "license": "MIT", @@ -7907,6 +8230,14 @@ "dev": true, "license": "MIT" }, + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "dev": true, @@ -7915,6 +8246,15 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "license": "MIT" @@ -7945,6 +8285,17 @@ "spdx-expression-parse": "^3.0.0" } }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/walker": { "version": "1.0.8", "dev": true, @@ -7953,6 +8304,45 @@ "makeerror": "1.0.12" } }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", + "dependencies": { + "tr46": "^5.0.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/which": { "version": "2.0.2", "dev": true, @@ -8051,6 +8441,39 @@ "dev": true, "license": "ISC" }, + "node_modules/ws": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", + "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" + }, "node_modules/xtend": { "version": "4.0.2", "license": "MIT", diff --git a/package.json b/package.json index 3413b97d3..944115147 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,9 @@ "figures": "^3.1.0", "find-up": "^5.0.0", "git-semver-tags": "^5.0.0", + "jsdom": "^23.2.0", "semver": "^7.5.4", + "w3c-xmlserializer": "^5.0.0", "yargs": "^17.7.2" }, "devDependencies": { diff --git a/test/core.spec.js b/test/core.spec.js index 8881cb27f..eb1fe701a 100644 --- a/test/core.spec.js +++ b/test/core.spec.js @@ -1180,29 +1180,97 @@ describe('cli', function () { }); }); + it('bumps version in Maven `pom.xml` file with CRLF Line Endings', async function () { + const expected = fs.readFileSync( + './test/mocks/pom-6.4.0-crlf.xml', + 'utf-8', + ); + const filename = 'pom.xml'; + mock({ + bump: 'minor', + realTestFiles: [ + { + filename, + path: './test/mocks/pom-6.3.1-crlf.xml', + }, + ], + }); + await exec({ + packageFiles: [{ filename, type: 'maven' }], + bumpFiles: [{ filename, type: 'maven' }], + }); + + // filePath is the first arg passed to writeFileSync + const packageJsonWriteFileSynchCall = findWriteFileCallForPath({ + writeFileSyncSpy, + filename, + }); + + if (!packageJsonWriteFileSynchCall) { + throw new Error(`writeFileSynch not invoked with path ${filename}`); + } + + const calledWithContentStr = packageJsonWriteFileSynchCall[1]; + expect(calledWithContentStr).toEqual(expected); + }); + + it('bumps version in Maven `pom.xml` file with LF Line Endings', async function () { + const expected = fs.readFileSync( + './test/mocks/pom-6.4.0-lf.xml', + 'utf-8', + ); + const filename = 'pom.xml'; + mock({ + bump: 'minor', + realTestFiles: [ + { + filename, + path: './test/mocks/pom-6.3.1-lf.xml', + }, + ], + }); + await exec({ + packageFiles: [{ filename, type: 'maven' }], + bumpFiles: [{ filename, type: 'maven' }], + }); + + // filePath is the first arg passed to writeFileSync + const packageJsonWriteFileSynchCall = findWriteFileCallForPath({ + writeFileSyncSpy, + filename, + }); + + if (!packageJsonWriteFileSynchCall) { + throw new Error(`writeFileSynch not invoked with path ${filename}`); + } + + const calledWithContentStr = packageJsonWriteFileSynchCall[1]; + expect(calledWithContentStr).toEqual(expected); + }); + it('bumps version in Gradle `build.gradle.kts` file', async function () { const expected = fs.readFileSync( './test/mocks/build-6.4.0.gradle.kts', 'utf-8', ); + const filename = 'build.gradle.kts'; mock({ bump: 'minor', realTestFiles: [ { - filename: 'build.gradle.kts', + filename, path: './test/mocks/build-6.3.1.gradle.kts', }, ], }); await exec({ - packageFiles: [{ filename: 'build.gradle.kts', type: 'gradle' }], - bumpFiles: [{ filename: 'build.gradle.kts', type: 'gradle' }], + packageFiles: [{ filename, type: 'gradle' }], + bumpFiles: [{ filename, type: 'gradle' }], }); // filePath is the first arg passed to writeFileSync - const filename = 'build.gradle.kts'; const packageJsonWriteFileSynchCall = findWriteFileCallForPath({ writeFileSyncSpy, filename, diff --git a/test/mocks/pom-6.3.1-crlf.xml b/test/mocks/pom-6.3.1-crlf.xml new file mode 100644 index 000000000..bfc60b070 --- /dev/null +++ b/test/mocks/pom-6.3.1-crlf.xml @@ -0,0 +1,30 @@ + + 4.0.0 + + + com.mycompany.app + my-app + 3.0.0 + + + com.mycompany.app + my-module + 6.3.1 + + + 2.0.0 + + + + + org.some.dependency + some-artifact + ${some.version} + + + org.another.dependency + another-artifact + 1.0.0 + + + diff --git a/test/mocks/pom-6.3.1-lf.xml b/test/mocks/pom-6.3.1-lf.xml new file mode 100644 index 000000000..194cd8bc3 --- /dev/null +++ b/test/mocks/pom-6.3.1-lf.xml @@ -0,0 +1,30 @@ + + 4.0.0 + + + com.mycompany.app + my-app + 3.0.0 + + + com.mycompany.app + my-module + 6.3.1 + + + 2.0.0 + + + + + org.some.dependency + some-artifact + ${some.version} + + + org.another.dependency + another-artifact + 1.0.0 + + + diff --git a/test/mocks/pom-6.4.0-crlf.xml b/test/mocks/pom-6.4.0-crlf.xml new file mode 100644 index 000000000..90b1bfdb7 --- /dev/null +++ b/test/mocks/pom-6.4.0-crlf.xml @@ -0,0 +1,30 @@ + + 4.0.0 + + + com.mycompany.app + my-app + 3.0.0 + + + com.mycompany.app + my-module + 6.4.0 + + + 2.0.0 + + + + + org.some.dependency + some-artifact + ${some.version} + + + org.another.dependency + another-artifact + 1.0.0 + + + diff --git a/test/mocks/pom-6.4.0-lf.xml b/test/mocks/pom-6.4.0-lf.xml new file mode 100644 index 000000000..99cb25900 --- /dev/null +++ b/test/mocks/pom-6.4.0-lf.xml @@ -0,0 +1,30 @@ + + 4.0.0 + + + com.mycompany.app + my-app + 3.0.0 + + + com.mycompany.app + my-module + 6.4.0 + + + 2.0.0 + + + + + org.some.dependency + some-artifact + ${some.version} + + + org.another.dependency + another-artifact + 1.0.0 + + +