Add core version check (#2891)

This commit is contained in:
the1812 2022-01-16 01:05:47 +08:00
parent de2fe7999c
commit 66ec569226
9 changed files with 55 additions and 15 deletions

View File

@ -6,6 +6,7 @@ import {
isUserComponent, isUserComponent,
} from '@/core/settings' } from '@/core/settings'
import { descendingSort } from '@/core/utils/sort' import { descendingSort } from '@/core/utils/sort'
import { isFeatureAcceptable } from '@/core/version'
import { LaunchBarActionProvider } from '../launch-bar/launch-bar-action' import { LaunchBarActionProvider } from '../launch-bar/launch-bar-action'
import { ComponentAction } from '../settings-panel/component-actions/component-actions' import { ComponentAction } from '../settings-panel/component-actions/component-actions'
@ -81,6 +82,9 @@ const checkUpdate = async (config: CheckUpdateConfig) => {
if (!code) { if (!code) {
return `[${itemName}] 更新下载失败, 取消更新` return `[${itemName}] 更新下载失败, 取消更新`
} }
if (!isFeatureAcceptable(code)) {
return `[${itemName}] 版本不匹配, 取消更新`
}
const { installFeatureFromCode } = await import('@/core/install-feature') const { installFeatureFromCode } = await import('@/core/install-feature')
const { message } = await installFeatureFromCode(code, url) const { message } = await installFeatureFromCode(code, url)
item.lastUpdateCheck = Number(new Date()) item.lastUpdateCheck = Number(new Date())

View File

@ -15,6 +15,17 @@ export type Author = {
name: string name: string
link: string link: string
} }
export interface FeatureBase {
// TODO: 可在编译时转换 Markdown 以提高运行时性能
/** 描述 (支持 markdown), 可以设置为对象提供多语言的描述 (`key: 语言代码`) */
description?: I18nDescription
/** 作者信息 */
author?: Author | Author[]
/** 编译时的 commit hash, 由 Babel 注入, 不需要手动填写 */
commitHash?: string
/** 编译时的 core version, 由 Babel 注入, 不需要手动填写 */
coreVersion?: string
}
type Optional<Target, Props extends keyof Target> = { type Optional<Target, Props extends keyof Target> = {
[P in Props]?: Target[P] [P in Props]?: Target[P]
} & Omit<Target, Props> } & Omit<Target, Props>
@ -168,7 +179,7 @@ export interface FunctionalMetadata {
urlExclude?: TestPattern urlExclude?: TestPattern
} }
/** 组件基本信息 */ /** 组件基本信息 */
export interface ComponentMetadata extends FunctionalMetadata { export interface ComponentMetadata extends FunctionalMetadata, FeatureBase {
/** 组件名称 */ /** 组件名称 */
name: string name: string
/** 显示名称 */ /** 显示名称 */
@ -181,16 +192,10 @@ export interface ComponentMetadata extends FunctionalMetadata {
configurable?: boolean configurable?: boolean
/** 是否在设置界面中隐藏 (代码仍可操作) */ /** 是否在设置界面中隐藏 (代码仍可操作) */
hidden?: boolean hidden?: boolean
/** 组件描述 (markdown), 可以设置为对象提供多语言的描述 (`key: 语言代码`) */
description?: I18nDescription
/** 组件子选项 */ /** 组件子选项 */
options?: ComponentOptions options?: ComponentOptions
/** i18n 数据 */ /** i18n 数据 */
i18n?: Record<string, LanguagePack> i18n?: Record<string, LanguagePack>
/** 作者信息 */
author?: Author | Author[]
/** 编译时的 commit hash, 由 Babel 注入, 不需要手动填写 */
commitHash?: string
} }
/** 用户组件的非函数基本信息, 用于直接保存为 JSON */ /** 用户组件的非函数基本信息, 用于直接保存为 JSON */
export type UserComponentMetadata = Omit<ComponentMetadata, keyof FunctionalMetadata> export type UserComponentMetadata = Omit<ComponentMetadata, keyof FunctionalMetadata>

View File

@ -1,3 +1,7 @@
import { FeatureBase } from '@/components/types'
import { parseExternalInput } from './external-input'
import { meta } from './meta'
export enum CompareResult { export enum CompareResult {
Less = -1, Less = -1,
Equal = 0, Equal = 0,
@ -40,3 +44,31 @@ export class Version {
return this.compareTo(other) === CompareResult.Equal return this.compareTo(other) === CompareResult.Equal
} }
} }
/**
*
* @param feature Metadata
*/
export const isFeatureAcceptable = async (feature: FeatureBase | string) => {
try {
if (typeof feature === 'string') {
feature = await parseExternalInput<FeatureBase>(feature)
}
// 无效代码
if (feature === null || feature === undefined) {
return false
}
const { version: currentVersionText } = meta.compilationInfo
const { coreVersion: requiredVersionText } = feature
// 没有版本信息, 按旧版行为默认通过检测
if (!requiredVersionText || !currentVersionText) {
return true
}
const currentVersion = new Version(currentVersionText)
const requiredVersion = new Version(requiredVersionText)
return currentVersion.equals(requiredVersion) || currentVersion.greaterThan(requiredVersion)
} catch (error) {
console.warn('[isFeatureAcceptable] check failed, feature =', feature)
// 版本号异常, 跳过检测
return true
}
}

