Skip to content

Commit 30935d8

Browse files
authored
Add warning to setup about latest tested version (#3895)
1 parent 8590ae8 commit 30935d8

File tree

20 files changed

+387
-128
lines changed

20 files changed

+387
-128
lines changed

extension/src/cli/dvc/version.test.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import {
22
isVersionCompatible,
33
extractSemver,
44
ParsedSemver,
5-
CliCompatible
5+
CliCompatible,
6+
isAboveLatestTestedVersion
67
} from './version'
78
import { MIN_CLI_VERSION, LATEST_TESTED_CLI_VERSION } from './contract'
89

@@ -161,3 +162,47 @@ describe('isVersionCompatible', () => {
161162
expect(isCompatible).toStrictEqual(CliCompatible.NO_CANNOT_VERIFY)
162163
})
163164
})
165+
166+
describe('isAboveLatestTestedVersion', () => {
167+
it('should return undefined if version is undefined', () => {
168+
const result = isAboveLatestTestedVersion(undefined)
169+
170+
expect(result).toStrictEqual(undefined)
171+
})
172+
173+
it('should return true for a version with a minor higher as the latest tested minor and any patch', () => {
174+
const {
175+
major: latestTestedMajor,
176+
minor: latestTestedMinor,
177+
patch: latestTestedPatch
178+
} = extractSemver(LATEST_TESTED_CLI_VERSION) as ParsedSemver
179+
180+
expect(0).toBeLessThan(latestTestedPatch)
181+
182+
let result = isAboveLatestTestedVersion(
183+
[latestTestedMajor, latestTestedMinor + 1, 0].join('.')
184+
)
185+
186+
expect(result).toStrictEqual(true)
187+
188+
result = isAboveLatestTestedVersion(
189+
[latestTestedMajor, latestTestedMinor + 1, latestTestedPatch + 1000].join(
190+
'.'
191+
)
192+
)
193+
194+
expect(result).toStrictEqual(true)
195+
196+
result = isAboveLatestTestedVersion(
197+
[latestTestedMajor, latestTestedMinor + 1, latestTestedPatch].join('.')
198+
)
199+
200+
expect(result).toStrictEqual(true)
201+
})
202+
203+
it('should return false if version is below the latest tested version', () => {
204+
const result = isAboveLatestTestedVersion(MIN_CLI_VERSION)
205+
206+
expect(result).toStrictEqual(false)
207+
})
208+
})

extension/src/cli/dvc/version.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { MAX_CLI_VERSION, MIN_CLI_VERSION } from './contract'
1+
import {
2+
LATEST_TESTED_CLI_VERSION,
3+
MAX_CLI_VERSION,
4+
MIN_CLI_VERSION
5+
} from './contract'
26

