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

Add Remotes section to setup webview #3901

Merged
merged 10 commits into from
May 17, 2023
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 extension/src/cli/dvc/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export enum Command {
PUSH = 'push',
QUEUE = 'queue',
REMOVE = 'remove',
REMOTE = 'remote',
ROOT = 'root',
PARAMS = 'params',
METRICS = 'metrics',
Expand Down
8 changes: 7 additions & 1 deletion extension/src/cli/dvc/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import {
ExperimentSubCommand,
Flag,
GcPreserveFlag,
QueueSubCommand
QueueSubCommand,
SubCommand
} from './constants'
import { addStudioAccessToken } from './options'
import { CliResult, CliStarted, typeCheckCommands } from '..'
Expand Down Expand Up @@ -35,6 +36,7 @@ export const autoRegisteredCommands = {
QUEUE_KILL: 'queueKill',
QUEUE_START: 'queueStart',
QUEUE_STOP: 'queueStop',
REMOTE: 'remote',
REMOVE: 'remove'
} as const

Expand Down Expand Up @@ -196,6 +198,10 @@ export class DvcExecutor extends DvcCli {
return this.blockAndExecuteProcess(cwd, Command.REMOVE, ...args)
}

public remote(cwd: string, arg: typeof SubCommand.LIST) {
return this.executeDvcProcess(cwd, Command.REMOTE, arg)
}

private executeExperimentProcess(cwd: string, ...args: Args) {
return this.executeDvcProcess(cwd, Command.EXPERIMENT, ...args)
}
Expand Down
30 changes: 30 additions & 0 deletions extension/src/setup/collect.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { collectRemoteList } from './collect'
import { dvcDemoPath } from '../test/util'
import { join } from '../test/util/path'

describe('collectRemoteList', () => {
it('should return the expected data structure', async () => {
const mockedRoot = join('some', 'other', 'root')
const remoteList = await collectRemoteList(
[dvcDemoPath, 'mockedOtherRoot', mockedRoot],
root =>
Promise.resolve(
{
[dvcDemoPath]:
'storage s3://dvc-public/remote/mnist-vscode\nbackup gdrive://appDataDir\nurl https://remote.dvc.org/mnist-vscode',
mockedOtherRoot: '',
[mockedRoot]: undefined
}[root]
)
)
expect(remoteList).toStrictEqual({
[dvcDemoPath]: {
backup: 'gdrive://appDataDir',
storage: 's3://dvc-public/remote/mnist-vscode',
url: 'https://remote.dvc.org/mnist-vscode'
},
mockedOtherRoot: undefined,
[mockedRoot]: undefined
})
})
})
31 changes: 30 additions & 1 deletion extension/src/setup/collect.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { DEFAULT_SECTION_COLLAPSED, SetupSection } from './webview/contract'
import {
DEFAULT_SECTION_COLLAPSED,
RemoteList,
SetupSection
} from './webview/contract'
import { trimAndSplit } from '../util/stdout'

export const collectSectionCollapsed = (
focusedSection?: SetupSection
Expand All @@ -16,3 +21,27 @@ export const collectSectionCollapsed = (

return acc
}

export const collectRemoteList = async (
mattseddon marked this conversation as resolved.
Show resolved Hide resolved
dvcRoots: string[],
getRemoteList: (cwd: string) => Promise<string | undefined>
): Promise<NonNullable<RemoteList>> => {
const acc: NonNullable<RemoteList> = {}

for (const dvcRoot of dvcRoots) {
const remoteList = await getRemoteList(dvcRoot)
if (!remoteList) {
acc[dvcRoot] = undefined
continue
}
const remotes = trimAndSplit(remoteList)
const dvcRootRemotes: { [alias: string]: string } = {}
for (const remote of remotes) {
const [alias, url] = remote.split(/\s+/)
dvcRootRemotes[alias] = url
}
acc[dvcRoot] = dvcRootRemotes
}

return acc
}
66 changes: 46 additions & 20 deletions extension/src/setup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
SetupSection,
SetupData as TSetupData
} from './webview/contract'
import { collectSectionCollapsed } from './collect'
import { collectRemoteList, collectSectionCollapsed } from './collect'
import { WebviewMessages } from './webview/messages'
import { validateTokenInput } from './inputBox'
import { findPythonBinForInstall } from './autoInstall'
Expand Down Expand Up @@ -47,7 +47,8 @@ import {
Flag,
ConfigKey as DvcConfigKey,
DOT_DVC,
Args
Args,
SubCommand
} from '../cli/dvc/constants'
import { GLOBAL_WEBVIEW_DVCROOT } from '../webview/factory'
import {
Expand Down Expand Up @@ -229,7 +230,7 @@ export class Setup
) {
this.cliCompatible = compatible
this.cliVersion = version
void this.updateIsStudioConnected()
void this.updateStudioAndSend()
const incompatible = compatible === undefined ? undefined : !compatible
void setContextValue(ContextKey.CLI_INCOMPATIBLE, incompatible)
}
Expand Down Expand Up @@ -339,7 +340,7 @@ export class Setup
}

