Skip to content

Commit

Permalink
Merge branch 'main' into mdonnalley/clear-legacy-commands
Browse files Browse the repository at this point in the history
  • Loading branch information
mdonnalley authored Oct 24, 2023
2 parents 13deca9 + 0ee44e4 commit c20c7ba
Show file tree
Hide file tree
Showing 33 changed files with 463 additions and 248 deletions.
62 changes: 62 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,65 @@
# [3.6.0](https://github.com/oclif/core/compare/3.4.1-dev.0...3.6.0) (2023-10-23)


### Bug Fixes

* safely fail if pnpapi cannot be found ([c2fc8d2](https://github.com/oclif/core/commit/c2fc8d2cfe4360602ad8be9ae5c4fe1947c9ef27))



# [3.5.0](https://github.com/oclif/core/compare/3.4.0...3.5.0) (2023-10-19)



## [3.4.1-dev.0](https://github.com/oclif/core/compare/3.5.0...3.4.1-dev.0) (2023-10-19)


### Features

* better support yarn PnP ([c5d87fc](https://github.com/oclif/core/commit/c5d87fc9bb30973fb055143c92df7bc27de16554))
* support pnp plugins ([8e217a6](https://github.com/oclif/core/commit/8e217a6b9a0d5824113f0c68c9be009440331f23))



# [3.5.0](https://github.com/oclif/core/compare/3.4.0...3.5.0) (2023-10-19)


### Bug Fixes

* compile error ([15d6556](https://github.com/oclif/core/commit/15d65561583e5f419ce0037435978f2a58745f0c))


### Features

* don't error on exit code 0 ([c62fb01](https://github.com/oclif/core/commit/c62fb012a8e579c46f76d66397abe40a3894a9b1))



# [3.4.0](https://github.com/oclif/core/compare/3.3.3...3.4.0) (2023-10-19)


### Bug Fixes

* add pluginPrefix type ([f14181e](https://github.com/oclif/core/commit/f14181e071f8c5d7f93646eef2e8d35b39dde0a7))


### Features

* export ux stubs ([4b7cdda](https://github.com/oclif/core/commit/4b7cddafef4e0f4a494b8be273f09575081a93c8))
* no longer use wrapped process.stdout and process.stderr ([3ff5f63](https://github.com/oclif/core/commit/3ff5f6357a1157aa402ca580babb05eb13e7a249))



## [3.3.3](https://github.com/oclif/core/compare/3.3.2...3.3.3) (2023-10-19)


### Bug Fixes

* allow github-installed plugins to be auto-transpiled ([6f2c5e2](https://github.com/oclif/core/commit/6f2c5e2ec9b9bafa7dea4ae2e7350ada64ff0e88))
* handle ModuleLoadError from hooks ([0321093](https://github.com/oclif/core/commit/0321093e4f8a0f659346a9e2e808ad44c6d3771f))



## [3.3.2](https://github.com/oclif/core/compare/3.3.1...3.3.2) (2023-10-17)


Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@oclif/core",
"description": "base library for oclif CLIs",
"version": "3.3.3-dev.0",
"version": "3.6.0",
"author": "Salesforce",
"bugs": "https://github.com/oclif/core/issues",
"dependencies": {
Expand Down Expand Up @@ -49,6 +49,7 @@
"@types/mocha": "^10.0.2",
"@types/node": "^18",
"@types/node-notifier": "^8.0.2",
"@types/pnpapi": "^0.0.4",
"@types/slice-ansi": "^4.0.0",
"@types/strip-ansi": "^5.2.1",
"@types/supports-color": "^8.1.1",
Expand All @@ -72,7 +73,7 @@
"nyc": "^15.1.0",
"prettier": "^3.0.3",
"shx": "^0.3.4",
"sinon": "^11.1.2",
"sinon": "^16.1.0",
"ts-node": "^10.9.1",
"tsd": "^0.29.0",
"typescript": "^5"
Expand Down
21 changes: 10 additions & 11 deletions src/cli-ux/action/base.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {inspect} from 'node:util'

import {castArray} from '../../util/util'
import {stderr, stdout} from '../stream'
import {Options} from './types'

export interface ITask {
Expand All @@ -20,8 +19,8 @@ export class ActionBase {
type!: ActionType

private stdmockOrigs = {
stderr: stderr.write,
stdout: stdout.write,
stderr: process.stderr.write,
stdout: process.stdout.write,
}

protected get output(): string | undefined {
Expand Down Expand Up @@ -158,26 +157,26 @@ export class ActionBase {
if (toggle) {
if (this.stdmocks) return
this.stdmockOrigs = {
stderr: stderr.write,
stdout: stdout.write,
stderr: process.stderr.write,
stdout: process.stdout.write,
}

this.stdmocks = []
stdout.write = (...args: any[]) => {
process.stdout.write = (...args: any[]) => {
this.stdmocks!.push(['stdout', args] as ['stdout', string[]])
return true
}

stderr.write = (...args: any[]) => {
process.stderr.write = (...args: any[]) => {
this.stdmocks!.push(['stderr', args] as ['stderr', string[]])
return true
}
} else {
if (!this.stdmocks) return
// this._write('stderr', '\nresetstdmock\n\n\n')
delete this.stdmocks
stdout.write = this.stdmockOrigs.stdout
stderr.write = this.stdmockOrigs.stderr
process.stdout.write = this.stdmockOrigs.stdout
process.stderr.write = this.stdmockOrigs.stderr
}
} catch (error) {
this._write('stderr', inspect(error))
Expand All @@ -196,12 +195,12 @@ export class ActionBase {
protected _write(std: 'stderr' | 'stdout', s: string | string[]): void {
switch (std) {
case 'stdout': {
this.stdmockOrigs.stdout.apply(stdout, castArray(s) as [string])
this.stdmockOrigs.stdout.apply(process.stdout, castArray(s) as [string])
break
}

case 'stderr': {
this.stdmockOrigs.stderr.apply(stderr, castArray(s) as [string])
this.stdmockOrigs.stderr.apply(process.stderr, castArray(s) as [string])
break
}

Expand Down
5 changes: 2 additions & 3 deletions src/cli-ux/flush.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {error} from '../errors'
import {stdout} from './stream'

function timeout(p: Promise<any>, ms: number) {
function wait(ms: number, unref = false) {
Expand All @@ -14,9 +13,9 @@ function timeout(p: Promise<any>, ms: number) {

async function _flush() {
const p = new Promise((resolve) => {
stdout.once('drain', () => resolve(null))
process.stdout.once('drain', () => resolve(null))
})
const flushed = stdout.write('')
const flushed = process.stdout.write('')

if (flushed) return

Expand Down
22 changes: 15 additions & 7 deletions src/cli-ux/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ import {format as utilFormat} from 'node:util'

import * as Errors from '../errors'
import {ActionBase} from './action/base'
import {Config, config} from './config'
import {config} from './config'
import {flush as _flush} from './flush'
import * as uxPrompt from './prompt'
import {stdout} from './stream'
import * as styled from './styled'
import uxWait from './wait'
import write from './write'

const hyperlinker = require('hyperlinker')

export class ux {
public static config: Config = config
public static config = config

public static get action(): ActionBase {
return config.action
Expand Down Expand Up @@ -42,7 +42,7 @@ export class ux {

public static debug(format: string, ...args: string[]): void {
if (['debug', 'trace'].includes(this.config.outputLevel)) {
stdout.write(utilFormat(format, ...args) + '\n')
this.info(utilFormat(format, ...args) + '\n')
}
}

Expand All @@ -55,13 +55,17 @@ export class ux {
}

public static info(format: string, ...args: string[]): void {
stdout.write(utilFormat(format, ...args) + '\n')
write.stdout(utilFormat(format, ...args) + '\n')
}

public static log(format?: string, ...args: string[]): void {
this.info(format || '', ...args)
}

public static logToStderr(format?: string, ...args: string[]): void {
write.stderr(utilFormat(format, ...args) + '\n')
}

public static get progress(): typeof styled.progress {
return styled.progress
}
Expand All @@ -77,7 +81,7 @@ export class ux {
public static styledJSON(obj: unknown): void {
const json = JSON.stringify(obj, null, 2)
if (!chalk.level) {
info(json)
this.info(json)
return
}

Expand All @@ -96,7 +100,7 @@ export class ux {

public static trace(format: string, ...args: string[]): void {
if (this.config.outputLevel === 'trace') {
stdout.write(utilFormat(format, ...args) + '\n')
this.info(utilFormat(format, ...args) + '\n')
}
}

Expand Down Expand Up @@ -128,6 +132,7 @@ const {
flush,
info,
log,
logToStderr,
progress,
prompt,
styledHeader,
Expand All @@ -153,6 +158,7 @@ export {
flush,
info,
log,
logToStderr,
progress,
prompt,
styledHeader,
Expand Down Expand Up @@ -186,4 +192,6 @@ export {ActionBase} from './action/base'
export {Config, config} from './config'
export {ExitError} from './exit'
export {IPromptOptions} from './prompt'
export {makeStubs} from './stub'

export {Table} from './styled'
7 changes: 3 additions & 4 deletions src/cli-ux/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import chalk from 'chalk'

import * as Errors from '../errors'
import {config} from './config'
import {stderr} from './stream'

export interface IPromptOptions {
default?: string
Expand Down Expand Up @@ -38,7 +37,7 @@ function normal(options: IPromptConfig, retries = 100): Promise<string> {
}

process.stdin.setEncoding('utf8')
stderr.write(options.prompt)
process.stderr.write(options.prompt)
process.stdin.resume()
process.stdin.once('data', (b) => {
if (timer) clearTimeout(timer)
Expand Down Expand Up @@ -77,7 +76,7 @@ async function single(options: IPromptConfig): Promise<string> {

function replacePrompt(prompt: string) {
const ansiEscapes = require('ansi-escapes')
stderr.write(
process.stderr.write(
ansiEscapes.cursorHide +
ansiEscapes.cursorUp(1) +
ansiEscapes.cursorLeft +
Expand Down Expand Up @@ -178,7 +177,7 @@ export async function anykey(message?: string): Promise<string> {
}

const char = await prompt(message, {required: false, type: 'single'})
if (tty) stderr.write('\n')
if (tty) process.stderr.write('\n')
if (char === 'q') Errors.error('quit')
if (char === '\u0003') Errors.error('ctrl-c')
return char
Expand Down
6 changes: 6 additions & 0 deletions src/cli-ux/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,11 @@ class Stream {
}
}

/**
* @deprecated Use process.stdout directly. This will be removed in the next major version
*/
export const stdout = new Stream('stdout')
/**
* @deprecated Use process.stderr directly. This will be removed in the next major version
*/
export const stderr = new Stream('stderr')
40 changes: 40 additions & 0 deletions src/cli-ux/stub.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import type {SinonSandbox, SinonStub} from 'sinon'

import write from './write'

type Stubs = {
stderr: SinonStub
stdout: SinonStub
}

/**
* Create sinon stubs for writing to stdout and stderr.
*
* @example
* import {ux} from '@oclif/core'
*
* describe('example', () => {
* let sandbox: SinonSandbox
* let stubs: ReturnType<typeof ux.makeStubs>
*
* beforeEach(() => {
* sandbox = createSandbox()
* stubs = ux.makeStubs(sandbox)
* })
*
* afterEach(() => {
* sandbox.restore()
* })
*
* it('should log text to the console', () => {
* ux.log('Hello, world!')
* expect(stubs.stdout.firstCall.firstArg).to.equal('Hello, world!\n')
* })
* })
*/
export function makeStubs(sandbox: SinonSandbox): Stubs {
return {
stderr: sandbox.stub(write, 'stderr'),
stdout: sandbox.stub(write, 'stdout'),
}
}
8 changes: 4 additions & 4 deletions src/cli-ux/styled/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import * as F from '../../flags'
import * as Interfaces from '../../interfaces'
import {stdtermwidth} from '../../screen'
import {capitalize, sumBy} from '../../util/util'
import {stdout} from '../stream'
import write from '../write'

class Table<T extends Record<string, unknown>> {
columns: (table.Column<T> & {key: string; maxWidth?: number; width?: number})[]
Expand Down Expand Up @@ -48,7 +48,7 @@ class Table<T extends Record<string, unknown>> {
'no-header': options['no-header'] ?? false,
'no-truncate': options['no-truncate'] ?? false,
output: csv ? 'csv' : output,
printLine: printLine ?? ((s: any) => stdout.write(s + '\n')),
printLine: printLine ?? ((s: any) => write.stdout(s + '\n')),
rowStart: ' ',
sort,
title,
Expand Down Expand Up @@ -97,7 +97,7 @@ class Table<T extends Record<string, unknown>> {
const filters = this.options.columns!.split(',')
this.columns = this.filterColumnsFromHeaders(filters)
} else if (!this.options.extended) {
// show extented columns/properties
// show extended columns/properties
this.columns = this.columns.filter((c) => !c.extended)
}

Expand Down Expand Up @@ -189,7 +189,7 @@ class Table<T extends Record<string, unknown>> {
// truncation logic
const shouldShorten = () => {
// don't shorten if full mode
if (options['no-truncate'] || (!stdout.isTTY && !process.env.CLI_UX_SKIP_TTY_CHECK)) return
if (options['no-truncate'] || (!process.stdout.isTTY && !process.env.CLI_UX_SKIP_TTY_CHECK)) return

// don't shorten if there is enough screen width
const dataMaxWidth = sumBy(columns, (c) => c.width!)
Expand Down
Loading

0 comments on commit c20c7ba

Please sign in to comment.