relion 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +64 -0
- package/dist/index.d.ts +231 -0
- package/dist/index.js +652 -0
- package/package.json +31 -50
- package/src/cli.js +0 -6
- package/src/commands.js +0 -176
- package/src/defaults.js +0 -60
- package/src/index.js +0 -75
- package/src/lib/checkpoint.js +0 -23
- package/src/lib/configuration.js +0 -35
- package/src/lib/detect-package-manager.js +0 -52
- package/src/lib/format-commit-message.js +0 -4
- package/src/lib/latest-semver-tag.js +0 -34
- package/src/lib/lifecycles/bump.js +0 -242
- package/src/lib/lifecycles/changelog.js +0 -106
- package/src/lib/lifecycles/commit.js +0 -67
- package/src/lib/lifecycles/tag.js +0 -61
- package/src/lib/print-error.js +0 -15
- package/src/lib/run-exec.js +0 -20
- package/src/lib/run-execFile.js +0 -20
- package/src/lib/run-lifecycle-script.js +0 -18
- package/src/lib/stringify-package.js +0 -34
- package/src/lib/updaters/index.js +0 -130
- package/src/lib/updaters/types/csproj.js +0 -13
- package/src/lib/updaters/types/gradle.js +0 -16
- package/src/lib/updaters/types/json.js +0 -25
- package/src/lib/updaters/types/maven.js +0 -43
- package/src/lib/updaters/types/openapi.js +0 -15
- package/src/lib/updaters/types/plain-text.js +0 -7
- package/src/lib/updaters/types/python.js +0 -30
- package/src/lib/updaters/types/yaml.js +0 -15
- package/src/lib/write-file.js +0 -6
- package/src/preset/constants.js +0 -16
- package/src/preset/index.js +0 -19
- package/src/preset/parser.js +0 -11
- package/src/preset/templates/commit.hbs +0 -19
- package/src/preset/templates/footer.hbs +0 -10
- package/src/preset/templates/header.hbs +0 -10
- package/src/preset/templates/index.js +0 -13
- package/src/preset/templates/main.hbs +0 -21
- package/src/preset/whatBump.js +0 -33
- package/src/preset/writer.js +0 -201
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import path from 'path'
|
|
2
|
-
import defaults from '../../defaults.js'
|
|
3
|
-
import * as jsonUpdater from './types/json.js'
|
|
4
|
-
import * as plainTextUpdater from './types/plain-text.js'
|
|
5
|
-
import * as mavenUpdater from './types/maven.js'
|
|
6
|
-
import * as gradleUpdater from './types/gradle.js'
|
|
7
|
-
import * as csprojUpdater from './types/csproj.js'
|
|
8
|
-
import * as yamlUpdater from './types/yaml.js'
|
|
9
|
-
import * as openapiUpdater from './types/openapi.js'
|
|
10
|
-
import * as pythonUpdater from './types/python.js'
|
|
11
|
-
|
|
12
|
-
const JSON_BUMP_FILES = defaults.bumpFiles
|
|
13
|
-
const updatersByType = {
|
|
14
|
-
'json': jsonUpdater,
|
|
15
|
-
'plain-text': plainTextUpdater,
|
|
16
|
-
'maven': mavenUpdater,
|
|
17
|
-
'gradle': gradleUpdater,
|
|
18
|
-
'csproj': csprojUpdater,
|
|
19
|
-
'yaml': yamlUpdater,
|
|
20
|
-
'openapi': openapiUpdater,
|
|
21
|
-
'python': pythonUpdater,
|
|
22
|
-
}
|
|
23
|
-
const PLAIN_TEXT_BUMP_FILES = ['VERSION.txt', 'version.txt']
|
|
24
|
-
|
|
25
|
-
function getUpdaterByType(type) {
|
|
26
|
-
const updater = updatersByType[type]
|
|
27
|
-
if (!updater) {
|
|
28
|
-
throw Error(`Unable to locate updater for provided type (${type}).`)
|
|
29
|
-
}
|
|
30
|
-
return updater
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function getUpdaterByFilename(filename) {
|
|
34
|
-
if (JSON_BUMP_FILES.includes(path.basename(filename))) {
|
|
35
|
-
return getUpdaterByType('json')
|
|
36
|
-
}
|
|
37
|
-
if (PLAIN_TEXT_BUMP_FILES.includes(filename)) {
|
|
38
|
-
return getUpdaterByType('plain-text')
|
|
39
|
-
}
|
|
40
|
-
if (/pom.xml/.test(filename)) {
|
|
41
|
-
return getUpdaterByType('maven')
|
|
42
|
-
}
|
|
43
|
-
if (/build.gradle/.test(filename)) {
|
|
44
|
-
return getUpdaterByType('gradle')
|
|
45
|
-
}
|
|
46
|
-
if (filename.endsWith('.csproj')) {
|
|
47
|
-
return getUpdaterByType('csproj')
|
|
48
|
-
}
|
|
49
|
-
if (/openapi.yaml/.test(filename)) {
|
|
50
|
-
return getUpdaterByType('openapi')
|
|
51
|
-
}
|
|
52
|
-
if (/\.ya?ml$/.test(filename)) {
|
|
53
|
-
return getUpdaterByType('yaml')
|
|
54
|
-
}
|
|
55
|
-
if (/pyproject.toml/.test(filename)) {
|
|
56
|
-
return getUpdaterByType('python')
|
|
57
|
-
}
|
|
58
|
-
throw Error(
|
|
59
|
-
`Unsupported file (${filename}) provided for bumping.\n Please specify the updater \`type\` or use a custom \`updater\`.`,
|
|
60
|
-
)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async function getCustomUpdaterFromPath(updater) {
|
|
64
|
-
if (typeof updater === 'string') {
|
|
65
|
-
return (await import(path.resolve(process.cwd(), updater))).default
|
|
66
|
-
}
|
|
67
|
-
if (
|
|
68
|
-
typeof updater.readVersion === 'function'
|
|
69
|
-
&& typeof updater.writeVersion === 'function'
|
|
70
|
-
) {
|
|
71
|
-
return updater
|
|
72
|
-
}
|
|
73
|
-
throw new Error('Updater must be a string path or an object with readVersion and writeVersion methods')
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Simple check to determine if the object provided is a compatible updater.
|
|
78
|
-
*/
|
|
79
|
-
function isValidUpdater(obj) {
|
|
80
|
-
return (
|
|
81
|
-
obj
|
|
82
|
-
&& typeof obj.readVersion === 'function'
|
|
83
|
-
&& typeof obj.writeVersion === 'function'
|
|
84
|
-
)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export async function resolveUpdaterObjectFromArgument(arg) {
|
|
88
|
-
/**
|
|
89
|
-
* If an Object was not provided, we assume it's the path/filename
|
|
90
|
-
* of the updater.
|
|
91
|
-
*/
|
|
92
|
-
let updater = arg
|
|
93
|
-
if (isValidUpdater(updater)) {
|
|
94
|
-
return updater
|
|
95
|
-
}
|
|
96
|
-
if (typeof updater !== 'object') {
|
|
97
|
-
updater = {
|
|
98
|
-
filename: arg,
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (!isValidUpdater(updater.updater)) {
|
|
103
|
-
try {
|
|
104
|
-
if (typeof updater.updater === 'string') {
|
|
105
|
-
updater.updater = await getCustomUpdaterFromPath(updater.updater)
|
|
106
|
-
}
|
|
107
|
-
else if (updater.type) {
|
|
108
|
-
updater.updater = getUpdaterByType(updater.type)
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
updater.updater = getUpdaterByFilename(updater.filename)
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
catch (err) {
|
|
115
|
-
if (err.code !== 'ENOENT')
|
|
116
|
-
console.warn(
|
|
117
|
-
`Unable to obtain updater for: ${JSON.stringify(arg)}\n - Error: ${err.message
|
|
118
|
-
}\n - Skipping...`,
|
|
119
|
-
)
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* We weren't able to resolve an updater for the argument.
|
|
124
|
-
*/
|
|
125
|
-
if (!isValidUpdater(updater.updater)) {
|
|
126
|
-
return false
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return updater
|
|
130
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
const versionRegex = /<Version>(.*)<\/Version>/
|
|
2
|
-
|
|
3
|
-
export function readVersion(contents) {
|
|
4
|
-
const matches = versionRegex.exec(contents)
|
|
5
|
-
if (matches === null || matches.length !== 2) {
|
|
6
|
-
throw new Error('Failed to read the Version field in your csproj file - is it present?')
|
|
7
|
-
}
|
|
8
|
-
return matches[1]
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function writeVersion(contents, version) {
|
|
12
|
-
return contents.replace(versionRegex, `<Version>${version}</Version>`)
|
|
13
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
const versionRegex = /^version\s+=\s+['"]([\d.]+)['"]/m
|
|
2
|
-
|
|
3
|
-
export function readVersion(contents) {
|
|
4
|
-
const matches = versionRegex.exec(contents)
|
|
5
|
-
if (matches === null) {
|
|
6
|
-
throw new Error('Failed to read the version field in your gradle file - is it present?')
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
return matches[1]
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function writeVersion(contents, version) {
|
|
13
|
-
return contents.replace(versionRegex, () => {
|
|
14
|
-
return `version = "${version}"`
|
|
15
|
-
})
|
|
16
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import stringifyPackage from '../../stringify-package.js'
|
|
2
|
-
import detectIndent from 'detect-indent'
|
|
3
|
-
import { detectNewline } from 'detect-newline'
|
|
4
|
-
|
|
5
|
-
export function readVersion(contents) {
|
|
6
|
-
return JSON.parse(contents).version
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function writeVersion(contents, version) {
|
|
10
|
-
const json = JSON.parse(contents)
|
|
11
|
-
const indent = detectIndent(contents).indent
|
|
12
|
-
const newline = detectNewline(contents)
|
|
13
|
-
json.version = version
|
|
14
|
-
|
|
15
|
-
if (json.packages && json.packages['']) {
|
|
16
|
-
// package-lock v2 stores version there too
|
|
17
|
-
json.packages[''].version = version
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return stringifyPackage(json, indent, newline)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function isPrivate(contents) {
|
|
24
|
-
return JSON.parse(contents).private
|
|
25
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import jsdomPkg from 'jsdom'
|
|
2
|
-
import serialize from 'w3c-xmlserializer'
|
|
3
|
-
import { detectNewline } from 'detect-newline'
|
|
4
|
-
const { JSDOM } = jsdomPkg
|
|
5
|
-
const CRLF = '\r\n'
|
|
6
|
-
const LF = '\n'
|
|
7
|
-
|
|
8
|
-
function pomDocument(contents) {
|
|
9
|
-
const dom = new JSDOM('')
|
|
10
|
-
const parser = new dom.window.DOMParser()
|
|
11
|
-
return parser.parseFromString(contents, 'application/xml')
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function pomVersionElement(document) {
|
|
15
|
-
const versionElement = document.querySelector('project > version')
|
|
16
|
-
|
|
17
|
-
if (!versionElement) {
|
|
18
|
-
throw new Error('Failed to read the version field in your pom file - is it present?')
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return versionElement
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function readVersion(contents) {
|
|
25
|
-
const document = pomDocument(contents)
|
|
26
|
-
return pomVersionElement(document).textContent
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function writeVersion(contents, version) {
|
|
30
|
-
const newline = detectNewline(contents)
|
|
31
|
-
const document = pomDocument(contents)
|
|
32
|
-
const versionElement = pomVersionElement(document)
|
|
33
|
-
|
|
34
|
-
versionElement.textContent = version
|
|
35
|
-
|
|
36
|
-
const xml = serialize(document)
|
|
37
|
-
|
|
38
|
-
if (newline === CRLF) {
|
|
39
|
-
return xml.replace(/\n/g, CRLF) + CRLF
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return xml + LF
|
|
43
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import yaml from 'yaml'
|
|
2
|
-
import { detectNewline } from 'detect-newline'
|
|
3
|
-
|
|
4
|
-
export function readVersion(contents) {
|
|
5
|
-
return yaml.parse(contents).info.version
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function writeVersion(contents, version) {
|
|
9
|
-
const newline = detectNewline(contents)
|
|
10
|
-
const document = yaml.parseDocument(contents)
|
|
11
|
-
|
|
12
|
-
document.get('info').set('version', version)
|
|
13
|
-
|
|
14
|
-
return document.toString().replace(/\r?\n/g, newline)
|
|
15
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
const versionExtractRegex = /version[" ]*=[ ]*["'](.*)["']/i
|
|
2
|
-
|
|
3
|
-
const getVersionIndex = function (lines) {
|
|
4
|
-
let version
|
|
5
|
-
const lineNumber = lines.findIndex((line) => {
|
|
6
|
-
const versionMatcher = line.match(versionExtractRegex)
|
|
7
|
-
// if version not found in lines provided, return false
|
|
8
|
-
if (versionMatcher == null) {
|
|
9
|
-
return false
|
|
10
|
-
}
|
|
11
|
-
version = versionMatcher[1]
|
|
12
|
-
return true
|
|
13
|
-
})
|
|
14
|
-
return { version, lineNumber }
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function readVersion(contents) {
|
|
18
|
-
const lines = contents.split('\n')
|
|
19
|
-
const versionIndex = getVersionIndex(lines)
|
|
20
|
-
return versionIndex.version
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function writeVersion(contents, version) {
|
|
24
|
-
const lines = contents.split('\n')
|
|
25
|
-
const versionIndex = getVersionIndex(lines)
|
|
26
|
-
const versionLine = lines[versionIndex.lineNumber]
|
|
27
|
-
const newVersionLine = versionLine.replace(versionIndex.version, version)
|
|
28
|
-
lines[versionIndex.lineNumber] = newVersionLine
|
|
29
|
-
return lines.join('\n')
|
|
30
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import yaml from 'yaml'
|
|
2
|
-
import { detectNewline } from 'detect-newline'
|
|
3
|
-
|
|
4
|
-
export function readVersion(contents) {
|
|
5
|
-
return yaml.parse(contents).version
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export function writeVersion(contents, version) {
|
|
9
|
-
const newline = detectNewline(contents)
|
|
10
|
-
const document = yaml.parseDocument(contents)
|
|
11
|
-
|
|
12
|
-
document.set('version', version)
|
|
13
|
-
|
|
14
|
-
return document.toString().replace(/\r?\n/g, newline)
|
|
15
|
-
}
|
package/src/lib/write-file.js
DELETED
package/src/preset/constants.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export const DEFAULT_COMMIT_TYPES = Object.freeze(
|
|
2
|
-
[
|
|
3
|
-
{ type: 'feat', section: 'Features' },
|
|
4
|
-
{ type: 'feature', section: 'Features' },
|
|
5
|
-
{ type: 'fix', section: 'Bug Fixes' },
|
|
6
|
-
{ type: 'perf', section: 'Performance Improvements' },
|
|
7
|
-
{ type: 'revert', section: 'Reverts' },
|
|
8
|
-
{ type: 'docs', section: 'Documentation', hidden: true },
|
|
9
|
-
{ type: 'style', section: 'Styles', hidden: true },
|
|
10
|
-
{ type: 'chore', section: 'Miscellaneous Chores', hidden: true },
|
|
11
|
-
{ type: 'refactor', section: 'Code Refactoring', hidden: true },
|
|
12
|
-
{ type: 'test', section: 'Tests', hidden: true },
|
|
13
|
-
{ type: 'build', section: 'Build System', hidden: true },
|
|
14
|
-
{ type: 'ci', section: 'Continuous Integration', hidden: true },
|
|
15
|
-
].map(Object.freeze),
|
|
16
|
-
)
|
package/src/preset/index.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_COMMIT_TYPES } from './constants.js'
|
|
2
|
-
import { createParserOpts } from './parser.js'
|
|
3
|
-
import { createWriterOpts } from './writer.js'
|
|
4
|
-
import { createWhatBump } from './whatBump.js'
|
|
5
|
-
|
|
6
|
-
export { DEFAULT_COMMIT_TYPES }
|
|
7
|
-
export * from './templates/index.js'
|
|
8
|
-
|
|
9
|
-
export default async function createPreset(config) {
|
|
10
|
-
return {
|
|
11
|
-
commits: {
|
|
12
|
-
ignore: config?.ignoreCommits,
|
|
13
|
-
merges: false,
|
|
14
|
-
},
|
|
15
|
-
parser: createParserOpts(config),
|
|
16
|
-
writer: await createWriterOpts(config),
|
|
17
|
-
whatBump: createWhatBump(config),
|
|
18
|
-
}
|
|
19
|
-
}
|
package/src/preset/parser.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export function createParserOpts(config) {
|
|
2
|
-
return {
|
|
3
|
-
headerPattern: /^(\w*)(?:\((.*)\))?!?: (.*)$/,
|
|
4
|
-
breakingHeaderPattern: /^(\w*)(?:\((.*)\))?!: (.*)$/,
|
|
5
|
-
headerCorrespondence: ['type', 'scope', 'subject'],
|
|
6
|
-
noteKeywords: ['BREAKING CHANGE', 'BREAKING-CHANGE'],
|
|
7
|
-
revertPattern: /^(?:Revert|revert:)\s"?([\s\S]+?)"?\s*This reverts commit (\w*)\./i,
|
|
8
|
-
revertCorrespondence: ['header', 'hash'],
|
|
9
|
-
issuePrefixes: config?.issuePrefixes || ['#'],
|
|
10
|
-
}
|
|
11
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
* {{#if scope}}`{{scope}}` {{/if~}}
|
|
2
|
-
{{#if subject}}{{subject}}{{else}}{{header}}{{/if}}
|
|
3
|
-
|
|
4
|
-
{{~! commit link}}
|
|
5
|
-
{{~#if hash}}
|
|
6
|
-
{{~#if @root.linkReferences}} ([{{shortHash}}]({{commitUrlFormat}}))
|
|
7
|
-
{{~else}} {{shortHash}}{{~/if}}
|
|
8
|
-
{{~/if}}
|
|
9
|
-
|
|
10
|
-
{{~! commit references}}
|
|
11
|
-
{{~#if references}} (
|
|
12
|
-
{{~#each references}}
|
|
13
|
-
{{#if @root.linkReferences~}}
|
|
14
|
-
[{{~#if owner}}{{owner}}/{{/if}}{{repository}}{{prefix}}{{issue}}]({{issueUrlFormat}})
|
|
15
|
-
{{~else}}
|
|
16
|
-
{{~#if owner}}{{owner}}/{{/if}}{{repository}}{{prefix}}{{issue}}
|
|
17
|
-
{{~/if}}{{~#unless @last}}, {{/unless}}{{~#if @last}}){{~/if}}
|
|
18
|
-
{{~/each}}
|
|
19
|
-
{{~/if}}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import fs from 'fs'
|
|
2
|
-
import path from 'path'
|
|
3
|
-
|
|
4
|
-
const dirpath = import.meta.dirname
|
|
5
|
-
|
|
6
|
-
function read(name) {
|
|
7
|
-
return fs.readFileSync(path.join(dirpath, `${name}.hbs`), 'utf-8')
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const main = read('main')
|
|
11
|
-
export const header = read('header')
|
|
12
|
-
export const commit = read('commit')
|
|
13
|
-
export const footer = read('footer')
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{{> header}}
|
|
2
|
-
{{#if noteGroups}}
|
|
3
|
-
{{#each noteGroups}}
|
|
4
|
-
### ⚠ {{title}}
|
|
5
|
-
{{#each notes}}
|
|
6
|
-
* {{#if commit.scope}}`{{commit.scope}}` {{/if}}{{text}}
|
|
7
|
-
{{/each}}
|
|
8
|
-
|
|
9
|
-
{{/each}}
|
|
10
|
-
{{/if}}
|
|
11
|
-
{{#each commitGroups}}
|
|
12
|
-
{{#if title}}
|
|
13
|
-
### {{title}}
|
|
14
|
-
{{/if}}
|
|
15
|
-
{{#each commits}}
|
|
16
|
-
{{> commit}}
|
|
17
|
-
|
|
18
|
-
{{/each}}
|
|
19
|
-
|
|
20
|
-
{{/each}}
|
|
21
|
-
{{> footer}}
|
package/src/preset/whatBump.js
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
export function createWhatBump(config) {
|
|
2
|
-
return function whatBump(commits) {
|
|
3
|
-
let level = 2
|
|
4
|
-
let breakings = 0
|
|
5
|
-
let features = 0
|
|
6
|
-
|
|
7
|
-
commits.forEach((commit) => {
|
|
8
|
-
if (commit.notes.length > 0) {
|
|
9
|
-
breakings += commit.notes.length
|
|
10
|
-
level = 0
|
|
11
|
-
}
|
|
12
|
-
else if (commit.type === 'feat' || commit.type === 'feature') {
|
|
13
|
-
features += 1
|
|
14
|
-
|
|
15
|
-
if (level === 2) {
|
|
16
|
-
level = 1
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
if (config?.preMajor && level < 2) {
|
|
22
|
-
level++
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
return {
|
|
26
|
-
level,
|
|
27
|
-
reason:
|
|
28
|
-
breakings === 1
|
|
29
|
-
? `There is ${breakings} BREAKING CHANGE and ${features} features`
|
|
30
|
-
: `There are ${breakings} BREAKING CHANGES and ${features} features`,
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
package/src/preset/writer.js
DELETED
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import compareFunc from 'compare-func'
|
|
2
|
-
import { DEFAULT_COMMIT_TYPES } from './constants.js'
|
|
3
|
-
import { main, commit, header, footer } from './templates/index.js'
|
|
4
|
-
|
|
5
|
-
const COMMIT_HASH_LENGTH = 7
|
|
6
|
-
const releaseAsRegex = /release-as:\s*\w*@?([0-9]+\.[0-9]+\.[0-9a-z]+(-[0-9a-z.]+)?)\s*/i
|
|
7
|
-
/**
|
|
8
|
-
* Handlebar partials for various property substitutions based on commit context.
|
|
9
|
-
*/
|
|
10
|
-
const owner = '{{#if this.owner}}{{~this.owner}}{{else}}{{~@root.owner}}{{/if}}'
|
|
11
|
-
const host = '{{~@root.host}}'
|
|
12
|
-
const repository = '{{#if this.repository}}{{~this.repository}}{{else}}{{~@root.repository}}{{/if}}'
|
|
13
|
-
|
|
14
|
-
export async function createWriterOpts(config) {
|
|
15
|
-
const finalConfig = {
|
|
16
|
-
types: DEFAULT_COMMIT_TYPES,
|
|
17
|
-
issueUrlFormat: '{{host}}/{{owner}}/{{repository}}/issues/{{id}}',
|
|
18
|
-
commitUrlFormat: '{{host}}/{{owner}}/{{repository}}/commit/{{hash}}',
|
|
19
|
-
compareUrlFormat: '{{host}}/{{owner}}/{{repository}}/compare/{{previousTag}}...{{currentTag}}',
|
|
20
|
-
userUrlFormat: '{{host}}/{{user}}',
|
|
21
|
-
issuePrefixes: ['#'],
|
|
22
|
-
...config,
|
|
23
|
-
}
|
|
24
|
-
const commitUrlFormat = expandTemplate(finalConfig.commitUrlFormat, {
|
|
25
|
-
host,
|
|
26
|
-
owner,
|
|
27
|
-
repository,
|
|
28
|
-
})
|
|
29
|
-
const compareUrlFormat = expandTemplate(finalConfig.compareUrlFormat, {
|
|
30
|
-
host,
|
|
31
|
-
owner,
|
|
32
|
-
repository,
|
|
33
|
-
})
|
|
34
|
-
const issueUrlFormat = expandTemplate(finalConfig.issueUrlFormat, {
|
|
35
|
-
host,
|
|
36
|
-
owner,
|
|
37
|
-
repository,
|
|
38
|
-
id: '{{this.issue}}',
|
|
39
|
-
prefix: '{{this.prefix}}',
|
|
40
|
-
})
|
|
41
|
-
const writerOpts = getWriterOpts(finalConfig)
|
|
42
|
-
|
|
43
|
-
writerOpts.mainTemplate = main
|
|
44
|
-
writerOpts.headerPartial = header
|
|
45
|
-
.replace(/{{compareUrlFormat}}/g, compareUrlFormat)
|
|
46
|
-
writerOpts.commitPartial = commit
|
|
47
|
-
.replace(/{{commitUrlFormat}}/g, commitUrlFormat)
|
|
48
|
-
.replace(/{{issueUrlFormat}}/g, issueUrlFormat)
|
|
49
|
-
writerOpts.footerPartial = footer
|
|
50
|
-
.replace(/{{compareUrlFormat}}/g, compareUrlFormat)
|
|
51
|
-
|
|
52
|
-
return writerOpts
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function getWriterOpts(config) {
|
|
56
|
-
const commitGroupOrder = config.types.flatMap(t => t.section).filter(t => t)
|
|
57
|
-
|
|
58
|
-
return {
|
|
59
|
-
finalizeContext: (context, _writerOpts, _filteredCommits, keyCommit) => {
|
|
60
|
-
if (keyCommit) {
|
|
61
|
-
const versionTagRegex = /tag:\s*([^,\s)]+)/i
|
|
62
|
-
const keyCommitTag = keyCommit.gitTags?.match(versionTagRegex)
|
|
63
|
-
if (keyCommitTag) {
|
|
64
|
-
context.currentTag = keyCommitTag[1]
|
|
65
|
-
const currentTagIndex = context.gitSemverTags.indexOf(context.currentTag)
|
|
66
|
-
context.previousTag = (currentTagIndex === -1) ? null : context.gitSemverTags[currentTagIndex + 1]
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
context.currentTag = context.newTag || null
|
|
71
|
-
context.previousTag = context.gitSemverTags[0] || null
|
|
72
|
-
}
|
|
73
|
-
return context
|
|
74
|
-
},
|
|
75
|
-
transform: (commit, context) => {
|
|
76
|
-
let discard = true
|
|
77
|
-
const issues = []
|
|
78
|
-
const entry = findTypeEntry(config.types, commit)
|
|
79
|
-
|
|
80
|
-
// Add an entry in the CHANGELOG if special Release-As footer
|
|
81
|
-
// is used:
|
|
82
|
-
if ((commit.footer && releaseAsRegex.test(commit.footer))
|
|
83
|
-
|| (commit.body && releaseAsRegex.test(commit.body))) {
|
|
84
|
-
discard = false
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const notes = commit.notes.map((note) => {
|
|
88
|
-
discard = false
|
|
89
|
-
|
|
90
|
-
return {
|
|
91
|
-
...note,
|
|
92
|
-
title: 'BREAKING CHANGES',
|
|
93
|
-
}
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
// breaking changes attached to any type are still displayed.
|
|
97
|
-
if (discard && (entry === undefined
|
|
98
|
-
|| entry.hidden)) {
|
|
99
|
-
return undefined
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const type = entry
|
|
103
|
-
? entry.section
|
|
104
|
-
: commit.type
|
|
105
|
-
const scope = commit.scope === '*'
|
|
106
|
-
? ''
|
|
107
|
-
: commit.scope
|
|
108
|
-
const shortHash = typeof commit.hash === 'string'
|
|
109
|
-
? commit.hash.substring(0, COMMIT_HASH_LENGTH)
|
|
110
|
-
: commit.shortHash
|
|
111
|
-
let { subject } = commit
|
|
112
|
-
|
|
113
|
-
if (typeof subject === 'string') {
|
|
114
|
-
// Issue URLs.
|
|
115
|
-
const issueRegEx = `(${config.issuePrefixes.join('|')})([a-z0-9]+)`
|
|
116
|
-
const re = new RegExp(issueRegEx, 'g')
|
|
117
|
-
|
|
118
|
-
subject = subject.replace(re, (_, prefix, issue) => {
|
|
119
|
-
issues.push(prefix + issue)
|
|
120
|
-
|
|
121
|
-
const url = expandTemplate(config.issueUrlFormat, {
|
|
122
|
-
host: context.host,
|
|
123
|
-
owner: context.owner,
|
|
124
|
-
repository: context.repository,
|
|
125
|
-
id: issue,
|
|
126
|
-
prefix,
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
return `[${prefix}${issue}](${url})`
|
|
130
|
-
})
|
|
131
|
-
// User URLs.
|
|
132
|
-
subject = subject.replace(/\B@([a-z0-9](?:-?[a-z0-9/]){0,38})/g, (_, user) => {
|
|
133
|
-
// TODO: investigate why this code exists.
|
|
134
|
-
if (user.includes('/')) {
|
|
135
|
-
return `@${user}`
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const usernameUrl = expandTemplate(config.userUrlFormat, {
|
|
139
|
-
host: context.host,
|
|
140
|
-
owner: context.owner,
|
|
141
|
-
repository: context.repository,
|
|
142
|
-
user,
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
return `[@${user}](${usernameUrl})`
|
|
146
|
-
})
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// remove references that already appear in the subject
|
|
150
|
-
const references = commit.references.filter(reference => !issues.includes(reference.prefix + reference.issue))
|
|
151
|
-
|
|
152
|
-
return {
|
|
153
|
-
notes,
|
|
154
|
-
type,
|
|
155
|
-
scope,
|
|
156
|
-
shortHash,
|
|
157
|
-
subject,
|
|
158
|
-
references,
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
groupBy: 'type',
|
|
162
|
-
// the groupings of commit messages, e.g., Features vs., Bug Fixes, are
|
|
163
|
-
// sorted based on their probable importance:
|
|
164
|
-
commitGroupsSort: (a, b) => {
|
|
165
|
-
const gRankA = commitGroupOrder.indexOf(a.title)
|
|
166
|
-
const gRankB = commitGroupOrder.indexOf(b.title)
|
|
167
|
-
|
|
168
|
-
return gRankA - gRankB
|
|
169
|
-
},
|
|
170
|
-
commitsSort: ['scope', 'subject'],
|
|
171
|
-
noteGroupsSort: 'title',
|
|
172
|
-
notesSort: compareFunc,
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function findTypeEntry(types, commit) {
|
|
177
|
-
const typeKey = (commit.revert ? 'revert' : commit.type || '').toLowerCase()
|
|
178
|
-
|
|
179
|
-
return types.find((entry) => {
|
|
180
|
-
if (entry.type !== typeKey) {
|
|
181
|
-
return false
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (entry.scope && entry.scope !== commit.scope) {
|
|
185
|
-
return false
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
return true
|
|
189
|
-
})
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// expand on the simple mustache-style templates supported in
|
|
193
|
-
// configuration (we may eventually want to use handlebars for this).
|
|
194
|
-
function expandTemplate(template, context) {
|
|
195
|
-
let expanded = template
|
|
196
|
-
|
|
197
|
-
Object.keys(context).forEach((key) => {
|
|
198
|
-
expanded = expanded.replace(new RegExp(`{{${key}}}`, 'g'), context[key])
|
|
199
|
-
})
|
|
200
|
-
return expanded
|
|
201
|
-
}
|