From 01f08e9093e255f81394c97bcac59e057f5717dc Mon Sep 17 00:00:00 2001 From: jgrant216 Date: Thu, 10 Oct 2024 09:40:37 -0400 Subject: [PATCH] feat(python): add poetry support (#188) * feat(python): add poetry support * chore: run autoformatter --------- Co-authored-by: Timothy Jones --- README.md | 9 +++++++++ lib/updaters/index.js | 4 ++++ lib/updaters/types/python.js | 30 +++++++++++++++++++++++++++ test/core.spec.js | 36 +++++++++++++++++++++++++++++++++ test/mocks/pyproject-1.0.0.toml | 12 +++++++++++ test/mocks/pyproject-1.1.0.toml | 12 +++++++++++ 6 files changed, 103 insertions(+) create mode 100644 lib/updaters/types/python.js create mode 100644 test/mocks/pyproject-1.0.0.toml create mode 100644 test/mocks/pyproject-1.1.0.toml diff --git a/README.md b/README.md index eaa655de5..6275c852a 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ _Having problems? Want to contribute? Join us on the [node-tooling community Sla - [.NET Support](#net-support) - [YAML Support](#yaml-support) - [OpenAPI Support](#openapi-support) + - [Python Support](#python-support) - [Installing `commit-and-tag-version`](#installing-commit-and-tag-version) - [As a local `npm run` script](#as-a-local-npm-run-script) - [As global `bin`](#as-global-bin) @@ -127,6 +128,14 @@ If you are using OpenAPI, then just point to your `openapi.yaml` file. commit-and-tag-version --packageFiles openapi.yaml --bumpFiles openapi.yaml ``` +### Python Support + +If you are using Python ***with Poetry***, then point to your `pyproject.toml` file. + +```sh +commit-and-tag-version --packageFiles pyproject.toml --bumpFiles pyproject.toml +``` + ## Installing `commit-and-tag-version` ### As a local `npm run` script diff --git a/lib/updaters/index.js b/lib/updaters/index.js index 47296e3d1..9eb6dd93f 100644 --- a/lib/updaters/index.js +++ b/lib/updaters/index.js @@ -8,6 +8,7 @@ const updatersByType = { csproj: require('./types/csproj'), yaml: require('./types/yaml'), openapi: require('./types/openapi'), + python: require('./types/python'), }; const PLAIN_TEXT_BUMP_FILES = ['VERSION.txt', 'version.txt']; @@ -41,6 +42,9 @@ function getUpdaterByFilename(filename) { if (/\.ya?ml$/.test(filename)) { return getUpdaterByType('yaml'); } + if (/pyproject.toml/.test(filename)) { + return getUpdaterByType('python'); + } 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/python.js b/lib/updaters/types/python.js new file mode 100644 index 000000000..afaca68a5 --- /dev/null +++ b/lib/updaters/types/python.js @@ -0,0 +1,30 @@ +const versionExtractRegex = /version[" ]*=[ ]*["'](.*)["']/i; + +const getVersionIndex = function (lines) { + let version; + const lineNumber = lines.findIndex((line) => { + const versionMatcher = line.match(versionExtractRegex); + // if version not found in lines provided, return false + if (versionMatcher == null) { + return false; + } + version = versionMatcher[1]; + return true; + }); + return { version, lineNumber }; +}; + +module.exports.readVersion = function (contents) { + const lines = contents.split('\n'); + const versionIndex = getVersionIndex(lines); + return versionIndex.version; +}; + +module.exports.writeVersion = function (contents, version) { + const lines = contents.split('\n'); + const versionIndex = getVersionIndex(lines); + const versionLine = lines[versionIndex.lineNumber]; + const newVersionLine = versionLine.replace(versionIndex.version, version); + lines[versionIndex.lineNumber] = newVersionLine; + return lines.join('\n'); +}; diff --git a/test/core.spec.js b/test/core.spec.js index 880220216..3a579d78a 100644 --- a/test/core.spec.js +++ b/test/core.spec.js @@ -1130,6 +1130,42 @@ describe('cli', function () { console.warn = origWarn; } }); + + it('bumps version in Python `pyproject.toml` file', async function () { + const expected = fs.readFileSync( + './test/mocks/pyproject-1.1.0.toml', + 'utf-8', + ); + + const filename = 'python.toml'; + mock({ + bump: 'minor', + realTestFiles: [ + { + filename, + path: './test/mocks/pyproject-1.0.0.toml', + }, + ], + }); + + await exec({ + packageFiles: [{ filename, type: 'python' }], + bumpFiles: [{ filename, type: 'python' }], + }); + + // 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('`packageFiles` are bumped along with `bumpFiles` defaults [commit-and-tag-version#533]', async function () { diff --git a/test/mocks/pyproject-1.0.0.toml b/test/mocks/pyproject-1.0.0.toml new file mode 100644 index 000000000..ed8392488 --- /dev/null +++ b/test/mocks/pyproject-1.0.0.toml @@ -0,0 +1,12 @@ +[tool.poetry] +name = "test" +version = "1.0.0" +description = "" +authors = [] + +[tool.poetry.dependencies] +python = "^3.8" + +[build-system] +requires = ["poetry>=1"] +build-backend = "poetry.masonry.api" diff --git a/test/mocks/pyproject-1.1.0.toml b/test/mocks/pyproject-1.1.0.toml new file mode 100644 index 000000000..03745363d --- /dev/null +++ b/test/mocks/pyproject-1.1.0.toml @@ -0,0 +1,12 @@ +[tool.poetry] +name = "test" +version = "1.1.0" +description = "" +authors = [] + +[tool.poetry.dependencies] +python = "^3.8" + +[build-system] +requires = ["poetry>=1"] +build-backend = "poetry.masonry.api"