1
src/global.d.ts vendored
View File

@ -11,6 +11,7 @@ declare global {
interface CompilationInfo { interface CompilationInfo {
commitHash: string commitHash: string
branch: string branch: string
version: string
nearestTag: string nearestTag: string
versionWithTag: string versionWithTag: string
// buildTime: number // buildTime: number

View File

@ -1,5 +1,4 @@
import { ComponentMetadata, Author } from '@/components/component' import { ComponentMetadata, FeatureBase } from '@/components/component'
import { I18nDescription } from '@/core/common-types'
import { deleteValue } from '@/core/utils' import { deleteValue } from '@/core/utils'
import { CoreApis } from '../core/core-apis' import { CoreApis } from '../core/core-apis'
import { addData, registerData, registerAndGetData } from './data' import { addData, registerData, registerAndGetData } from './data'
@ -16,17 +15,13 @@ export interface PluginSetupParameters {
} }
/** 插件基本信息 */ /** 插件基本信息 */
export interface PluginMinimalData { export interface PluginMinimalData extends FeatureBase {
/** 初始化函数, 可在其中注册数据, 添加代码注入等 */ /** 初始化函数, 可在其中注册数据, 添加代码注入等 */
setup: (params: PluginSetupParameters) => void | Promise<void> setup: (params: PluginSetupParameters) => void | Promise<void>
/** 插件名称 */ /** 插件名称 */
name: string name: string
/** 显示名称, 默认同插件名称 */ /** 显示名称, 默认同插件名称 */
displayName?: string displayName?: string
/** 插件描述, 类型同 `ComponentMetadata.description` */
description?: I18nDescription
/** 作者信息, 类型同 `ComponentMetadata.author` */
author?: Author | Author[]
} }
type PartialRequired<Target, Props extends keyof Target> = Target & { type PartialRequired<Target, Props extends keyof Target> = Target & {
[P in Props]-?: Target[P] [P in Props]-?: Target[P]

View File

@ -1,4 +1,5 @@
const process = require('child_process') const process = require('child_process')
const commonMeta = require('../src/client/common.meta.json')
const commitHash = process const commitHash = process
.execSync('git rev-parse HEAD') .execSync('git rev-parse HEAD')
@ -19,6 +20,7 @@ const versionWithTag = process
const compilationInfo = { const compilationInfo = {
commitHash, commitHash,
branch, branch,
version: commonMeta.version,
nearestTag, nearestTag,
versionWithTag, versionWithTag,
// buildTime: Number(new Date()), // buildTime: Number(new Date()),

View File

@ -21,6 +21,7 @@ module.exports = function (babel) {
return return
} }
d.init.properties.push(types.objectProperty(types.identifier('commitHash'), types.stringLiteral(compilationInfo.commitHash))) d.init.properties.push(types.objectProperty(types.identifier('commitHash'), types.stringLiteral(compilationInfo.commitHash)))
d.init.properties.push(types.objectProperty(types.identifier('coreVersion'), types.stringLiteral(compilationInfo.version)))
}) })
} }
} }

View File

@ -14,7 +14,7 @@ const babelLoader = {
], ],
plugins: [ plugins: [
['@babel/plugin-proposal-class-properties'], ['@babel/plugin-proposal-class-properties'],
'./webpack/commit-hash.js', './webpack/inject-metadata.js',
], ],
}, },
} }