await this.accessConfig(cwd, Flag.GLOBAL, DvcConfigKey.STUDIO_TOKEN, token)
return this.updateIsStudioConnected()
return this.updateStudioAndSend()
}

public getStudioLiveShareToken() {
Expand Down Expand Up @@ -375,14 +376,28 @@ export class Setup
}
}

private async getRemoteList() {
await this.config.isReady()

if (!this.hasRoots()) {
return undefined
}

return collectRemoteList(this.dvcRoots, (cwd: string) =>
this.accessRemote(cwd, SubCommand.LIST)
)
}

private async sendDataToWebview() {
const projectInitialized = this.hasRoots()
const hasData = this.getHasData()

const [isPythonExtensionUsed, dvcCliDetails] = await Promise.all([
this.isPythonExtensionUsed(),
this.getDvcCliDetails()
])
const [isPythonExtensionUsed, dvcCliDetails, remoteList] =
await Promise.all([
this.isPythonExtensionUsed(),
this.getDvcCliDetails(),
this.getRemoteList()
])

const needsGitInitialized =
!projectInitialized && !!(await this.needsGitInit())
Expand All @@ -405,6 +420,7 @@ export class Setup
needsGitInitialized,
projectInitialized,
pythonBinPath: getBinDisplayText(pythonBinPath),
remoteList,
sectionCollapsed: collectSectionCollapsed(this.focusedSection),
shareLiveToStudio: getConfigValue(
ExtensionConfigKey.STUDIO_SHARE_EXPERIMENTS_LIVE
Expand Down Expand Up @@ -644,16 +660,16 @@ export class Setup
}
}

private async updateStudioAndSend() {
await this.updateIsStudioConnected()
return this.sendDataToWebview()
}

private async updateIsStudioConnected() {
await this.setStudioAccessToken()
const storedToken = this.getStudioAccessToken()
const isConnected = isStudioAccessToken(storedToken)
return this.setStudioIsConnected(isConnected)
}

private setStudioIsConnected(isConnected: boolean) {
this.studioIsConnected = isConnected
void this.sendDataToWebview()
return setContextValue(ContextKey.STUDIO_CONNECTED, isConnected)
}

Expand All @@ -667,7 +683,7 @@ export class Setup
path.endsWith(join('dvc', 'config')) ||
path.endsWith(join('dvc', 'config.local'))
) {
void this.updateIsStudioConnected()
void this.updateStudioAndSend()
}
}
)
Expand Down Expand Up @@ -705,13 +721,23 @@ export class Setup
)
}

