Socket
Socket
Sign inDemoInstall

standard-version

Package Overview
Dependencies
168
Maintainers
4
Versions
42
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 4.1.0-candidate.0 to 4.1.0-candidate.1

lib/format-commit-message.js

47

command.js

@@ -9,4 +9,3 @@ var defaults = require('./defaults')

requiresArg: true,
string: true,
global: true
string: true
})

@@ -16,4 +15,3 @@ .option('prerelease', {

describe: 'make a pre-release with optional option value to specify a tag id',
string: true,
global: true
string: true
})

@@ -23,4 +21,3 @@ .option('infile', {

describe: 'Read the CHANGELOG from this file',
default: defaults.infile,
global: true
default: defaults.infile
})

@@ -31,4 +28,3 @@ .option('message', {

type: 'string',
default: defaults.message,
global: true
default: defaults.message
})

@@ -39,4 +35,3 @@ .option('first-release', {

type: 'boolean',
default: defaults.firstRelease,
global: true
default: defaults.firstRelease
})

@@ -47,4 +42,3 @@ .option('sign', {

type: 'boolean',
default: defaults.sign,
global: true
default: defaults.sign
})

@@ -55,4 +49,3 @@ .option('no-verify', {

type: 'boolean',
default: defaults.noVerify,
global: true
default: defaults.noVerify
})

@@ -63,4 +56,3 @@ .option('commit-all', {

type: 'boolean',
default: defaults.commitAll,
global: true
default: defaults.commitAll
})

@@ -70,4 +62,3 @@ .option('silent', {

type: 'boolean',
default: defaults.silent,
global: true
default: defaults.silent
})

