-
Notifications
You must be signed in to change notification settings - Fork 30
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
Experiment Commands #3: Add command for exp gc
with selectable flags
#269
Conversation
dvc gc
with selectable flagsdvc gc
with selectable flags
dvc gc
with selectable flagsexp gc
with selectable flags
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few questions on this one
extension/src/cli/commands.ts
Outdated
EXPERIMENT_GC = 'exp gc -f -w' | ||
} | ||
|
||
export enum DvcGcPreserveFlag { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[N] no need for Dvc
DvcGcQuickPickItem, | ||
experimentGcCommand, | ||
queueExperimentCommand | ||
} from './index' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[N] use '.'
@@ -9,7 +9,15 @@ export enum Commands { | |||
PUSH = 'push', | |||
STATUS = 'status --show-json', | |||
QUEUE_EXPERIMENT = 'exp run --queue', | |||
RUN_ALL_EXPERIMENTS = 'exp run --run-all' | |||
RUN_ALL_EXPERIMENTS = 'exp run --run-all', | |||
EXPERIMENT_GC = 'exp gc -f -w' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[I] Hoist with other experiment commands
|
||
test('it invokes a QuickPick with snapshotted options', async () => { | ||
await experimentGcCommand(exampleConfig) | ||
expect(mockedShowQuickPick.mock.calls).toMatchInlineSnapshot(` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Q] What is the benefit of using a snapshot here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Q] I see all the other tests have mockedShowQuickPick.mockResolvedValue
how does this one get it's resolved value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you moved the implementation to a constant like so
export const gcQuickPickItems = [
{
label: 'All Branches',
detail: 'Preserve Experiments derived from all Git branches',
flag: DvcGcPreserveFlag.ALL_BRANCHES
},
{
label: 'All Tags',
detail: 'Preserve Experiments derived from all Git tags',
flag: DvcGcPreserveFlag.ALL_TAGS
},
{
label: 'All Commits',
detail: 'Preserve Experiments derived from all Git commits',
flag: DvcGcPreserveFlag.ALL_COMMITS
},
{
label: 'Queued Experiments',
detail: 'Preserve all queued Experiments',
flag: DvcGcPreserveFlag.QUEUED
}
]
export const gcQuickPickOptions = {
canPickMany: true,
placeHolder: 'Select which Experiments to preserve'
}
then you could import that into the test and check that is what is being passed to show quick pick.
You could also use gcQuickPickItems.slice(1,3) for the next test down giving this implementation in the test:
it('should invoke a QuickPick with the gcQuickPickItems options', async () => {
await experimentGcCommand(exampleConfig)
expect(mockedShowQuickPick.mock.calls).toEqual([
[gcQuickPickItems, gcQuickPickOptions]
])
})
it('should executes the proper command given a mocked selection', async () => {
mockedShowQuickPick.mockResolvedValue(gcQuickPickItems.slice(1, 3))
await experimentGcCommand(exampleConfig)
expect(mockedExecPromise).toBeCalledWith(
'dvc exp gc -f -w --all-tags --all-commits',
{
cwd: exampleConfig.workspaceRoot
}
)
})
and this in the code:
export const gcQuickPickOptions = {
canPickMany: true,
placeHolder: 'Select which Experiments to preserve'
}
export const experimentGcCommand = async (config: Config) => {
const quickPickResult = (await window.showQuickPick<DvcGcQuickPickItem>(
gcQuickPickItems,
gcQuickPickOptions
)) as undefined | DvcGcQuickPickItem[]
if (quickPickResult) {
try {
const stdout = await experimentGarbageCollect(
{
cwd: config.workspaceRoot,
cliPath: config.dvcPath
},
quickPickResult.map(({ flag }) => flag)
)
window.showInformationMessage(stdout)
} catch (e) {
window.showErrorMessage(e.stderr || e.message)
}
}
}
I still think that quick pick functionality should be outsourced from this file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Q] What is the benefit of using a snapshot here?
This test acts as check that allows us to refactor the experiment GC command in any way and expect the same shape, and with a snapshot a dev can compare changed outputs and deliberately accept the changes with a jest -u
.
[Q] I see all the other tests have
mockedShowQuickPick.mockResolvedValue
how does this one get it's resolved value?
This test doesn't set a resolved value because the resolved value of showQuickPick
doesn't matter in this test, just the arguments passed to it. Explicitly defining the mock implementation to return something like undefined
would be more explicit, but functionally the exact same.
If you moved the implementation to a constant like so [...] then you could import that into the test and check that is what is being passed to show quick pick.
While that is doable, it would add unnecessary exports and overhead while not adding any benefit over using a snapshot.
Directly comparing an exported argument constant would require the test to be changed around for most implementation changes, while the snapshot holds true regardless of where the QuickPick options come from and how they're build.
I still think that quick pick functionality should be outsourced from this file.
At the risk of sounding like I'm pulling a "no, you!", I think index
would be best as a module that handles how the dvc commands interface to VSCode with stuff like quickpicks, and the functions that run the commands be in their own file.
I do agree that the cli
dir needs a bit of restructuring, as it's become a bit of a big ball of mud over time.
extension/src/cli/index.ts
Outdated
} | ||
|
||
export const experimentGcCommand = async (config: Config) => { | ||
const quickPickResult = await window.showQuickPick<DvcGcQuickPickItem>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Q] do you think this would be better placed in another file? This is probably also a better candidate for an integration test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you think this would be better placed in another file?
Maybe these defined vscode callbacks and the registerCommands
function could find a better home in something like a module named commands
.
This is probably also a better candidate for an integration test.
I disagree, mocks test this functionality perfectly fine. The integration tests are already quite heavy and often flaky, we should only use them when they're really necessary. Jest tests also provide coverage and are much more easily integrated into all forms of CI.
* Change execCommand to resolve to stdout and simplify its consumers * runDvcCommand => runCommand * Reorganize command enum to distinguish exp commands with a prefix * DvcGc => Gc
* Add "Run Queued Experiments" command * Add test for "runQueuedExperiments" * Experiment Commands #3: Add command for `exp gc` with selectable flags (#269) * Add command for GC * Change gc to exp gc, and add leading `--` to enum flags * Add GC command tests and export GC QuickPickItem interface * Rename exp gc enum entry and reader command * Change gcExperiments to experimentGarbageCollect * Replace test() with it() for consistency * Experiment Commands #4: Addressing comments from 1-3 (#271) * Change execCommand to resolve to stdout and simplify its consumers * runDvcCommand => runCommand * Reorganize command enum to distinguish exp commands with a prefix * DvcGc => Gc
* Add a "Queue Experiments" command No tests yet, but there is info message functionality which seems to work well. * Try to make a test for the new queue command * Re-add failing test * Move individual test file into index test file * Use commands enum for queue experiment * Rename `queue_experiment` enum to follow new allcaps convention * Experiments Commands #2: Add "Run All Queued Experiments" Command (#268) * Add "Run Queued Experiments" command * Add test for "runQueuedExperiments" * Experiment Commands #3: Add command for `exp gc` with selectable flags (#269) * Add command for GC * Change gc to exp gc, and add leading `--` to enum flags * Add GC command tests and export GC QuickPickItem interface * Rename exp gc enum entry and reader command * Change gcExperiments to experimentGarbageCollect * Replace test() with it() for consistency * Experiment Commands #4: Addressing comments from 1-3 (#271) * Change execCommand to resolve to stdout and simplify its consumers * runDvcCommand => runCommand * Reorganize command enum to distinguish exp commands with a prefix * DvcGc => Gc Co-authored-by: mattseddon <37993418+mattseddon@users.noreply.github.com>
Based on #268. Part of #229, which is part of #239
This PR adds a single VSCode Command for
dvc gc
, which invokes aQuickPick
menu that allows the user to select any of--all-branches
,--all-tags
,--all-commits
, and--queue
.dvc gc
in one command.dvc exp gc -f -w
. This is also the command run when the quickpick is properly submitted with no selected options.-f
to skip the CLI warning (if anything, we'll implement our own)-w
because it is effectively always enabled, and it only exists sodvc exp gc
with no options won't do anything.stdout
orstderr
of a command will be reported through theshowInformationMessage
andshowErrorMessage
functions, respectively.We could handle this more gracefully by intercepting known errors and displaying more concise messages, but I think that can be considered its own issue that could best be handled with a more unified way of command output reporting.