Skip to content

Commit

Permalink
Merge pull request #892 from oclif/mdonnalley/no-tsconfck
Browse files Browse the repository at this point in the history
feat: no longer use tsconfck
  • Loading branch information
iowillhoit authored Jan 9, 2024
2 parents 6d6fc12 + eafdba3 commit 1542bd7
Show file tree
Hide file tree
Showing 19 changed files with 396 additions and 79 deletions.
36 changes: 18 additions & 18 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
windows-unit-tests:
needs: linux-unit-tests
uses: salesforcecli/github-workflows/.github/workflows/unitTestsWindows.yml@main
e2e:
integration:
needs: linux-unit-tests
strategy:
matrix:
Expand All @@ -33,10 +33,10 @@ jobs:
- uses: salesforcecli/github-workflows/.github/actions/yarnInstallWithRetries@main
- run: yarn build
- if: runner.os == 'Windows'
run: yarn mocha --forbid-only "test/**/*.e2e.ts" --exclude "test/integration/sf.e2e.ts" --parallel --timeout 1200000
run: yarn mocha --forbid-only "test/**/*.integration.ts" --exclude "test/integration/sf.integration.ts" --parallel --timeout 1200000
- if: runner.os == 'Linux'
run: yarn test:e2e
windows-sf-e2e:
run: yarn test:integration
windows-sf-integration:
# For whatever reason the windows-latest runner doesn't like it when you shell yarn commands in the sf repo
# which is an integral part of the setup for the tests. Instead, we replicate the setup here.
needs: linux-unit-tests
Expand All @@ -52,8 +52,8 @@ jobs:
- uses: salesforcecli/github-workflows/.github/actions/yarnInstallWithRetries@main
- run: yarn build
- run: yarn link
- run: New-Item -Path D:\a -Name "e2e" -ItemType "directory"
- run: New-Item -Path D:\a\e2e -Name "sf.e2e.ts" -ItemType "directory"
- run: New-Item -Path D:\a -Name "integration" -ItemType "directory"
- run: New-Item -Path D:\a\integration -Name "sf.integration.ts" -ItemType "directory"
- run: |
git clone https://github.com/salesforcecli/cli.git
cd cli
Expand All @@ -66,12 +66,12 @@ jobs:
yarn install --network-timeout 600000
yarn link @oclif/core
yarn build
working-directory: D:\a\e2e\sf.e2e.ts
- run: yarn mocha --forbid-only "test/integration/sf.e2e.ts" --parallel --timeout 1200000
working-directory: D:\a\integration\sf.integration.ts
- run: yarn mocha --forbid-only "test/integration/sf.integration.ts" --parallel --timeout 1200000
env:
OCLIF_CORE_E2E_SKIP_SETUP: true
OCLIF_CORE_E2E_TEST_DIR: D:\a\e2e
DEBUG: e2e:*
OCLIF_CORE_INTEGRATION_SKIP_SETUP: true
OCLIF_CORE_INTEGRATION_TEST_DIR: D:\a\integration
DEBUG: integration:*
esm-cjs-interop:
needs: linux-unit-tests
strategy:
Expand Down Expand Up @@ -108,13 +108,13 @@ jobs:
- https://github.com/salesforcecli/plugin-schema
- https://github.com/salesforcecli/plugin-user
with:
packageName: "@oclif/core"
packageName: '@oclif/core'
externalProjectGitUrl: ${{ matrix.externalProjectGitUrl }}
command: "yarn test:nuts"
command: 'yarn test:nuts'
os: ${{ matrix.os }}
useCache: false
preSwapCommands: "npx yarn-deduplicate; yarn install"
preExternalBuildCommands: "shx rm -rf node_modules/@salesforce/sf-plugins-core/node_modules/@oclif/core"
preSwapCommands: 'npx yarn-deduplicate; yarn install'
preExternalBuildCommands: 'shx rm -rf node_modules/@salesforce/sf-plugins-core/node_modules/@oclif/core'
ignoreScripts: true
secrets:
TESTKIT_AUTH_URL: ${{ secrets.TESTKIT_AUTH_URL }}
Expand Down Expand Up @@ -142,7 +142,7 @@ jobs:
with:
repo: ${{ matrix.repo }}
os: ${{ matrix.os }}
command: "yarn mocha test/**/*.test.ts --timeout 1200000"
command: 'yarn mocha test/**/*.test.ts --timeout 1200000'
plugin-plugins-integration:
needs: linux-unit-tests
strategy:
Expand All @@ -153,7 +153,7 @@ jobs:
with:
repo: oclif/plugin-plugins
os: ${{ matrix.os }}
command: "yarn test:integration"
command: 'yarn test:integration'
# plugin-plugins integration tests depend on sf being installed globally
other-setup: npm install -g @salesforce/cli@nightly
plugin-update-integration:
Expand All @@ -166,4 +166,4 @@ jobs:
with:
repo: oclif/plugin-update
os: ${{ matrix.os }}
command: "yarn test:integration:sf"
command: 'yarn test:integration:sf'
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@
/test/tmp
.DS_Store
.idea
/test/**/node_modules
/test/**/yarn.lock
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
"strip-ansi": "^6.0.1",
"supports-color": "^8.1.1",
"supports-hyperlinks": "^2.2.0",
"tsconfck": "^3.0.0",
"widest-line": "^3.1.0",
"wordwrap": "^1.0.0",
"wrap-ansi": "^7.0.0"
Expand Down Expand Up @@ -121,8 +120,8 @@
"pretest": "yarn build && tsc -p test --noEmit --skipLibCheck",
"test:circular-deps": "madge lib/ -c",
"test:debug": "nyc mocha --debug-brk --inspect \"test/**/*.test.ts\"",
"test:e2e": "mocha --forbid-only \"test/**/*.e2e.ts\" --parallel --timeout 1200000",
"test:esm-cjs": "cross-env DEBUG=e2e:* ts-node test/integration/esm-cjs.ts",
"test:integration": "mocha --forbid-only \"test/**/*.integration.ts\" --parallel --timeout 1200000",
"test:esm-cjs": "cross-env DEBUG=integration:* ts-node test/integration/esm-cjs.ts",
"test:perf": "ts-node test/perf/parser.perf.ts",
"test:dev": "nyc mocha \"test/**/*.test.ts\"",
"test": "nyc mocha --forbid-only \"test/**/*.test.ts\""
Expand Down
7 changes: 4 additions & 3 deletions src/config/ts-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import Cache from '../cache'
import {memoizedWarn} from '../errors'
import {Plugin, TSConfig} from '../interfaces'
import {settings} from '../settings'
import {existsSync, readTSConfig} from '../util/fs'
import {existsSync} from '../util/fs'
import {readTSConfig} from '../util/read-tsconfig'
import {isProd} from '../util/util'
import {Debug} from './util'
// eslint-disable-next-line new-cap
const debug = Debug('ts-node')

