Skip to content

Commit

Permalink
chore: Migrate from TSLint to ESLint (#54)
Browse files Browse the repository at this point in the history
* chore: convert to eslint

* chore: fix eslint issues

* chore(deps): use correct @types/node for node 8
  • Loading branch information
Chase McCarthy authored Nov 20, 2019
1 parent 6a3a895 commit 23b64a0
Show file tree
Hide file tree
Showing 15 changed files with 941 additions and 359 deletions.
7 changes: 6 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
{
"extends": "oclif"
"extends": [
"oclif",
"oclif-typescript"
],
"rules": {
}
}
18 changes: 10 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,21 @@
"@oclif/plugin-legacy": "^1.1.3",
"@oclif/plugin-plugins": "^1.7.6",
"@oclif/test": "^1.2.2",
"@oclif/tslint": "^3.1.1",
"@types/chai": "^4.1.7",
"@types/indent-string": "^3.2.0",
"@types/lodash.template": "^4.4.4",
"@types/mocha": "^5.2.5",
"@types/node": "^10.12.19",
"@types/node": "^8.10.59",
"@types/strip-ansi": "^3.0.0",
"@types/wrap-ansi": "^3.0.0",
"chai": "^4.2.0",
"eslint": "^6.6.0",
"eslint-config-oclif": "^3.1.0",
"eslint-config-oclif-typescript": "^0.1.0",
"globby": "^9.0.0",
"mocha": "^5.2.0",
"ts-node": "^8.0.2",
"tslint": "^5.12.1",
"typescript": "^3.2.4"
"typescript": "^3.7.2"
},
"engines": {
"node": ">=8.0.0"
Expand All @@ -60,11 +61,12 @@
"repository": "oclif/plugin-help",
"scripts": {
"build": "rm -rf lib && tsc",
"lint": "tsc -p test --noEmit && tslint -p test",
"postpack": "rm oclif.manifest.json",
"posttest": "yarn run lint",
"lint": "eslint . --ext .ts --config .eslintrc",
"pretest": "tsc -p test --noEmit",
"test": "mocha --forbid-only \"test/**/*.test.ts\"",
"posttest": "yarn lint",
"prepack": "yarn run build && oclif-dev manifest",
"test": "mocha --forbid-only \"test/**/*.test.ts\""
"postpack": "rm oclif.manifest.json"
},
"types": "./lib/index.d.ts"
}
30 changes: 17 additions & 13 deletions src/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ import {HelpOptions} from '.'
import {renderList} from './list'
import {castArray, compact, sortBy, template} from './util'

