diff --git a/extension/package.json b/extension/package.json index 1fa049cb03..76946185d4 100644 --- a/extension/package.json +++ b/extension/package.json @@ -123,6 +123,18 @@ "category": "DVC", "icon": "$(discard)" }, + { + "title": "%command.commit%", + "command": "dvc.commit", + "category": "DVC", + "icon": "$(check)" + }, + { + "title": "%command.commitTarget%", + "command": "dvc.commitTarget", + "category": "DVC", + "icon": "$(check)" + }, { "title": "%command.pullTarget%", "command": "dvc.pullTarget", @@ -161,6 +173,14 @@ "command": "dvc.checkoutTarget", "when": "false" }, + { + "command": "dvc.commit", + "when": "false" + }, + { + "command": "dvc.commitTarget", + "when": "false" + }, { "command": "dvc.pullTarget", "when": "false" @@ -170,19 +190,17 @@ "when": "false" } ], - "scm/change/title": [ - { - "command": "dvc.addTarget", - "group": "inline", - "when": "scmProvider == dvc" - } - ], "scm/title": [ { "command": "dvc.checkout", "group": "navigation", "when": "scmProvider == dvc" }, + { + "command": "dvc.commit", + "group": "navigation", + "when": "scmProvider == dvc" + }, { "command": "dvc.showExperiments", "group": "experiments", @@ -220,6 +238,11 @@ "group": "inline", "when": "scmProvider == dvc && scmResourceState != untracked && scmResourceState != notInCache" }, + { + "command": "dvc.commitTarget", + "group": "inline", + "when": "scmProvider == dvc" + }, { "command": "dvc.pushTarget", "group": "inline", diff --git a/extension/package.nls.json b/extension/package.nls.json index 08651ac4e6..1fe9177d20 100644 --- a/extension/package.nls.json +++ b/extension/package.nls.json @@ -5,6 +5,7 @@ "command.checkout": "Checkout", "command.checkoutTarget": "Checkout Target", "command.commit": "Commit", + "command.commitTarget": "Commit Target", "command.init": "Init DVC", "command.initNoScm": "Init DVC --no-scm", "command.pull": "Pull", diff --git a/extension/src/cli/commands.ts b/extension/src/cli/commands.ts index eb8c929c36..3454592cf1 100644 --- a/extension/src/cli/commands.ts +++ b/extension/src/cli/commands.ts @@ -1,6 +1,7 @@ export enum Commands { ADD = 'add', CHECKOUT = 'checkout', + COMMIT = 'commit', EXPERIMENT_GC = 'exp gc -f -w', EXPERIMENT_QUEUE = 'exp run --queue', EXPERIMENT_RUN = 'exp run', @@ -24,6 +25,10 @@ export enum ListFlag { RECURSIVE = '-R' } +export enum CommitFlag { + FORCE = '-f' +} + export enum GcPreserveFlag { ALL_BRANCHES = '--all-branches', ALL_TAGS = '--all-tags', diff --git a/extension/src/cli/index.ts b/extension/src/cli/index.ts index a19da8b55f..4331f9904c 100644 --- a/extension/src/cli/index.ts +++ b/extension/src/cli/index.ts @@ -1,6 +1,6 @@ import { ensureDir } from 'fs-extra' import { basename, dirname } from 'path' -import { buildCommand, Commands } from './commands' +import { buildCommand, Commands, CommitFlag } from './commands' import { execProcess } from './execution' const runTargetCommand = async ( @@ -28,6 +28,13 @@ export const addTarget = async (options: { pythonBinPath: string | undefined }): Promise => runTargetCommand(options, Commands.ADD) +export const commitTarget = (options: { + fsPath: string + cliPath: string | undefined + pythonBinPath: string | undefined +}): Promise => + runTargetCommand(options, buildCommand(Commands.COMMIT, CommitFlag.FORCE)) + export const checkoutTarget = (options: { fsPath: string cliPath: string | undefined diff --git a/extension/src/cli/reader.test.ts b/extension/src/cli/reader.test.ts index 8dcf7edc21..4ebafbff6b 100644 --- a/extension/src/cli/reader.test.ts +++ b/extension/src/cli/reader.test.ts @@ -1,5 +1,6 @@ import { checkout, + commit, experimentApply, getExperiments, getRoot, @@ -86,6 +87,7 @@ describe('initializeDirectory', () => { ) }) }) + describe('checkout', () => { it('should call execPromise with the correct parameters', async () => { const fsPath = __dirname @@ -111,6 +113,31 @@ describe('checkout', () => { }) }) +describe('commit', () => { + it('should call execPromise with the correct parameters', async () => { + const cwd = __dirname + const stdout = "Updating lock file 'dvc.lock'" + mockedExecPromise.mockResolvedValueOnce({ + stdout, + stderr: '' + }) + + const output = await commit({ + cliPath: 'dvc', + cwd, + pythonBinPath: undefined + }) + expect(output).toEqual(stdout) + + expect(mockedExecPromise).toBeCalledWith( + 'dvc commit -f', + expect.objectContaining({ + cwd + }) + ) + }) +}) + describe('getRoot', () => { it('should return the root relative to the cwd', async () => { const mockRelativeRoot = join('..', '..') diff --git a/extension/src/cli/reader.ts b/extension/src/cli/reader.ts index 5cb0024e87..680ecbe659 100644 --- a/extension/src/cli/reader.ts +++ b/extension/src/cli/reader.ts @@ -1,4 +1,10 @@ -import { buildCommand, Commands, GcPreserveFlag, ListFlag } from './commands' +import { + buildCommand, + CommitFlag, + Commands, + GcPreserveFlag, + ListFlag +} from './commands' import { trimAndSplit } from '../util/stdout' import { ExperimentsRepoJSONOutput } from '../webviews/experiments/contract' import { execProcess, ReaderOptions } from './execution' @@ -6,6 +12,9 @@ import { execProcess, ReaderOptions } from './execution' export const checkout = async (options: ReaderOptions): Promise => execProcess(options, Commands.CHECKOUT, trimAndSplit) +export const commit = async (options: ReaderOptions): Promise => + execProcess(options, buildCommand(Commands.COMMIT, CommitFlag.FORCE)) + export const getRoot = async (options: ReaderOptions): Promise => execProcess(options, Commands.ROOT) diff --git a/extension/src/cli/register.ts b/extension/src/cli/register.ts index a329d1ae92..dbc8d26562 100644 --- a/extension/src/cli/register.ts +++ b/extension/src/cli/register.ts @@ -1,8 +1,14 @@ import { commands } from 'vscode' -import { addTarget, checkoutTarget, pullTarget, pushTarget } from '.' +import { + addTarget, + checkoutTarget, + commitTarget, + pullTarget, + pushTarget +} from '.' import { Config } from '../Config' import { Disposer } from '../extension' -import { checkout, initializeDirectory } from './reader' +import { checkout, commit, initializeDirectory } from './reader' import { applyExperimentFromQuickPick, branchExperimentFromQuickPick, @@ -51,6 +57,27 @@ const registerCommands = (config: Config, disposer: Disposer) => { }) ) ) + + disposer.track( + commands.registerCommand('dvc.commit', ({ rootUri }) => { + commit({ + cwd: rootUri.fsPath, + cliPath: config.dvcPath, + pythonBinPath: config.pythonBinPath + }) + }) + ) + + disposer.track( + commands.registerCommand('dvc.commitTarget', ({ resourceUri }) => + commitTarget({ + fsPath: resourceUri.fsPath, + cliPath: config.dvcPath, + pythonBinPath: config.pythonBinPath + }) + ) + ) + disposer.track( commands.registerCommand('dvc.pushTarget', ({ resourceUri }) => pushTarget({