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.
Files changed (42) hide show
  1. package/dist/cli.js +64 -0
  2. package/dist/index.d.ts +231 -0
  3. package/dist/index.js +652 -0
  4. package/package.json +31 -50
  5. package/src/cli.js +0 -6
  6. package/src/commands.js +0 -176
  7. package/src/defaults.js +0 -60
  8. package/src/index.js +0 -75
  9. package/src/lib/checkpoint.js +0 -23
  10. package/src/lib/configuration.js +0 -35
  11. package/src/lib/detect-package-manager.js +0 -52
  12. package/src/lib/format-commit-message.js +0 -4
  13. package/src/lib/latest-semver-tag.js +0 -34
  14. package/src/lib/lifecycles/bump.js +0 -242
  15. package/src/lib/lifecycles/changelog.js +0 -106
  16. package/src/lib/lifecycles/commit.js +0 -67
  17. package/src/lib/lifecycles/tag.js +0 -61
  18. package/src/lib/print-error.js +0 -15
  19. package/src/lib/run-exec.js +0 -20
  20. package/src/lib/run-execFile.js +0 -20
  21. package/src/lib/run-lifecycle-script.js +0 -18
  22. package/src/lib/stringify-package.js +0 -34
  23. package/src/lib/updaters/index.js +0 -130
  24. package/src/lib/updaters/types/csproj.js +0 -13
  25. package/src/lib/updaters/types/gradle.js +0 -16
  26. package/src/lib/updaters/types/json.js +0 -25
  27. package/src/lib/updaters/types/maven.js +0 -43
  28. package/src/lib/updaters/types/openapi.js +0 -15
  29. package/src/lib/updaters/types/plain-text.js +0 -7
  30. package/src/lib/updaters/types/python.js +0 -30
  31. package/src/lib/updaters/types/yaml.js +0 -15
  32. package/src/lib/write-file.js +0 -6
  33. package/src/preset/constants.js +0 -16
  34. package/src/preset/index.js +0 -19
  35. package/src/preset/parser.js +0 -11
  36. package/src/preset/templates/commit.hbs +0 -19
  37. package/src/preset/templates/footer.hbs +0 -10
  38. package/src/preset/templates/header.hbs +0 -10
  39. package/src/preset/templates/index.js +0 -13
  40. package/src/preset/templates/main.hbs +0 -21
  41. package/src/preset/whatBump.js +0 -33
  42. package/src/preset/writer.js +0 -201
