Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/canary-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@ jobs:

strategy:
matrix:
node-version: [12]
node-version: [18]

steps:
- name: Checkout project
uses: actions/checkout@v1

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
registry-url: 'https://registry.npmjs.org'

- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Publish Canary version
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-and-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

strategy:
matrix:
node-version: [12]
node-version: [18, 20, 22]

steps:
- name: Checkout project
Expand Down
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
lts/*
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:12.14.1-alpine3.11
FROM node:lts-alpine3.20
ENV NODE_ENV=production

# install dependencies
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@
},
"workspaces": [
"packages/*"
]
],
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
3 changes: 2 additions & 1 deletion packages/gitmoji-changelog-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"description": "Gitmoji Changelog CLI",
"main": "src/index.js",
"engines": {
"node": ">=10"
"node": ">=18"
},
"bin": {
"gitmoji-changelog": "./src/index.js"
Expand Down Expand Up @@ -45,6 +45,7 @@
"semver": "^5.6.0",
"semver-compare": "^1.0.0",
"simple-git": "^1.113.0",
"smol-toml": "^1.3.1",
"toml": "^3.0.0",
"yaml": "^1.10.2",
"yargs": "^17.3.1"
Expand Down
124 changes: 89 additions & 35 deletions packages/gitmoji-changelog-cli/src/presets/python.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,60 @@
const toml = require('toml')
const fs = require('fs')
const toml = require('smol-toml')
const ChildProcess = require('child_process')

module.exports = async () => {
try {
const pyprojectPromise = new Promise((resolve, reject) => {
try {
resolve(toml.parse(fs.readFileSync('pyproject.toml', 'utf-8')))
} catch (err) {
reject(err)
}
})

const projectFile = await pyprojectPromise
const name = recursiveKeySearch('name', projectFile)[0]
const version = recursiveKeySearch('version', projectFile)[0]
let description = recursiveKeySearch('description', projectFile)[0]
const pyproject = toml.parse(fs.readFileSync('pyproject.toml', 'utf-8'))
const meta = pyproject.project || (pyproject.tool && pyproject.tool.poetry)
const dynamicFields = meta.dynamic || []

const name = meta.name
if (!name) {
throw new Error('Could not find name metadata in pyproject.toml')
}

let version = meta.version
const isDynamicVersion = dynamicFields.includes('version')
if (isDynamicVersion) {
const backend = pyproject['build-system'] && pyproject['build-system']['build-backend']
if (!backend) {
throw new Error('Cannot resolve dynamic version: build-backend is not set')
}

switch (backend) {
case 'hatchling.build':
version = getHatchVersion()
break

case 'flit_core.buildapi':
version = getFlitVersion()
break

case 'setuptools.build_meta':
version = getSetuptoolsScmVersion()
break

case 'pdm.backend':
version = getPdmVersion()
break

default:
throw new Error(`Unsupported build-backend: ${backend}`)
}
}
if (!version) {
throw new Error('Could not find version metadata in pyproject.toml')
throw new Error('Could not find version metadata (static or dynamic)')
}
if (!description) {
description = ''

let description = meta.description || ''
const isDynamicDescription = dynamicFields.includes('description')
if (isDynamicDescription) {
let readme = meta.readme
if (typeof readme === 'object') {
readme = readme.file
}

description = getDescriptionFromReadme(readme) || ''
}

return {
Expand All @@ -37,32 +68,55 @@ module.exports = async () => {
}


function recursiveKeySearch(key, data) {
// https://codereview.stackexchange.com/a/143914
if (data === null) {
return []
function getHatchVersion() {
try {
const version = ChildProcess.execSync('hatch version', { encoding: 'utf-8' }).trim()
return version
} catch (e) {
throw new Error('Failed to run `hatch version`: ' + e.message)
}
}


if (data !== Object(data)) {
return []
function getFlitVersion() {
try {
const output = ChildProcess.execSync('flit info', { encoding: 'utf-8' })
const match = output.match(/^Version:\s*(.+)$/m)
if (match) return match[1].trim()
throw new Error('Could not extract version from `flit info` output')
} catch (e) {
throw new Error('Failed to run `flit info`: ' + e.message)
}
}

let results = []

if (data.constructor === Array) {
for (let i = 0, len = data.length; i < len; i += 1) {
results = results.concat(recursiveKeySearch(key, data[i]))
}
return results
function getSetuptoolsScmVersion() {
try {
return ChildProcess.execSync('python -m setuptools_scm', { encoding: 'utf-8' }).trim()
} catch (e) {
throw new Error('Failed to run `setuptools_scm`: ' + e.message)
}
}

for (let i = 0; i < Object.keys(data).length; i += 1) {
const dataKey = Object.keys(data)[i]
if (key === dataKey) {
results.push(data[key])
}
results = results.concat(recursiveKeySearch(key, data[dataKey]))

function getPdmVersion() {
try {
return ChildProcess.execSync('pdm show --version', { encoding: 'utf-8' }).trim()
} catch (e) {
throw new Error('Failed to run `pdm show --version`: ' + e.message)
}
}


function getDescriptionFromReadme(readmePath = 'README.md') {
if (!fs.existsSync(readmePath)) {
return ''
}

return results
const content = fs.readFileSync(readmePath, 'utf-8').trim()

const paragraphs = content.split(/\r?\n\r?\n/)
const first = paragraphs.find(p => p.trim().length > 0)

return first ? first.replace(/^#\s*/, '').trim() : null
}
Loading