37
export enum CliCompatible {
48
NO_CANNOT_VERIFY = 'no-cannot-verify',
@@ -67,3 +71,19 @@ export const isVersionCompatible = (
6771

6872
return checkCLIVersion(currentSemVer)
6973
}
74+
75+
export const isAboveLatestTestedVersion = (version: string | undefined) => {
76+
if (!version) {
77+
return undefined
78+
}
79+
80+
const { major: currentMajor, minor: currentMinor } = extractSemver(
81+
version
82+
) as ParsedSemver
83+
84+
const { major: latestTestedMajor, minor: latestTestedMinor } = extractSemver(
85+
LATEST_TESTED_CLI_VERSION
86+
) as ParsedSemver
87+
88+
return currentMajor === latestTestedMajor && currentMinor > latestTestedMinor
89+
}

extension/src/setup/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ import { getValidInput } from '../vscode/inputBox'
5959
import { Title } from '../vscode/title'
6060
import { getDVCAppDir } from '../util/appdirs'
6161
import { getOptions } from '../cli/dvc/options'
62+
import { isAboveLatestTestedVersion } from '../cli/dvc/version'
6263

6364
export class Setup
6465
extends BaseRepository<TSetupData>
@@ -414,6 +415,7 @@ export class Setup
414415
cliCompatible: this.getCliCompatible(),
415416
dvcCliDetails,
416417
hasData,
418+
isAboveLatestTestedVersion: isAboveLatestTestedVersion(this.cliVersion),
417419
isPythonExtensionUsed,
418420
isStudioConnected: this.studioIsConnected,
419421
needsGitCommit,

extension/src/setup/webview/contract.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export type SetupData = {
2121
remoteList: RemoteList
2222
sectionCollapsed: typeof DEFAULT_SECTION_COLLAPSED | undefined
2323
shareLiveToStudio: boolean
24+
isAboveLatestTestedVersion: boolean | undefined
2425
}
2526

2627
export enum SetupSection {

extension/src/setup/webview/messages.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,15 @@ export class WebviewMessages {
4242
pythonBinPath,
4343
remoteList,
4444
sectionCollapsed,
45-
shareLiveToStudio
45+
shareLiveToStudio,
46+
isAboveLatestTestedVersion
4647
}: SetupData) {
4748
void this.getWebview()?.show({
4849
canGitInitialize,
4950
cliCompatible,
5051
dvcCliDetails,
5152
hasData,
53+
isAboveLatestTestedVersion,
5254
isPythonExtensionUsed,
5355
isStudioConnected,
5456
needsGitCommit,

extension/src/test/suite/setup/index.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ suite('Setup Test Suite', () => {
240240
cliCompatible: undefined,
241241
dvcCliDetails: { command: 'dvc', version: undefined },
242242
hasData: false,
243+
isAboveLatestTestedVersion: undefined,
243244
isPythonExtensionUsed: false,
244245
isStudioConnected: false,
245246
needsGitCommit: true,
@@ -282,6 +283,7 @@ suite('Setup Test Suite', () => {
282283
cliCompatible: true,
283284
dvcCliDetails: { command: 'dvc', version: MIN_CLI_VERSION },
284285
hasData: false,
286+
isAboveLatestTestedVersion: false,
285287
isPythonExtensionUsed: false,
286288
isStudioConnected: false,
287289
needsGitCommit: true,
@@ -333,6 +335,7 @@ suite('Setup Test Suite', () => {
333335
version: MIN_CLI_VERSION
334336
},
335337
hasData: false,
338+
isAboveLatestTestedVersion: false,
336339
isPythonExtensionUsed: false,
337340
isStudioConnected: false,
338341
needsGitCommit: false,
@@ -384,6 +387,7 @@ suite('Setup Test Suite', () => {
384387
version: MIN_CLI_VERSION
385388
},
386389
hasData: false,
390+
isAboveLatestTestedVersion: false,
387391
isPythonExtensionUsed: false,
388392
isStudioConnected: false,
389393
needsGitCommit: true,

webview/icons/codicons.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@ export const codicons = [
2424
'sort-precedence',
2525
'star-empty',
2626
'star-full',
27-
'trash'
27+
'trash',
28+
'warning'
2829
]

webview/src/plots/components/App.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ import {
5353
dragEnter,
5454
dragLeave
5555
} from '../../test/dragDrop'
56-
import { SectionDescription } from '../../shared/components/sectionContainer/SectionContainer'
56+
import { SectionDescriptionMainText } from '../../shared/components/sectionContainer/SectionDescription'
5757
import { DragEnterDirection } from '../../shared/components/dragDrop/util'
5858
import { clearSelection, createWindowTextSelection } from '../../test/selection'
5959
import * as EventCurrentTargetDistances from '../../shared/components/dragDrop/currentTarget'
@@ -648,7 +648,7 @@ describe('App', () => {
648648
const summaryElement = await screen.findByText('Custom')
649649
createWindowTextSelection(
650650
// eslint-disable-next-line testing-library/no-node-access
651-
SectionDescription['custom-plots'].props.children,
651+
SectionDescriptionMainText['custom-plots'].props.children,
652652
2
653653
)
654654
fireEvent.click(summaryElement, {

webview/src/setup/components/App.test.tsx

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const DEFAULT_DATA = {
3131
version: '1.0.0'
3232
},
3333
hasData: false,
34+
isAboveLatestTestedVersion: false,
3435
isPythonExtensionUsed: false,
3536
isStudioConnected: false,
3637
needsGitCommit: false,
@@ -394,7 +395,9 @@ describe('App', () => {
394395
projectInitialized: false
395396
})
396397

397-
const iconWrapper = screen.getAllByTestId('info-tooltip-toggle')[0]
398+
const iconWrapper = within(
399+
screen.getByTestId('dvc-section-details')
400+
).getByTestId('info-tooltip-toggle')
398401

399402
expect(
400403
within(iconWrapper).getByTestId(TooltipIconType.ERROR)
@@ -405,13 +408,47 @@ describe('App', () => {
405408
renderApp({ remoteList: { mockRoot: undefined } })
406409
expect(screen.queryByText('DVC is not setup')).not.toBeInTheDocument()
407410

408-
const iconWrapper = screen.getAllByTestId('info-tooltip-toggle')[0]
411+
const iconWrapper = within(
412+
screen.getByTestId('dvc-section-details')
413+
).getByTestId('info-tooltip-toggle')
409414

410415
expect(
411416
within(iconWrapper).getByTestId(TooltipIconType.PASSED)
412417
).toBeInTheDocument()
413418
})
414419

420+
it('should add a warning icon and message if version is above the latest tested version', () => {
421+
renderApp({
422+
isAboveLatestTestedVersion: true
423+
})
424+
425+
const iconWrapper = within(
426+
screen.getByTestId('dvc-section-details')
427+
).getByTestId('info-tooltip-toggle')
428+
429+
expect(
430+
within(iconWrapper).getByTestId(TooltipIconType.WARNING)
431+
).toBeInTheDocument()
432+
433+
fireEvent.mouseEnter(iconWrapper)
434+
435+
expect(
436+
screen.getByText(
437+
'The located version has not been tested against the extension. If you are experiencing unexpected behaviour, first try to update the extension. If there are no updates available, please downgrade DVC to the same minor version as displayed and reload the window.'
438+
)
439+
).toBeInTheDocument()
440+
})
441+
})
442+
443+
describe('Experiments', () => {
444+
it('should show a screen saying that dvc is not setup if the project is not initialized', () => {
445+
renderApp({
446+
projectInitialized: false
447+
})
448+
449+
expect(screen.getByText('DVC is not setup')).toBeInTheDocument()
450+
})
451+
415452
it('should open the dvc section when clicking the Setup DVC button on the dvc is not setup screen', () => {
416453
renderApp({
417454
projectInitialized: false,
@@ -489,7 +526,9 @@ describe('App', () => {
489526
it('should show an error icon if experiments are not setup', () => {
490527
renderApp()
491528

492-
const iconWrapper = screen.getAllByTestId('info-tooltip-toggle')[1]
529+
const iconWrapper = within(
530+
screen.getByTestId('experiments-section-details')
531+
).getByTestId('info-tooltip-toggle')
493532

494533
expect(
495534
within(iconWrapper).getByTestId(TooltipIconType.ERROR)
@@ -501,7 +540,9 @@ describe('App', () => {
501540
cliCompatible: false
502541
})
503542

504-
const iconWrapper = screen.getAllByTestId('info-tooltip-toggle')[1]
543+
const iconWrapper = within(
544+
screen.getByTestId('experiments-section-details')
545+
).getByTestId('info-tooltip-toggle')
505546

506547
expect(
507548
within(iconWrapper).getByTestId(TooltipIconType.ERROR)
@@ -513,7 +554,9 @@ describe('App', () => {
513554
hasData: true
514555
})
515556

516-
const iconWrapper = screen.getAllByTestId('info-tooltip-toggle')[1]
557+
const iconWrapper = within(
558+
screen.getByTestId('experiments-section-details')
559+
).getByTestId('info-tooltip-toggle')
517560

518561
expect(
519562
within(iconWrapper).getByTestId(TooltipIconType.PASSED)
@@ -571,7 +614,9 @@ describe('App', () => {
571614
cliCompatible: false
572615
})
573616

574-
const iconWrapper = screen.getAllByTestId('info-tooltip-toggle')[3]
617+
const iconWrapper = within(
618+
screen.getByTestId('studio-section-details')
619+
).getByTestId('info-tooltip-toggle')
575620

576621
expect(
577622
within(iconWrapper).getByTestId(TooltipIconType.ERROR)
@@ -581,7 +626,9 @@ describe('App', () => {
581626
it('should show an info icon if dvc is compatible but studio is not connected', () => {
582627
renderApp()
583628

584-
const iconWrapper = screen.getAllByTestId('info-tooltip-toggle')[3]
629+
const iconWrapper = within(
630+
screen.getByTestId('studio-section-details')
631+
).getByTestId('info-tooltip-toggle')
585632

586633
expect(
587634
within(iconWrapper).getByTestId(TooltipIconType.INFO)
@@ -622,7 +669,9 @@ describe('App', () => {
622669
isStudioConnected: true
623670
})
624671

625-
const iconWrapper = screen.getAllByTestId('info-tooltip-toggle')[3]
672+
const iconWrapper = within(
673+
screen.getByTestId('studio-section-details')
674+
).getByTestId('info-tooltip-toggle')
626675

627676
expect(
628677
within(iconWrapper).getByTestId(TooltipIconType.PASSED)

0 commit comments

Comments
 (0)