From 9a90153c44cfbeaf5c9c4d15a495472dcfbff331 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Sat, 16 Jun 2018 20:47:48 +0200 Subject: [PATCH 1/4] tslint: Adjust enabled rules --- tslint.json | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tslint.json b/tslint.json index 32fa6e5e..98c4a404 100644 --- a/tslint.json +++ b/tslint.json @@ -4,6 +4,19 @@ "tslint:recommended" ], "jsRules": {}, - "rules": {}, + "rules": { + "arrow-parens": false, + "curly": false, + "interface-name": false, + "no-string-literal": false, + "no-var-requires": false, + "object-literal-sort-keys": false, + "only-arrow-functions": false, + "ordered-imports": false, + "prefer-const": false, + "quotemark": { + "options": "double" + } + }, "rulesDirectory": [] -} \ No newline at end of file +} From f1b16dce3e467c68efe9681d5ac3360b89c5bea8 Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Sat, 16 Jun 2018 20:56:16 +0200 Subject: [PATCH 2/4] Fix TSLint issues --- src/__mocks__/changelog.ts | 8 ++-- src/__mocks__/fetch.ts | 7 ++-- src/__mocks__/github-api.ts | 2 +- src/changelog.spec.ts | 47 ++++++++++++---------- src/changelog.ts | 56 +++++++++++++------------- src/cli.ts | 16 ++++---- src/configuration-error.spec.ts | 8 ++-- src/configuration-error.ts | 4 +- src/configuration.spec.ts | 30 +++++++------- src/configuration.ts | 6 +-- src/find-pull-request-id.spec.ts | 2 + src/functional/markdown-full.spec.ts | 59 ++++++++++++++-------------- src/git.ts | 2 +- src/github-api.ts | 28 ++++++------- src/index.ts | 2 +- src/markdown-renderer.spec.ts | 56 +++++++++++++------------- src/markdown-renderer.ts | 32 +++++++-------- src/progress-bar.ts | 18 ++++----- 18 files changed, 196 insertions(+), 187 deletions(-) diff --git a/src/__mocks__/changelog.ts b/src/__mocks__/changelog.ts index 35738ebf..6d885cde 100644 --- a/src/__mocks__/changelog.ts +++ b/src/__mocks__/changelog.ts @@ -9,16 +9,16 @@ const defaultConfig = { "Type: Bug": ":bug: Bug Fix", "Type: Enhancement": ":nail_care: Enhancement", "Type: Documentation": ":memo: Documentation", - "Type: Maintenance": ":house: Maintenance" + "Type: Maintenance": ":house: Maintenance", }, - cacheDir: ".changelog" + cacheDir: ".changelog", }; class MockedChangelog extends Changelog { - getConfig() { + private getConfig() { return defaultConfig; } - getToday() { + private getToday() { return "2099-01-01"; } } diff --git a/src/__mocks__/fetch.ts b/src/__mocks__/fetch.ts index a2988800..2e693866 100644 --- a/src/__mocks__/fetch.ts +++ b/src/__mocks__/fetch.ts @@ -1,4 +1,4 @@ -'use strict'; +"use strict"; let mockResponses: { [url: string]: string } = {}; @@ -7,12 +7,11 @@ export default async function fetch(url: string) { if (mockResponse) { return { json: () => mockResponse }; } - console.log(url); throw new Error(`Unknown URL: ${url}`); -}; +} export function __setMockResponses(newMockResponses: { [url: string]: string }) { - mockResponses = newMockResponses + mockResponses = newMockResponses; } export function __resetMockResponses() { diff --git a/src/__mocks__/github-api.ts b/src/__mocks__/github-api.ts index a6c4012c..7305c1d4 100644 --- a/src/__mocks__/github-api.ts +++ b/src/__mocks__/github-api.ts @@ -1,7 +1,7 @@ const GithubAPI = require.requireActual("../github-api").default; class MockedGithubAPI extends GithubAPI { - getAuthToken() { + private getAuthToken() { return "123"; } } diff --git a/src/changelog.spec.ts b/src/changelog.spec.ts index 4af4e083..cb14d705 100644 --- a/src/changelog.spec.ts +++ b/src/changelog.spec.ts @@ -19,13 +19,13 @@ describe("Changelog", () => { const MockedChangelog = require("./changelog").default; const TESTS = [ - ['', ''], - ['foo.js', ''], - ['packages/foo.js', ''], - ['packages/foo/bar.js', 'foo'], - ['packages/foo/bar/baz.js', 'foo'], - ['packages/@foo/bar.js', '@foo'], - ['packages/@foo/bar/baz.js', '@foo/bar'], + ["", ""], + ["foo.js", ""], + ["packages/foo.js", ""], + ["packages/foo/bar.js", "foo"], + ["packages/foo/bar/baz.js", "foo"], + ["packages/@foo/bar.js", "@foo"], + ["packages/@foo/bar/baz.js", "@foo/bar"], ]; for (let [input, expected] of TESTS) { @@ -41,11 +41,16 @@ describe("Changelog", () => { require("./fetch").__resetMockResponses(); require("./git").listCommits.mockImplementation(() => [ - { sha: "a0000005", refName:"HEAD -> master, tag: v0.2.0, origin/master, origin/HEAD", summary: "chore(release): releasing component", date: "2017-01-01" }, - { sha: "a0000004", refName:"", summary: "Merge pull request #2 from my-feature", date: "2017-01-01" }, - { sha: "a0000003", refName:"", summary: "feat(module) Add new module (#2)", date: "2017-01-01" }, - { sha: "a0000002", refName:"", summary: "refactor(module) Simplify implementation", date: "2017-01-01" }, - { sha: "a0000001", refName:"tag: v0.1.0", summary: "chore(release): releasing component", date: "2017-01-01" }, + { + sha: "a0000005", + refName: "HEAD -> master, tag: v0.2.0, origin/master, origin/HEAD", + summary: "chore(release): releasing component", + date: "2017-01-01", + }, + { sha: "a0000004", refName: "", summary: "Merge pull request #2 from my-feature", date: "2017-01-01" }, + { sha: "a0000003", refName: "", summary: "feat(module) Add new module (#2)", date: "2017-01-01" }, + { sha: "a0000002", refName: "", summary: "refactor(module) Simplify implementation", date: "2017-01-01" }, + { sha: "a0000001", refName: "tag: v0.1.0", summary: "chore(release): releasing component", date: "2017-01-01" }, ]); require("./git").listTagNames.mockImplementation(() => [ @@ -61,7 +66,7 @@ describe("Changelog", () => { "https://api.github.com/users/test-user": { login: "test-user", html_url: "https://github.com/test-user", - name: "Test User" + name: "Test User", }, }; const issuesCache = { @@ -73,7 +78,7 @@ describe("Changelog", () => { { name: "Status: In Progress" }, ], user: usersCache["https://api.github.com/users/test-user"], - } + }, }; require("./fetch").__setMockResponses({ ...usersCache, @@ -102,22 +107,22 @@ describe("Changelog", () => { "https://api.github.com/users/test-user": { login: "test-user", html_url: "https://github.com/test-user", - name: "Test User" + name: "Test User", }, "https://api.github.com/users/test-user-1": { login: "test-user-1", html_url: "https://github.com/test-user-1", - name: "Test User 1" + name: "Test User 1", }, "https://api.github.com/users/test-user-2": { login: "test-user-2", html_url: "https://github.com/test-user-2", - name: "Test User 2" + name: "Test User 2", }, "https://api.github.com/users/user-bot": { login: "user-bot", html_url: "https://github.com/user-bot", - name: "User Bot" + name: "User Bot", }, }; require("./fetch").__setMockResponses(usersCache); @@ -126,7 +131,7 @@ describe("Changelog", () => { it("get list of valid commiters", async () => { const MockedChangelog = require("./changelog").default; const changelog = new MockedChangelog({ - ignoreCommitters: ["user-bot"] + ignoreCommitters: ["user-bot"], }); const testCommits = [ @@ -140,11 +145,11 @@ describe("Changelog", () => { expect(committers).toEqual([{ login: "test-user-1", html_url: "https://github.com/test-user-1", - name: "Test User 1" + name: "Test User 1", }, { login: "test-user-2", html_url: "https://github.com/test-user-2", - name: "Test User 2" + name: "Test User 2", }]); }); }); diff --git a/src/changelog.ts b/src/changelog.ts index e81752d1..853188ce 100644 --- a/src/changelog.ts +++ b/src/changelog.ts @@ -1,8 +1,8 @@ const pMap = require("p-map"); -import progressBar from "./progress-bar"; +import progressBar from "./progress-bar"; import * as Configuration from "./configuration"; -import findPullRequestId from "./find-pull-request-id"; +import findPullRequestId from "./find-pull-request-id"; import * as Git from "./git"; import GithubAPI, {GitHubUserResponse} from "./github-api"; import {CommitInfo, Release} from "./interfaces"; @@ -16,9 +16,9 @@ interface Options { } export default class Changelog { - config: any; - github: GithubAPI; - renderer: MarkdownRenderer; + private config: any; + private github: GithubAPI; + private renderer: MarkdownRenderer; constructor(options: Options = {}) { this.config = Object.assign(this.getConfig(), options); @@ -29,11 +29,17 @@ export default class Changelog { }); } - getConfig() { + public async createMarkdown() { + const releases = await this.listReleases(); + + return this.renderer.renderMarkdown(releases); + } + + private getConfig() { return Configuration.fromGitRoot(process.cwd()); } - async getCommitInfos(): Promise { + private async getCommitInfos(): Promise { // Step 1: Get list of commits between tag A and B (local) const commits = await this.getListOfCommits(); @@ -52,7 +58,7 @@ export default class Changelog { return commitInfos; } - async listReleases(): Promise { + private async listReleases(): Promise { // Get all info about commits in a certain tags range const commits = await this.getCommitInfos(); @@ -65,20 +71,14 @@ export default class Changelog { return releases; } - async createMarkdown() { - const releases = await this.listReleases(); - - return this.renderer.renderMarkdown(releases); - } - - async getListOfUniquePackages(sha: string): Promise { + private async getListOfUniquePackages(sha: string): Promise { return (await Git.changedPaths(sha)) .map(path => this.packageFromPath(path)) .filter(Boolean) .filter(onlyUnique); } - packageFromPath(path: string): string { + private packageFromPath(path: string): string { const parts = path.split("/"); if (parts[0] !== "packages" || parts.length < 3) { return ""; @@ -91,7 +91,7 @@ export default class Changelog { return parts[1]; } - async getListOfCommits(): Promise { + private async getListOfCommits(): Promise { // Determine the tags range to get the commits for. Custom from/to can be // provided via command-line options. // Default is "from last tag". @@ -99,7 +99,7 @@ export default class Changelog { return Git.listCommits(tagFrom, this.config.tagTo); } - async getCommitters(commits: CommitInfo[]): Promise { + private async getCommitters(commits: CommitInfo[]): Promise { const committers: { [id: string]: GitHubUserResponse } = {}; for (const commit of commits) { @@ -116,15 +116,15 @@ export default class Changelog { return Object.keys(committers).map((k) => committers[k]); } - ignoreCommitter(login: string): boolean { + private ignoreCommitter(login: string): boolean { if (!this.config.ignoreCommitters) { return false; } - return this.config.ignoreCommitters.some((c: string) => c === login || login.indexOf(c) > -1) + return this.config.ignoreCommitters.some((c: string) => c === login || login.indexOf(c) > -1); } - async toCommitInfos(commits: Git.CommitListItem[]): Promise { + private async toCommitInfos(commits: Git.CommitListItem[]): Promise { const allTags = await Git.listTagNames(); return commits.map((commit) => { const { sha, refName, summary: message, date } = commit; @@ -140,7 +140,7 @@ export default class Changelog { return { commitSHA: sha, - message: message, + message, // Note: Only merge commits or commits referencing an issue / PR // will be kept in the changelog. tags: tagsInCommit, @@ -150,7 +150,7 @@ export default class Changelog { }); } - async downloadIssueData(commitInfos: CommitInfo[]) { + private async downloadIssueData(commitInfos: CommitInfo[]) { progressBar.init(commitInfos.length); await pMap(commitInfos, async (commitInfo: CommitInfo) => { progressBar.setTitle(commitInfo.commitSHA); @@ -164,7 +164,7 @@ export default class Changelog { progressBar.terminate(); } - groupByRelease(commits: CommitInfo[]): Release[] { + private groupByRelease(commits: CommitInfo[]): Release[] { // Analyze the commits and group them by tag. // This is useful to generate multiple release logs in case there are // multiple release tags. @@ -194,12 +194,12 @@ export default class Changelog { return Object.keys(releaseMap).map((tag) => releaseMap[tag]); } - getToday() { + private getToday() { const date = new Date().toISOString(); return date.slice(0, date.indexOf("T")); } - fillInCategories(commits: CommitInfo[]) { + private fillInCategories(commits: CommitInfo[]) { for (const commit of commits) { if (!commit.githubIssue || !commit.githubIssue.labels) continue; @@ -211,7 +211,7 @@ export default class Changelog { } } - async fillInPackages(commits: CommitInfo[]) { + private async fillInPackages(commits: CommitInfo[]) { progressBar.init(commits.length); await pMap(commits, async (commit: CommitInfo) => { @@ -225,7 +225,7 @@ export default class Changelog { progressBar.terminate(); } - async fillInContributors(releases: Release[]) { + private async fillInContributors(releases: Release[]) { for (const release of releases) { release.contributors = await this.getCommitters(release.commits); } diff --git a/src/cli.ts b/src/cli.ts index dcc44df1..0656e7f0 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,3 +1,5 @@ +/* tslint:disable:no-console */ + const chalk = require("chalk"); import Changelog from "./changelog"; @@ -9,28 +11,28 @@ export async function run() { .options({ "tag-from": { type: "string", - desc: "A git tag that determines the lower bound of the range of commits (defaults to last available)" + desc: "A git tag that determines the lower bound of the range of commits (defaults to last available)", }, "tag-to": { type: "string", - desc: "A git tag that determines the upper bound of the range of commits" - } + desc: "A git tag that determines the upper bound of the range of commits", + }, }) .example( "lerna-changelog", - "create a changelog for the changes after the latest available tag" + "create a changelog for the changes after the latest available tag", ) .example( "lerna-changelog --tag-from 0.1.0 --tag-to 0.3.0", - "create a changelog for the changes in all tags within the given range" + "create a changelog for the changes in all tags within the given range", ) .version() .help() .argv; let options = { - tagFrom: argv['tag-from'], - tagTo: argv['tag-to'], + tagFrom: argv["tag-from"], + tagTo: argv["tag-to"], }; try { diff --git a/src/configuration-error.spec.ts b/src/configuration-error.spec.ts index d062402e..5ee4d13d 100644 --- a/src/configuration-error.spec.ts +++ b/src/configuration-error.spec.ts @@ -2,15 +2,15 @@ import ConfigurationError from "./configuration-error"; describe("ConfigurationError", function() { it("can be identified using `instanceof`", function() { - const configError = new ConfigurationError('foobar'); + const configError = new ConfigurationError("foobar"); expect(configError instanceof ConfigurationError).toEqual(true); - const error = new Error('foobar'); + const error = new Error("foobar"); expect(error instanceof ConfigurationError).toEqual(false); }); it("`message` property equals first constructor argument", function() { - const error = new ConfigurationError('foobar'); - expect(error.message).toEqual('foobar'); + const error = new ConfigurationError("foobar"); + expect(error.message).toEqual("foobar"); }); }); diff --git a/src/configuration-error.ts b/src/configuration-error.ts index 47d8fdc8..1de747df 100644 --- a/src/configuration-error.ts +++ b/src/configuration-error.ts @@ -1,6 +1,6 @@ export default class ConfigurationError { - name = "ConfigurationError"; - message: string; + public name = "ConfigurationError"; + public message: string; constructor(message: string) { Error.apply(this, arguments); diff --git a/src/configuration.spec.ts b/src/configuration.spec.ts index e2b337ef..b4deb9cd 100644 --- a/src/configuration.spec.ts +++ b/src/configuration.spec.ts @@ -2,7 +2,7 @@ const os = require("os"); const fs = require("fs-extra"); const path = require("path"); -import { fromGitRoot, fromPath, findRepoFromPkg } from "./configuration"; +import { findRepoFromPkg, fromGitRoot, fromPath } from "./configuration"; import ConfigurationError from "./configuration-error"; describe("Configuration", function() { @@ -11,16 +11,16 @@ describe("Configuration", function() { const rootPath = path.resolve(`${__dirname}/..`); const result = fromGitRoot(path.join(rootPath, "src")); expect(result).toEqual({ - "repo": "lerna/lerna-changelog", - "labels": { + repo: "lerna/lerna-changelog", + labels: { "Tag: Breaking Change": ":boom: Breaking Change", "Tag: Enhancement": ":rocket: Enhancement", "Tag: Bug Fix": ":bug: Bug Fix", "Tag: Polish": ":nail_care: Polish", "Tag: Documentation": ":memo: Documentation", - "Tag: Internal": ":house: Internal" + "Tag: Internal": ":house: Internal", }, - "cacheDir": ".changelog", + cacheDir: ".changelog", rootPath, }); }); @@ -75,20 +75,20 @@ describe("Configuration", function() { describe("findRepoFromPkg", function() { const tests = [ - ['git+https://github.com/ember-cli/ember-rfc176-data.git', 'ember-cli/ember-rfc176-data'], - ['https://github.com/ember-cli/ember-rfc176-data.git', 'ember-cli/ember-rfc176-data'], - ['https://github.com/babel/ember-cli-babel', 'babel/ember-cli-babel'], - ['https://github.com/babel/ember-cli-babel.git', 'babel/ember-cli-babel'], - ['git@github.com:babel/ember-cli-babel.git', 'babel/ember-cli-babel'], - ['https://gitlab.com/gnachman/iterm2.git', undefined], - ['git@gitlab.com:gnachman/iterm2.git', undefined], + ["git+https://github.com/ember-cli/ember-rfc176-data.git", "ember-cli/ember-rfc176-data"], + ["https://github.com/ember-cli/ember-rfc176-data.git", "ember-cli/ember-rfc176-data"], + ["https://github.com/babel/ember-cli-babel", "babel/ember-cli-babel"], + ["https://github.com/babel/ember-cli-babel.git", "babel/ember-cli-babel"], + ["git@github.com:babel/ember-cli-babel.git", "babel/ember-cli-babel"], + ["https://gitlab.com/gnachman/iterm2.git", undefined], + ["git@gitlab.com:gnachman/iterm2.git", undefined], ]; tests.forEach(([input, output]) => { it(`'${input}' -> '${output}'`, function() { expect(findRepoFromPkg({ repository: { - type: 'git', + type: "git", url: input, }, })).toEqual(output); @@ -97,8 +97,8 @@ describe("Configuration", function() { it(`works with shorthand 'repository' syntax`, function() { expect(findRepoFromPkg({ - repository: 'https://github.com/babel/ember-cli-babel', - })).toEqual('babel/ember-cli-babel'); + repository: "https://github.com/babel/ember-cli-babel", + })).toEqual("babel/ember-cli-babel"); }); }); }); diff --git a/src/configuration.ts b/src/configuration.ts index 62cbda39..eac5f182 100644 --- a/src/configuration.ts +++ b/src/configuration.ts @@ -16,7 +16,7 @@ export function fromPath(rootPath: string): any { if (!config) { throw new ConfigurationError( "Missing changelog config in `lerna.json`.\n" + - "See docs for setup: https://github.com/lerna/lerna-changelog#readme" + "See docs for setup: https://github.com/lerna/lerna-changelog#readme", ); } @@ -46,8 +46,8 @@ function guessConfig(rootPath: string): any | undefined { } const labels = { - "enhancement": ":rocket: Enhancement", - "bug": ":bug: Bug Fix", + enhancement: ":rocket: Enhancement", + bug: ":bug: Bug Fix", }; return { repo, labels }; diff --git a/src/find-pull-request-id.spec.ts b/src/find-pull-request-id.spec.ts index 0ebc787c..b82da747 100644 --- a/src/find-pull-request-id.spec.ts +++ b/src/find-pull-request-id.spec.ts @@ -1,3 +1,5 @@ +/* tslint:disable:max-line-length */ + import findPullRequestId from "./find-pull-request-id"; describe("findPullRequestId", function() { diff --git a/src/functional/markdown-full.spec.ts b/src/functional/markdown-full.spec.ts index 35637931..3fafc332 100644 --- a/src/functional/markdown-full.spec.ts +++ b/src/functional/markdown-full.spec.ts @@ -1,3 +1,5 @@ +/* tslint:disable:max-line-length */ + import {CommitListItem} from "../git"; jest.mock("../../src/progress-bar"); @@ -7,21 +9,21 @@ jest.mock("../git"); jest.mock("../fetch"); const listOfCommits: CommitListItem[] = [ - { sha: "a0000015", refName:"", summary: "chore: making of episode viii", date: "2015-12-18" }, - { sha: "a0000014", refName:"", summary: "feat: infiltration (#7)", date: "2015-12-18" }, - { sha: "a0000013", refName:"HEAD -> master, tag: v6.0.0, origin/master, origin/HEAD", summary: "chore(release): releasing component", date: "1983-05-25" }, - { sha: "a0000012", refName:"", summary: "Merge pull request #6 from return-of-the-jedi", date: "1983-05-25" }, - { sha: "a0000011", refName:"", summary: "feat: I am your father (#5)", date: "1983-05-25" }, - { sha: "a0000010", refName:"", summary: "fix(han-solo): unfreezes (#4)", date: "1983-05-25" }, - { sha: "a0000009", refName:"tag: v5.0.0", summary: "chore(release): releasing component", date: "1980-05-17" }, - { sha: "a0000008", refName:"", summary: "Merge pull request #3 from empire-strikes-back", date: "1980-05-17" }, - { sha: "a0000007", refName:"", summary: "fix: destroy rebels base", date: "1980-05-17" }, - { sha: "a0000006", refName:"", summary: "chore: the end of Alderaan (#2)", date: "1980-05-17" }, - { sha: "a0000005", refName:"", summary: "refactor(death-star): add deflector shield", date: "1980-05-17" }, - { sha: "a0000004", refName:"tag: v4.0.0", summary: "chore(release): releasing component", date: "1977-05-25" }, - { sha: "a0000003", refName:"", summary: "Merge pull request #1 from star-wars", date: "1977-05-25" }, - { sha: "a0000002", refName:"tag: v0.1.0", summary: "chore(release): releasing component", date: "1966-01-01" }, - { sha: "a0000001", refName:"", summary: "fix: some random fix which will be ignored", date: "1966-01-01" }, + { sha: "a0000015", refName: "", summary: "chore: making of episode viii", date: "2015-12-18" }, + { sha: "a0000014", refName: "", summary: "feat: infiltration (#7)", date: "2015-12-18" }, + { sha: "a0000013", refName: "HEAD -> master, tag: v6.0.0, origin/master, origin/HEAD", summary: "chore(release): releasing component", date: "1983-05-25" }, + { sha: "a0000012", refName: "", summary: "Merge pull request #6 from return-of-the-jedi", date: "1983-05-25" }, + { sha: "a0000011", refName: "", summary: "feat: I am your father (#5)", date: "1983-05-25" }, + { sha: "a0000010", refName: "", summary: "fix(han-solo): unfreezes (#4)", date: "1983-05-25" }, + { sha: "a0000009", refName: "tag: v5.0.0", summary: "chore(release): releasing component", date: "1980-05-17" }, + { sha: "a0000008", refName: "", summary: "Merge pull request #3 from empire-strikes-back", date: "1980-05-17" }, + { sha: "a0000007", refName: "", summary: "fix: destroy rebels base", date: "1980-05-17" }, + { sha: "a0000006", refName: "", summary: "chore: the end of Alderaan (#2)", date: "1980-05-17" }, + { sha: "a0000005", refName: "", summary: "refactor(death-star): add deflector shield", date: "1980-05-17" }, + { sha: "a0000004", refName: "tag: v4.0.0", summary: "chore(release): releasing component", date: "1977-05-25" }, + { sha: "a0000003", refName: "", summary: "Merge pull request #1 from star-wars", date: "1977-05-25" }, + { sha: "a0000002", refName: "tag: v0.1.0", summary: "chore(release): releasing component", date: "1966-01-01" }, + { sha: "a0000001", refName: "", summary: "fix: some random fix which will be ignored", date: "1966-01-01" }, ]; const listOfTags = [ @@ -80,43 +82,43 @@ const usersCache = { "https://api.github.com/users/luke": { login: "luke", html_url: "https://github.com/luke", - name: "Luke Skywalker" + name: "Luke Skywalker", }, "https://api.github.com/users/princess-leia": { login: "princess-leia", html_url: "https://github.com/princess-leia", - name: "Princess Leia Organa" + name: "Princess Leia Organa", }, "https://api.github.com/users/vader": { login: "vader", html_url: "https://github.com/vader", - name: "Darth Vader" + name: "Darth Vader", }, "https://api.github.com/users/gtarkin": { login: "gtarkin", html_url: "https://github.com/gtarkin", - name: "Governor Tarkin" + name: "Governor Tarkin", }, "https://api.github.com/users/han-solo": { login: "han-solo", html_url: "https://github.com/han-solo", - name: "Han Solo" + name: "Han Solo", }, "https://api.github.com/users/chewbacca": { login: "chewbacca", html_url: "https://github.com/chewbacca", - name: "Chwebacca" + name: "Chwebacca", }, "https://api.github.com/users/rd-d2": { login: "rd-d2", html_url: "https://github.com/rd-d2", - name: "R2-D2" + name: "R2-D2", }, "https://api.github.com/users/c-3po": { login: "c-3po", html_url: "https://github.com/c-3po", - name: "C-3PO" - } + name: "C-3PO", + }, }; const issuesCache = { "https://api.github.com/repos/lerna/lerna-changelog/issues/1": { @@ -200,7 +202,6 @@ const issuesCache = { }, }; - describe("createMarkdown", () => { beforeEach(() => { require("../fetch").__resetMockResponses(); @@ -236,10 +237,10 @@ describe("createMarkdown", () => { require("../git").changedPaths.mockImplementation((sha: string) => listOfPackagesForEachCommit[sha]); require("../git").lastTag.mockImplementation(() => "v8.0.0"); require("../git").listCommits.mockImplementation(() => [ - { sha: "a0000004", refName:"tag: a-new-hope@4.0.0, tag: empire-strikes-back@5.0.0, tag: return-of-the-jedi@6.0.0", summary: "chore(release): releasing component", date: "1977-05-25" }, - { sha: "a0000003", refName:"", summary: "Merge pull request #1 from star-wars", date: "1977-05-25" }, - { sha: "a0000002", refName:"tag: v0.1.0", summary: "chore(release): releasing component", date: "1966-01-01" }, - { sha: "a0000001", refName:"", summary: "fix: some random fix which will be ignored", date: "1966-01-01" }, + { sha: "a0000004", refName: "tag: a-new-hope@4.0.0, tag: empire-strikes-back@5.0.0, tag: return-of-the-jedi@6.0.0", summary: "chore(release): releasing component", date: "1977-05-25" }, + { sha: "a0000003", refName: "", summary: "Merge pull request #1 from star-wars", date: "1977-05-25" }, + { sha: "a0000002", refName: "tag: v0.1.0", summary: "chore(release): releasing component", date: "1966-01-01" }, + { sha: "a0000001", refName: "", summary: "fix: some random fix which will be ignored", date: "1966-01-01" }, ]); require("../git").listTagNames.mockImplementation(() => [ "a-new-hope@4.0.0", diff --git a/src/git.ts b/src/git.ts index 21232a5a..37daa860 100644 --- a/src/git.ts +++ b/src/git.ts @@ -1,7 +1,7 @@ const execa = require("execa"); export async function changedPaths(sha: string): Promise { - const result = await execa("git", ["show", "-m", "--name-only" ,"--pretty=format:", "--first-parent", sha]); + const result = await execa("git", ["show", "-m", "--name-only" , "--pretty=format:", "--first-parent", sha]); return result.stdout.split("\n"); } diff --git a/src/github-api.ts b/src/github-api.ts index 79378d2c..e0c83681 100644 --- a/src/github-api.ts +++ b/src/github-api.ts @@ -15,9 +15,9 @@ export interface GitHubIssueResponse { pull_request?: { html_url: string; }; - labels: { + labels: Array<{ name: string; - }[]; + }>; user: { login: string; html_url: string; @@ -31,40 +31,40 @@ export interface Options { } export default class GithubAPI { - cacheDir: string | undefined; - auth: string; + private cacheDir: string | undefined; + private auth: string; constructor(config: Options) { - this.cacheDir = config.cacheDir && path.join(config.rootPath, config.cacheDir, 'github'); + this.cacheDir = config.cacheDir && path.join(config.rootPath, config.cacheDir, "github"); this.auth = this.getAuthToken(); if (!this.auth) { throw new ConfigurationError("Must provide GITHUB_AUTH"); } } - getAuthToken(): string { - return process.env.GITHUB_AUTH; - } - - getBaseIssueUrl(repo: string): string { + public getBaseIssueUrl(repo: string): string { return `https://github.com/${repo}/issues/`; } - async getIssueData(repo: string, issue: string): Promise { + public async getIssueData(repo: string, issue: string): Promise { return this._fetch(`https://api.github.com/repos/${repo}/issues/${issue}`); } - async getUserData(login: string): Promise { + public async getUserData(login: string): Promise { return this._fetch(`https://api.github.com/users/${login}`); } - async _fetch(url: string): Promise { + private async _fetch(url: string): Promise { const res = await fetch(url, { cacheManager: this.cacheDir, headers: { - "Authorization": `token ${this.auth}`, + Authorization: `token ${this.auth}`, }, }); return res.json(); } + + private getAuthToken(): string { + return process.env.GITHUB_AUTH; + } } diff --git a/src/index.ts b/src/index.ts index 92638753..35c6c878 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,5 +3,5 @@ import ConfigurationError from "./configuration-error"; export { Changelog, - ConfigurationError + ConfigurationError, }; diff --git a/src/markdown-renderer.spec.ts b/src/markdown-renderer.spec.ts index 5da09ca0..03a5999f 100644 --- a/src/markdown-renderer.spec.ts +++ b/src/markdown-renderer.spec.ts @@ -1,53 +1,53 @@ -import MarkdownRenderer from "./markdown-renderer"; import {CommitInfo} from "./interfaces"; +import MarkdownRenderer from "./markdown-renderer"; const BASIC_COMMIT = { githubIssue: { - title: 'My cool PR', + title: "My cool PR", user: { - login: 'hzoo', - html_url: 'http://hzoo.com', + login: "hzoo", + html_url: "http://hzoo.com", }, }, } as CommitInfo; const COMMIT_WITH_NUMBER = { githubIssue: { - title: 'My cool PR', + title: "My cool PR", user: { - login: 'hzoo', - html_url: 'http://hzoo.com', + login: "hzoo", + html_url: "http://hzoo.com", }, number: 42, pull_request: { - html_url: 'http://github.com/42', + html_url: "http://github.com/42", }, }, } as CommitInfo; const COMMIT_WITH_GH_ISSUE_REF = { githubIssue: { - title: 'My cool PR (resolved #123)', + title: "My cool PR (resolved #123)", user: { - login: 'hzoo', - html_url: 'http://hzoo.com', + login: "hzoo", + html_url: "http://hzoo.com", }, }, } as CommitInfo; const COMMIT_WITH_PHAB_ISSUE_REF = { githubIssue: { - title: 'My cool PR (resolved T42)', + title: "My cool PR (resolved T42)", user: { - login: 'hzoo', - html_url: 'http://hzoo.com', + login: "hzoo", + html_url: "http://hzoo.com", }, }, } as CommitInfo; function renderer(options: any = {}): MarkdownRenderer { return new MarkdownRenderer({ - baseIssueUrl: 'http://foo.bar/', + baseIssueUrl: "http://foo.bar/", categories: [], ...options, }); @@ -109,15 +109,15 @@ describe("MarkdownRenderer", () => { describe("renderContributorList", () => { it(`renders a list of GitHub users`, () => { const user1 = { - login: 'hzoo', - name: '', - html_url: 'https://github.com/hzoo', + login: "hzoo", + name: "", + html_url: "https://github.com/hzoo", }; const user2 = { - login: 'Turbo87', - name: 'Tobias Bieniek', - html_url: 'https://github.com/Turbo87', + login: "Turbo87", + name: "Tobias Bieniek", + html_url: "https://github.com/Turbo87", }; const result = renderer().renderContributorList([user1, user2]); @@ -129,9 +129,9 @@ describe("MarkdownRenderer", () => { describe("renderContributor", () => { it(`renders GitHub user without name`, () => { const result = renderer().renderContributor({ - login: 'foo', - name: '', - html_url: 'http://github.com/foo', + login: "foo", + name: "", + html_url: "http://github.com/foo", }); expect(result).toEqual("[foo](http://github.com/foo)"); @@ -139,9 +139,9 @@ describe("MarkdownRenderer", () => { it(`renders GitHub user with name`, () => { const result = renderer().renderContributor({ - login: 'foo', - name: 'Foo Bar', - html_url: 'http://github.com/foo', + login: "foo", + name: "Foo Bar", + html_url: "http://github.com/foo", }); expect(result).toEqual("Foo Bar ([foo](http://github.com/foo))"); @@ -167,7 +167,7 @@ describe("MarkdownRenderer", () => { { commitSHA: "a0000002", categories: [] }, { commitSHA: "a0000001", categories: [":bug: Bug Fix"] }, ]; - const commitsByCategory = r.groupByCategory(testCommits as CommitInfo[]); + const commitsByCategory = r["groupByCategory"](testCommits as CommitInfo[]); expect(commitsByCategory).toMatchSnapshot(); }); diff --git a/src/markdown-renderer.ts b/src/markdown-renderer.ts index 06507705..cfb9958f 100644 --- a/src/markdown-renderer.ts +++ b/src/markdown-renderer.ts @@ -21,14 +21,14 @@ export default class MarkdownRenderer { this.options = options; } - renderMarkdown(releases: Release[]) { + public renderMarkdown(releases: Release[]) { return `\n${releases .map((release) => this.renderRelease(release)) .filter(Boolean) .join("\n\n\n")}`; } - renderRelease(release: Release): string | undefined { + public renderRelease(release: Release): string | undefined { // Group commits in release by category const categories = this.groupByCategory(release.commits); const categoriesWithCommits = categories.filter((category) => category.commits.length > 0); @@ -57,11 +57,7 @@ export default class MarkdownRenderer { return markdown; } - hasPackages(commits: CommitInfo[]) { - return commits.some((commit) => commit.packages !== undefined && commit.packages.length > 0); - } - - renderContributionsByPackage(commits: CommitInfo[]) { + public renderContributionsByPackage(commits: CommitInfo[]) { // Group commits in category by package const commitsByPackage: { [id: string]: CommitInfo[] } = {}; for (const commit of commits) { @@ -77,18 +73,18 @@ export default class MarkdownRenderer { const packageNames = Object.keys(commitsByPackage); return packageNames.map((packageName) => { - const commits = commitsByPackage[packageName]; - return `* ${packageName}\n${this.renderContributionList(commits, " ")}`; + const pkgCommits = commitsByPackage[packageName]; + return `* ${packageName}\n${this.renderContributionList(pkgCommits, " ")}`; }).join("\n"); } - renderPackageNames(packageNames: string[]) { + public renderPackageNames(packageNames: string[]) { return packageNames.length > 0 ? packageNames.map((pkg) => `\`${pkg}\``).join(", ") : "Other"; } - renderContributionList(commits: CommitInfo[], prefix: string = ""): string { + public renderContributionList(commits: CommitInfo[], prefix: string = ""): string { return commits .map((commit) => this.renderContribution(commit)) .filter(Boolean) @@ -96,7 +92,7 @@ export default class MarkdownRenderer { .join("\n"); } - renderContribution(commit: CommitInfo): string | undefined { + public renderContribution(commit: CommitInfo): string | undefined { const issue = commit.githubIssue; if (issue) { let markdown = ""; @@ -109,7 +105,7 @@ export default class MarkdownRenderer { if (issue.title && issue.title.match(COMMIT_FIX_REGEX)) { issue.title = issue.title.replace( COMMIT_FIX_REGEX, - `Closes [#$3](${this.options.baseIssueUrl}$3)` + `Closes [#$3](${this.options.baseIssueUrl}$3)`, ); } @@ -119,13 +115,13 @@ export default class MarkdownRenderer { } } - renderContributorList(contributors: GitHubUserResponse[]) { + public renderContributorList(contributors: GitHubUserResponse[]) { const renderedContributors = contributors.map((contributor) => `- ${this.renderContributor(contributor)}`).sort(); return `#### Committers: ${contributors.length}\n${renderedContributors.join("\n")}`; } - renderContributor(contributor: GitHubUserResponse): string { + public renderContributor(contributor: GitHubUserResponse): string { const userNameAndLink = `[${contributor.login}](${contributor.html_url})`; if (contributor.name) { return `${contributor.name} (${userNameAndLink})`; @@ -134,7 +130,11 @@ export default class MarkdownRenderer { } } - groupByCategory(allCommits: CommitInfo[]): CategoryInfo[] { + private hasPackages(commits: CommitInfo[]) { + return commits.some((commit) => commit.packages !== undefined && commit.packages.length > 0); + } + + private groupByCategory(allCommits: CommitInfo[]): CategoryInfo[] { return this.options.categories.map((name) => { // Keep only the commits that have a matching label with the one // provided in the lerna.json config. diff --git a/src/progress-bar.ts b/src/progress-bar.ts index 6b6d31e8..f332c681 100644 --- a/src/progress-bar.ts +++ b/src/progress-bar.ts @@ -2,13 +2,13 @@ const ProgressBar = require("progress"); const padEnd = require("string.prototype.padend"); class ProgressBarController { - bar: any; + private bar: any; constructor() { this.bar = null; } - init(total: number) { + public init(total: number) { if (this.bar) { this.terminate(); } @@ -20,37 +20,37 @@ class ProgressBarController { } this.bar = new ProgressBar(":packagename ╢:bar╟", { - total: total, + total, complete: "█", incomplete: "░", clear: true, // terminal columns - package name length - additional characters length - width: ((process.stdout as any).columns || 100) - 50 - 3 + width: ((process.stdout as any).columns || 100) - 50 - 3, }); } - setTitle(name: string) { + public setTitle(name: string) { if (this.bar) { this.bar.tick(0, { - packagename: padEnd(name.slice(0, 50), 50) + packagename: padEnd(name.slice(0, 50), 50), }); } } - tick() { + public tick() { if (this.bar) { this.bar.tick(1); } } - clear() { + public clear() { if (this.bar) { this.bar.terminate(); } } - terminate() { + public terminate() { this.clear(); this.bar = null; } From b978184d1c969c9580e96a0d8349551d4c1c33cb Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Sat, 16 Jun 2018 21:01:06 +0200 Subject: [PATCH 3/4] package.json: Fix `lint` script invocation --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1f0c37ab..588d3d9e 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "changelog": "node ./bin/cli.js", "clean": "rimraf lib", "fix": "npm run lint -- --fix", - "lint": "tslint src test", + "lint": "tslint --project . --format stylish", "prepublish": "npm run build", "test": "jest", "test-ci": "npm run build && jest", From b4ece64551df3fdd04bbaa15bdacf894a75a3feb Mon Sep 17 00:00:00 2001 From: Tobias Bieniek Date: Sat, 16 Jun 2018 20:39:05 +0200 Subject: [PATCH 4/4] Update `tslint` to v5.10.0 --- package.json | 2 +- yarn.lock | 79 +++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/package.json b/package.json index 588d3d9e..f03738e4 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "jest": "^20.0.4", "rimraf": "^2.5.4", "ts-jest": "^20.0.4", - "tslint": "^5.3.2", + "tslint": "^5.10.0", "typescript": "^2.9.2" }, "changelog": { diff --git a/yarn.lock b/yarn.lock index 3945e144..e17178ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -66,6 +66,12 @@ ansi-styles@^3.0.0: dependencies: color-convert "^1.0.0" +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + anymatch@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" @@ -388,7 +394,7 @@ bser@^2.0.0: dependencies: node-int64 "^0.4.0" -builtin-modules@^1.0.0: +builtin-modules@^1.0.0, builtin-modules@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -447,6 +453,14 @@ chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" +chalk@^2.3.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + chownr@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" @@ -481,20 +495,30 @@ color-convert@^1.0.0: dependencies: color-name "^1.1.1" +color-convert@^1.9.0: + version "1.9.2" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147" + dependencies: + color-name "1.1.1" + +color-name@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" + color-name@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.2.tgz#5c8ab72b64bd2215d617ae9559ebb148475cf98d" -colors@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" - combined-stream@^1.0.5, combined-stream@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" dependencies: delayed-stream "~1.0.0" +commander@^2.12.1: + version "2.15.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" + commander@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" @@ -704,7 +728,7 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -escape-string-regexp@^1.0.2: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -1027,6 +1051,10 @@ has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + has@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" @@ -1955,7 +1983,7 @@ once@~1.3.0: dependencies: wrappy "1" -optimist@^0.6.1, optimist@~0.6.0: +optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" dependencies: @@ -2529,6 +2557,12 @@ supports-color@^3.1.2: dependencies: has-flag "^1.0.0" +supports-color@^5.3.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + dependencies: + has-flag "^3.0.0" + symbol-tree@^3.2.1: version "3.2.2" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" @@ -2594,27 +2628,32 @@ tsconfig@^6.0.0: strip-bom "^3.0.0" strip-json-comments "^2.0.0" -tslib@^1.6.0: - version "1.7.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.7.1.tgz#bc8004164691923a79fe8378bbeb3da2017538ec" +tslib@^1.8.0, tslib@^1.8.1: + version "1.9.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.2.tgz#8be0cc9a1f6dc7727c38deb16c2ebd1a2892988e" -tslint@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.3.2.tgz#e56459fb095a7307f103b84052174f5e3bbef6ed" +tslint@^5.10.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.10.0.tgz#11e26bccb88afa02dd0d9956cae3d4540b5f54c3" dependencies: babel-code-frame "^6.22.0" - colors "^1.1.2" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" diff "^3.2.0" glob "^7.1.1" - optimist "~0.6.0" + js-yaml "^3.7.0" + minimatch "^3.0.4" resolve "^1.3.2" semver "^5.3.0" - tslib "^1.6.0" - tsutils "^2.0.0" + tslib "^1.8.0" + tsutils "^2.12.1" -tsutils@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.2.0.tgz#218614657f21c677e4536b4ba75daf8ebce1b367" +tsutils@^2.12.1: + version "2.27.1" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.27.1.tgz#ab0276ac23664f36ce8fd4414daec4aebf4373ee" + dependencies: + tslib "^1.8.1" tunnel-agent@~0.4.1: version "0.4.3"