Skip to content

Abstract bad input reporter to make it more consistent #384

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

Merged
merged 5 commits into from
Mar 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/commands/audit-log/cmd-audit-log.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,9 @@ describe('socket audit-log', async () => {
|__ | . | _| '_| -_| _| | Node: <redacted>, API token set: <redacted>
|_____|___|___|_,_|___|_|.dev | Command: \`socket audit-log\`, cwd: <redacted>

\\x1b[31m\\xd7\\x1b[39m \\x1b[41m\\x1b[37mInput error\\x1b[39m\\x1b[49m: Please provide the required fields:
\\x1b[31m\\xd7\\x1b[39m \\x1b[41m\\x1b[1m\\x1b[37m Input error: \\x1b[39m\\x1b[22m\\x1b[49m \\x1b[1mPlease review the input requirements and try again\\x1b[22m:

- Org name as the first argument \\x1b[31m(missing!)\\x1b[39m"
- Org name should be the first arg (\\x1b[31mmissing\\x1b[39m)"
`)

expect(code, 'dry-run should exit with code 2 if missing input').toBe(2)
Expand Down
24 changes: 8 additions & 16 deletions src/commands/audit-log/cmd-audit-log.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { stripIndents } from 'common-tags'
import colors from 'yoctocolors-cjs'

import { logger } from '@socketsecurity/registry/lib/logger'

import { handleAuditLog } from './handle-audit-log'
import constants from '../../constants'
import { commonFlags, outputFlags } from '../../flags'
import { getConfigValue } from '../../utils/config'
import { handleBadInput } from '../../utils/handle-bad-input'
import { meowOrExit } from '../../utils/meow-with-subcommands'
import { getFlagListOutput } from '../../utils/output-formatting'

Expand Down Expand Up @@ -79,19 +77,13 @@ async function run(
const defaultOrgSlug = getConfigValue('defaultOrg')
const orgSlug = defaultOrgSlug || cli.input[0] || ''

if (!orgSlug) {
// Use exit status of 2 to indicate incorrect usage, generally invalid
// options or missing arguments.
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
process.exitCode = 2
logger.fail(
stripIndents`
${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:\n
- Org name as the first argument ${!orgSlug ? colors.red('(missing!)') : colors.green('(ok)')}
`
)
return
}
const waswasInput = handleBadInput({
test: orgSlug,
message: 'Org name should be the first arg',
pass: 'ok',
fail: 'missing'
})
if (waswasInput) return

if (cli.flags['dryRun']) {
logger.log(DRY_RUN_BAIL_TEXT)
Expand Down
22 changes: 8 additions & 14 deletions src/commands/config/cmd-config-auto.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { stripIndents } from 'common-tags'
import colors from 'yoctocolors-cjs'

import { logger } from '@socketsecurity/registry/lib/logger'

import { handleConfigAuto } from './handle-config-auto'
import constants from '../../constants'
import { commonFlags, outputFlags } from '../../flags'
import { supportedConfigKeys } from '../../utils/config'
import { handleBadInput } from '../../utils/handle-bad-input'
import { meowOrExit } from '../../utils/meow-with-subcommands'
import { getFlagListOutput } from '../../utils/output-formatting'

Expand Down Expand Up @@ -67,17 +65,13 @@ async function run(
const { json, markdown } = cli.flags
const [key = ''] = cli.input

if (!supportedConfigKeys.has(key as keyof LocalConfig) && key !== 'test') {
// Use exit status of 2 to indicate incorrect usage, generally invalid
// options or missing arguments.
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
process.exitCode = 2
logger.fail(stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:

- Config key should be the first arg ${!key ? colors.red('(missing!)') : !supportedConfigKeys.has(key as any) ? colors.red('(invalid config key!)') : colors.green('(ok)')}
`)
return
}
const wasBadInput = handleBadInput({
test: supportedConfigKeys.has(key as keyof LocalConfig) && key !== 'test',
message: 'Config key should be the first arg',
pass: 'ok',
fail: key ? 'invalid config key' : 'missing'
})
if (wasBadInput) return

if (cli.flags['dryRun']) {
logger.log(DRY_RUN_BAIL_TEXT)
Expand Down
46 changes: 24 additions & 22 deletions src/commands/config/cmd-config-get.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,28 @@ describe('socket config get', async () => {
const { code, stderr, stdout } = await invokeNpm(entryPath, cmd)
expect(stdout).toMatchInlineSnapshot(
`
"Get the value of a local CLI config item
"Get the value of a local CLI config item

Usage
$ socket config get <org slug>
Usage
$ socket config get <org slug>

Options
--dryRun Do input validation for a command and exit 0 when input is ok
--help Print this help.
--json Output result as json
--markdown Output result as markdown
Options
--dryRun Do input validation for a command and exit 0 when input is ok
--help Print this help.
--json Output result as json
--markdown Output result as markdown

Keys:
Keys:

- apiBaseUrl -- Base URL of the API endpoint
- apiProxy -- A proxy through which to access the API
- apiToken -- The API token required to access most API endpoints
- defaultOrg -- The default org slug to use when appropriate; usually the org your API token has access to. When set, all orgSlug arguments are implied to be this value.
- enforcedOrgs -- Orgs in this list have their security policies enforced on this machine
- apiBaseUrl -- Base URL of the API endpoint
- apiProxy -- A proxy through which to access the API
- apiToken -- The API token required to access most API endpoints
- defaultOrg -- The default org slug to use when appropriate; usually the org your API token has access to. When set, all orgSlug arguments are implied to be this value.
- enforcedOrgs -- Orgs in this list have their security policies enforced on this machine

Examples
$ socket config get FakeOrg --repoName=test-repo"
`
Examples
$ socket config get FakeOrg --repoName=test-repo"
`
)
expect(`\n ${stderr}`).toMatchInlineSnapshot(`
"
Expand Down Expand Up @@ -69,27 +69,29 @@ describe('socket config get', async () => {
|__ | . | _| '_| -_| _| | Node: <redacted>, API token set: <redacted>
|_____|___|___|_,_|___|_|.dev | Command: \`socket config get\`, cwd: <redacted>

\\x1b[31m\\xd7\\x1b[39m \\x1b[41m\\x1b[37mInput error\\x1b[39m\\x1b[49m: Please provide the required fields:
\\x1b[31m\\xd7\\x1b[39m \\x1b[41m\\x1b[1m\\x1b[37m Input error: \\x1b[39m\\x1b[22m\\x1b[49m \\x1b[1mPlease review the input requirements and try again\\x1b[22m:

- Config key should be the first arg \\x1b[31m(missing!)\\x1b[39m"
- Config key should be the first arg (\\x1b[31mmissing\\x1b[39m)"
`)

expect(code, 'dry-run should exit with code 2 if missing input').toBe(2)
}
)

cmdit(
['config', 'get', 'test', '--dry-run', '--config', '{}'],
['config', 'test', 'test', '--dry-run', '--config', '{}'],
'should require args with just dry-run',
async cmd => {
const { code, stderr, stdout } = await invokeNpm(entryPath, cmd)
expect(stdout).toMatchInlineSnapshot(`"[DryRun]: Bailing now"`)
expect(stdout).toMatchInlineSnapshot(
`"[DryRun]: No-op, call a sub-command; ok"`
)
expect(`\n ${stderr}`).toMatchInlineSnapshot(`
"
_____ _ _ /---------------
| __|___ ___| |_ ___| |_ | Socket.dev CLI ver <redacted>
|__ | . | _| '_| -_| _| | Node: <redacted>, API token set: <redacted>
|_____|___|___|_,_|___|_|.dev | Command: \`socket config get\`, cwd: <redacted>"
|_____|___|___|_,_|___|_|.dev | Command: \`socket config\`, cwd: <redacted>"
`)

expect(code, 'dry-run should exit with code 0 if input ok').toBe(0)
Expand Down
22 changes: 8 additions & 14 deletions src/commands/config/cmd-config-get.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { stripIndents } from 'common-tags'
import colors from 'yoctocolors-cjs'

import { logger } from '@socketsecurity/registry/lib/logger'

import { handleConfigGet } from './handle-config-get'
import constants from '../../constants'
import { commonFlags, outputFlags } from '../../flags'
import { supportedConfigKeys } from '../../utils/config'
import { handleBadInput } from '../../utils/handle-bad-input'
import { meowOrExit } from '../../utils/meow-with-subcommands'
import { getFlagListOutput } from '../../utils/output-formatting'

Expand Down Expand Up @@ -62,17 +60,13 @@ async function run(
const { json, markdown } = cli.flags
const [key = ''] = cli.input

if (!supportedConfigKeys.has(key as keyof LocalConfig) && key !== 'test') {
// Use exit status of 2 to indicate incorrect usage, generally invalid
// options or missing arguments.
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
process.exitCode = 2
logger.fail(stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:

- Config key should be the first arg ${!key ? colors.red('(missing!)') : !supportedConfigKeys.has(key as any) ? colors.red('(invalid config key!)') : colors.green('(ok)')}
`)
return
}
const wasBadInput = handleBadInput({
test: supportedConfigKeys.has(key as keyof LocalConfig) || key === 'test',
message: 'Config key should be the first arg',
pass: 'ok',
fail: key ? 'invalid config key' : 'missing'
})
if (wasBadInput) return

if (cli.flags['dryRun']) {
logger.log(DRY_RUN_BAIL_TEXT)
Expand Down
36 changes: 18 additions & 18 deletions src/commands/config/cmd-config-list.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,29 @@ describe('socket config get', async () => {
const { code, stderr, stdout } = await invokeNpm(entryPath, cmd)
expect(stdout).toMatchInlineSnapshot(
`
"Show all local CLI config items and their values
"Show all local CLI config items and their values

Usage
$ socket config list <org slug>
Usage
$ socket config list <org slug>

Options
--dryRun Do input validation for a command and exit 0 when input is ok
--full Show full tokens in plaintext (unsafe)
--help Print this help.
--json Output result as json
--markdown Output result as markdown
Options
--dryRun Do input validation for a command and exit 0 when input is ok
--full Show full tokens in plaintext (unsafe)
--help Print this help.
--json Output result as json
--markdown Output result as markdown

Keys:
Keys:

- apiBaseUrl -- Base URL of the API endpoint
- apiProxy -- A proxy through which to access the API
- apiToken -- The API token required to access most API endpoints
- defaultOrg -- The default org slug to use when appropriate; usually the org your API token has access to. When set, all orgSlug arguments are implied to be this value.
- enforcedOrgs -- Orgs in this list have their security policies enforced on this machine
- apiBaseUrl -- Base URL of the API endpoint
- apiProxy -- A proxy through which to access the API
- apiToken -- The API token required to access most API endpoints
- defaultOrg -- The default org slug to use when appropriate; usually the org your API token has access to. When set, all orgSlug arguments are implied to be this value.
- enforcedOrgs -- Orgs in this list have their security policies enforced on this machine

Examples
$ socket config list FakeOrg --repoName=test-repo"
`
Examples
$ socket config list FakeOrg --repoName=test-repo"
`
)
expect(`\n ${stderr}`).toMatchInlineSnapshot(`
"
Expand Down
46 changes: 23 additions & 23 deletions src/commands/config/cmd-config-set.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,33 +18,33 @@ describe('socket config get', async () => {
const { code, stderr, stdout } = await invokeNpm(entryPath, cmd)
expect(stdout).toMatchInlineSnapshot(
`
"Update the value of a local CLI config item
"Update the value of a local CLI config item

Usage
$ socket config set <key> <value>
Usage
$ socket config set <key> <value>

Options
--dryRun Do input validation for a command and exit 0 when input is ok
--help Print this help.
--json Output result as json
--markdown Output result as markdown
Options
--dryRun Do input validation for a command and exit 0 when input is ok
--help Print this help.
--json Output result as json
--markdown Output result as markdown

This is a crude way of updating the local configuration for this CLI tool.
This is a crude way of updating the local configuration for this CLI tool.

Note that updating a value here is nothing more than updating a key/value
store entry. No validation is happening. The server may reject your config.
Note that updating a value here is nothing more than updating a key/value
store entry. No validation is happening. The server may reject your config.

Keys:
Keys:

- apiBaseUrl -- Base URL of the API endpoint
- apiProxy -- A proxy through which to access the API
- apiToken -- The API token required to access most API endpoints
- defaultOrg -- The default org slug to use when appropriate; usually the org your API token has access to. When set, all orgSlug arguments are implied to be this value.
- enforcedOrgs -- Orgs in this list have their security policies enforced on this machine
- apiBaseUrl -- Base URL of the API endpoint
- apiProxy -- A proxy through which to access the API
- apiToken -- The API token required to access most API endpoints
- defaultOrg -- The default org slug to use when appropriate; usually the org your API token has access to. When set, all orgSlug arguments are implied to be this value.
- enforcedOrgs -- Orgs in this list have their security policies enforced on this machine

Examples
$ socket config set apiProxy https://example.com"
`
Examples
$ socket config set apiProxy https://example.com"
`
)
expect(`\n ${stderr}`).toMatchInlineSnapshot(`
"
Expand Down Expand Up @@ -74,11 +74,11 @@ describe('socket config get', async () => {
|__ | . | _| '_| -_| _| | Node: <redacted>, API token set: <redacted>
|_____|___|___|_,_|___|_|.dev | Command: \`socket config set\`, cwd: <redacted>

\\x1b[31m\\xd7\\x1b[39m \\x1b[41m\\x1b[37mInput error\\x1b[39m\\x1b[49m: Please provide the required fields:
\\x1b[31m\\xd7\\x1b[39m \\x1b[41m\\x1b[1m\\x1b[37m Input error: \\x1b[39m\\x1b[22m\\x1b[49m \\x1b[1mPlease review the input requirements and try again\\x1b[22m:

- Config key should be the first arg \\x1b[31m(missing!)\\x1b[39m
- Config key should be the first arg (\\x1b[31mmissing\\x1b[39m)

- Key value should be the remaining args (use \`del\` to unset a value) \\x1b[31m(missing!)\\x1b[39m"
- Key value should be the remaining args (use \`unset\` to unset a value) (\\x1b[31mmissing\\x1b[39m)"
`)

expect(code, 'dry-run should exit with code 2 if missing input').toBe(2)
Expand Down
35 changes: 17 additions & 18 deletions src/commands/config/cmd-config-set.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { stripIndents } from 'common-tags'
import colors from 'yoctocolors-cjs'

import { logger } from '@socketsecurity/registry/lib/logger'

import { handleConfigSet } from './handle-config-set'
import constants from '../../constants'
import { commonFlags, outputFlags } from '../../flags'
import { supportedConfigKeys } from '../../utils/config'
import { handleBadInput } from '../../utils/handle-bad-input'
import { meowOrExit } from '../../utils/meow-with-subcommands'
import { getFlagListOutput } from '../../utils/output-formatting'

Expand Down Expand Up @@ -68,21 +66,22 @@ async function run(
const [key = '', ...rest] = cli.input
const value = rest.join(' ')

if (
(!supportedConfigKeys.has(key as keyof LocalConfig) && key !== 'test') ||
!value
) {
// Use exit status of 2 to indicate incorrect usage, generally invalid
// options or missing arguments.
// https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html
process.exitCode = 2
logger.fail(stripIndents`${colors.bgRed(colors.white('Input error'))}: Please provide the required fields:

- Config key should be the first arg ${!key ? colors.red('(missing!)') : !supportedConfigKeys.has(key as any) ? colors.red('(invalid config key!)') : colors.green('(ok)')}

- Key value should be the remaining args (use \`del\` to unset a value) ${!value ? colors.red('(missing!)') : colors.green('(ok)')}`)
return
}
const wasBadInput = handleBadInput(
{
test: supportedConfigKeys.has(key as keyof LocalConfig) || key === 'test',
message: 'Config key should be the first arg',
pass: 'ok',
fail: key ? 'invalid config key' : 'missing'
},
{
test: value, // This is a string, empty string is not ok
message:
'Key value should be the remaining args (use `unset` to unset a value)',
pass: 'ok',
fail: 'missing'
}
)
if (wasBadInput) return

if (cli.flags['dryRun']) {
logger.log(DRY_RUN_BAIL_TEXT)
Expand Down
Loading
Loading