Skip to content

Commit

Permalink
🔀 Merge pull request #25
Browse files Browse the repository at this point in the history
Force version reset
  • Loading branch information
Sergei Orlov committed Jul 4, 2020
2 parents d21758d + 9c819b7 commit b738a24
Show file tree
Hide file tree
Showing 14 changed files with 144 additions and 83 deletions.
64 changes: 39 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ Check out the [roadmap for the project](https://github.com/priestine/versions/pr
- [Bump Minor](#bump-minor)
- [Bump Major](#bump-major)
- [Public](#public)
- [Prefix Reset](#prefix-reset)
- [No Trailing Zeroes](#no-trailing-zeroes)
- [Dry Run](#dry-run)
- [Show Changelog](#show-changelog)
- [Conventions](#conventions)
Expand Down Expand Up @@ -119,23 +121,25 @@ All options that accept `true` or `false` as a value are **false** by default.

### Overview

| Option | CLI Usage Example | Environment Usage Example | Default |
| --------------------------------- | -------------------------------------------- | ------------------------------------------------------------ | --------- |
| [Config File](#config-file) | **--config-file=PATH** | **PRIESTINE_VERSIONS_CONFIG_FILE**=PATH | `""` |
| [Token](#token) | **--token=\$SOME_TOKEN** | **PRIESTINE_VERSIONS_TOKEN**=\$SOME_TOKEN | `""` |
| [Repository](#repository) | **--repository=octocat/github** | **PRIESTINE_VERSIONS_REPOSITORY**=octocat/github | `""` |
| [Latest Version](#latest-version) | **--latest-version=0.0.0** | **PRIESTINE_VERSIONS_LATEST_VERSION**=0.0.0 | `""` |
| [Prefix](#prefix) | **--prefix=v** | **PRIESTINE_VERSIONS_PREFIX**=v | `""` |
| [Pre-Release](#pre-release) | **--pre-release=\$(git rev-parse HEAD)** | **PRIESTINE_VERSIONS_PRE_RELEAS**=\$(git rev-parse HEAD) | `""` |
| [Build Metadata](#build-metadata) | **--build-metadata=\$(date)** | **PRIESTINE_VERSIONS_BUILD_METADATA**=\$(date) | `""` |
| [Custom URL](#custom-url) | **--custom-url=https://api.mygh.com/repos/** | **PRIESTINE_VERSIONS_CUSTOM_URL**=https://api.mygh.com/repos | `""` |
| [Merges](#merges) | **--merges=\<include \| exclude \| only>** | **PRIESTINE_VERSIONS_MERGES**=\<include \| exclude \| only> | `exclude` |
| [Bump Patch](#bump-patch) | **--bump-patch**[=\<true \| false>] | **PRIESTINE_VERSIONS_BUMP_PATCH**=\<true \| false> | `false` |
| [Bump Minor](#bump-minor) | **--bump-minor**[=\<true \| false>] | **PRIESTINE_VERSIONS_BUMP_MINOR**=\<true \| false> | `false` |
| [Bump Major](#bump-major) | **--bump-patch**[=\<true \| false>] | **PRIESTINE_VERSIONS_BUMP_MAJOR**=\<true \| false> | `false` |
| [Public](#public) | **--public**[=\<true \| false>] | **PRIESTINE_VERSIONS_PUBLIC**=\<true \| false> | `false` |
| [Dry Run](#dry-run) | **--dry-run**[=\<true \| false>] | **PRIESTINE_VERSIONS_DRY_RUN**=\<true \| false> | `false` |
| [Show Changelog](#show-changelog) | **--show-changelog**[=\<true \| false>] | **PRIESTINE_VERSIONS_SHOW_CHANGELOG**=[=\<true \| false>] | `false` |
| Option | CLI Usage Example | Environment Usage Example | Default |
| ----------------------------------------- | -------------------------------------------- | ------------------------------------------------------------ | --------- |
| [Config File](#config-file) | **--config-file=PATH** | **PRIESTINE_VERSIONS_CONFIG_FILE**=PATH | `""` |
| [Token](#token) | **--token=\$SOME_TOKEN** | **PRIESTINE_VERSIONS_TOKEN**=\$SOME_TOKEN | `""` |
| [Repository](#repository) | **--repository=octocat/github** | **PRIESTINE_VERSIONS_REPOSITORY**=octocat/github | `""` |
| [Latest Version](#latest-version) | **--latest-version=0.0.0** | **PRIESTINE_VERSIONS_LATEST_VERSION**=0.0.0 | `""` |
| [Prefix](#prefix) | **--prefix=v** | **PRIESTINE_VERSIONS_PREFIX**=v | `""` |
| [Pre-Release](#pre-release) | **--pre-release=\$(git rev-parse HEAD)** | **PRIESTINE_VERSIONS_PRE_RELEAS**=\$(git rev-parse HEAD) | `""` |
| [Build Metadata](#build-metadata) | **--build-metadata=\$(date)** | **PRIESTINE_VERSIONS_BUILD_METADATA**=\$(date) | `""` |
| [Custom URL](#custom-url) | **--custom-url=https://api.mygh.com/repos/** | **PRIESTINE_VERSIONS_CUSTOM_URL**=https://api.mygh.com/repos | `""` |
| [Merges](#merges) | **--merges=\<include \| exclude \| only>** | **PRIESTINE_VERSIONS_MERGES**=\<include \| exclude \| only> | `exclude` |
| [Bump Patch](#bump-patch) | **--bump-patch**[=\<true \| false>] | **PRIESTINE_VERSIONS_BUMP_PATCH**=\<true \| false> | `false` |
| [Bump Minor](#bump-minor) | **--bump-minor**[=\<true \| false>] | **PRIESTINE_VERSIONS_BUMP_MINOR**=\<true \| false> | `false` |
| [Bump Major](#bump-major) | **--bump-patch**[=\<true \| false>] | **PRIESTINE_VERSIONS_BUMP_MAJOR**=\<true \| false> | `false` |
| [Public](#public) | **--public**[=\<true \| false>] | **PRIESTINE_VERSIONS_PUBLIC**=\<true \| false> | `false` |
| [Prefix Reset](#prefix-reset) | **--prefix-reset**[=\<true \| false>] | **PRIESTINE_VERSIONS_PREFIX_RESET**=\<true \| false> | `false` |
| [No Trailing Zeroes](#no-trailing-zeroes) | **--no-trailing-zeroes**[=\<true \| false>] | **PRIESTINE_VERSIONS_NO_TRAILING_ZEROES**=\<true \| false> | `false` |
| [Dry Run](#dry-run) | **--dry-run**[=\<true \| false>] | **PRIESTINE_VERSIONS_DRY_RUN**=\<true \| false> | `false` |
| [Show Changelog](#show-changelog) | **--show-changelog**[=\<true \| false>] | **PRIESTINE_VERSIONS_SHOW_CHANGELOG**=[=\<true \| false>] | `false` |

> With CLI options that accept **boolean** values, providing those values is **_optional_**. `--bump-patch` and `--bump-patch=true` are completely the same.
>
Expand Down Expand Up @@ -197,6 +201,14 @@ According to the Semantic Versioning specification, releases that have a MAJOR v

Applying this option is irreversible. This option is only applicable if you don't have releases with MAJOR version higher than **0**. Otherwise, your project is considered to have public API declared already and you cannot publish `0.x.x` versions anymore.

#### Prefix Reset

Setting this option to true will reset major version to **1** if the prefix changes. This option does not affect the versioning process if prefix is not provided. This option requires declaring public API. If major version was `0`, this option will force it to be set to `1`.

#### No Trailing Zeroes

Remove trailing zeroes in the new version, e.g. `14.0.0` -> `14` or `10.15.0` -> `10.15`. **NOTE**: this is not compliant with Semantic Versioning. This option may be useful for creating new versions under the scheme Apple uses for their software. Alternatively, it can be applied to prettify CalVer-like versions.

#### Dry Run

Execute the command but skip publishing the release. May be useful for debugging or just to check what version your application is going to have next.
Expand Down Expand Up @@ -284,40 +296,42 @@ Here is a JSON example with the default settings for @priestine/versions. You ca
"repository": "",
"latestVersion": "",
"prefix": "",
"merges": "exclude",
"buildMetadata": "",
"preRelease": "",
"buildMetadata": "",
"customUrl": "",
"merges": "exclude",
"bumpPatch": false,
"bumpMinor": false,
"bumpMajor": false,
"public": false,
"prefixReset": false,
"noTrailingZeroes": false,
"dryRun": false,
"showChangelog": false,
"conventions": [
{
"match": ["^:ambulance:", "^:bug:", "^:lock:"],
"bumps": "patch",
"groupTitleFormat": "\n\n## :bug: ∘ :ambulance: ∘ :lock: Fixes\n\n",
"groupTitleFormat": "\n\n## :bug: ∘ :ambulance: ∘ :lock: Fixes\n",
"groupDescription": "",
"itemDescriptionFormat": "- %commit.description% (%commit.abbrevHash%)",
"itemBodyFormat": "\n\n> %commit.body%\n\n",
"itemBodyFormat": "> %commit.body%\n",
},
{
"match": ["^:sparkles:"],
"bumps": "minor",
"groupTitleFormat": "\n\n## :sparkles: Features\n\n",
"groupTitleFormat": "\n\n## :sparkles: Features\n",
"groupDescription": "",
"itemDescriptionFormat": "- %commit.description% (%commit.abbrevHash%)",
"itemBodyFormat": "\n\n> %commit.body%\n\n",
"itemBodyFormat": "> %commit.body%\n",
},
{
"match": ["^:boom:"],
"bumps": "major",
"groupTitleFormat": "\n\n## :boom: Breaking Changes\n\n",
"groupTitleFormat": "\n\n## :boom: Breaking Changes\n",
"groupDescription": "",
"itemDescriptionFormat": "- %commit.description% (%commit.abbrevHash%)",
"itemBodyFormat": "\n\n> %commit.body%\n\n",
"itemBodyFormat": "> %commit.body%\n",
}
]
```
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"bitbucket"
],
"license": "MIT",
"homepage": "https://orlove.dev/repos/versions",
"homepage": "https://github.com/priestine/versions",
"bugs": {
"email": "orlove.dev@gmail.com",
"url": "https://github.com/priestine/versions/issues"
Expand Down
10 changes: 7 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,11 @@ ${({ g }) => g('--bump-patch')}[=<true|false>] Force bumping patch version
${({ g }) => g('--bump-minor')}[=<true|false>] Force bumping minor version
${({ g }) => g('--bump-major')}[=<true|false>] Force bumping major version
${({ g }) => g('--public')}[=<true|false>] Declare public API (allow bumping major versions)
${({ g }) => g('--prefix-reset')}[=<true|false>] Reset major version on prefix change
${({ g }) => g('--dry-run')}[=<true|false>] Skip publishing new release
${({ g }) => g('--debug')}[=<true|false>] Run the app in debug mode
--version Display current @priestine/versions version
--help Show usage help message (this one)
`
Expand Down Expand Up @@ -105,30 +107,32 @@ ExtendPipe.empty<IAppCtx, Partial<IAppCtx>>()
preRelease: '',
transport: 'github',
customUrl: '',
prefixReset: false,
noTrailingZeroes: false,
conventions: [
{
match: ['^:ambulance:', '^:bug:', '^:lock:'],
bumps: 'patch',
groupTitleFormat: '\n\n## :bug: ∘ :ambulance: ∘ :lock: Fixes\n',
groupDescription: '',
itemDescriptionFormat: '- %commit.description% (%commit.abbrevHash%)',
itemBodyFormat: '> %commit.body%',
itemBodyFormat: '> %commit.body%\n',
},
{
match: ['^:sparkles:'],
bumps: 'minor',
groupTitleFormat: '\n\n## :sparkles: Features\n',
groupDescription: '',
itemDescriptionFormat: '- %commit.description% (%commit.abbrevHash%)',
itemBodyFormat: '> %commit.body%',
itemBodyFormat: '> %commit.body%\n',
},
{
match: ['^:boom:'],
bumps: 'major',
groupTitleFormat: '\n\n## :boom: Breaking Changes\n',
groupDescription: '',
itemDescriptionFormat: '- %commit.description% (%commit.abbrevHash%)',
itemBodyFormat: '> %commit.body%',
itemBodyFormat: '> %commit.body%\n',
},
],
})
3 changes: 3 additions & 0 deletions src/pipes/make-new-version-pipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { makeNewVersion } from '../pure/make-new-version'
import { ExtendPipe } from '../utils/pipe'
import { addBuildMetadata } from '../pure/add-build-metadata'
import { addPrefix } from '../pure/add-prefix'
import { removeTrailingZeroes } from '../pure/remove-trailing-zeroes'

interface IDeps {
logSuccess: LogFunction
Expand All @@ -22,6 +23,8 @@ export const makeNewVersionPipe = ({ logSuccess, logInfo, logExitingWarning }: I
.pipeExtend(forceBumping({ key: 'bumpMajor', logInfo }))
.pipeTap(exitIfNoBumping({ logExitingWarning }))
.pipeExtend(makeNewVersion)
.pipeExtend(removeTrailingZeroes)
.pipeExtend(removeTrailingZeroes)
.pipeExtend(addPreRelease)
.pipeExtend(addBuildMetadata)
.pipeExtend(addPrefix)
Expand Down
4 changes: 2 additions & 2 deletions src/pure/force-bumping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export const forceBumping = ({ key, logInfo }: IDeps) => (ctx: Ctx) => ({
ctx.conventions.find((convention) => convention.bumps === key.slice(4).toLowerCase()),
).chain((convention) =>
Either.fromNullable(
convention.match.filter((match) =>
commits.some((commit) => new RegExp(match).test(commit.type)),
commits.filter((commit) =>
convention.match.some((match) => new RegExp(match).test(commit.type)),
),
).map(
tap((commits) => logInfo`${key.slice(4)} level changes: ${({ g }) => g(commits.length)}`),
Expand Down
13 changes: 3 additions & 10 deletions src/pure/getters/get-all-tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,12 @@ export const getAllTags = ({ execEither }: IDeps) => () => ({
// ------------------------------------------------------------------------------------------------

const bySemVer = (a: string, b: string): -1 | 0 | 1 => {
if (!/\d+.\d+.\d+/.test(a)) {
return 1
}

if (!/\d+.\d+.\d+/.test(b)) {
return -1
}

const aTuple: [number, number, number, string] = /(\d+)\.(\d+)\.(\d+)(.*)/
const aTuple: [number, number, number, string] = /(\d+)\.?(\d+)?\.?(\d+)?(.*)/
.exec(a)
?.slice(1, 5)
.map((n, i) => (i < 3 ? Number(n) : n)) as any
const bTuple: [number, number, number, string] = /(\d+)\.(\d+)\.(\d+)(.*)/

const bTuple: [number, number, number, string] = /(\d+)\.?(\d+)?\.?(\d+)?(.*)/
.exec(b)
?.slice(1, 5)
.map((n, i) => (i < 3 ? Number(n) : n)) as any
Expand Down
34 changes: 22 additions & 12 deletions src/pure/getters/get-latest-version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,27 @@ interface IDeps {
logWarning: LogFunction
}

type Ctx = Pick<IAppCtx, 'latestVersion' | 'allTags'>
type Ctx = Pick<IAppCtx, 'latestVersion' | 'allTags' | 'noTrailingZeroes'>

export const getLatestVersion = ({ logWarning }: IDeps) => ({ latestVersion, allTags }: Ctx) => ({
latestVersion: latestVersion
? latestVersion
: Either.fromNullable(allTags.find((tag) => /^(\w+)?\d+\.\d+\.\d+$/.test(tag)))
.leftMap(
() => logWarning`Could not find previous semantic versions. Using ${({ y }) => y('0.0.0')}.`,
)
.fold(
() => '0.0.0',
(latestVersion) => latestVersion,
),
export const getLatestVersion = ({ logWarning }: IDeps) => ({
latestVersion,
allTags,
noTrailingZeroes,
}: Ctx) => ({
latestVersion:
latestVersion ||
Either.fromNullable(
allTags.find((tag) =>
noTrailingZeroes
? /^(\w+)?\d+\.?(\d+)?\.?(\d+)?$/.test(tag)
: /^(\w+)?\d+\.\d+\.\d+$/.test(tag),
),
)
.leftMap(
() => logWarning`Could not find previous semantic versions. Using ${({ y }) => y('0.0.0')}.`,
)
.fold(
() => '0.0.0',
(latestVersion) => latestVersion,
),
})
27 changes: 17 additions & 10 deletions src/pure/make-changelog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,20 @@ const prettifyCommit = (convention: IConvention) => (commit: IRawCommit): string
.replace('%commit.hash%', commit.hash)
.replace('%commit.author.email%', commit.author.email)
.replace('%commit.author.name%', commit.author.name)
.concat(
commit.body
? '\n\n'.concat(
convention.itemBodyFormat.replace(
'%commit.body%',
commit.body.split(', ').filter(Boolean).join(', '),
),
)
: '',
)
.concat(prettifyCommitBody(commit.body, convention.itemBodyFormat))

const prettifyCommitBody = (commitBody: string, bodyFormat: string) => {
const cleanCommitBody = commitBody
.split(', ')
.filter(filterOutIssueReferences)
.filter(Boolean)
.join(', ')

return cleanCommitBody ? '\n\n'.concat(bodyFormat.replace('%commit.body%', cleanCommitBody)) : ''
}

const filterOutIssueReferences = (bodyLine: string) =>
!/clos(e|ed|es|ing)\s.*(#|http)/i.test(bodyLine) &&
!/resolv(e|ed|es|ing)\s.*(#|http)/i.test(bodyLine) &&
!/fix(e|ed|es|ing)\s.*(#|http)/i.test(bodyLine) &&
!/implement(ed|es|ing)\s.*(#|http)/i.test(bodyLine)
6 changes: 5 additions & 1 deletion src/pure/make-new-version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@ import type { BumpKey } from '../types/common-types'
import { Either } from '../utils/either'
import { extractVersionTuple } from '../utils/helpers'

type Ctx = Pick<IAppCtx, 'latestVersion' | 'public' | BumpKey>
type Ctx = Pick<IAppCtx, 'latestVersion' | 'public' | 'prefixReset' | 'prefix' | BumpKey>

export const makeNewVersion = ({
latestVersion,
public: isPublic,
prefixReset,
prefix,
bumpPatch,
bumpMinor,
bumpMajor,
}: Ctx) => ({
newVersion: Either.fromNullable(extractVersionTuple(latestVersion))
.map((tuple) => tuple.slice(1, 4))
.map((tuple) => tuple.map(Number))
.map((tuple) => tuple.map((x) => (Number.isNaN(x) ? 0 : x)))
.map(([major, minor, patch]) => [major, minor, bumpPatch ? patch + 1 : patch])
.map(([major, minor, patch]) => (bumpMinor ? [major, minor + 1, 0] : [major, minor, patch]))
.map(([major, minor, patch]) =>
Expand All @@ -24,6 +27,7 @@ export const makeNewVersion = ({
? [major, bumpMajor ? minor : minor + 1, 0]
: [major, minor, patch],
)
.map((result) => (prefixReset && !latestVersion.startsWith(prefix) ? [1, 0, 0] : result))
.map((tuple) => tuple.join('.'))
.fold(
() => `${isPublic ? '1.0' : '0.1'}.0`,
Expand Down
22 changes: 11 additions & 11 deletions src/pure/normalizers/normalize-public.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import type { IAppCtx } from '../../types/app-ctx'
import { Either } from '../../utils/either'
import { extractVersionTuple } from '../../utils/helpers'

type Ctx = Pick<IAppCtx, 'latestVersion' | 'public'>
type Ctx = Pick<IAppCtx, 'latestVersion' | 'public' | 'prefixReset'>

export const validatePublic = ({ latestVersion, public: isPublic }: Ctx) => ({
public: isPublic
? isPublic
: Either.fromNullable(extractVersionTuple(latestVersion))
.map(([_, major]) => major)
.map(Number)
.fold(
() => isPublic,
(major) => major > 0,
),
export const validatePublic = ({ latestVersion, public: isPublic, prefixReset }: Ctx) => ({
public:
isPublic ||
Either.fromNullable(extractVersionTuple(latestVersion))
.map(([_, __, major]) => major)
.map(Number)
.fold(
() => prefixReset,
(major) => prefixReset || major > 0,
),
})
9 changes: 9 additions & 0 deletions src/pure/remove-trailing-zeroes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { IAppCtx } from '../types/app-ctx'

export const removeTrailingZeroes = ({
newVersion,
noTrailingZeroes,
}: Pick<IAppCtx, 'newVersion' | 'noTrailingZeroes'>) => ({
newVersion:
noTrailingZeroes && newVersion.endsWith('.0') ? newVersion.replace(/\.0$/, '') : newVersion,
})
Loading

0 comments on commit b738a24

Please sign in to comment.