private async accessConfig(cwd: string, ...args: Args) {
private accessConfig(cwd: string, ...args: Args) {
return this.accessDvc(AvailableCommands.CONFIG, cwd, ...args)
}

private accessRemote(cwd: string, ...args: Args) {
return this.accessDvc(AvailableCommands.REMOTE, cwd, ...args)
}

private async accessDvc(
commandId:
| typeof AvailableCommands.CONFIG
| typeof AvailableCommands.REMOTE,
cwd: string,
...args: Args
) {
try {
return await this.internalCommands.executeCommand(
AvailableCommands.CONFIG,
cwd,
...args
)
return await this.internalCommands.executeCommand(commandId, cwd, ...args)
} catch {}
}
}
15 changes: 11 additions & 4 deletions extension/src/setup/webview/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ export type DvcCliDetails = {
version: string | undefined
}

export type RemoteList =
| { [dvcRoot: string]: { [alias: string]: string } | undefined }
| undefined

export type SetupData = {
canGitInitialize: boolean
cliCompatible: boolean | undefined
Expand All @@ -14,20 +18,23 @@ export type SetupData = {
needsGitInitialized: boolean | undefined
projectInitialized: boolean
pythonBinPath: string | undefined
remoteList: RemoteList
sectionCollapsed: typeof DEFAULT_SECTION_COLLAPSED | undefined
shareLiveToStudio: boolean
}

export enum SetupSection {
DVC = 'dvc',
EXPERIMENTS = 'experiments',
STUDIO = 'studio',
DVC = 'dvc'
REMOTES = 'remotes',
STUDIO = 'studio'
}

export const DEFAULT_SECTION_COLLAPSED = {
[SetupSection.DVC]: false,
[SetupSection.EXPERIMENTS]: false,
[SetupSection.STUDIO]: false,
[SetupSection.DVC]: false
[SetupSection.REMOTES]: false,
[SetupSection.STUDIO]: false
}

export type SectionCollapsed = typeof DEFAULT_SECTION_COLLAPSED
Expand Down
2 changes: 2 additions & 0 deletions extension/src/setup/webview/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export class WebviewMessages {
needsGitInitialized,
projectInitialized,
pythonBinPath,
remoteList,
sectionCollapsed,
shareLiveToStudio
}: SetupData) {
Expand All @@ -54,6 +55,7 @@ export class WebviewMessages {
needsGitInitialized,
projectInitialized,
pythonBinPath,
remoteList,
sectionCollapsed,
shareLiveToStudio
})
Expand Down
4 changes: 4 additions & 0 deletions extension/src/test/suite/setup/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ suite('Setup Test Suite', () => {
needsGitInitialized: true,
projectInitialized: false,
pythonBinPath: undefined,
remoteList: undefined,
sectionCollapsed: undefined,
shareLiveToStudio: false
})
Expand Down Expand Up @@ -287,6 +288,7 @@ suite('Setup Test Suite', () => {
needsGitInitialized: true,
projectInitialized: false,
pythonBinPath: undefined,
remoteList: undefined,
sectionCollapsed: undefined,
shareLiveToStudio: false
})
Expand Down Expand Up @@ -337,6 +339,7 @@ suite('Setup Test Suite', () => {
needsGitInitialized: false,
projectInitialized: false,
pythonBinPath: undefined,
remoteList: undefined,
sectionCollapsed: undefined,
shareLiveToStudio: false
})
Expand Down Expand Up @@ -387,6 +390,7 @@ suite('Setup Test Suite', () => {
needsGitInitialized: false,
projectInitialized: true,
pythonBinPath: undefined,
remoteList: { [dvcDemoPath]: undefined },
sectionCollapsed: undefined,
shareLiveToStudio: false
})
Expand Down
1 change: 1 addition & 0 deletions extension/src/test/suite/setup/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const buildSetup = (

const mockEmitter = disposer.track(new EventEmitter())
stub(dvcReader, 'root').resolves(mockDvcRoot)
stub(dvcExecutor, 'remote').resolves('')
const mockVersion = stub(dvcReader, 'version').resolves(MIN_CLI_VERSION)
const mockGlobalVersion = stub(dvcReader, 'globalVersion').resolves(
MIN_CLI_VERSION
Expand Down
Loading