@@ -78,12 +69,22 @@ .option('tag-prefix', {

type: 'string',
default: defaults.tagPrefix,
global: true
default: defaults.tagPrefix
})
.option('scripts', {
describe: 'Scripts to execute for lifecycle events (prebump, precommit, etc.,)',
default: {}
describe: 'Provide scripts to execute for lifecycle events (prebump, precommit, etc.,)',
default: defaults.scripts
})
.option('skip', {
describe: 'Map of steps in the release process that should be skipped',
default: defaults.scripts
})
.option('dry-run', {
type: 'boolean',
default: defaults.dryRun,
describe: 'See the commands that running standard-version would run'
})
.check((argv) => {
if (typeof argv.scripts !== 'object' || Array.isArray(argv.scripts)) {
throw Error('hooks must be an object')
throw Error('scripts must be an object')
} else if (typeof argv.skip !== 'object' || Array.isArray(argv.skip)) {
throw Error('skip must be an object')
} else {

@@ -90,0 +91,0 @@ return true

@@ -9,3 +9,6 @@ {

"silent": false,
"tagPrefix": "v"
"tagPrefix": "v",
"scripts": {},
"skip": {},
"dryRun": false
}

@@ -1,17 +0,9 @@

const conventionalRecommendedBump = require('conventional-recommended-bump')
const conventionalChangelog = require('conventional-changelog')
const path = require('path')
const printError = require('./lib/print-error')
const chalk = require('chalk')
const figures = require('figures')
const fs = require('fs')
const accessSync = require('fs-access').sync
const semver = require('semver')
const util = require('util')
const bump = require('./lib/lifecycles/bump')
const changelog = require('./lib/lifecycles/changelog')
const commit = require('./lib/lifecycles/commit')
const tag = require('./lib/lifecycles/tag')
const checkpoint = require('./lib/checkpoint')
const printError = require('./lib/print-error')
const runExec = require('./lib/run-exec')
const runLifecycleScript = require('./lib/run-lifecycle-script')
module.exports = function standardVersion (argv) {

@@ -21,30 +13,16 @@ var pkgPath = path.resolve(process.cwd(), './package.json')

var newVersion = pkg.version
var scripts = argv.scripts || {}
var defaults = require('./defaults')
var args = Object.assign({}, defaults, argv)
return runLifecycleScript(args, 'prebump', null, scripts)
.then((stdout) => {
if (stdout && stdout.trim().length) args.releaseAs = stdout.trim()
return bumpVersion(args.releaseAs)
return Promise.resolve()
.then(() => {
return bump(args, pkg)
})
.then((release) => {
if (!args.firstRelease) {
var releaseType = getReleaseType(args.prerelease, release.releaseType, pkg.version)
newVersion = semver.valid(releaseType) || semver.inc(pkg.version, releaseType, args.prerelease)
updateConfigs(args, newVersion)
} else {
checkpoint(args, 'skip version bump on first release', [], chalk.red(figures.cross))
}
return runLifecycleScript(args, 'postbump', newVersion, scripts)
.then((_newVersion) => {
// if bump runs, it calculaes the new version that we
// should release at.
if (_newVersion) newVersion = _newVersion
return changelog(args, newVersion)
})
.then(() => {
return outputChangelog(args)
})
.then(() => {
return runLifecycleScript(args, 'precommit', newVersion, scripts)
})
.then((message) => {
if (message && message.length) args.message = message
return commit(args, newVersion)

@@ -60,198 +38,1 @@ })

}
/**
* attempt to update the version # in a collection of common config
* files, e.g., package.json, bower.json.
*
* @param argv config object
* @param newVersion version # to update to.
* @return {string}
*/
var configsToUpdate = {}
function updateConfigs (args, newVersion) {
configsToUpdate[path.resolve(process.cwd(), './package.json')] = false
configsToUpdate[path.resolve(process.cwd(), './npm-shrinkwrap.json')] = false
configsToUpdate[path.resolve(process.cwd(), './bower.json')] = false
Object.keys(configsToUpdate).forEach(function (configPath) {
try {
var stat = fs.lstatSync(configPath)
if (stat.isFile()) {
var config = require(configPath)
var filename = path.basename(configPath)
checkpoint(args, 'bumping version in ' + filename + ' from %s to %s', [config.version, newVersion])
config.version = newVersion
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8')
// flag any config files that we modify the version # for
// as having been updated.
configsToUpdate[configPath] = true
}
} catch (err) {
if (err.code !== 'ENOENT') console.warn(err.message)
}
})
}
function getReleaseType (prerelease, expectedReleaseType, currentVersion) {
if (isString(prerelease)) {
if (isInPrerelease(currentVersion)) {
if (shouldContinuePrerelease(currentVersion, expectedReleaseType) ||
getTypePriority(getCurrentActiveType(currentVersion)) > getTypePriority(expectedReleaseType)
) {
return 'prerelease'
}
}
return 'pre' + expectedReleaseType
} else {
return expectedReleaseType
}
}
function isString (val) {
return typeof val === 'string'
}
/**
* if a version is currently in pre-release state,
* and if it current in-pre-release type is same as expect type,
* it should continue the pre-release with the same type
*
* @param version
* @param expectType
* @return {boolean}
*/
function shouldContinuePrerelease (version, expectType) {
return getCurrentActiveType(version) === expectType
}
function isInPrerelease (version) {
return Array.isArray(semver.prerelease(version))
}
var TypeList = ['major', 'minor', 'patch'].reverse()
/**
* extract the in-pre-release type in target version
*
* @param version
* @return {string}
*/
function getCurrentActiveType (version) {
var typelist = TypeList
for (var i = 0; i < typelist.length; i++) {
if (semver[typelist[i]](version)) {
return typelist[i]
}
}
}
/**
* calculate the priority of release type,
* major - 2, minor - 1, patch - 0
*
* @param type
* @return {number}
*/
function getTypePriority (type) {
return TypeList.indexOf(type)
}
function bumpVersion (releaseAs, callback) {
return new Promise((resolve, reject) => {
if (releaseAs) {
return resolve({
releaseType: releaseAs
})
} else {
conventionalRecommendedBump({
preset: 'angular'
}, function (err, release) {
if (err) return reject(err)
else return resolve(release)
})
}
})
}
function outputChangelog (argv) {
return new Promise((resolve, reject) => {
createIfMissing(argv)
var header = '# Change Log\n\nAll notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.\n'
var oldContent = fs.readFileSync(argv.infile, 'utf-8')
// find the position of the last release and remove header:
if (oldContent.indexOf('<a name=') !== -1) {
oldContent = oldContent.substring(oldContent.indexOf('<a name='))
}
var content = ''
var changelogStream = conventionalChangelog({
preset: 'angular'
}, undefined, {merges: null})
.on('error', function (err) {
return reject(err)
})
changelogStream.on('data', function (buffer) {
content += buffer.toString()
})
changelogStream.on('end', function () {
checkpoint(argv, 'outputting changes to %s', [argv.infile])
fs.writeFileSync(argv.infile, header + '\n' + (content + oldContent).replace(/\n+$/, '\n'), 'utf-8')
return resolve()
})
})
}
function commit (argv, newVersion) {
var msg = 'committing %s'
var args = [argv.infile]
var verify = argv.verify === false || argv.n ? '--no-verify ' : ''
var toAdd = ''
// commit any of the config files that we've updated
// the version # for.
Object.keys(configsToUpdate).forEach(function (p) {
if (configsToUpdate[p]) {
msg += ' and %s'
args.unshift(path.basename(p))
toAdd += ' ' + path.relative(process.cwd(), p)
}
})
checkpoint(argv, msg, args)
return runExec(argv, 'git add' + toAdd + ' ' + argv.infile)
.then(() => {
return runExec(argv, 'git commit ' + verify + (argv.sign ? '-S ' : '') + (argv.commitAll ? '' : (argv.infile + toAdd)) + ' -m "' + formatCommitMessage(argv.message, newVersion) + '"')
})
}
function formatCommitMessage (msg, newVersion) {
return String(msg).indexOf('%s') !== -1 ? util.format(msg, newVersion) : msg
}
function tag (newVersion, pkgPrivate, argv) {
var tagOption
if (argv.sign) {
tagOption = '-s '
} else {
tagOption = '-a '
}
checkpoint(argv, 'tagging release %s', [newVersion])
return runExec(argv, 'git tag ' + tagOption + argv.tagPrefix + newVersion + ' -m "' + formatCommitMessage(argv.message, newVersion) + '"')
.then(() => {
var message = 'git push --follow-tags origin master'
if (pkgPrivate !== true) message += '; npm publish'
checkpoint(argv, 'Run `%s` to publish', [message], chalk.blue(figures.info))
})
}
function createIfMissing (argv) {
try {
accessSync(argv.infile, fs.F_OK)
} catch (err) {
if (err.code === 'ENOENT') {
checkpoint(argv, 'created %s', [argv.infile])
argv.outputUnreleased = true
fs.writeFileSync(argv.infile, '\n', 'utf-8')
}
}
}

@@ -6,4 +6,5 @@ const chalk = require('chalk')

module.exports = function (argv, msg, args, figure) {
const defaultFigure = args.dryRun ? chalk.yellow(figures.tick) : chalk.green(figures.tick)
if (!argv.silent) {
console.info((figure || chalk.green(figures.tick)) + ' ' + util.format.apply(util, [msg].concat(args.map(function (arg) {
console.info((figure || defaultFigure) + ' ' + util.format.apply(util, [msg].concat(args.map(function (arg) {
return chalk.bold(arg)

@@ -10,0 +11,0 @@ }))))

const chalk = require('chalk')
module.exports = function (argv, msg, opts) {
if (!argv.silent) {
module.exports = function (args, msg, opts) {
if (!args.silent) {
opts = Object.assign({

@@ -6,0 +6,0 @@ level: 'error',

const exec = require('child_process').exec
const printError = require('./print-error')
module.exports = function (argv, cmd) {
module.exports = function (args, cmd) {
if (args.dryRun) return Promise.resolve()
return new Promise((resolve, reject) => {

@@ -11,6 +12,6 @@ // Exec given cmd and handle possible errors

if (err) {
printError(argv, stderr || err.message)
printError(args, stderr || err.message)
return reject(err)
} else if (stderr) {
printError(argv, stderr, {level: 'warn', color: 'yellow'})
printError(args, stderr, {level: 'warn', color: 'yellow'})
}

@@ -17,0 +18,0 @@ return resolve(stdout)

@@ -6,8 +6,8 @@ const chalk = require('chalk')

module.exports = function (argv, hookName, newVersion, hooks, cb) {
module.exports = function (args, hookName, newVersion, hooks, cb) {
if (!hooks[hookName]) return Promise.resolve()
var command = hooks[hookName] + ' --new-version="' + newVersion + '"'
checkpoint(argv, 'Running lifecycle hook "%s"', [hookName])
checkpoint(argv, '- hook command: "%s"', [command], chalk.blue(figures.info))
return runExec(argv, command)
checkpoint(args, 'Running lifecycle hook "%s"', [hookName])
checkpoint(args, '- hook command: "%s"', [command], chalk.blue(figures.info))
return runExec(args, command)
}

@@ -6,9 +6,10 @@ const chalk = require('chalk')

module.exports = function (argv, hookName, newVersion, scripts, cb) {
if (!scripts[hookName]) return Promise.resolve()
module.exports = function (args, hookName, newVersion) {
const scripts = args.scripts
if (!scripts || !scripts[hookName]) return Promise.resolve()
var command = scripts[hookName]
if (newVersion) command += ' --new-version="' + newVersion + '"'
checkpoint(argv, 'Running lifecycle script "%s"', [hookName])
checkpoint(argv, '- execute command: "%s"', [command], chalk.blue(figures.info))
return runExec(argv, command)
checkpoint(args, 'Running lifecycle script "%s"', [hookName])
checkpoint(args, '- execute command: "%s"', [command], chalk.blue(figures.info))
return runExec(args, command)
}
{
"name": "standard-version",
"version": "4.1.0-candidate.0",
"version": "4.1.0-candidate.1",
"description": "replacement for `npm version` with automatic CHANGELOG generation",

@@ -5,0 +5,0 @@ "bin": "bin/cli.js",

@@ -159,14 +159,12 @@ # Standard Version

own supplementary commands during the release. The following
hooks are available:
hooks are available and execute in the order documented:
* `prebump`: executed before the version bump is calculated. If the `prebump`
* `prebump`/`postbump`: executed before and after the version is bumped. If the `prebump`
script returns a version #, it will be used rather than
the version calculated by `standard-version`.
* `postbump`: executed after the version has been bumped and written to
package.json. The flag `--new-version` is populated with the version that is
being released.
* `precommit`: called after CHANGELOG.md and package.json have been updated,
but before changes have been committed to git.
* `prechangelog`/`postchangelog`: executes before and after the CHANGELOG is generated.
* `precommit`/`postcommit`: called before and after the commit step.
* `pretag`/`posttag`: called before and after the tagging step.
Simply add the following to your package.json, to enable lifecycle scripts:
Simply add the following to your package.json to configure lifecycle scripts:

@@ -183,2 +181,17 @@ ```json

### Skipping lifecycle steps
You can skip any of the lifecycle steps (`bump`, `changelog`, `commit`, `tag`),
by adding the following to your package.json:
```json
{
"standard-version": {
"skip": {
"changelog": true
}
}
}
```
### Committing generated artifacts in the release commit

@@ -193,2 +206,14 @@

### Dry run mode
running `standard-version` with the flag `--dry-run` allows you to see what
commands would be run, without committing to git or updating files.
```sh
# npm run script
npm run release -- --dry-run
# or global bin
standard-version --dry-run
```
### CLI Help

@@ -195,0 +220,0 @@

@@ -678,2 +678,47 @@ /* global describe it beforeEach afterEach */

})
describe('dry-run', function () {
it('skips all non-idempotent steps', function (done) {
commit('feat: first commit')
shell.exec('git tag -a v1.0.0 -m "my awesome first release"')
commit('feat: new feature!')
execCli('--dry-run').stdout.should.match(/### Features/)
shell.exec('git log --oneline -n1').stdout.should.match(/feat: new feature!/)
shell.exec('git tag').stdout.should.match(/1\.0\.0/)
getPackageVersion().should.equal('1.0.0')
return done()
})
})
describe('skip', () => {
it('allows bump and changelog generation to be skipped', function () {
let changelogContent = 'legacy header format<a name="1.0.0">\n'
writePackageJson('1.0.0')
fs.writeFileSync('CHANGELOG.md', changelogContent, 'utf-8')
commit('feat: first commit')
return execCliAsync('--skip.bump true --skip.changelog true')
.then(function () {
getPackageVersion().should.equal('1.0.0')
var content = fs.readFileSync('CHANGELOG.md', 'utf-8')
content.should.equal(changelogContent)
})
})
it('allows the commit phase to be skipped', function () {
let changelogContent = 'legacy header format<a name="1.0.0">\n'
writePackageJson('1.0.0')
fs.writeFileSync('CHANGELOG.md', changelogContent, 'utf-8')
commit('feat: new feature from branch')
return execCliAsync('--skip.commit true')
.then(function () {
getPackageVersion().should.equal('1.1.0')
var content = fs.readFileSync('CHANGELOG.md', 'utf-8')
content.should.match(/new feature from branch/)
// check last commit message
shell.exec('git log --oneline -n1').stdout.should.match(/feat: new feature from branch/)
})
})
})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc