UNPKG

@henriquehbr/tagit

Version:

A git tag bumper that strictly follows semver

121 lines (96 loc) 3.52 kB
#!/usr/bin/env node import minimist from "minimist" import semverInc from "semver/functions/inc.js" import semverMajor from "semver/functions/major.js" import showHelp from "./showHelp.js" import showVersion from "./showVersion.js" import getLatestGitTag from "./getLatestGitTag.js" import getCommitsSinceTag from "./getCommitsSinceTag.js" import validateCommits from "./validateCommits.js" import isVersionPreRelease from "./isVersionPreRelease.js" const argsWithoutExecutable = process.argv.slice(2) const args = minimist(argsWithoutExecutable) const flags = { p: args.p, f: args.f, forceVersion: args.forceVersion, v: args.v, version: args.version, h: args.h === true, help: args.help === true } const knownFlags = Object.keys(flags) const passedFlags = Object.keys(args).filter(flag => flag !== "_") const unknownFlags = passedFlags.filter(flag => !knownFlags.includes(flag)) const hasUnknownFlags = unknownFlags.length > 0 // defines who will be displayed in case both "-h" and "-v" are passed const [shouldShowHelpOrVersion] = passedFlags.filter(flag => /^(h(elp)?|v(ersion)?)$/.test(flag) ) const shouldShowHelp = (flags.h || flags.help || hasUnknownFlags) && shouldShowHelpOrVersion === "h" if (shouldShowHelp) { if (hasUnknownFlags) { const formattedUnknownFlags = unknownFlags.join(", ") throw new Error(`unknown option: ${formattedUnknownFlags}\n`) } showHelp() process.exit(0) } const shouldShowVersion = (flags.v || flags.version) && shouldShowHelpOrVersion === "v" if (shouldShowVersion) { showVersion() process.exit(0) } const forcedVersion = args.f || args.forcedVersion if (forcedVersion) { const prefixedForcedVersion = "v" + forcedVersion console.log(prefixedForcedVersion) process.exit(0) } const latestGitTag = getLatestGitTag() if (!latestGitTag) { console.log("v0.1.0") process.exit(0) } const commits = getCommitsSinceTag(latestGitTag) const commitArray = commits.split("\n") const validCommits = validateCommits(commitArray) const hasCommitsSinceLastTag = validCommits.length > 0 if (!hasCommitsSinceLastTag) { throw new Error("no elligible commits for a release") } const validPreReleaseTypes = ["alpha", "beta", "rc"] const shouldBecomePreRelease = validPreReleaseTypes.includes(args.p) const shouldIncrementPreRelease = !shouldBecomePreRelease && isVersionPreRelease(latestGitTag) if (shouldIncrementPreRelease) { const isLeavingPreRelease = args.p === "stable" const bumpType = isLeavingPreRelease ? "patch" : "prerelease" const newVersion = semverInc(latestGitTag, bumpType, args.p) const prefixedNewVersion = "v" + newVersion console.log(prefixedNewVersion) process.exit(0) } const breakingChangesCommitRegex = /^[a-z]+(\([\S]+\))?!: / const featureCommitRegex = /^feat(\([\S]+\))?: / const shouldBumpMajor = validCommits.some(commit => breakingChangesCommitRegex.test(commit) ) const shouldBumpMinor = validCommits.some(commit => featureCommitRegex.test(commit) ) const isVersionStable = semverMajor(latestGitTag) !== 0 const bumpTypes = { major: shouldBumpMajor && isVersionStable, minor: shouldBumpMinor || (shouldBumpMajor && !isVersionStable), patch: true } const iterableBumpTypes = Object.entries(bumpTypes) const [bumpType] = iterableBumpTypes.find(([_, bumpCondition]) => bumpCondition) const possiblyPrefixedBumpType = (shouldBecomePreRelease ? "pre" : "") + bumpType const newVersion = semverInc(latestGitTag, possiblyPrefixedBumpType, args.p) const prefixedNewVersion = "v" + newVersion console.log(prefixedNewVersion)