Skip to content

Commit 44bbae1

Browse files
committed
fix: warn user when choosen profile is not defined in config
1 parent 6ec2af4 commit 44bbae1

7 files changed

Lines changed: 62 additions & 2 deletions

File tree

‎.changeset/brave-links-mend.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@smartthings/cli": patch
3+
---
4+
5+
Fix broken configuration documentation links in config and logging error messages.

‎.changeset/quiet-owls-warn.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@smartthings/cli": patch
3+
---
4+
5+
Warn when the selected non-default profile is not defined in configuration.

‎doc/configuration.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@ specified. Most users can simply put their configuration options here.
2121
environment variable or use the `--profile` (shortcut `-p`) command line
2222
argument. (When both are used, the command line argument overrides the
2323
environment variable.)
24+
* The CLI warns when the selected profile (other than "default") is not defined in
25+
`config.yaml`. To use a profile without any configuration options, such as one used only to
26+
log in with a different account, define it with an empty value:
27+
28+
```yaml
29+
work: {}
30+
```
2431
2532
The [YAML Primer](https://github.com/darvid/trine/wiki/YAML-Primer) is a good source of information
2633
on YAML. Note, however, some features (like merge keys) have been removed in 1.2. The YAML parser

‎src/__tests__/lib/command/smartthings-command.test.ts‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type { Paths } from 'env-paths'
55
import type log4js from 'log4js'
66

77
import type { CLIConfig, loadConfig } from '../../../lib/cli-config.js'
8+
import type { yellow } from '../../../lib/colors.js'
89
import type { ensureDir } from '../../../lib/file-util.js'
910
import type { buildDefaultLog4jsConfig, loadLog4jsConfig } from '../../../lib/log-utils.js'
1011
import type { SmartThingsCommandFlags } from '../../../lib/command/smartthings-command.js'
@@ -30,6 +31,11 @@ jest.unstable_mockModule('../../../lib/cli-config.js', () => ({
3031
loadConfig: loadConfigMock,
3132
}))
3233

34+
const yellowMock = jest.fn<typeof yellow>()
35+
jest.unstable_mockModule('../../../lib/colors.js', () => ({
36+
yellow: yellowMock,
37+
}))
38+
3339
const ensureDirMock = jest.fn<typeof ensureDir>()
3440
jest.unstable_mockModule('../../../lib/file-util.js', () => ({
3541
ensureDir: ensureDirMock,
@@ -58,6 +64,7 @@ jest.unstable_mockModule('../../../lib/yargs-transition-temp.js', () => ({
5864
}))
5965

6066
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { /* do nothing */ })
67+
const consoleWarnSpy = jest.spyOn(console, 'warn').mockImplementation(() => { /* do nothing */ })
6168

6269

6370
const {
@@ -94,6 +101,7 @@ describe('smartThingsCommand', () => {
94101
.mockReturnValue(true)
95102
const cliConfig = {
96103
profile: {},
104+
mergedProfiles: {},
97105
booleanConfigValue: booleanConfigValueMock,
98106
} as unknown as CLIConfig
99107
loadConfigMock.mockResolvedValue(cliConfig)
@@ -121,5 +129,31 @@ describe('smartThingsCommand', () => {
121129
}, loggerMock)
122130
expect(defaultTableGeneratorMock).toHaveBeenCalledTimes(1)
123131
expect(defaultTableGeneratorMock).toHaveBeenCalledWith({ groupRows: true })
132+
expect(consoleWarnSpy).not.toHaveBeenCalled()
133+
})
134+
135+
it('warns when a non-default profile is missing', async () => {
136+
yellowMock.mockReturnValueOnce('yellow warning')
137+
138+
await smartThingsCommand({ profile: 'other' })
139+
140+
expect(yellowMock).toHaveBeenCalledExactlyOnceWith(
141+
'warning: profile other not found in configuration\n' +
142+
'To use a profile with no configuration options, add "other: {}" to config.yaml.\n' +
143+
'See https://github.com/SmartThingsCommunity/smartthings-cli/blob/main/doc/configuration.md#profiles' +
144+
' for more information.',
145+
)
146+
expect(consoleWarnSpy).toHaveBeenCalledExactlyOnceWith('yellow warning')
147+
})
148+
149+
it('does not warn when a non-default profile exists but is empty', async () => {
150+
loadConfigMock.mockResolvedValueOnce({
151+
...cliConfig,
152+
mergedProfiles: { other: {} },
153+
} as unknown as CLIConfig)
154+
155+
await smartThingsCommand({ profile: 'other' })
156+
157+
expect(consoleWarnSpy).not.toHaveBeenCalled()
124158
})
125159
})

‎src/lib/cli-config.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { fatalError } from './util.js'
88

99

1010
export const seeConfigDocs = 'see https://github.com/SmartThingsCommunity/smartthings-cli/blob/' +
11-
'main/packages/cli/doc/configuration.md for more information'
11+
'main/doc/configuration.md for more information'
1212

1313
export type Profile = Record<string, unknown>
1414
export type ProfilesByName = Record<string, Profile>

‎src/lib/command/smartthings-command.ts‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import log4js from 'log4js'
33
import { type Argv } from 'yargs'
44

55
import { type CLIConfig, loadConfig, type Profile } from '../cli-config.js'
6+
import { yellow } from '../colors.js'
67
import { ensureDir } from '../file-util.js'
78
import { buildDefaultLog4jsConfig, loadLog4jsConfig } from '../log-utils.js'
89
import { defaultTableGenerator, type TableGenerator } from '../table-generator.js'
@@ -136,6 +137,9 @@ export const getConfigDirsCheckingForOldConfig = async (
136137
return { configDir, dataDir, logDir }
137138
}
138139

140+
const profileDocsURL =
141+
'https://github.com/SmartThingsCommunity/smartthings-cli/blob/main/doc/configuration.md#profiles'
142+
139143
/**
140144
* A function to be called at the start of every CLI command that sets up shared things.
141145
*/
@@ -162,6 +166,11 @@ export const smartThingsCommand = async <T extends SmartThingsCommandFlags>(
162166
}, logger)
163167

164168
const profile = cliConfig.profile
169+
if (profileName !== 'default' && !(profileName in cliConfig.mergedProfiles)) {
170+
console.warn(yellow(`warning: profile ${profileName} not found in configuration\n` +
171+
`To use a profile with no configuration options, add "${profileName}: {}" to config.yaml.\n` +
172+
`See ${profileDocsURL} for more information.`))
173+
}
165174

166175
const groupRowsFlag = (flags as Pick<BuildOutputFormatterFlags, 'groupRows'>).groupRows
167176
const groupRows = groupRowsFlag ?? cliConfig.booleanConfigValue('groupTableOutputRows', true)

‎src/lib/log-utils.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { fatalError } from './util.js'
1111

1212
const defaultLogFileSize = 1_000_000 // bytes
1313
const loggingDocsURL = 'https://github.com/SmartThingsCommunity/smartthings-cli/' +
14-
'blob/main/packages/cli/doc/configuration.md#logging'
14+
'blob/main/doc/configuration.md#logging'
1515

1616

1717
export function buildDefaultLog4jsConfig(logFilename: string): Log4jsConfig {

0 commit comments

Comments
 (0)