diff --git a/README.md b/README.md index 233001c77..4c21f4f55 100644 --- a/README.md +++ b/README.md @@ -108,6 +108,15 @@ This is going to read and update only the `` tag in the file. commit-and-tag-version --packageFiles .csproj --bumpFiles .csproj ``` +### YAML Support + +If you are using YAML files. +This is going to read and update only the `version:` tag in the file. + +```sh +commit-and-tag-version --packageFiles file.yaml --bumpFiles file.yaml +``` + ## Installing `commit-and-tag-version` ### As a local `npm run` script diff --git a/lib/updaters/index.js b/lib/updaters/index.js index 3698045dc..29521d4af 100644 --- a/lib/updaters/index.js +++ b/lib/updaters/index.js @@ -6,6 +6,7 @@ const updatersByType = { maven: require('./types/maven'), gradle: require('./types/gradle'), csproj: require('./types/csproj'), + yaml: require('./types/yaml'), }; const PLAIN_TEXT_BUMP_FILES = ['VERSION.txt', 'version.txt']; @@ -33,6 +34,9 @@ function getUpdaterByFilename(filename) { if (filename.endsWith('.csproj')) { return getUpdaterByType('csproj'); } + if (/\.ya?ml$/.test(filename)) { + return getUpdaterByType('yaml'); + } throw Error( `Unsupported file (${filename}) provided for bumping.\n Please specify the updater \`type\` or use a custom \`updater\`.`, ); diff --git a/lib/updaters/types/yaml.js b/lib/updaters/types/yaml.js new file mode 100644 index 000000000..0812514ad --- /dev/null +++ b/lib/updaters/types/yaml.js @@ -0,0 +1,15 @@ +const yaml = require('yaml'); +const detectNewline = require('detect-newline'); + +module.exports.readVersion = function (contents) { + return yaml.parse(contents).version; +}; + +module.exports.writeVersion = function (contents, version) { + const newline = detectNewline(contents); + const document = yaml.parseDocument(contents); + + document.set('version', version); + + return document.toString().replace(/\r?\n/g, newline); +}; diff --git a/package-lock.json b/package-lock.json index a2a1c1f91..8f388ad9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,6 +23,7 @@ "jsdom": "^23.2.0", "semver": "^7.5.4", "w3c-xmlserializer": "^5.0.0", + "yaml": "^2.4.1", "yargs": "^17.7.2" }, "bin": { @@ -8492,6 +8493,17 @@ "version": "4.0.0", "license": "ISC" }, + "node_modules/yaml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz", + "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/yargs": { "version": "17.7.2", "license": "MIT", diff --git a/package.json b/package.json index 98de772c3..93a253b25 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "jsdom": "^23.2.0", "semver": "^7.5.4", "w3c-xmlserializer": "^5.0.0", + "yaml": "^2.4.1", "yargs": "^17.7.2" }, "devDependencies": { diff --git a/test/core.spec.js b/test/core.spec.js index eb1fe701a..b64cc9c3a 100644 --- a/test/core.spec.js +++ b/test/core.spec.js @@ -1365,6 +1365,78 @@ describe('cli', function () { verifyPackageVersion({ writeFileSyncSpy, expectedVersion: '1.1.0' }); }); + it('bumps version in Dart `pubspec.yaml` file', async function () { + const expected = fs.readFileSync( + './test/mocks/pubspec-6.4.0.yaml', + 'utf-8', + ); + + const filename = 'pubspec.yaml'; + mock({ + bump: 'minor', + realTestFiles: [ + { + filename, + path: './test/mocks/pubspec-6.3.1.yaml', + }, + ], + }); + + await exec({ + packageFiles: [{ filename, type: 'yaml' }], + bumpFiles: [{ filename, type: 'yaml' }], + }); + + // 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 Dart `pubspec.yaml` file with CRLF line endings', async function () { + const expected = fs.readFileSync( + './test/mocks/pubspec-6.4.0-crlf.yaml', + 'utf-8', + ); + + const filename = 'pubspec.yaml'; + mock({ + bump: 'minor', + realTestFiles: [ + { + filename, + path: './test/mocks/pubspec-6.3.1-crlf.yaml', + }, + ], + }); + + await exec({ + packageFiles: [{ filename, type: 'yaml' }], + bumpFiles: [{ filename, type: 'yaml' }], + }); + + // 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); + }); + describe('skip', function () { it('allows bump and changelog generation to be skipped', async function () { const changelogContent = 'legacy header format\n'; diff --git a/test/mocks/pubspec-6.3.1-crlf.yaml b/test/mocks/pubspec-6.3.1-crlf.yaml new file mode 100644 index 000000000..20548f164 --- /dev/null +++ b/test/mocks/pubspec-6.3.1-crlf.yaml @@ -0,0 +1,33 @@ +# This is a comment that should be preserved +name: mock +description: "A mock YAML file" +version: 6.3.1 + +environment: + dart: ">=3.2.6 <4.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + uses-material-design: true + generate: true + + # More comments here nested under one entry + # + # These comments should also be preserved. + + # Another comment block, separated from the first one + assets: + - assets/icons/ + - assets/images/ diff --git a/test/mocks/pubspec-6.3.1.yaml b/test/mocks/pubspec-6.3.1.yaml new file mode 100644 index 000000000..cfcdaf5d4 --- /dev/null +++ b/test/mocks/pubspec-6.3.1.yaml @@ -0,0 +1,33 @@ +# This is a comment that should be preserved +name: mock +description: "A mock YAML file" +version: 6.3.1 + +environment: + dart: ">=3.2.6 <4.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + uses-material-design: true + generate: true + + # More comments here nested under one entry + # + # These comments should also be preserved. + + # Another comment block, separated from the first one + assets: + - assets/icons/ + - assets/images/ diff --git a/test/mocks/pubspec-6.4.0-crlf.yaml b/test/mocks/pubspec-6.4.0-crlf.yaml new file mode 100644 index 000000000..25a039bc7 --- /dev/null +++ b/test/mocks/pubspec-6.4.0-crlf.yaml @@ -0,0 +1,33 @@ +# This is a comment that should be preserved +name: mock +description: "A mock YAML file" +version: 6.4.0 + +environment: + dart: ">=3.2.6 <4.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + uses-material-design: true + generate: true + + # More comments here nested under one entry + # + # These comments should also be preserved. + + # Another comment block, separated from the first one + assets: + - assets/icons/ + - assets/images/ diff --git a/test/mocks/pubspec-6.4.0.yaml b/test/mocks/pubspec-6.4.0.yaml new file mode 100644 index 000000000..44e27ed7a --- /dev/null +++ b/test/mocks/pubspec-6.4.0.yaml @@ -0,0 +1,33 @@ +# This is a comment that should be preserved +name: mock +description: "A mock YAML file" +version: 6.4.0 + +environment: + dart: ">=3.2.6 <4.0.0" + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + uses-material-design: true + generate: true + + # More comments here nested under one entry + # + # These comments should also be preserved. + + # Another comment block, separated from the first one + assets: + - assets/icons/ + - assets/images/