Skip to content
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
5 changes: 5 additions & 0 deletions .changeset/brave-links-mend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@smartthings/cli": patch
---

Fix broken configuration documentation links in config and logging error messages.
5 changes: 5 additions & 0 deletions .changeset/quiet-owls-warn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@smartthings/cli": patch
---

Warn when the selected non-default profile is not defined in configuration.
7 changes: 7 additions & 0 deletions doc/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ specified. Most users can simply put their configuration options here.
environment variable or use the `--profile` (shortcut `-p`) command line
argument. (When both are used, the command line argument overrides the
environment variable.)
* The CLI warns when the selected profile (other than "default") is not defined in
`config.yaml`. To use a profile without any configuration options, such as one used only to
log in with a different account, define it with an empty value:

```yaml
work: {}
```

The [YAML Primer](https://github.com/darvid/trine/wiki/YAML-Primer) is a good source of information
on YAML. Note, however, some features (like merge keys) have been removed in 1.2. The YAML parser
Expand Down
34 changes: 34 additions & 0 deletions src/__tests__/lib/command/smartthings-command.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { Paths } from 'env-paths'
import type log4js from 'log4js'

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

const yellowMock = jest.fn<typeof yellow>()
jest.unstable_mockModule('../../../lib/colors.js', () => ({
yellow: yellowMock,
}))

const ensureDirMock = jest.fn<typeof ensureDir>()
jest.unstable_mockModule('../../../lib/file-util.js', () => ({
ensureDir: ensureDirMock,
Expand Down Expand Up @@ -58,6 +64,7 @@ jest.unstable_mockModule('../../../lib/yargs-transition-temp.js', () => ({
}))

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


const {
Expand Down Expand Up @@ -94,6 +101,7 @@ describe('smartThingsCommand', () => {
.mockReturnValue(true)
const cliConfig = {
profile: {},
mergedProfiles: {},
booleanConfigValue: booleanConfigValueMock,
} as unknown as CLIConfig
loadConfigMock.mockResolvedValue(cliConfig)
Expand Down Expand Up @@ -121,5 +129,31 @@ describe('smartThingsCommand', () => {
}, loggerMock)
expect(defaultTableGeneratorMock).toHaveBeenCalledTimes(1)
expect(defaultTableGeneratorMock).toHaveBeenCalledWith({ groupRows: true })
expect(consoleWarnSpy).not.toHaveBeenCalled()
})

it('warns when a non-default profile is missing', async () => {
yellowMock.mockReturnValueOnce('yellow warning')

await smartThingsCommand({ profile: 'other' })

expect(yellowMock).toHaveBeenCalledExactlyOnceWith(
'warning: profile other not found in configuration\n' +
'To use a profile with no configuration options, add "other: {}" to config.yaml.\n' +
'See https://github.com/SmartThingsCommunity/smartthings-cli/blob/main/doc/configuration.md#profiles' +
' for more information.',
)
expect(consoleWarnSpy).toHaveBeenCalledExactlyOnceWith('yellow warning')
})

it('does not warn when a non-default profile exists but is empty', async () => {
loadConfigMock.mockResolvedValueOnce({
...cliConfig,
mergedProfiles: { other: {} },
} as unknown as CLIConfig)

await smartThingsCommand({ profile: 'other' })

expect(consoleWarnSpy).not.toHaveBeenCalled()
})
})
2 changes: 1 addition & 1 deletion src/lib/cli-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { fatalError } from './util.js'


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

export type Profile = Record<string, unknown>
export type ProfilesByName = Record<string, Profile>
Expand Down
9 changes: 9 additions & 0 deletions src/lib/command/smartthings-command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import log4js from 'log4js'
import { type Argv } from 'yargs'

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

const profileDocsURL =
'https://github.com/SmartThingsCommunity/smartthings-cli/blob/main/doc/configuration.md#profiles'

/**
* A function to be called at the start of every CLI command that sets up shared things.
*/
Expand All @@ -162,6 +166,11 @@ export const smartThingsCommand = async <T extends SmartThingsCommandFlags>(
}, logger)

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

const groupRowsFlag = (flags as Pick<BuildOutputFormatterFlags, 'groupRows'>).groupRows
const groupRows = groupRowsFlag ?? cliConfig.booleanConfigValue('groupTableOutputRows', true)
Expand Down
2 changes: 1 addition & 1 deletion src/lib/log-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { fatalError } from './util.js'

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


export function buildDefaultLog4jsConfig(logFilename: string): Log4jsConfig {
Expand Down
Loading