@@ -1,242 +0,0 @@
1
- import checkpoint from '../checkpoint.js'
2
- import { Bumper } from 'conventional-recommended-bump'
3
- import fs from 'fs'
4
- import DotGitignore from 'dotgitignore'
5
- import path from 'path'
6
- import runLifecycleScript from '../run-lifecycle-script.js'
7
- import semver from 'semver'
8
- import writeFile from '../write-file.js'
9
- import { resolveUpdaterObjectFromArgument } from '../updaters/index.js'
10
- let configsToUpdate = {}
11
- const sanitizeQuotesRegex = /['"]+/g
12
-
13
- async function Bump(args, newVersion) {
14
- // reset the cache of updated config files each
15
- // time we perform the version bump step.
16
- configsToUpdate = {}
17
-
18
- if (
19
- args.releaseAs
20
- && !(['major', 'minor', 'patch'].includes(args.releaseAs.toLowerCase()) || semver.valid(args.releaseAs))
21
- ) {
22
- throw new Error('releaseAs must be one of \'major\', \'minor\' or \'patch\', or a valid semvar version.')
23
- }
24
-
25
- await runLifecycleScript(args, 'prerelease')
26
- const stdout = await runLifecycleScript(args, 'prebump')
27
- if (stdout?.trim().length) {
28
- const prebumpString = stdout.trim().replace(sanitizeQuotesRegex, '')
29
- if (semver.valid(prebumpString)) args.releaseAs = prebumpString
30
- }
31
- updateConfigs(args, newVersion)
32
- await runLifecycleScript(args, 'postbump')
33
- return newVersion
34
- }
35
-
36
- Bump.getUpdatedConfigs = function () {
37
- return configsToUpdate
38
- }
39
-
40
- /**
41
- * Get the new version number
42
- * @param args
43
- * @param version
44
- * @returns Promise<string>
45
- */
46
- export async function getNewVersion(args, version) {
47
- let newVersion = version
48
- if (semver.valid(args.releaseAs)) {
49
- const releaseAs = new semver.SemVer(args.releaseAs)
50
- if (
51
- isString(args.prerelease)
52
- && releaseAs.prerelease.length
53
- && releaseAs.prerelease.slice(0, -1).join('.') !== args.prerelease
54
- ) {
55
- // If both releaseAs and the prerelease identifier are supplied, they must match. The behavior
56
- // for a mismatch is undefined, so error out instead.
57
- throw new Error('releaseAs and prerelease have conflicting prerelease identifiers')
58
- }
59
- else if (isString(args.prerelease) && releaseAs.prerelease.length) {
60
- newVersion = releaseAs.version
61
- }
62
- else if (isString(args.prerelease)) {
63
- newVersion = `${releaseAs.major}.${releaseAs.minor}.${releaseAs.patch}-${args.prerelease}.0`
64
- }
65
- else {
66
- newVersion = releaseAs.version
67
- }
68
-
69
- // Check if the previous version is the same version and prerelease, and increment if so
70
- if (
71
- isString(args.prerelease)
72
- && ['prerelease', null].includes(semver.diff(version, newVersion))
73
- && semver.lte(newVersion, version)
74
- ) {
75
- newVersion = semver.inc(version, 'prerelease', args.prerelease)
76
- }
77
-
78
- // Append any build info from releaseAs
79
- newVersion = semvarToVersionStr(newVersion, releaseAs.build)
80
- }
81
- else {
82
- const release = await bumpVersion(args.releaseAs, version, args)
83
- const releaseType = getReleaseType(args.prerelease, release.releaseType, version)
84
-
85
- newVersion = semver.inc(version, releaseType, args.prerelease)
86
- }
87
- return newVersion
88
- }
89
-
90
- /**
91
- * Convert a semver object to a full version string including build metadata
92
- * @param {string} semverVersion The semvar version string
93
- * @param {string[]} semverBuild An array of the build metadata elements, to be joined with '.'
94
- * @returns {string}
95
- */
96
- function semvarToVersionStr(semverVersion, semverBuild) {
97
- return [semverVersion, semverBuild.join('.')].filter(Boolean).join('+')
98
- }
99
-
100
- function getReleaseType(prerelease, expectedReleaseType, currentVersion) {
101
- if (isString(prerelease)) {
102
- if (isInPrerelease(currentVersion)) {
103
- if (
104
- shouldContinuePrerelease(currentVersion, expectedReleaseType)
105
- || getTypePriority(getCurrentActiveType(currentVersion)) > getTypePriority(expectedReleaseType)
106
- ) {
107
- return 'prerelease'
108
- }
109
- }
110
-
111
- return 'pre' + expectedReleaseType
112
- }
113
- else {
114
- return expectedReleaseType
115
- }
116
- }
117
-
118
- function isString(val) {
119
- return typeof val === 'string'
120
- }
121
-
122
- /**
123
- * if a version is currently in pre-release state,
124
- * and if it current in-pre-release type is same as expect type,
125
- * it should continue the pre-release with the same type
126
- *
127
- * @param version
128
- * @param expectType
129
- * @return {boolean}
130
- */
131
- function shouldContinuePrerelease(version, expectType) {
132
- return getCurrentActiveType(version) === expectType
133
- }
134
-
135
- function isInPrerelease(version) {
136
- return Array.isArray(semver.prerelease(version))
137
- }
138
-
139
- const TypeList = ['major', 'minor', 'patch'].reverse()
140
-
141
- /**
142
- * extract the in-pre-release type in target version
143
- *
144
- * @param version
145
- * @return {string}
146
- */
147
- function getCurrentActiveType(version) {
148
- const typelist = TypeList
149
- for (let i = 0; i < typelist.length; i++) {
150
- if (semver[typelist[i]](version)) {
151
- return typelist[i]
152
- }
153
- }
154
- }
155
-
156
- /**
157
- * calculate the priority of release type,
158
- * major - 2, minor - 1, patch - 0
159
- *
160
- * @param type
161
- * @return {number}
162
- */
163
- function getTypePriority(type) {
164
- return TypeList.indexOf(type)
165
- }
166
-
167
- async function bumpVersion(releaseAs, currentVersion, args) {
168
- if (releaseAs) {
169
- return {
170
- releaseType: releaseAs,
171
- }
172
- }
173
- else {
174
- const recommendation = await getRecommendedBump(args, currentVersion)
175
- if (recommendation) {
176
- return recommendation
177
- }
178
- else {
179
- throw new Error('No recommendation found')
180
- }
181
- }
182
- }
183
-
184
- async function getRecommendedBump(args, currentVersion) {
185
- const bumper = new Bumper(args.path)
186
- bumper.loadPreset({
187
- preMajor: semver.lt(currentVersion, '1.0.0'),
188
- ...args.preset,
189
- })
190
- bumper.tag({
191
- tagPrefix: args.tagPrefix,
192
- lernaPackage: args.lernaPackage,
193
- })
194
- bumper.commits({}, args.parserOpts)
195
- const recommendation = await bumper.bump()
196
- return recommendation
197
- }
198
-
199
- /**
200
- * attempt to update the version number in provided `bumpFiles`
201
- * @param args config object
202
- * @param newVersion version number to update to.
203
- * @return void
204
- */
205
- function updateConfigs(args, newVersion) {
206
- const dotgit = DotGitignore()
207
- args.bumpFiles.forEach(async function (bumpFile) {
208
- const updater = await resolveUpdaterObjectFromArgument(bumpFile)
209
- if (!updater) {
210
- return
211
- }
212
- const configPath = path.resolve(process.cwd(), updater.filename)
213
- try {
214
- if (dotgit.ignore(updater.filename)) {
215
- console.debug(`Not updating file '${updater.filename}', as it is ignored in Git`)
216
- return
217
- }
218
- const stat = fs.lstatSync(configPath)
219
-
220
- if (!stat.isFile()) {
221
- console.debug(`Not updating '${updater.filename}', as it is not a file`)
222
- return
223
- }
224
- const contents = fs.readFileSync(configPath, 'utf8')
225
- const newContents = updater.updater.writeVersion(contents, newVersion)
226
- const realNewVersion = updater.updater.readVersion(newContents)
227
- checkpoint(args, 'bumping version in ' + updater.filename + ' from %s to %s', [
228
- updater.updater.readVersion(contents),
229
- realNewVersion,
230
- ])
231
- writeFile(args, configPath, newContents)
232
- // flag any config files that we modify the version # for
233
- // as having been updated.
234
- configsToUpdate[updater.filename] = true
235
- }
236
- catch (err) {
237
- if (err.code !== 'ENOENT') console.warn(err.message)
238
- }
239
- })
240
- }
241
-
242
- export default Bump
@@ -1,106 +0,0 @@
1
- import chalk from 'chalk'
2
- import checkpoint from '../checkpoint.js'
3
- import conventionalChangelog from 'conventional-changelog'
4
- import fs from 'fs'
5
- import runLifecycleScript from '../run-lifecycle-script.js'
6
- import writeFile from '../write-file.js'
7
- const START_OF_LAST_RELEASE_PATTERN = /(^#.*?[0-9]+\.[0-9]+\.[0-9]+|<a name=)/m
8
-
9
- async function Changelog(args, newVersion) {
10
- await runLifecycleScript(args, 'prechangelog')
11
- await outputChangelog(args, newVersion)
12
- await runLifecycleScript(args, 'postchangelog')
13
- }
14
-
15
- Changelog.START_OF_LAST_RELEASE_PATTERN = START_OF_LAST_RELEASE_PATTERN
16
-
17
- export default Changelog
18
-
19
- /**
20
- * Front matter is only extracted and therefore retained in final output where Changelog "header" begins with #Changelog,
21
- * e.g. meets Standard-Version (last release) or relion(current) format
22
- */
23
- function extractFrontMatter(oldContent) {
24
- const headerStart = oldContent.indexOf('# Changelog')
25
- return headerStart !== -1 || headerStart !== 0
26
- ? oldContent.substring(0, headerStart)
27
- : ''
28
- }
29
-
30
- /**
31
- * find the position of the last release and remove header
32
- */
33
- function extractChangelogBody(oldContent) {
34
- const oldContentStart = oldContent.search(START_OF_LAST_RELEASE_PATTERN)
35
- return oldContentStart !== -1
36
- ? oldContent.substring(oldContentStart)
37
- : oldContent
38
- }
39
-
40
- function outputChangelog(args) {
41
- return new Promise((resolve, reject) => {
42
- createIfMissing(args)
43
- const header = args.preset.header
44
-
45
- const oldContent
46
- = args.dryRun || args.releaseCount === 0
47
- ? ''
48
- : fs.readFileSync(args.infile, 'utf-8')
49
-
50
- const oldContentBody = extractChangelogBody(oldContent)
51
-
52
- const changelogFrontMatter = extractFrontMatter(oldContent)
53
-
54
- let content = ''
55
- const changelogStream = conventionalChangelog(
56
- {
57
- preset: args.preset,
58
- tagPrefix: args.tagPrefix,
59
- releaseCount: args.releaseCount,
60
- ...(args.verbose
61
- ? {
62
- debug: console.info.bind(console, 'conventional-recommended-bump'),
63
- }
64
- : {}),
65
- },
66
- args.context,
67
- { merges: null, path: args.path, showSignature: false },
68
- args.parserOpts,
69
- args.writerOpts,
70
- ).on('error', function (err) {
71
- return reject(err)
72
- })
73
-
74
- changelogStream.on('data', function (buffer) {
75
- content += buffer.toString()
76
- })
77
-
78
- changelogStream.on('end', function () {
79
- checkpoint(args, 'outputting changes to %s', [args.infile])
80
- if (args.dryRun)
81
- console.info(`\n---\n${chalk.gray(content.trim())}\n---\n`)
82
- else
83
- writeFile(
84
- args,
85
- args.infile,
86
- changelogFrontMatter
87
- + header
88
- + (content + oldContentBody).replace(/\n+$/, '\n'),
89
- )
90
- return resolve()
91
- })
92
- })
93
- }
94
-
95
- function createIfMissing(args) {
96
- try {
97
- fs.accessSync(args.infile, fs.F_OK)
98
- }
99
- catch (err) {
100
- if (err.code === 'ENOENT') {
101
- checkpoint(args, 'created %s', [args.infile])
102
- args.outputUnreleased = true
103
- writeFile(args, args.infile, '\n')
104
- }
105
- }
106
- }
@@ -1,67 +0,0 @@
1
- import bump from '../lifecycles/bump.js'
2
- import checkpoint from '../checkpoint.js'
3
- import formatCommitMessage from '../format-commit-message.js'
4
- import path from 'path'
5
- import runExecFile from '../run-execFile.js'
6
- import runLifecycleScript from '../run-lifecycle-script.js'
7
-
8
- export default async function (args, newVersion) {
9
- const message = await runLifecycleScript(args, 'precommit')
10
- if (message && message.length) args.preset.releaseCommitMessageFormat = message
11
- await execCommit(args, newVersion)
12
- await runLifecycleScript(args, 'postcommit')
13
- }
14
-
15
- async function execCommit(args) {
16
- let msg = 'committing %s'
17
- let paths = []
18
- const verify = args.verify === false || args.n ? ['--no-verify'] : []
19
- const sign = args.sign ? ['-S'] : []
20
- const signoff = args.signoff ? ['--signoff'] : []
21
- const toAdd = []
22
-
23
- // only start with a pre-populated paths list when CHANGELOG processing is not skipped
24
- if (args.changelog) {
25
- paths = [args.infile]
26
- toAdd.push(args.infile)
27
- }
28
-
29
- // commit any of the config files that we've updated
30
- // the version # for.
31
- Object.keys(bump.getUpdatedConfigs()).forEach(function (p) {
32
- paths.unshift(p)
33
- toAdd.push(path.relative(process.cwd(), p))
34
-
35
- // account for multiple files in the output message
36
- if (paths.length > 1) {
37
- msg += ' and %s'
38
- }
39
- })
40
-
41
- if (args.commitAll) {
42
- msg += ' and %s'
43
- paths.push('all staged files')
44
- }
45
-
46
- checkpoint(args, msg, paths)
47
-
48
- // nothing to do, exit without commit anything
49
- if (
50
- !args.commitAll
51
- && !args.changelog
52
- && !args.bump
53
- && toAdd.length === 0
54
- ) {
55
- return
56
- }
57
-
58
- await runExecFile(args, 'git', ['add'].concat(toAdd))
59
- await runExecFile(
60
- args,
61
- 'git',
62
- ['commit'].concat(verify, sign, signoff, args.commitAll ? [] : toAdd, [
63
- '-m',
64
- `${formatCommitMessage(args)}`,
65
- ]),
66
- )
67
- }
@@ -1,61 +0,0 @@
1
- import bump from '../lifecycles/bump.js'
2
- import chalk from 'chalk'
3
- import checkpoint from '../checkpoint.js'
4
- import figures from 'figures'
5
- import formatCommitMessage from '../format-commit-message.js'
6
- import runExecFile from '../run-execFile.js'
7
- import runLifecycleScript from '../run-lifecycle-script.js'
8
- import { detectPMByLockFile } from '../detect-package-manager.js'
9
-
10
- export default async function (newVersion, pkgPrivate, args) {
11
- await runLifecycleScript(args, 'pretag')
12
- await execTag(newVersion, pkgPrivate, args)
13
- await runLifecycleScript(args, 'posttag')
14
- }
15
-
16
- async function detectPublishHint() {
17
- const npmClientName = await detectPMByLockFile()
18
- const publishCommand = 'publish'
19
- return `${npmClientName} ${publishCommand}`
20
- }
21
-
22
- async function execTag(newVersion, pkgPrivate, args) {
23
- const tagOption = []
24
- if (args.sign) {
25
- tagOption.push('-s')
26
- }
27
- else {
28
- tagOption.push('-a')
29
- }
30
- if (args.tagForce) {
31
- tagOption.push('-f')
32
- }
33
- checkpoint(args, 'tagging release %s%s', [args.tagPrefix, newVersion])
34
- await runExecFile(args, 'git', [
35
- 'tag',
36
- ...tagOption,
37
- args.tagPrefix + newVersion,
38
- '-m',
39
- `${formatCommitMessage(args)}`,
40
- ])
41
- const currentBranch = await runExecFile('', 'git', [
42
- 'rev-parse',
43
- '--abbrev-ref',
44
- 'HEAD',
45
- ])
46
- let message = 'git push --follow-tags origin ' + currentBranch.trim()
47
- if (pkgPrivate !== true && bump.getUpdatedConfigs()['package.json']) {
48
- const npmPublishHint = args.npmPublishHint || (await detectPublishHint())
49
- message += ` && ${npmPublishHint}`
50
- if (args.prerelease !== undefined) {
51
- if (args.prerelease === '') {
52
- message += ' --tag prerelease'
53
- }
54
- else {
55
- message += ' --tag ' + args.prerelease
56
- }
57
- }
58
- }
59
-
60
- checkpoint(args, 'Run `%s` to publish', [message], chalk.blue(figures.info))
61
- }
@@ -1,15 +0,0 @@
1
- import chalk from 'chalk'
2
-
3
- export default function (args, msg, opts) {
4
- if (!args.silent) {
5
- opts = Object.assign(
6
- {
7
- level: 'error',
8
- color: 'red',
9
- },
10
- opts,
11
- )
12
-
13
- console[opts.level](chalk[opts.color](msg))
14
- }
15
- }
@@ -1,20 +0,0 @@
1
- import { promisify } from 'util'
2
- import printError from './print-error.js'
3
- import { exec as execCb } from 'child_process'
4
-
5
- const exec = promisify(execCb)
6
-
7
- export default async function (args, cmd) {
8
- if (args.dryRun) return
9
- try {
10
- const { stderr, stdout } = await exec(cmd)
11
- // If exec returns content in stderr, but no error, print it as a warning
12
- if (stderr) printError(args, stderr, { level: 'warn', color: 'yellow' })
13
- return stdout
14
- }
15
- catch (error) {
16
- // If exec returns an error, print it and exit with return code 1
17
- printError(args, error.stderr || error.message)
18
- throw error
19
- }
20
- }
@@ -1,20 +0,0 @@
1
- import { promisify } from 'util'
2
- import printError from './print-error.js'
3
- import { execFile as execFileCb } from 'child_process'
4
-
5
- const execFile = promisify(execFileCb)
6
-
7
- export default async function (args, cmd, cmdArgs) {
8
- if (args.dryRun) return
9
- try {
10
- const { stderr, stdout } = await execFile(cmd, cmdArgs)
11
- // If execFile returns content in stderr, but no error, print it as a warning
12
- if (stderr) printError(args, stderr, { level: 'warn', color: 'yellow' })
13
- return stdout
14
- }
15
- catch (error) {
16
- // If execFile returns an error, print it and exit with return code 1
17
- printError(args, error.stderr || error.message)
18
- throw error
19
- }
20
- }
@@ -1,18 +0,0 @@
1
- import chalk from 'chalk'
2
- import checkpoint from './checkpoint.js'
3
- import figures from 'figures'
4
- import runExec from './run-exec.js'
5
-
6
- export default function (args, hookName) {
7
- const scripts = args.scripts
8
- if (!scripts || !scripts[hookName]) return Promise.resolve()
9
- const command = scripts[hookName]
10
- checkpoint(args, 'Running lifecycle script "%s"', [hookName])
11
- checkpoint(
12
- args,
13
- '- execute command: "%s"',
14
- [command],
15
- chalk.blue(figures.info),
16
- )
17
- return runExec(args, command)
18
- }
@@ -1,34 +0,0 @@
1
- /*
2
- Copyright npm, Inc
3
-
4
- Permission to use, copy, modify, and/or distribute this software for any
5
- purpose with or without fee is hereby granted, provided that the above
6
- copyright notice and this permission notice appear in all copies.
7
-
8
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
- ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
- ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
-
16
- https://github.com/npm/stringify-package/blob/main/LICENSE
17
- */
18
-
19
- 'use strict'
20
-
21
- const DEFAULT_INDENT = 2
22
- const CRLF = '\r\n'
23
- const LF = '\n'
24
-
25
- export default function stringifyPackage(data, indent, newline) {
26
- indent = indent || (indent === 0 ? 0 : DEFAULT_INDENT)
27
- const json = JSON.stringify(data, null, indent)
28
-
29
- if (newline === CRLF) {
30
- return json.replace(/\n/g, CRLF) + CRLF
31
- }
32
-
33
- return json + LF
34
- }