export const TS_CONFIGS: Record<string, TSConfig> = {}
export const TS_CONFIGS: Record<string, TSConfig | undefined> = {}
const REGISTERED = new Set<string>()

function isErrno(error: any): error is NodeJS.ErrnoException {
Expand All @@ -22,7 +23,7 @@ async function loadTSConfig(root: string): Promise<TSConfig | undefined> {
try {
if (TS_CONFIGS[root]) return TS_CONFIGS[root]

TS_CONFIGS[root] = await readTSConfig(join(root, 'tsconfig.json'))
TS_CONFIGS[root] = await readTSConfig(root)

return TS_CONFIGS[root]
} catch (error) {
Expand Down
98 changes: 65 additions & 33 deletions src/flags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,23 @@ import {BooleanFlag, CustomOptions, FlagDefinition, OptionFlag} from './interfac
import {dirExists, fileExists} from './util/fs'

type NotArray<T> = T extends Array<any> ? never : T

/**
* Create a custom flag.
*
* @example
* type Id = string
* type IdOpts = { startsWith: string; length: number }
*
* export const myFlag = custom<Id, IdOpts>({
* parse: async (input, opts) => {
* if (input.startsWith(opts.startsWith) && input.length === opts.length) {
* return input
* }
*
* throw new Error('Invalid id')
* },
* })
*/
export function custom<T = string, P extends CustomOptions = CustomOptions>(
defaults: Partial<OptionFlag<T[], P>> & {
multiple: true
Expand Down Expand Up @@ -40,23 +56,7 @@ export function custom<T = string, P extends CustomOptions = CustomOptions>(): F
P,
{multiple: false; requiredOrDefaulted: false}
>
/**
* Create a custom flag.
*
* @example
* type Id = string
* type IdOpts = { startsWith: string; length: number };
*
* export const myFlag = custom<Id, IdOpts>({
* parse: async (input, opts) => {
* if (input.startsWith(opts.startsWith) && input.length === opts.length) {
* return input
* }
*
* throw new Error('Invalid id')
* },
* })
*/

export function custom<T = string, P extends CustomOptions = CustomOptions>(
defaults?: Partial<OptionFlag<T, P>>,
): FlagDefinition<T, P, {multiple: boolean; requiredOrDefaulted: boolean}> {
Expand All @@ -70,6 +70,11 @@ export function custom<T = string, P extends CustomOptions = CustomOptions>(
})
}

/**
* A boolean flag. Defaults to `false` unless default is set to `true`.
*
* - `allowNo` option allows `--no-` prefix to negate boolean flag.
*/
export function boolean<T = boolean>(options: Partial<BooleanFlag<T>> = {}): BooleanFlag<T> {
return {
parse: async (b, _) => b,
Expand All @@ -79,6 +84,12 @@ export function boolean<T = boolean>(options: Partial<BooleanFlag<T>> = {}): Boo
} as BooleanFlag<T>
}

/**
* An integer flag. Throws an error if the provided value is not a valid integer.
*
* - `min` option allows to set a minimum value.
* - `max` option allows to set a maximum value.
*/
export const integer = custom<number, {max?: number; min?: number}>({
async parse(input, _, opts) {
if (!/^-?\d+$/.test(input)) throw new CLIError(`Expected an integer but received: ${input}`)
Expand All @@ -91,6 +102,11 @@ export const integer = custom<number, {max?: number; min?: number}>({
},
})

/**
* A directory flag.
*
* - `exists` option allows you to throw an error if the directory does not exist.
*/
export const directory = custom<string, {exists?: boolean}>({
async parse(input, _, opts) {
if (opts.exists) return dirExists(input)
Expand All @@ -99,6 +115,11 @@ export const directory = custom<string, {exists?: boolean}>({
},
})

/**
* A file flag.
*
* - `exists` option allows you to throw an error if the file does not exist.
*/
export const file = custom<string, {exists?: boolean}>({
async parse(input, _, opts) {
if (opts.exists) return fileExists(input)
Expand All @@ -108,8 +129,9 @@ export const file = custom<string, {exists?: boolean}>({
})

/**
* Initializes a string as a URL. Throws an error
* if the string is not a valid URL.
* A URL flag that converts the provided value is a string.
*
* Throws an error if the string is not a valid URL.
*/
export const url = custom<URL>({
async parse(input) {
Expand All @@ -121,8 +143,14 @@ export const url = custom<URL>({
},
})

/**
* A string flag.
*/
export const string = custom()

/**
* Version flag that will print the CLI version and exit.
*/
export const version = (opts: Partial<BooleanFlag<boolean>> = {}): BooleanFlag<void> =>
boolean({
description: 'Show CLI version.',
Expand All @@ -133,6 +161,9 @@ export const version = (opts: Partial<BooleanFlag<boolean>> = {}): BooleanFlag<v
},
})

/**
* A help flag that will print the CLI help and exit.
*/
export const help = (opts: Partial<BooleanFlag<boolean>> = {}): BooleanFlag<void> =>
boolean({
description: 'Show CLI help.',
Expand All @@ -147,7 +178,20 @@ export const help = (opts: Partial<BooleanFlag<boolean>> = {}): BooleanFlag<void
})

type ReadonlyElementOf<T extends ReadonlyArray<unknown>> = T[number]

/**
* Create a custom flag that infers the flag type from the provided options.
*
* The provided `options` must be a readonly array in order for type inference to work.
*
* @example
* export default class MyCommand extends Command {
* static flags = {
* name: Flags.option({
* options: ['foo', 'bar'] as const,
* })(),
* }
* }
*/
export function option<T extends readonly string[], P extends CustomOptions>(
defaults: Partial<OptionFlag<ReadonlyElementOf<T>[], P>> & {
multiple: true
Expand Down Expand Up @@ -185,18 +229,6 @@ export function option<T extends readonly string[], P extends CustomOptions>(
},
): FlagDefinition<(typeof defaults.options)[number], P, {multiple: true; requiredOrDefaulted: false}>

/**
* Create a custom flag that infers the flag type from the provided options.
*
* @example
* export default class MyCommand extends Command {
* static flags = {
* name: Flags.option({
* options: ['foo', 'bar'] as const,
* })(),
* }
* }
*/
export function option<T extends readonly string[], P extends CustomOptions>(
defaults: Partial<OptionFlag<ReadonlyElementOf<T>, P>> & {options: T},
): FlagDefinition<(typeof defaults.options)[number], P, {multiple: boolean; requiredOrDefaulted: boolean}> {
Expand Down
9 changes: 0 additions & 9 deletions src/util/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ import {Stats, existsSync as fsExistsSync, readFileSync} from 'node:fs'
import {readFile, stat} from 'node:fs/promises'
import {join} from 'node:path'

import {mergeNestedObjects} from './util'

export function requireJson<T>(...pathParts: string[]): T {
return JSON.parse(readFileSync(join(...pathParts), 'utf8'))
}
Expand Down Expand Up @@ -71,10 +69,3 @@ export async function safeReadJson<T>(path: string): Promise<T | undefined> {
export function existsSync(path: string): boolean {
return fsExistsSync(path)
}

export async function readTSConfig(path: string) {
const {parse} = await import('tsconfck')
const result = await parse(path)
const tsNodeOpts = mergeNestedObjects(result.extended ?? [result], 'tsconfig.ts-node')
return {...result.tsconfig, 'ts-node': tsNodeOpts}
}
Loading

0 comments on commit 1542bd7

Please sign in to comment.