Skip to content

Commit

Permalink
fix: redesign API and CLI
Browse files Browse the repository at this point in the history
BREAKING CHANGE: The API and CLI options have changed.  See README.md for the new
options.
  • Loading branch information
jedwards1211 committed May 7, 2019
1 parent 64b071d commit 7885998
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 41 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@
"chalk": "^2.4.2",
"js-base64": "^2.5.1",
"npm-registry-fetch": "^3.9.0",
"semver": "^6.0.0"
"semver": "^6.0.0",
"yargs": "^13.2.2"
},
"renovate": {
"extends": [
Expand Down
127 changes: 87 additions & 40 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import chalk from 'chalk'
import npmRegistryFetch from 'npm-registry-fetch'
import { Base64 } from 'js-base64'
import parseChangelog, { type Release } from './changelog-parser'
import parseChangelog, { type Release } from './parseChangelog'
import semver from 'semver'
import _Octokit from '@octokit/rest'
import octokitThrottling from '@octokit/plugin-throttling'
Expand Down Expand Up @@ -45,6 +45,7 @@ const octokit = new Octokit(octokitOptions)
export const getChangelog = memoize(
async (owner: string, repo: string): Promise<{ [string]: Release }> => {
let changelog
let lastError: ?Error
for (const file of ['CHANGELOG.md', 'changelog.md']) {
try {
const {
Expand All @@ -57,10 +58,13 @@ export const getChangelog = memoize(
changelog = Base64.decode(content)
break
} catch (error) {
lastError = error
continue
}
}
if (!changelog) throw new Error('failed to get changelog')
if (!changelog) {
throw lastError || new Error(`failed to find changelog file`)
}
return await parseChangelog(changelog)
},
(owner, repo) => `${owner}/${repo}`
Expand All @@ -73,45 +77,45 @@ function parseRepositoryUrl(url: string): { owner: string, repo: string } {
return { owner, repo }
}

export async function whatBroke(
export type IncludeOption =
| ((version: string) => boolean)
| {
range?: ?string,
prerelease?: ?boolean,
minor?: ?boolean,
patch?: ?boolean,
}

function includeFilter(include: ?IncludeOption): (version: string) => boolean {
if (!include) return () => true
if (typeof include === 'function') return include
const { range, prerelease, minor, patch = minor } = include
return (version: string): boolean => {
if (range && !semver.satisfies(version, range)) return false
if (!prerelease && semver.prerelease(version)) return false
if (minor === false && semver.minor(version)) return false
if (patch === false && semver.patch(version)) return false
return true
}
}

export type Options = {
include?: ?IncludeOption,
}

export async function fetchChangelog(
pkg: string,
{
fromVersion,
toVersion,
full,
}: {
fromVersion?: ?string,
toVersion?: ?string,
full?: ?boolean,
} = {}
{ include }: Options = {}
): Promise<Object> {
const npmInfo = await npmRegistryFetch.json(pkg, {
token: await getNpmToken(),
})

const versions = Object.keys(npmInfo.versions).filter(
(v: string): boolean => {
if (fromVersion && !semver.gt(v, fromVersion)) return false
if (toVersion && !semver.lt(v, toVersion)) return false
return true
}
)
const versions = Object.keys(npmInfo.versions).filter(includeFilter(include))

const releases = []

let prevVersion = fromVersion
for (let version of versions) {
if (
!full &&
prevVersion != null &&
!semver.prerelease(version) &&
semver.satisfies(version, `^${prevVersion}`) &&
!(semver.prerelease(prevVersion) && !semver.prerelease(version))
) {
continue
}
prevVersion = version

const release: Release = {
version,
header: `# ${version}`,
Expand Down Expand Up @@ -174,26 +178,69 @@ export async function whatBroke(
}

if (!module.parent) {
const full = process.argv.indexOf('--full') >= 0
const args = process.argv.slice(2).filter(a => a[0] !== '-')
const pkg = args[0]
let fromVersion = args[1],
toVersion = args[2]
if (!fromVersion) {
let {
argv: {
_: [pkg],
range,
includePrereleases: prereleases,
minor,
patch,
},
} = require('yargs')
.usage(
`Usage: $0 <package name>
Fetches changelog entries for an npm package from GitHub.
(Other repository hosts aren't currently supported.)`
)
.option('r', {
alias: 'range',
describe: 'semver version range to get changelog entries for',
type: 'string',
})
.option('prereleases', {
describe: 'include prerelease versions',
type: 'boolean',
default: false,
})
.default('minor', true)
.boolean('minor')
.hide('minor')
.describe('no-minor', 'exclude minor versions')
.default('patch', undefined)
.boolean('patch')
.hide('patch')
.describe('no-patch', 'exclude patch versions')
.hide('version')

if (!pkg) {
require('yargs').showHelp()
process.exit(1)
}
if (!range) {
try {
// $FlowFixMe
fromVersion = require(require.resolve(
const { version } = require(require.resolve(
require('path').join(pkg, 'package.json'),
{
paths: [process.cwd()],
}
)).version
))
range = `>${version}`
} catch (error) {
// ignore
}
}

/* eslint-env node */
whatBroke(pkg, { fromVersion, toVersion, full }).then(
fetchChangelog(pkg, {
include: {
range,
prereleases,
minor,
patch,
},
}).then(
(changelog: Array<Release>) => {
for (const { header, body, error } of changelog) {
process.stdout.write(chalk.bold(header) + '\n\n')
Expand Down
File renamed without changes.
70 changes: 70 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,11 @@ ansi-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=

ansi-regex@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==

ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
Expand Down Expand Up @@ -2619,6 +2624,11 @@ elegant-spinner@^1.0.1:
resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e"
integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=

emoji-regex@^7.0.1:
version "7.0.3"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==

encoding@^0.1.11:
version "0.1.12"
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb"
Expand Down Expand Up @@ -3462,6 +3472,11 @@ get-caller-file@^1.0.1:
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a"
integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==

get-caller-file@^2.0.1:
version "2.0.5"
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==

get-func-name@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41"
Expand Down Expand Up @@ -6111,6 +6126,15 @@ os-locale@^3.0.0:
lcid "^2.0.0"
mem "^4.0.0"

os-locale@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a"
integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==
dependencies:
execa "^1.0.0"
lcid "^2.0.0"
mem "^4.0.0"

os-name@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/os-name/-/os-name-2.0.1.tgz#b9a386361c17ae3a21736ef0599405c9a8c5dc5e"
Expand Down Expand Up @@ -6922,6 +6946,11 @@ require-main-filename@^1.0.1:
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=

require-main-filename@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==

require-relative@^0.8.7:
version "0.8.7"
resolved "https://registry.yarnpkg.com/require-relative/-/require-relative-0.8.7.tgz#7999539fc9e047a37928fa196f8e1563dabd36de"
Expand Down Expand Up @@ -7557,6 +7586,15 @@ string-width@^1.0.1:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"

string-width@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
dependencies:
emoji-regex "^7.0.1"
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"

string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
Expand Down Expand Up @@ -7597,6 +7635,13 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"

strip-ansi@^5.1.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
dependencies:
ansi-regex "^4.1.0"

strip-bom-buffer@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/strip-bom-buffer/-/strip-bom-buffer-0.1.1.tgz#ca3ddc4919c13f9fddf30b1dff100a9835248b4d"
Expand Down Expand Up @@ -8310,6 +8355,14 @@ yargs-parser@^10.1.0:
dependencies:
camelcase "^4.1.0"

yargs-parser@^13.0.0:
version "13.1.0"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.0.tgz#7016b6dd03e28e1418a510e258be4bff5a31138f"
integrity sha512-Yq+32PrijHRri0vVKQEm+ys8mbqWjLiwQkMFNXEENutzLPP0bE4Lcd4iA3OQY5HF+GD3xXxf0MEHb8E4/SA3AA==
dependencies:
camelcase "^5.0.0"
decamelize "^1.2.0"

yargs-parser@^9.0.2:
version "9.0.2"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077"
Expand Down Expand Up @@ -8379,3 +8432,20 @@ yargs@^12.0.0, yargs@^12.0.1:
which-module "^2.0.0"
y18n "^3.2.1 || ^4.0.0"
yargs-parser "^10.1.0"

yargs@^13.2.2:
version "13.2.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.2.tgz#0c101f580ae95cea7f39d927e7770e3fdc97f993"
integrity sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==
dependencies:
cliui "^4.0.0"
find-up "^3.0.0"
get-caller-file "^2.0.1"
os-locale "^3.1.0"
require-directory "^2.1.1"
require-main-filename "^2.0.0"
set-blocking "^2.0.0"
string-width "^3.0.0"
which-module "^2.0.0"
y18n "^4.0.0"
yargs-parser "^13.0.0"

0 comments on commit 7885998

Please sign in to comment.