Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: frinyvonnick/gitmoji-changelog
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v2.3.0
Choose a base ref
...
head repository: frinyvonnick/gitmoji-changelog
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
  • 3 commits
  • 7 files changed
  • 3 contributors

Commits on Sep 30, 2022

  1. Copy the full SHA
    584d065 View commit details

Commits on Jun 9, 2023

  1. Copy the full SHA
    305a371 View commit details
  2. Copy the full SHA
    d0edd29 View commit details
2 changes: 1 addition & 1 deletion packages/gitmoji-changelog-cli/src/cli.e2e.js
Original file line number Diff line number Diff line change
@@ -443,7 +443,7 @@ describe('generate changelog', () => {
})

async function makeChanges(fileName) {
fs.writeFileSync(path.join(testDir, fileName))
fs.writeFileSync(path.join(testDir, fileName), '')
}

async function makeCustomConfig(config) {
4 changes: 2 additions & 2 deletions packages/gitmoji-changelog-cli/src/cli.js
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ const semver = require('semver')
const semverCompare = require('semver-compare')
const rc = require('rc')

const { generateChangelog, logger } = require('@gitmoji-changelog/core')
const { generateChangelog, logger, FunctionalError } = require('@gitmoji-changelog/core')
const { buildMarkdownFile, getLatestVersion } = require('@gitmoji-changelog/markdown')

const issueReporter = require('issue-reporter')
@@ -138,7 +138,7 @@ async function getChangelog(options, projectInfo) {
const release = options.release === 'from-package' ? projectInfo.version : options.release

if (!semver.valid(release)) {
throw new Error(`${release} is not a valid semver version.`)
throw new FunctionalError(`${release} is not a valid semver version.`)
}

const enhancedOptions = {
2 changes: 1 addition & 1 deletion packages/gitmoji-changelog-cli/src/index.js
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ yargs
}, execute('update'))

.option('format', { default: 'markdown', desc: 'changelog format (markdown, json)' })
.option('preset', { default: 'node', desc: 'define preset mode', choices: ['node', 'generic', 'maven', 'cargo', 'helm'] })
.option('preset', { default: 'node', desc: 'define preset mode', choices: ['node', 'generic', 'maven', 'cargo', 'helm', 'python'] })
.option('output', { desc: 'output changelog file' })
.option('group-similar-commits', { desc: '[⚗️ - beta] try to group similar commits', default: false })
.option('author', { default: false, desc: 'add the author in changelog lines' })
68 changes: 68 additions & 0 deletions packages/gitmoji-changelog-cli/src/presets/python.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const toml = require('toml')
const fs = require('fs')

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]

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

return {
name,
version,
description,
}
} catch (e) {
return null
}
}


function recursiveKeySearch(key, data) {
// https://codereview.stackexchange.com/a/143914
if (data === null) {
return []
}

if (data !== Object(data)) {
return []
}

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
}

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]))
}

return results
}
137 changes: 137 additions & 0 deletions packages/gitmoji-changelog-cli/src/presets/python.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
const fs = require('fs')

const loadProjectInfo = require('./python.js')

describe('getPackageInfo', () => {
it('should extract metadata from a pyproject.toml made by poetry', async () =>{
// Note the TOML section is distinct for poetry
fs.readFileSync.mockReturnValue(`
[tool.poetry]
name = "poetry-package-name"
version = "0.1.0"
description = "Description of the poetry package"
`)

const result = await loadProjectInfo()

expect(result).toEqual({
name: 'poetry-package-name',
version: '0.1.0',
description: 'Description of the poetry package',
})
})

it('should extract metadata from the PEP621 example pyproject.toml', async () =>{
// [project] is the usual TOML section for the metadata
fs.readFileSync.mockReturnValue(`
[project]
name = "spam"
version = "2020.0.0"
description = "Lovely Spam! Wonderful Spam!"
readme = "README.rst"
requires-python = ">=3.8"
license = {file = "LICENSE.txt"}
keywords = ["egg", "bacon", "sausage", "tomatoes", "Lobster Thermidor"]
authors = [
{email = "hi@pradyunsg.me"},
{name = "Tzu-Ping Chung"}
]
maintainers = [
{name = "Brett Cannon", email = "brett@python.org"}
]
classifiers = [
"Development Status :: 4 - Beta",
"Programming Language :: Python"
]
dependencies = [
"httpx",
"gidgethub[httpx]>4.0.0",
"django>2.1; os_name != 'nt'",
"django>2.0; os_name == 'nt'"
]
[project.optional-dependencies]
test = [
"pytest < 5.0.0",
"pytest-cov[all]"
]
[project.urls]
homepage = "example.com"
documentation = "readthedocs.org"
repository = "github.com"
changelog = "github.com/me/spam/blob/master/CHANGELOG.md"
[project.scripts]
spam-cli = "spam:main_cli"
[project.gui-scripts]
spam-gui = "spam:main_gui"
[project.entry-points."spam.magical"]
tomatoes = "spam:main_tomatoes"
`)

const result = await loadProjectInfo()

expect(result).toEqual({
name: 'spam',
version: '2020.0.0',
description: 'Lovely Spam! Wonderful Spam!',
})
})

it('should extract metadata despite a missing description', async () =>{
// The description metadata is optional.
fs.readFileSync.mockReturnValue(`
[project]
name = "no-description"
version = "0.0.1"
readme = "README.rst"
`)

const result = await loadProjectInfo()

expect(result).toEqual({
name: 'no-description',
version: '0.0.1',
description: '',
})
})

it('should use the first metadata value found from the top', async () =>{
// Only the first occurance of the expected key names are taken.
fs.readFileSync.mockReturnValue(`
[other.section]
somebody = "once told me the"
world = "is gonna roll me"
[project]
name = "project-1"
version = "0.0.1"
description = "Project 1 Description"
[tool.poetry]
name = "project-2"
version = "0.0.2"
description = "Project 2 Description"
[tool.something.else]
name = "project-3"
version = "0.0.3"
description = "Project 3 Description"
`)

const result = await loadProjectInfo()

expect(result).toEqual({
name: 'project-1',
version: '0.0.1',
description: 'Project 1 Description',
})
})
})


jest.mock('fs')
1 change: 1 addition & 0 deletions packages/gitmoji-changelog-core/src/index.js
Original file line number Diff line number Diff line change
@@ -187,4 +187,5 @@ function getLastCommitDate(commits) {
module.exports = {
generateChangelog,
logger,
FunctionalError,
}
11 changes: 11 additions & 0 deletions packages/gitmoji-changelog-documentation/README.md
Original file line number Diff line number Diff line change
@@ -106,6 +106,7 @@ _This workflow is related to the `node` preset but can be adapted to your own te
- generic
- maven
- cargo
- helm

Didn't see the preset you need in the list? Consider adding it. Presets are stored in a [presets](https://github.com/frinyvonnick/gitmoji-changelog/blob/master/packages/gitmoji-changelog-cli/src/presets) folder in the `cli` package.

@@ -164,6 +165,16 @@ The helm preset looks for 3 properties in your `Chart.yaml`:
- version
- description

#### Python

The python preset looks for 3 properties in your `pyproject.toml`:

- name
- version
- description

(The value taken is the first one found in your `pyproject.toml` that matches the expected key name given above.)

### Add a preset

A preset need to export a function. When called this function must return three mandatory information about the project in which the cli has been called. The name of the project, a short description of it and its current version.