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

SAM: change config to "machine" scope; handle failed config write #1241

Merged
merged 3 commits into from
Aug 17, 2020
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
},
"aws.samcli.location": {
"type": "string",
"scope": "machine",
"default": "",
"markdownDescription": "%AWS.configuration.description.samcli.location%"
},
Expand Down
2 changes: 1 addition & 1 deletion src/shared/sam/cli/samCliConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class DefaultSamCliConfiguration implements SamCliConfiguration {
const detectedLocation = (await this._samCliLocationProvider.getLocation()) ?? ''
// Avoid setting the value redundantly (could cause a loop because we
// listen to the `onDidChangeConfiguration` event).
if (configLocation !== detectedLocation) {
if (detectedLocation && configLocation !== detectedLocation) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If SAM CLI is no longer detected, why aren't we writing this to the config? Seems like the toolkit would incorrectly think the CLI is at some location.

Copy link
Contributor Author

@justinmk3 justinmk3 Aug 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any callsites where that would matter. Calls to sam will fail in any case.

But #1242 is a more complete solution that updates all call sites to explicitly deal with just-in-time autodetection instead of doing contortions to update the user's config (which is not actually necessary and a bit of an anti-pattern).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could be misleading in that you've run the "detect sam cli" command, and the toolkit shows the location configured as the old path (instead of no path). I'm fine proceeding with this in anticipation of 1242 then.

await this.setSamCliLocation(detectedLocation)
}
}
Expand Down
39 changes: 29 additions & 10 deletions src/shared/settingsConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,39 @@
*/

import * as vscode from 'vscode'
import { getLogger } from './logger'

// defines helper methods for interacting with VSCode's configuration
// persistence mechanisms, allowing us to test with mocks.
/**
* Wraps the VSCode configuration API and provides Toolkit-related
* configuration functions.
*/
export interface SettingsConfiguration {
readSetting<T>(settingKey: string): T | undefined
readSetting<T>(settingKey: string, defaultValue: T): T

// array values are serialized as a comma-delimited string
writeSetting<T>(settingKey: string, value: T | undefined, target: vscode.ConfigurationTarget): Promise<void>
/**
* Sets a config value.
*
* Writing to the (VSCode) config store may fail if the user does not have
* write permissions, or if some requirement is not met. For example, the
* `vscode.ConfigurationTarget.Workspace` scope requires a workspace.
*
* @param settingKey Config key name
* @param value Config value
* @param target Config _scope_
*
* @returns true on success, else false
*/
writeSetting<T>(settingKey: string, value: T | undefined, target: vscode.ConfigurationTarget): Promise<boolean>
}

// default configuration settings handler for production release
export class DefaultSettingsConfiguration implements SettingsConfiguration {
public constructor(public readonly extensionSettingsPrefix: string) {}

public readSetting<T>(settingKey: string, defaultValue?: T): T | undefined {
// tslint:disable-next-line:no-null-keyword
const settings = vscode.workspace.getConfiguration(this.extensionSettingsPrefix, null)
justinmk3 marked this conversation as resolved.
Show resolved Hide resolved
const settings = vscode.workspace.getConfiguration(this.extensionSettingsPrefix)

if (!settings) {
return defaultValue
Expand All @@ -31,10 +46,14 @@ export class DefaultSettingsConfiguration implements SettingsConfiguration {
return val ?? defaultValue
}

public async writeSetting<T>(settingKey: string, value: T, target: vscode.ConfigurationTarget): Promise<void> {
// tslint:disable-next-line:no-null-keyword
const settings = vscode.workspace.getConfiguration(this.extensionSettingsPrefix, null)

await settings.update(settingKey, value, target)
public async writeSetting<T>(settingKey: string, value: T, target: vscode.ConfigurationTarget): Promise<boolean> {
try {
const settings = vscode.workspace.getConfiguration(this.extensionSettingsPrefix)
await settings.update(settingKey, value, target)
return true
} catch (e) {
getLogger().error('failed to set config: %O=%O, error: %O', settingKey, value, e)
return false
justinmk3 marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
3 changes: 2 additions & 1 deletion src/test/utilities/testSettingsConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ export class TestSettingsConfiguration implements SettingsConfiguration {
return this._data[settingKey] as T
}

public async writeSetting<T>(settingKey: string, value: T, target?: any): Promise<void> {
public async writeSetting<T>(settingKey: string, value: T, target?: any): Promise<boolean> {
this._data[settingKey] = value
return true
}
}