Files
vscodium/patches/version-1-update.patch
2026-02-17 12:22:40 +01:00

279 lines
13 KiB
Diff

diff --git a/src/vs/platform/update/common/update.ts b/src/vs/platform/update/common/update.ts
index 8e3db7c..1a3226c 100644
--- a/src/vs/platform/update/common/update.ts
+++ b/src/vs/platform/update/common/update.ts
@@ -54,3 +54,4 @@ export const enum UpdateType {
Archive,
- Snap
+ Snap,
+ WindowsInstaller,
}
@@ -116 +117,38 @@ export interface IUpdateService {
}
+
+export type Architecture =
+ | "arm"
+ | "arm64"
+ | "ia32"
+ | "loong64"
+ | "mips"
+ | "mipsel"
+ | "ppc"
+ | "ppc64"
+ | "riscv64"
+ | "s390"
+ | "s390x"
+ | "x64";
+
+export type Platform =
+ | "aix"
+ | "android"
+ | "darwin"
+ | "freebsd"
+ | "haiku"
+ | "linux"
+ | "openbsd"
+ | "sunos"
+ | "win32"
+ | "cygwin"
+ | "netbsd";
+
+export type Quality =
+ | "insider"
+ | "stable";
+
+export type Target =
+ | "archive"
+ | "msi"
+ | "system"
+ | "user";
\ No newline at end of file
diff --git a/src/vs/platform/update/electron-main/abstractUpdateService.ts b/src/vs/platform/update/electron-main/abstractUpdateService.ts
index 05c4489..59d0bd7 100644
--- a/src/vs/platform/update/electron-main/abstractUpdateService.ts
+++ b/src/vs/platform/update/electron-main/abstractUpdateService.ts
@@ -17,3 +17,3 @@ import { IProductService } from '../../product/common/productService.js';
import { IRequestService } from '../../request/common/request.js';
-import { AvailableForDownload, DisablementReason, IUpdateService, State, StateType, UpdateType } from '../common/update.js';
+import { Architecture, AvailableForDownload, DisablementReason, IUpdateService, Platform, State, StateType, Target, UpdateType } from '../common/update.js';
@@ -23,10 +23,8 @@ export interface IUpdateURLOptions {
-export function createUpdateURL(baseUpdateUrl: string, platform: string, quality: string, commit: string, options?: IUpdateURLOptions): string {
- const url = new URL(`${baseUpdateUrl}/api/update/${platform}/${quality}/${commit}`);
-
- if (options?.background) {
- url.searchParams.set('bg', 'true');
+export function createUpdateURL(productService: IProductService, quality: string, platform: Platform, architecture: Architecture, target?: Target): string {
+ if (target) {
+ return `${productService.updateUrl}/${quality}/${platform}/${architecture}/${target}/latest.json`;
+ } else {
+ return `${productService.updateUrl}/${quality}/${platform}/${architecture}/latest.json`;
}
-
- return url.toString();
}
@@ -299,3 +297,3 @@ export abstract class AbstractUpdateService implements IUpdateService {
- if (mode === 'none') {
+ if (mode === 'none' || mode === 'manual') {
return undefined;
diff --git a/src/vs/platform/update/electron-main/updateService.darwin.ts b/src/vs/platform/update/electron-main/updateService.darwin.ts
index e65a982..950291b 100644
--- a/src/vs/platform/update/electron-main/updateService.darwin.ts
+++ b/src/vs/platform/update/electron-main/updateService.darwin.ts
@@ -21,2 +21,3 @@ import { IMeteredConnectionService } from '../../meteredConnection/common/metere
import { AbstractUpdateService, createUpdateURL, getUpdateRequestHeaders, IUpdateURLOptions, UpdateErrorClassification } from './abstractUpdateService.js';
+import * as semver from 'semver';
@@ -90,16 +91,5 @@ export class DarwinUpdateService extends AbstractUpdateService implements IRelau
- protected buildUpdateFeedUrl(quality: string, commit: string, options?: IUpdateURLOptions): string | undefined {
- const assetID = this.productService.darwinUniversalAssetId ?? (process.arch === 'x64' ? 'darwin' : 'darwin-arm64');
- const url = createUpdateURL(this.productService.updateUrl!, assetID, quality, commit, options);
- const headers = getUpdateRequestHeaders(this.productService.version);
- try {
- this.logService.trace('update#buildUpdateFeedUrl - setting feed URL for Electron autoUpdater', { url, assetID, quality, commit, headers });
- electron.autoUpdater.setFeedURL({ url, headers });
- } catch (e) {
- // application is very likely not signed
- this.logService.error('Failed to set update feed URL', e);
- return undefined;
- }
- return url;
- }
+ protected buildUpdateFeedUrl(quality: string, _commit: string, _options?: IUpdateURLOptions): string | undefined {
+ return createUpdateURL(this.productService, quality, process.platform, process.arch);
+ }
@@ -137,3 +127,30 @@ export class DarwinUpdateService extends AbstractUpdateService implements IRelau
this.logService.trace('update#doCheckForUpdates - using Electron autoUpdater', { url, explicit, background });
- electron.autoUpdater.checkForUpdates();
+ this.requestService.request({ url }, CancellationToken.None)
+ .then<IUpdate | null>(asJson)
+ .then(update => {
+ if (!update || !update.url || !update.version || !update.productVersion) {
+ this.setState(State.Idle(UpdateType.Setup));
+
+ return Promise.resolve(null);
+ }
+
+ const fetchedVersion = /\d+\.\d+\.\d+\.\d+/.test(update.productVersion) ? update.productVersion.replace(/(\d+\.\d+\.\d+)\.\d+(\-\w+)?/, '$1$2') : update.productVersion.replace(/(\d+\.\d+\.)0+(\d+)(\-\w+)?/, '$1$2$3')
+ const currentVersion = this.productService.version.replace(/(\d+\.\d+\.)0+(\d+)(\-\w+)?/, '$1$2$3')
+
+ if(semver.compareBuild(currentVersion, fetchedVersion) >= 0) {
+ this.setState(State.Idle(UpdateType.Setup));
+ }
+ else {
+ electron.autoUpdater.setFeedURL({ url });
+ electron.autoUpdater.checkForUpdates();
+ }
+
+ return Promise.resolve(null);
+ })
+ .then(undefined, err => {
+ this.logService.error(err);
+ // only show message when explicitly checking for updates
+ const message: string | undefined = explicit ? (err.message || err) : undefined;
+ this.setState(State.Idle(UpdateType.Setup, message));
+ });
}
diff --git a/src/vs/platform/update/electron-main/updateService.linux.ts b/src/vs/platform/update/electron-main/updateService.linux.ts
index ee4b291..01d0d9d 100644
--- a/src/vs/platform/update/electron-main/updateService.linux.ts
+++ b/src/vs/platform/update/electron-main/updateService.linux.ts
@@ -16,2 +16,3 @@ import { AvailableForDownload, IUpdate, State, UpdateType } from '../common/upda
import { AbstractUpdateService, createUpdateURL, IUpdateURLOptions } from './abstractUpdateService.js';
+import * as semver from 'semver';
@@ -32,4 +33,4 @@ export class LinuxUpdateService extends AbstractUpdateService {
- protected buildUpdateFeedUrl(quality: string, commit: string, options?: IUpdateURLOptions): string {
- return createUpdateURL(this.productService.updateUrl!, `linux-${process.arch}`, quality, commit, options);
+ protected buildUpdateFeedUrl(quality: string, _commit: string, _options?: IUpdateURLOptions): string {
+ return createUpdateURL(this.productService, quality, process.platform, process.arch);
}
@@ -50,5 +51,17 @@ export class LinuxUpdateService extends AbstractUpdateService {
this.setState(State.Idle(UpdateType.Archive));
- } else {
+
+ return Promise.resolve(null);
+ }
+
+ const fetchedVersion = /\d+\.\d+\.\d+\.\d+/.test(update.productVersion) ? update.productVersion.replace(/(\d+\.\d+\.\d+)\.\d+(\-\w+)?/, '$1$2') : update.productVersion.replace(/(\d+\.\d+\.)0+(\d+)(\-\w+)?/, '$1$2$3')
+ const currentVersion = this.productService.version.replace(/(\d+\.\d+\.)0+(\d+)(\-\w+)?/, '$1$2$3')
+
+ if(semver.compareBuild(currentVersion, fetchedVersion) >= 0) {
+ this.setState(State.Idle(UpdateType.Archive));
+ }
+ else {
this.setState(State.AvailableForDownload(update));
}
+
+ return Promise.resolve(null);
})
diff --git a/src/vs/platform/update/electron-main/updateService.win32.ts b/src/vs/platform/update/electron-main/updateService.win32.ts
index da4c875..fa634dc 100644
--- a/src/vs/platform/update/electron-main/updateService.win32.ts
+++ b/src/vs/platform/update/electron-main/updateService.win32.ts
@@ -14,3 +14,2 @@ import { CancellationToken, CancellationTokenSource } from '../../../base/common
import { memoize } from '../../../base/common/decorators.js';
-import { hash } from '../../../base/common/hash.js';
import * as path from '../../../base/common/path.js';
@@ -31,4 +30,5 @@ import { asJson, IRequestService } from '../../request/common/request.js';
import { ITelemetryService } from '../../telemetry/common/telemetry.js';
-import { AvailableForDownload, DisablementReason, IUpdate, State, StateType, UpdateType } from '../common/update.js';
-import { AbstractUpdateService, createUpdateURL, IUpdateURLOptions, UpdateErrorClassification } from './abstractUpdateService.js';
+import { AvailableForDownload, DisablementReason, IUpdate, State, StateType, Target, UpdateType } from '../common/update.js';
+import { AbstractUpdateService, createUpdateURL, IUpdateURLOptions } from './abstractUpdateService.js';
+import * as semver from 'semver';
@@ -46,5 +46,9 @@ function getUpdateType(): UpdateType {
if (typeof _updateType === 'undefined') {
- _updateType = existsSync(path.join(path.dirname(process.execPath), 'unins000.exe'))
- ? UpdateType.Setup
- : UpdateType.Archive;
+ if (existsSync(path.join(path.dirname(process.execPath), 'unins000.exe'))) {
+ _updateType = UpdateType.Setup;
+ } else if (path.basename(path.normalize(path.join(process.execPath, '..', '..'))) === 'Program Files') {
+ _updateType = UpdateType.WindowsInstaller;
+ } else {
+ _updateType = UpdateType.Archive;
+ }
}
@@ -68,2 +72,3 @@ export class Win32UpdateService extends AbstractUpdateService implements IRelaun
@IConfigurationService configurationService: IConfigurationService,
+ // @ts-expect-error
@ITelemetryService private readonly telemetryService: ITelemetryService,
@@ -140,3 +145,3 @@ export class Win32UpdateService extends AbstractUpdateService implements IRelaun
} else {
- const fastUpdatesEnabled = this.configurationService.getValue('update.enableWindowsBackgroundUpdates');
+ const fastUpdatesEnabled = getUpdateType() === UpdateType.Setup && this.configurationService.getValue('update.enableWindowsBackgroundUpdates');
// GC for background updates in system setup happens via inno_setup since it requires
@@ -158,12 +163,22 @@ export class Win32UpdateService extends AbstractUpdateService implements IRelaun
- protected buildUpdateFeedUrl(quality: string, commit: string, options?: IUpdateURLOptions): string | undefined {
- let platform = `win32-${process.arch}`;
-
- if (getUpdateType() === UpdateType.Archive) {
- platform += '-archive';
- } else if (this.productService.target === 'user') {
- platform += '-user';
- }
+ protected buildUpdateFeedUrl(quality: string, _commit: string, _options?: IUpdateURLOptions): string | undefined {
+ let target: Target;
+
+ switch (getUpdateType()) {
+ case UpdateType.Archive:
+ target = "archive"
+ break;
+ case UpdateType.WindowsInstaller:
+ target = "msi"
+ break;
+ default:
+ if (this.productService.target === 'user') {
+ target = "user"
+ }
+ else {
+ target = "system"
+ }
+ }
- return createUpdateURL(this.productService.updateUrl!, platform, quality, commit, options);
+ return createUpdateURL(this.productService, quality, process.platform, process.arch, target);
}
@@ -200,2 +215,10 @@ export class Win32UpdateService extends AbstractUpdateService implements IRelaun
+ const fetchedVersion = /\d+\.\d+\.\d+\.\d+/.test(update.productVersion) ? update.productVersion.replace(/(\d+\.\d+\.\d+)\.\d+(\-\w+)?/, '$1$2') : update.productVersion.replace(/(\d+\.\d+\.)0+(\d+)(\-\w+)?/, '$1$2$3')
+ const currentVersion = this.productService.version.replace(/(\d+\.\d+\.)0+(\d+)(\-\w+)?/, '$1$2$3')
+
+ if(semver.compareBuild(currentVersion, fetchedVersion) >= 0) {
+ this.setState(State.Idle(updateType));
+ return Promise.resolve(null);
+ }
+
if (updateType === UpdateType.Archive) {
@@ -271,3 +294,2 @@ export class Win32UpdateService extends AbstractUpdateService implements IRelaun
.then(undefined, err => {
- this.telemetryService.publicLog2<{ messageHash: string }, UpdateErrorClassification>('update:error', { messageHash: String(hash(String(err))) });
this.logService.error(err);
@@ -494,6 +516,14 @@ export class Win32UpdateService extends AbstractUpdateService implements IRelaun
} else {
- spawn(this.availableUpdate.packagePath, ['/silent', '/log', '/mergetasks=runcode,!desktopicon,!quicklaunchicon'], {
- detached: true,
- stdio: ['ignore', 'ignore', 'ignore']
- });
+ const type = getUpdateType();
+ if (type == UpdateType.WindowsInstaller) {
+ spawn('msiexec.exe', ['/i', this.availableUpdate.packagePath], {
+ detached: true,
+ stdio: ['ignore', 'ignore', 'ignore']
+ });
+ } else {
+ spawn(this.availableUpdate.packagePath, ['/silent', '/log', '/mergetasks=runcode,!desktopicon,!quicklaunchicon'], {
+ detached: true,
+ stdio: ['ignore', 'ignore', 'ignore']
+ });
+ }
}