Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade Yargs v17 #3624

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/api-server/package.json
Expand Up @@ -28,7 +28,7 @@
"pretty-ms": "7.0.1",
"qs": "6.10.3",
"split2": "4.1.0",
"yargs": "16.2.0"
"yargs": "17.3.1"
},
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/package.json
Expand Up @@ -49,7 +49,7 @@
"rimraf": "3.0.2",
"secure-random-password": "0.2.3",
"terminal-link": "2.1.1",
"yargs": "16.2.0"
"yargs": "17.3.1"
},
"devDependencies": {
"@babel/cli": "7.16.7",
Expand Down
136 changes: 115 additions & 21 deletions packages/cli/src/index.js
@@ -1,31 +1,74 @@
#!/usr/bin/env node
/**
* This file is the CLI's main entry point.
* (This is specified in the package.json's `bin` property.)
*
* ```
* yarn rw # <-- you are here
* ```
*
* This file:
*
* 1) sets up up middleware
* 2) loads the rest of the CLI via this package's command-module structure.
*
* @see {@link https://github.com/yargs/yargs/blob/main/docs/advanced.md#providing-a-command-module}
*
* @remarks
*
* The yargs codebase can appear to be a bit complicated at first.
* If you ever have to dig into the source, know that most of the methods are defined here:
* {@link https://github.com/yargs/yargs/blob/3d2a6aa8c954a58589d7a199b2496bd894dcde25/lib/yargs-factory.ts}
*/
import fs from 'fs'
import path from 'path'

import { config } from 'dotenv-defaults'
import yargs from 'yargs'
import { hideBin } from 'yargs/helpers'
/**
* This is the blessed way of doing things now, as opposed to:
*
* ```
* import yargs from 'yargs
* ```
*
* The above is the older, singleton API, which hasn't been deprecated but has been discouraged:
* {@link https://github.com/yargs/yargs/issues/2045#issuecomment-942442554}
*/
import yargs from 'yargs/yargs'

import { getPaths, getConfigPath } from '@redwoodjs/internal'

/**
* The current working directory can be set via:
* 1. A `--cwd` option
* 2. The `RWJS_CWD` env-var
* 3. Found by traversing directories upwards for the first `redwood.toml`
* Yargs middleware.
*
* Middleware functions get access to `argv`:
* {@link https://yargs.js.org/docs/#api-reference-middlewarecallbacks-applybeforevalidation}
*
* This middleware parses, validates, and sets current working directory in the following order:
*
* 1. the `--cwd` option
* 2. the `RWJS_CWD` env var
* 3. by traversing directories upwards for the first `redwood.toml`
*
* This middleware parses, validates, and sets current working directory
* in the order above.
* This is mainly for contributors.
*
* @param {import('yargs').Argv} argv
*/
const getCwdMiddleware = (argv) => {
const setCwdMiddleware = (argv) => {
let configPath

try {
let cwd

if (argv.cwd) {
cwd = argv.cwd
// We delete the argument because it's not actually referenced in CLI,
// we use the `RWJS_CWD` env-var,
// and it conflicts with "forwarding" commands such as test and prisma.

/**
* We delete `cwd` because it's not actually referenced in the CLI.
* We use the `RWJS_CWD` env var instead.
* That, and it conflicts with "forwarding" commands such as test and prisma.
*/
delete argv.cwd
} else if (process.env.RWJS_CWD) {
cwd = process.env.RWJS_CWD
Expand All @@ -34,6 +77,7 @@ const getCwdMiddleware = (argv) => {
}

configPath = path.resolve(process.cwd(), cwd, 'redwood.toml')

if (!fs.existsSync(configPath)) {
throw new Error('Could not find `redwood.toml` config file.')
}
Expand All @@ -51,25 +95,75 @@ const getCwdMiddleware = (argv) => {
}
}

/**
* Loads the env vars in `.env` and `.env.defaults`.
*
* @remarks
*
* We should only do this if we're in a Redwood project,
* which is why this is a middleware function that comes after `setCwdMiddleware`.
*/
const loadDotEnvDefaultsMiddleware = () => {
const { base } = getPaths()

config({
path: path.join(getPaths().base, '.env'),
defaults: path.join(getPaths().base, '.env.defaults'),
path: path.join(base, '.env'),
defaults: path.join(base, '.env.defaults'),
encoding: 'utf8',
})
}

// eslint-disable-next-line no-unused-expressions
yargs
/**
* `yargs` takes an array (which is what `process.argv` is),
* but yargs expects this array to only have the args that come after program name.
* So if the command run at the CLI is:
*
* ```
* yarn rw --help
* ```
*
* yargs expects `['--help']`, not `['rw', '--help']`.
*
* `hideBin` is a yargs helper-function that removes the program name from the array for us:
* {@link https://yargs.js.org/docs/#api-reference}
*
* @remarks
*
* Assigning the return of this to a variable
* because we should be able to run the cli "programmatically" this way:
* - {@link https://github.com/yargs/yargs/issues/1605}
* - {@link https://yargs.js.org/docs/#api-reference-parseargs-context-parsecallback}
*/
const parser = yargs(hideBin(process.argv))
.scriptName('rw')
.middleware([getCwdMiddleware, loadDotEnvDefaultsMiddleware])
.middleware([setCwdMiddleware, loadDotEnvDefaultsMiddleware])
.option('cwd', {
describe: 'Working directory to use (where `redwood.toml` is located.)',
demandOption: false,
description:
'Current working directory to use (i.e., where `redwood.toml` is located). Useful for development',
type: 'string',
})
.commandDir('./commands')
.example(
'yarn rw g page home /',
"\"Create a page component named 'Home' at path '/'\""
'$0 g page home /',
"Create a page component named 'Home' at path '/'"
)
.demandCommand()
.strict().argv
.commandDir('./commands')
.demandCommand(1, '')
.recommendCommands()
.strict()

/**
* `yargs` seems to be moving away from `argv`:
* {@link https://github.com/yargs/yargs/pull/2036}
*
* Note that calling `parse` with no args is equivalent to `argv`.
* - {@link https://yargs.js.org/docs/#api-reference}
* - {@link https://github.com/yargs/yargs/blob/3d2a6aa8c954a58589d7a199b2496bd894dcde25/lib/yargs-factory.ts#L72-L77}
*
* @remarks
*
* This should pretty much only ever be used here, at the top level, according to:
* {@link https://yargs.js.org/docs/#api-reference-argv}
*/
parser.parse()
2 changes: 1 addition & 1 deletion packages/codemods/package.json
Expand Up @@ -23,7 +23,7 @@
"tasuku": "1.0.2",
"toml": "3.0.0",
"vscode-ripgrep": "1.13.2",
"yargs": "16.2.0"
"yargs": "17.3.1"
},
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/create-redwood-app/package.json
Expand Up @@ -19,7 +19,7 @@
"fs-extra": "10.0.0",
"listr": "0.14.3",
"tmp": "0.2.1",
"yargs": "16.2.0"
"yargs": "17.3.1"
},
"repository": {
"type": "git",
Expand Down
18 changes: 13 additions & 5 deletions packages/create-redwood-app/src/create-redwood-app.js
Expand Up @@ -13,7 +13,8 @@ import checkNodeVersion from 'check-node-version'
import execa from 'execa'
import fs from 'fs-extra'
import Listr from 'listr'
import yargs from 'yargs'
import { hideBin } from 'yargs/helpers'
import yargs from 'yargs/yargs'

import { name, version } from '../package'

Expand Down Expand Up @@ -48,10 +49,16 @@ const {
'yarn-install': yarnInstall,
typescript,
overwrite,
} = yargs
} = yargs(hideBin(process.argv))
.scriptName(name)
.usage('Usage: $0 <project directory> [option]')
.example('$0 newapp')
.usage('Usage: yarn create redwood-app <project directory> [option]')
.example([
['yarn create redwood-app my-app', 'Create a Redwood App in `./my-app`'],
[
'yarn create redwood-app my-ts-app --ts',
'Create a Redwood App in TypeScript',
],
])
.option('yarn-install', {
default: true,
type: 'boolean',
Expand All @@ -70,9 +77,10 @@ const {
describe: 'Create even if target directory is empty',
})
.version(version)
.strict().argv
.parse()

const targetDir = String(args).replace(/,/g, '-')

if (!targetDir) {
console.error('Please specify the project directory')
console.log(
Expand Down
7 changes: 4 additions & 3 deletions tasks/run-e2e
Expand Up @@ -6,7 +6,8 @@ const path = require('path')

const execa = require('execa')
const fs = require('fs-extra')
const yargs = require('yargs')
const { hideBin } = require('yargs/helpers')
const yargs = require('yargs/yargs')

// This script sets up a blank RedwoodJS app into a directory.
// It uses the packages from the RedwoodJS framework (../packages).
Expand Down Expand Up @@ -188,7 +189,7 @@ const initGit = () => {
})
}

const args = yargs
const args = yargs(hideBin(process.argv))
.option('create-project', { default: true, type: 'boolean', alias: 'create' })
.option('build-framework', { default: true, type: 'boolean', alias: 'build' })
.option('copy-framework', { default: true, type: 'boolean', alias: 'copy' })
Expand All @@ -198,7 +199,7 @@ const args = yargs
.example('run-e2e')
.example('run-e2e /tmp/redwood-app --ts')
.help()
.strict().argv
.parse()

const REDWOODJS_FRAMEWORK_PATH = path.resolve(__dirname, '..')
let REDWOOD_PROJECT_DIRECTORY =
Expand Down
32 changes: 16 additions & 16 deletions yarn.lock
Expand Up @@ -5342,7 +5342,7 @@ __metadata:
qs: 6.10.3
split2: 4.1.0
typescript: 4.5.4
yargs: 16.2.0
yargs: 17.3.1
bin:
rw-api-server: ./dist/index.js
rw-api-server-watch: ./dist/watch.js
Expand Down Expand Up @@ -5442,7 +5442,7 @@ __metadata:
secure-random-password: 0.2.3
terminal-link: 2.1.1
typescript: 4.5.4
yargs: 16.2.0
yargs: 17.3.1
bin:
redwood: ./dist/index.js
rw: ./dist/index.js
Expand Down Expand Up @@ -5475,7 +5475,7 @@ __metadata:
tempy: 1.0.1
toml: 3.0.0
vscode-ripgrep: 1.13.2
yargs: 16.2.0
yargs: 17.3.1
bin:
codemods: ./dist/codemods.js
languageName: unknown
Expand Down Expand Up @@ -12170,7 +12170,7 @@ __metadata:
listr: 0.14.3
tmp: 0.2.1
typescript: 4.5.4
yargs: 16.2.0
yargs: 17.3.1
bin:
create-redwood-app: ./dist/create-redwood-app.js
languageName: unknown
Expand Down Expand Up @@ -30219,18 +30219,18 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard

"yargs@npm:16.2.0, yargs@npm:^16.1.1, yargs@npm:^16.2.0":
version: 16.2.0
resolution: "yargs@npm:16.2.0"
"yargs@npm:17.3.1, yargs@npm:^17.0.0, yargs@npm:^17.3.0":
version: 17.3.1
resolution: "yargs@npm:17.3.1"
dependencies:
cliui: ^7.0.2
escalade: ^3.1.1
get-caller-file: ^2.0.5
require-directory: ^2.1.1
string-width: ^4.2.0
string-width: ^4.2.3
y18n: ^5.0.5
yargs-parser: ^20.2.2
checksum: b1dbfefa679848442454b60053a6c95d62f2d2e21dd28def92b647587f415969173c6e99a0f3bab4f1b67ee8283bf735ebe3544013f09491186ba9e8a9a2b651
yargs-parser: ^21.0.0
checksum: 2c5ff77132468093a1872b8a9798cdcc5da0bcf7a2b0660264ffa91766324b0926c3346e091d249dc3a86caf7e8e623aa0f8de660c9baf440188d4da7d4378c4
languageName: node
linkType: hard

Expand All @@ -30253,18 +30253,18 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard

"yargs@npm:^17.0.0, yargs@npm:^17.3.0":
version: 17.3.1
resolution: "yargs@npm:17.3.1"
"yargs@npm:^16.1.1, yargs@npm:^16.2.0":
version: 16.2.0
resolution: "yargs@npm:16.2.0"
dependencies:
cliui: ^7.0.2
escalade: ^3.1.1
get-caller-file: ^2.0.5
require-directory: ^2.1.1
string-width: ^4.2.3
string-width: ^4.2.0
y18n: ^5.0.5
yargs-parser: ^21.0.0
checksum: 2c5ff77132468093a1872b8a9798cdcc5da0bcf7a2b0660264ffa91766324b0926c3346e091d249dc3a86caf7e8e623aa0f8de660c9baf440188d4da7d4378c4
yargs-parser: ^20.2.2
checksum: b1dbfefa679848442454b60053a6c95d62f2d2e21dd28def92b647587f415969173c6e99a0f3bab4f1b67ee8283bf735ebe3544013f09491186ba9e8a9a2b651
languageName: node
linkType: hard

Expand Down