Skip to content

Commit ddce5b1

Browse files
authored
Add command to add remote (#3929)
* add add remote command * add tests * refactor * apply review feedback
1 parent 2558f1f commit ddce5b1

File tree

22 files changed

+297
-30
lines changed

22 files changed

+297
-30
lines changed

.eslintrc.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module.exports = {
33
env: {
44
'jest/globals': true
55
},
6+
67
extends: [
78
'prettier-standard/prettier-file',
89
'plugin:@typescript-eslint/eslint-recommended',
@@ -22,7 +23,8 @@ module.exports = {
2223
'**/*.js',
2324
'*.d.ts',
2425
'tsconfig.json',
25-
'webpack.config.ts'
26+
'webpack.config.ts',
27+
'scripts/virtualenv-install.ts'
2628
],
2729
overrides: [
2830
{

demo

Submodule demo updated from a20953b to 5f06c37

extension/package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,12 @@
100100
"category": "DVC",
101101
"icon": "$(add)"
102102
},
103+
{
104+
"title": "Add Remote",
105+
"command": "dvc.addRemote",
106+
"category": "DVC",
107+
"icon": "$(add)"
108+
},
103109
{
104110
"title": "Filter Experiments Table to Starred",
105111
"command": "dvc.addStarredExperimentsTableFilter",
@@ -654,6 +660,10 @@
654660
"command": "dvc.addExperimentsTableSort",
655661
"when": "dvc.commands.available && dvc.project.available"
656662
},
663+
{
664+
"command": "dvc.addRemote",
665+
"when": "dvc.commands.available && dvc.project.available && !dvc.experiment.running.workspace"
666+
},
657667
{
658668
"command": "dvc.addStarredExperimentsTableFilter",
659669
"when": "dvc.commands.available && dvc.project.available"

extension/src/cli/dvc/constants.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export enum Command {
3838
}
3939

4040
export enum SubCommand {
41+
ADD = 'add',
4142
DIFF = 'diff',
4243
LIST = 'list',
4344
STATUS = 'status',
@@ -47,13 +48,15 @@ export enum SubCommand {
4748
export enum Flag {
4849
ALL_COMMITS = '-A',
4950
FOLLOW = '-f',
51+
DEFAULT = '-d',
5052
FORCE = '-f',
5153
GLOBAL = '--global',
5254
GRANULAR = '--granular',
53-
LOCAL = '--local',
5455
JOBS = '-j',
5556
JSON = '--json',
5657
KILL = '--kill',
58+
LOCAL = '--local',
59+
PROJECT = '--project',
5760
NUM_COMMIT = '-n',
5861
OUTPUT_PATH = '-o',
5962
SUBDIRECTORY = '--subdir',

extension/src/cli/dvc/executor.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import {
77
ExperimentSubCommand,
88
Flag,
99
GcPreserveFlag,
10-
QueueSubCommand,
11-
SubCommand
10+
QueueSubCommand
1211
} from './constants'
1312
import { addStudioAccessToken } from './options'
1413
import { CliResult, CliStarted, typeCheckCommands } from '..'
@@ -198,8 +197,8 @@ export class DvcExecutor extends DvcCli {
198197
return this.blockAndExecuteProcess(cwd, Command.REMOVE, ...args)
199198
}
200199

201-
public remote(cwd: string, arg: typeof SubCommand.LIST) {
202-
return this.executeDvcProcess(cwd, Command.REMOTE, arg)
200+
public remote(cwd: string, ...args: Args) {
201+
return this.executeDvcProcess(cwd, Command.REMOTE, ...args)
203202
}
204203

205204
private executeExperimentProcess(cwd: string, ...args: Args) {

extension/src/commands/external.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ export enum RegisteredCliCommands {
4141
REMOVE_TARGET = 'dvc.removeTarget',
4242
RENAME_TARGET = 'dvc.renameTarget',
4343

44+
REMOTE_ADD = 'dvc.addRemote',
45+
4446
GIT_STAGE_ALL = 'dvc.gitStageAll',
4547
GIT_UNSTAGE_ALL = 'dvc.gitUnstageAll'
4648
}

extension/src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import { Flag } from './cli/dvc/constants'
4747
import { LanguageClient } from './languageClient'
4848
import { collectRunningExperimentPids } from './experiments/processExecution/collect'
4949
import { DvcViewer } from './cli/dvc/viewer'
50-
import { registerSetupCommands } from './setup/register'
50+
import { registerSetupCommands } from './setup/commands/register'
5151
import { Status } from './status'
5252
import { registerPersistenceCommands } from './persistence/register'
5353

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { Setup } from '..'
2+
import { Flag, SubCommand } from '../../cli/dvc/constants'
3+
import { AvailableCommands, InternalCommands } from '../../commands/internal'
4+
import { definedAndNonEmpty } from '../../util/array'
5+
import { getInput } from '../../vscode/inputBox'
6+
import { quickPickYesOrNo } from '../../vscode/quickPick'
7+
import { Title } from '../../vscode/title'
8+
import { Toast } from '../../vscode/toast'
9+
import { getOnlyOrPickProject } from '../../workspace/util'
10+
11+
const noExistingOrUserConfirms = async (
12+
internalCommands: InternalCommands,
13+
dvcRoot: string
14+
): Promise<boolean | undefined> => {
15+
const remoteList = await internalCommands.executeCommand(
16+
AvailableCommands.REMOTE,
17+
dvcRoot,
18+
SubCommand.LIST
19+
)
20+
21+
if (!remoteList) {
22+
return true
23+
}
24+
25+
return await quickPickYesOrNo(
26+
'make this new remote the default',
27+
'keep the current default',
28+
{
29+
placeHolder: 'Would you like to set this new remote as the default?',
30+
title: Title.SET_REMOTE_AS_DEFAULT
31+
}
32+
)
33+
}
34+
35+
const addRemoteToProject = async (
36+
internalCommands: InternalCommands,
37+
dvcRoot: string
38+
): Promise<void> => {
39+
const name = await getInput(Title.ENTER_REMOTE_NAME)
40+
if (!name) {
41+
return
42+
}
43+
44+
const url = await getInput(Title.ENTER_REMOTE_URL)
45+
if (!url) {
46+
return
47+
}
48+
49+
const args = [Flag.PROJECT, name, url]
50+
51+
const shouldSetAsDefault = await noExistingOrUserConfirms(
52+
internalCommands,
53+
dvcRoot
54+
)
55+
if (shouldSetAsDefault === undefined) {
56+
return
57+
}
58+
59+
if (shouldSetAsDefault) {
60+
args.unshift(Flag.DEFAULT)
61+
}
62+
63+
return await Toast.showOutput(
64+
internalCommands.executeCommand(
65+
AvailableCommands.REMOTE,
66+
dvcRoot,
67+
SubCommand.ADD,
68+
...args
69+
)
70+
)
71+
}
72+
73+
export const getAddRemoteCommand =
74+
(setup: Setup, internalCommands: InternalCommands) =>
75+
async (): Promise<void> => {
76+
const dvcRoots = setup.getRoots()
77+
if (!definedAndNonEmpty(dvcRoots)) {
78+
return Toast.showError('Cannot add a remote without a DVC project')
79+
}
80+
const dvcRoot = await getOnlyOrPickProject(dvcRoots)
81+
82+
if (!dvcRoot) {
83+
return
84+
}
85+
return addRemoteToProject(internalCommands, dvcRoot)
86+
}

extension/src/setup/register.ts renamed to extension/src/setup/commands/register.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import { commands } from 'vscode'
2-
import { Setup } from '.'
3-
import { run } from './runner'
4-
import { SetupSection } from './webview/contract'
5-
import { AvailableCommands, InternalCommands } from '../commands/internal'
6-
import { RegisteredCliCommands, RegisteredCommands } from '../commands/external'
7-
import { getFirstWorkspaceFolder } from '../vscode/workspaceFolders'
2+
import { getAddRemoteCommand } from '.'
3+
import { Setup } from '..'
4+
import { run } from '../runner'
5+
import { SetupSection } from '../webview/contract'
6+
import { AvailableCommands, InternalCommands } from '../../commands/internal'
7+
import {
8+
RegisteredCliCommands,
9+
RegisteredCommands
10+
} from '../../commands/external'
11+
import { getFirstWorkspaceFolder } from '../../vscode/workspaceFolders'
812

913
const registerSetupConfigCommands = (
1014
setup: Setup,
@@ -100,6 +104,11 @@ export const registerSetupCommands = (
100104
}
101105
)
102106

107+
internalCommands.registerExternalCliCommand(
108+
RegisteredCliCommands.REMOTE_ADD,
109+
getAddRemoteCommand(setup, internalCommands)
110+
)
111+
103112
registerSetupConfigCommands(setup, internalCommands)
104113
registerSetupShowCommands(setup, internalCommands)
105114
registerSetupStudioCommands(setup, internalCommands)

extension/src/setup/webview/messages.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ export class WebviewMessages {
104104
)
105105
case MessageFromWebviewType.OPEN_EXPERIMENTS_WEBVIEW:
106106
return commands.executeCommand(RegisteredCommands.EXPERIMENT_SHOW)
107+
case MessageFromWebviewType.REMOTE_ADD:
108+
return commands.executeCommand(RegisteredCliCommands.REMOTE_ADD)
107109

108110
default:
109111
Logger.error(`Unexpected message: ${JSON.stringify(message)}`)

0 commit comments

Comments
 (0)