let {
const {
underline,
dim,
bold,
} = chalk
let {
dim,
} = chalk

if (process.env.ConEmuANSI === 'ON') {
dim = chalk.gray
Expand All @@ -21,6 +23,7 @@ const wrap = require('wrap-ansi')

export default class CommandHelp {
render: (input: string) => string

constructor(public command: Config.Command, public config: Config.IConfig, public opts: HelpOptions) {
this.render = template(this)
}
Expand Down Expand Up @@ -48,7 +51,7 @@ export default class CommandHelp {

protected usage(flags: Config.Command.Flag[]): string {
const usage = this.command.usage
let body = (usage ? castArray(usage) : [this.defaultUsage(flags)])
const body = (usage ? castArray(usage) : [this.defaultUsage(flags)])
.map(u => `$ ${this.config.bin} ${u}`.trim())
.join('\n')
return [
Expand All @@ -67,7 +70,7 @@ export default class CommandHelp {

protected description(): string | undefined {
const cmd = this.command
let description = cmd.description && this.render(cmd.description).split('\n').slice(1).join('\n')
const description = cmd.description && this.render(cmd.description).split('\n').slice(1).join('\n')
if (!description) return
return [
bold('DESCRIPTION'),
Expand All @@ -76,26 +79,26 @@ export default class CommandHelp {
}

protected aliases(aliases: string[] | undefined): string | undefined {
if (!aliases || !aliases.length) return
let body = aliases.map(a => ['$', this.config.bin, a].join(' ')).join('\n')
if (!aliases || aliases.length === 0) return
const body = aliases.map(a => ['$', this.config.bin, a].join(' ')).join('\n')
return [
bold('ALIASES'),
indent(wrap(body, this.opts.maxWidth - 2, {trim: false, hard: true}), 2),
].join('\n')
}

protected examples(examples: string[] | undefined | string): string | undefined {
if (!examples || !examples.length) return
let body = castArray(examples).map(a => this.render(a)).join('\n')
if (!examples || examples.length === 0) return
const body = castArray(examples).map(a => this.render(a)).join('\n')
return [
bold('EXAMPLE' + (examples.length > 1 ? 'S' : '')),
indent(wrap(body, this.opts.maxWidth - 2, {trim: false, hard: true}), 2),
].join('\n')
}

protected args(args: Config.Command['args']): string | undefined {
if (!args.filter(a => a.description).length) return
let body = renderList(args.map(a => {
if (args.filter(a => a.description).length === 0) return
const body = renderList(args.map(a => {
const name = a.name.toUpperCase()
let description = a.description || ''
if (a.default) description = `[default: ${a.default}] ${description}`
Expand All @@ -107,15 +110,16 @@ export default class CommandHelp {
indent(body, 2),
].join('\n')
}

protected arg(arg: Config.Command['args'][0]): string {
let name = arg.name.toUpperCase()
const name = arg.name.toUpperCase()
if (arg.required) return `${name}`
return `[${name}]`
}

protected flags(flags: Config.Command.Flag[]): string | undefined {
if (!flags.length) return
let body = renderList(flags.map(flag => {
if (flags.length === 0) return
const body = renderList(flags.map(flag => {
let left = flag.helpLabel

if (!left) {
Expand Down
7 changes: 5 additions & 2 deletions src/commands/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import Help from '..'

export default class HelpCommand extends Command {
static description = 'display help for <%= config.bin %>'

static flags = {
all: flags.boolean({description: 'see all commands in CLI'}),
}

static args = [
{name: 'command', required: false, description: 'command to show help for'}
{name: 'command', required: false, description: 'command to show help for'},
]

static strict = false

async run() {
const {flags, argv} = this.parse(HelpCommand)
let help = new Help(this.config, {all: flags.all})
const help = new Help(this.config, {all: flags.all})
help.showHelp(argv)
}
}
4 changes: 1 addition & 3 deletions src/global.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
// tslint:disable

declare namespace NodeJS {
interface Global {
'columns': number
'columns': number;
}
}
65 changes: 38 additions & 27 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,27 @@ const {
} = chalk

export interface HelpOptions {
all?: boolean
maxWidth: number
stripAnsi?: boolean
all?: boolean;
maxWidth: number;
stripAnsi?: boolean;
}

function getHelpSubject(args: string[]): string | undefined {
// special case
// if (['help:help', 'help:--help', '--help:help'].includes(argv.slice(0, 2).join(':'))) {
// if (argv[0] === 'help') return 'help'

for (const arg of args) {
if (arg === '--') return
if (arg.startsWith('-')) continue
if (arg === 'help') continue
return arg
}
}

export default class Help {
opts: HelpOptions

render: (input: string) => string

constructor(public config: Config.IConfig, opts: Partial<HelpOptions> = {}) {
Expand All @@ -31,25 +45,22 @@ export default class Help {
}

showHelp(argv: string[]) {
const getHelpSubject = () => {
// special case
// if (['help:help', 'help:--help', '--help:help'].includes(argv.slice(0, 2).join(':'))) {
// if (argv[0] === 'help') return 'help'

for (let arg of argv) {
if (arg === '--') return
if (arg.startsWith('-')) continue
if (arg === 'help') continue
return arg
}
}
let topics = this.config.topics
topics = topics.filter(t => this.opts.all || !t.hidden)
topics = sortBy(topics, t => t.name)
topics = uniqBy(topics, t => t.name)
let subject = getHelpSubject()
const subject = getHelpSubject(argv)

let command: Config.Command | undefined
if (subject) {
command = this.config.findCommand(subject)
}

let topic: Config.Topic | undefined
if (subject && !command) {
topic = this.config.findTopic(subject)
}

if (!subject) {
console.log(this.root())
console.log()
Expand All @@ -58,14 +69,14 @@ export default class Help {
}
console.log(this.topics(topics))
console.log()
} else if (command = this.config.findCommand(subject)) {
} else if (command) {
this.showCommandHelp(command, topics)
} else if (topic = this.config.findTopic(subject)) {
} else if (topic) {
const name = topic.name
const depth = name.split(':').length
topics = topics.filter(t => t.name.startsWith(name + ':') && t.name.split(':').length === depth + 1)
console.log(this.topic(topic))
if (topics.length) {
if (topics.length > 0) {
console.log(this.topics(topics))
console.log()
}
Expand All @@ -78,11 +89,11 @@ export default class Help {
const name = command.id
const depth = name.split(':').length
topics = topics.filter(t => t.name.startsWith(name + ':') && t.name.split(':').length === depth + 1)
let title = command.description && this.render(command.description).split('\n')[0]
const title = command.description && this.render(command.description).split('\n')[0]
if (title) console.log(title + '\n')
console.log(this.command(command))
console.log()
if (topics.length) {
if (topics.length > 0) {
console.log(this.topics(topics))
console.log()
}
Expand All @@ -95,7 +106,7 @@ export default class Help {

topic(topic: Config.Topic): string {
let description = this.render(topic.description || '')
let title = description.split('\n')[0]
const title = description.split('\n')[0]
description = description.split('\n').slice(1).join('\n')
let output = compact([
title,
Expand All @@ -105,8 +116,8 @@ export default class Help {
].join('\n'),
description && ([
bold('DESCRIPTION'),
indent(wrap(description, this.opts.maxWidth - 2, {trim: false, hard: true}), 2)
].join('\n'))
indent(wrap(description, this.opts.maxWidth - 2, {trim: false, hard: true}), 2),
].join('\n')),
]).join('\n\n')
if (this.opts.stripAnsi) output = stripAnsi(output)
return output + '\n'
Expand All @@ -118,10 +129,10 @@ export default class Help {
}

topics(topics: Config.Topic[]): string | undefined {
if (!topics.length) return
let body = renderList(topics.map(c => [
if (topics.length === 0) return
const body = renderList(topics.map(c => [
c.name,
c.description && this.render(c.description.split('\n')[0])
c.description && this.render(c.description.split('\n')[0]),
]), {
spacer: '\n',
stripAnsi: this.opts.stripAnsi,
Expand Down
7 changes: 4 additions & 3 deletions src/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ const wrap = require('wrap-ansi')

const widestLine = require('widest-line')

export function renderList(input: (string | undefined)[][], opts: {maxWidth: number, multiline?: boolean, stripAnsi?: boolean, spacer?: string}): string {
export function renderList(input: (string | undefined)[][], opts: {maxWidth: number; multiline?: boolean; stripAnsi?: boolean; spacer?: string}): string {
if (input.length === 0) {
return ''
}
const renderMultiline = () => {
output = ''
let output = ''
for (let [left, right] of input) {
if (!left && !right) continue
if (left) {
Expand All @@ -32,7 +32,8 @@ export function renderList(input: (string | undefined)[][], opts: {maxWidth: num
let output = ''
let spacer = opts.spacer || '\n'
let cur = ''
for (let [left, right] of input) {
for (const [left, r] of input) {
let right = r
if (cur) {
output += spacer
output += cur
Expand Down
1 change: 0 additions & 1 deletion src/root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,4 @@ export default class RootHelp {
indent(wrap(this.config.userAgent, this.opts.maxWidth - 2, {trim: false, hard: true}), 2),
].join('\n')
}

}
4 changes: 2 additions & 2 deletions src/screen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ function termwidth(stream: any): number {

const columns: number | null = parseInt(process.env.COLUMNS!, 10) || (global as any).columns

export let stdtermwidth = columns || termwidth(process.stdout)
export let errtermwidth = columns || termwidth(process.stderr)
export const stdtermwidth = columns || termwidth(process.stdout)
export const errtermwidth = columns || termwidth(process.stderr)
15 changes: 10 additions & 5 deletions src/util.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import Template = require('lodash.template')
import lodashTemplate = require('lodash.template')

export function uniqBy<T>(arr: T[], fn: (cur: T) => any): T[] {
return arr.filter((a, i) => {
let aVal = fn(a)
const aVal = fn(a)
return !arr.find((b, j) => j > i && fn(b) === aVal)
})
}

export function compact<T>(a: (T | undefined)[]): T[] {
return a.filter((a): a is T => !!a)
return a.filter((a): a is T => Boolean(a))
}

export function castArray<T>(input?: T | T[]): T[] {
Expand All @@ -23,7 +23,7 @@ export function sortBy<T>(arr: T[], fn: (i: T) => sort.Types | sort.Types[]): T[

if (Array.isArray(a) && Array.isArray(b)) {
if (a.length === 0 && b.length === 0) return 0
let diff = compare(a[0], b[0])
const diff = compare(a[0], b[0])
if (diff !== 0) return diff
return compare(a.slice(1), b.slice(1))
}
Expand All @@ -40,4 +40,9 @@ export namespace sort {
export type Types = string | number | undefined | boolean
}

export const template = (context: any) => (t: string): string => Template(t)(context)
export function template(context: any): (t: string) => string {
function render(t: string): string {
return lodashTemplate(t)(context)
}
return render
}
Loading

0 comments on commit 23b64a0

Please sign in to comment.