Skip to content
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/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const MIN_CLI_VERSION = '2.11.0'
export const LATEST_TESTED_CLI_VERSION = '2.13.0'
export const MAX_CLI_VERSION = '3'

export enum Command {
Expand Down
67 changes: 59 additions & 8 deletions extension/src/cli/version.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { isVersionCompatible, extractSemver, ParsedSemver } from './version'
import { MIN_CLI_VERSION } from './constants'
import { MIN_CLI_VERSION, LATEST_TESTED_CLI_VERSION } from './constants'
import { Toast } from '../vscode/toast'

jest.mock('./constants', () => ({
...jest.requireActual('./constants'),
LATEST_TESTED_CLI_VERSION: '2.11.1',
MIN_CLI_VERSION: '2.9.4'
}))
jest.mock('../vscode/config')
Expand Down Expand Up @@ -50,31 +51,78 @@ describe('isVersionCompatible', () => {
patch: minPatch
} = extractSemver(MIN_CLI_VERSION) as ParsedSemver

const {
major: latestTestedMajor,
minor: latestTestedMinor,
patch: latestTestedPatch
} = extractSemver(LATEST_TESTED_CLI_VERSION) as ParsedSemver

it('should be compatible and not send a toast message if the provided version matches the min version', () => {
const isCompatible = isVersionCompatible(MIN_CLI_VERSION)

expect(isCompatible).toBe(true)
expect(mockedWarnWithOptions).not.toBeCalled()
})

it('should be compatible and not send a toast for a version with the same minor and higher patch', () => {
it('should be compatible and not send a toast for a version with the same minor and higher patch as the min compatible version', () => {
mockedWarnWithOptions.mockResolvedValueOnce(undefined)

const isCompatible = isVersionCompatible(
[minMajor, minMinor, minPatch + 10000].join(',')
[minMajor, minMinor, minPatch + 10000].join('.')
)

expect(isCompatible).toBe(true)
expect(mockedWarnWithOptions).not.toBeCalled()
})

it('should be compatible but send a toast for a version with a higher minor but lower patch', () => {
it('should be compatible and not send a toast for a version with the same minor and higher patch as the latest tested version', () => {
mockedWarnWithOptions.mockResolvedValueOnce(undefined)

const isCompatible = isVersionCompatible('2.10.0')
const isCompatible = isVersionCompatible(
[latestTestedMajor, latestTestedMinor, latestTestedPatch + 10000].join(
'.'
)
)

expect(isCompatible).toBe(true)
expect(mockedWarnWithOptions).toBeCalledTimes(1)
expect(mockedWarnWithOptions).not.toBeCalled()
})

it('should be compatible and not send a toast for a major and minor version in between the min compatible and the latest tested', () => {
mockedWarnWithOptions.mockResolvedValueOnce(undefined)
expect(minMinor + 1).toBeLessThan(latestTestedMinor)
expect(minMajor).toStrictEqual(latestTestedMajor)

const isCompatible = isVersionCompatible(
[minMajor, minMinor + 1, 0].join('.')
)

expect(isCompatible).toBe(true)
expect(mockedWarnWithOptions).not.toBeCalled()
})

it('should be compatible and send a toast for a version with a minor higher as the latest tested minor and any patch', () => {
mockedWarnWithOptions.mockResolvedValueOnce(undefined)
expect(0).toBeLessThan(latestTestedPatch)

let isCompatible = isVersionCompatible(
[latestTestedMajor, latestTestedMinor + 1, 0].join('.')
)
expect(isCompatible).toBe(true)

isCompatible = isVersionCompatible(
[latestTestedMajor, latestTestedMinor + 1, latestTestedPatch + 1000].join(
'.'
)
)
expect(isCompatible).toBe(true)

isCompatible = isVersionCompatible(
[latestTestedMajor, latestTestedMinor + 1, latestTestedPatch].join('.')
)
expect(isCompatible).toBe(true)

expect(mockedWarnWithOptions).toBeCalledTimes(3)
})

it('should not be compatible and send a toast message if the provided version is a patch version before the minimum expected version', () => {
Expand Down Expand Up @@ -122,9 +170,12 @@ describe('isVersionCompatible', () => {
it('should not be compatible and send a toast message if the provided version is malformed', () => {
mockedWarnWithOptions.mockResolvedValueOnce(undefined)

const isCompatible = isVersionCompatible('not a valid version')
let isCompatible = isVersionCompatible('not a valid version')
expect(isCompatible).toBe(false)

isCompatible = isVersionCompatible('1,2,3')
expect(isCompatible).toBe(false)
expect(mockedWarnWithOptions).toBeCalledTimes(1)

expect(mockedWarnWithOptions).toBeCalledTimes(2)
})
})
29 changes: 20 additions & 9 deletions extension/src/cli/version.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { MAX_CLI_VERSION, MIN_CLI_VERSION } from './constants'
import {
MAX_CLI_VERSION,
LATEST_TESTED_CLI_VERSION,
MIN_CLI_VERSION
} from './constants'
import { Toast } from '../vscode/toast'

export type ParsedSemver = { major: number; minor: number; patch: number }
Expand All @@ -23,14 +27,16 @@ const getTextAndSend = (version: string, update: 'CLI' | 'extension'): void => {
Toast.warnWithOptions(text)
}

const warnIfMinorAhead = (
const warnIfAheadOfLatestTested = (
currentMajor: number,
minMajor: number,
currentMinor: number,
minMinor: number
currentMinor: number
) => {
if (currentMajor === minMajor && currentMinor > minMinor) {
Toast.warnWithOptions(`The located version of the CLI is at least a minor version ahead of the expected version.
const { major: latestTestedMajor, minor: latestTestedMinor } = extractSemver(
LATEST_TESTED_CLI_VERSION
) as ParsedSemver

if (currentMajor === latestTestedMajor && currentMinor > latestTestedMinor) {
Toast.warnWithOptions(`The located DVC CLI is at least a minor version ahead of the latest version the extension was tested with.
This could lead to unexpected behaviour.
Please upgrade to the most recent version of the extension and reload this window.`)
}
Expand Down Expand Up @@ -66,14 +72,19 @@ const checkCLIVersion = (
return false
}

warnIfMinorAhead(currentMajor, minMajor, currentMinor, minMinor)
warnIfAheadOfLatestTested(currentMajor, currentMinor)

return true
}

export const isVersionCompatible = (version: string): boolean => {
const currentSemVer = extractSemver(version)
if (!currentSemVer) {
if (
!currentSemVer ||
Number.isNaN(currentSemVer.major) ||
Number.isNaN(currentSemVer.minor) ||
Number.isNaN(currentSemVer.patch)
) {
Toast.warnWithOptions(
'The extension cannot initialize as we were unable to verify the DVC CLI version.'
)
Expand Down