Merge from vscode a348d103d1256a06a2c9b3f9b406298a9fef6898 (#15681)

* Merge from vscode a348d103d1256a06a2c9b3f9b406298a9fef6898

* Fixes and cleanup

* Distro

* Fix hygiene yarn

* delete no yarn lock changes file

* Fix hygiene

* Fix layer check

* Fix CI

* Skip lib checks

* Remove tests deleted in vs code

* Fix tests

* Distro

* Fix tests and add removed extension point

* Skip failing notebook tests for now

* Disable broken tests and cleanup build folder

* Update yarn.lock and fix smoke tests

* Bump sqlite

* fix contributed actions and file spacing

* Fix user data path

* Update yarn.locks

Co-authored-by: ADS Merger <karlb@microsoft.com>
This commit is contained in:
Charles Gagnon
2021-06-17 08:17:11 -07:00
committed by GitHub
parent fdcb97c7f7
commit 3cb2f552a6
2582 changed files with 124827 additions and 87099 deletions

View File

@@ -6,7 +6,7 @@
import { open, close, read, write, fdatasync, Stats, promises } from 'fs';
import { promisify } from 'util';
import { IDisposable, Disposable, toDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle';
import { FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileOpenOptions, FileSystemProviderErrorCode, createFileSystemProviderError, FileSystemProviderError, IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithFileReadStreamCapability, IFileSystemProviderWithOpenReadWriteCloseCapability, FileReadStreamOptions, IFileSystemProviderWithFileFolderCopyCapability } from 'vs/platform/files/common/files';
import { FileSystemProviderCapabilities, IFileChange, IWatchOptions, IStat, FileType, FileDeleteOptions, FileOverwriteOptions, FileWriteOptions, FileOpenOptions, FileSystemProviderErrorCode, createFileSystemProviderError, FileSystemProviderError, IFileSystemProviderWithFileReadWriteCapability, IFileSystemProviderWithFileReadStreamCapability, IFileSystemProviderWithOpenReadWriteCloseCapability, FileReadStreamOptions, IFileSystemProviderWithFileFolderCopyCapability, isFileOpenForWriteOptions } from 'vs/platform/files/common/files';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { isLinux, isWindows } from 'vs/base/common/platform';
@@ -30,7 +30,7 @@ import { VSBuffer } from 'vs/base/common/buffer';
export interface IWatcherOptions {
pollingInterval?: number;
usePolling: boolean;
usePolling: boolean | string[];
}
export interface IDiskFileSystemProviderOptions {
@@ -64,7 +64,8 @@ export class DiskFileSystemProvider extends Disposable implements
FileSystemProviderCapabilities.FileReadWrite |
FileSystemProviderCapabilities.FileOpenReadWriteClose |
FileSystemProviderCapabilities.FileReadStream |
FileSystemProviderCapabilities.FileFolderCopy;
FileSystemProviderCapabilities.FileFolderCopy |
FileSystemProviderCapabilities.FileWriteUnlock;
if (isLinux) {
this._capabilities |= FileSystemProviderCapabilities.PathCaseSensitive;
@@ -188,12 +189,12 @@ export class DiskFileSystemProvider extends Disposable implements
}
// Open
handle = await this.open(resource, { create: true });
handle = await this.open(resource, { create: true, unlock: opts.unlock });
// Write content at once
await this.write(handle, 0, content, 0, content.byteLength);
} catch (error) {
throw this.toFileSystemProviderError(error);
throw await this.toFileSystemProviderWriteError(resource, error);
} finally {
if (typeof handle === 'number') {
await this.close(handle);
@@ -203,15 +204,28 @@ export class DiskFileSystemProvider extends Disposable implements
private readonly mapHandleToPos: Map<number, number> = new Map();
private readonly writeHandles: Set<number> = new Set();
private readonly writeHandles = new Map<number, URI>();
private canFlush: boolean = true;
async open(resource: URI, opts: FileOpenOptions): Promise<number> {
try {
const filePath = this.toFilePath(resource);
// Determine wether to unlock the file (write only)
if (isFileOpenForWriteOptions(opts) && opts.unlock) {
try {
const { stat } = await SymlinkSupport.stat(filePath);
if (!(stat.mode & 0o200 /* File mode indicating writable by owner */)) {
await promises.chmod(filePath, stat.mode | 0o200);
}
} catch (error) {
this.logService.trace(error); // ignore any errors here and try to just write
}
}
// Determine file flags for opening (read vs write)
let flags: string | undefined = undefined;
if (opts.create) {
if (isFileOpenForWriteOptions(opts)) {
if (isWindows) {
try {
// On Windows and if the file exists, we use a different strategy of saving the file
@@ -252,13 +266,17 @@ export class DiskFileSystemProvider extends Disposable implements
this.mapHandleToPos.set(handle, 0);
// remember that this handle was used for writing
if (opts.create) {
this.writeHandles.add(handle);
if (isFileOpenForWriteOptions(opts)) {
this.writeHandles.set(handle, resource);
}
return handle;
} catch (error) {
throw this.toFileSystemProviderError(error);
if (isFileOpenForWriteOptions(opts)) {
throw await this.toFileSystemProviderWriteError(resource, error);
} else {
throw this.toFileSystemProviderError(error);
}
}
}
@@ -388,7 +406,7 @@ export class DiskFileSystemProvider extends Disposable implements
return bytesWritten;
} catch (error) {
throw this.toFileSystemProviderError(error);
throw await this.toFileSystemProviderWriteError(this.writeHandles.get(fd), error);
} finally {
this.updatePos(fd, normalizedPos, bytesWritten);
}
@@ -690,9 +708,29 @@ export class DiskFileSystemProvider extends Disposable implements
return createFileSystemProviderError(error, code);
}
private async toFileSystemProviderWriteError(resource: URI | undefined, error: NodeJS.ErrnoException): Promise<FileSystemProviderError> {
let fileSystemProviderWriteError = this.toFileSystemProviderError(error);
// If the write error signals permission issues, we try
// to read the file's mode to see if the file is write
// locked.
if (resource && fileSystemProviderWriteError.code === FileSystemProviderErrorCode.NoPermissions) {
try {
const { stat } = await SymlinkSupport.stat(this.toFilePath(resource));
if (!(stat.mode & 0o200 /* File mode indicating writable by owner */)) {
fileSystemProviderWriteError = createFileSystemProviderError(error, FileSystemProviderErrorCode.FileWriteLocked);
}
} catch (error) {
this.logService.trace(error); // ignore - return original error
}
}
return fileSystemProviderWriteError;
}
//#endregion
dispose(): void {
override dispose(): void {
super.dispose();
dispose(this.recursiveWatcher);

View File

@@ -124,7 +124,7 @@ export class FileWatcher extends Disposable {
}
}
dispose(): void {
override dispose(): void {
this.isDisposed = true;
super.dispose();

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nsfw from 'vscode-nsfw';
import * as nsfw from 'nsfw';
import * as glob from 'vs/base/common/glob';
import { join } from 'vs/base/common/path';
import { isMacintosh } from 'vs/base/common/platform';
@@ -61,9 +61,7 @@ export class NsfwWatcherService extends Disposable implements IWatcherService {
});
// Logging
if (this.verboseLogging) {
this.log(`Start watching: [${rootsToStartWatching.map(r => r.path).join(',')}]\nStop watching: [${rootsToStopWatching.join(',')}]`);
}
this.debug(`Start watching: [${rootsToStartWatching.map(r => r.path).join(',')}]\nStop watching: [${rootsToStopWatching.join(',')}]`);
// Stop watching some roots
rootsToStopWatching.forEach(root => {
@@ -133,9 +131,7 @@ export class NsfwWatcherService extends Disposable implements IWatcherService {
}
}
if (this.verboseLogging) {
this.log(`Start watching with nsfw: ${request.path}`);
}
this.debug(`Start watching with nsfw: ${request.path}`);
nsfw(request.path, events => {
for (const e of events) {
@@ -249,4 +245,8 @@ export class NsfwWatcherService extends Disposable implements IWatcherService {
private error(message: string) {
this._onDidLogMessage.fire({ type: 'error', message: `[File Watcher (nsfw)] ` + message });
}
private debug(message: string) {
this._onDidLogMessage.fire({ type: 'debug', message: `[File Watcher (nsfw)] ` + message });
}
}

View File

@@ -10,7 +10,7 @@ import { IWatcherRequest } from 'vs/platform/files/node/watcher/nsfw/watcher';
suite('NSFW Watcher Service', async () => {
// Load `nsfwWatcherService` within the suite to prevent all tests
// from failing to start if `vscode-nsfw` was not properly installed
// from failing to start if `nsfw` was not properly installed
const { NsfwWatcherService } = await import('vs/platform/files/node/watcher/nsfw/nsfwWatcherService');
class TestNsfwWatcherService extends NsfwWatcherService {

View File

@@ -5,8 +5,8 @@
import { Server } from 'vs/base/parts/ipc/node/ipc.cp';
import { NsfwWatcherService } from 'vs/platform/files/node/watcher/nsfw/nsfwWatcherService';
import { createChannelReceiver } from 'vs/base/parts/ipc/common/ipc';
import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc';
const server = new Server('watcher');
const service = new NsfwWatcherService();
server.registerChannel('watcher', createChannelReceiver(service));
server.registerChannel('watcher', ProxyChannel.fromService(service));

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { createChannelSender, getNextTickChannel } from 'vs/base/parts/ipc/common/ipc';
import { ProxyChannel, getNextTickChannel } from 'vs/base/parts/ipc/common/ipc';
import { Client } from 'vs/base/parts/ipc/node/ipc.cp';
import { IDiskFileChange, ILogMessage } from 'vs/platform/files/node/watcher/watcher';
import { Disposable } from 'vs/base/common/lifecycle';
@@ -61,7 +61,7 @@ export class FileWatcher extends Disposable {
}));
// Initialize watcher
this.service = createChannelSender<IWatcherService>(getNextTickChannel(client.getChannel('watcher')));
this.service = ProxyChannel.toService<IWatcherService>(getNextTickChannel(client.getChannel('watcher')));
this.service.setVerboseLogging(this.verboseLogging);
@@ -91,7 +91,7 @@ export class FileWatcher extends Disposable {
}
}
dispose(): void {
override dispose(): void {
this.isDisposed = true;
super.dispose();

View File

@@ -49,7 +49,7 @@ export class ChokidarWatcherService extends Disposable implements IWatcherServic
get wacherCount() { return this._watcherCount; }
private pollingInterval?: number;
private usePolling?: boolean;
private usePolling?: boolean | string[];
private verboseLogging: boolean | undefined;
private spamCheckStartTime: number | undefined;
@@ -101,7 +101,11 @@ export class ChokidarWatcherService extends Disposable implements IWatcherServic
private watch(basePath: string, requests: IWatcherRequest[]): IWatcher {
const pollingInterval = this.pollingInterval || 5000;
const usePolling = this.usePolling;
let usePolling = this.usePolling; // boolean or a list of path patterns
if (Array.isArray(usePolling)) {
// switch to polling if one of the paths matches with a watched path
usePolling = usePolling.some(pattern => requests.some(r => glob.match(pattern, r.path)));
}
const watcherOpts: chokidar.WatchOptions = {
ignoreInitial: true,
@@ -142,9 +146,7 @@ export class ChokidarWatcherService extends Disposable implements IWatcherServic
this.warn(`Watcher basePath does not match version on disk and was corrected (original: ${basePath}, real: ${realBasePath})`);
}
if (this.verboseLogging) {
this.log(`Start watching with chokidar: ${realBasePath}, excludes: ${excludes.join(',')}, usePolling: ${usePolling ? 'true, interval ' + pollingInterval : 'false'}`);
}
this.debug(`Start watching with chokidar: ${realBasePath}, excludes: ${excludes.join(',')}, usePolling: ${usePolling ? 'true, interval ' + pollingInterval : 'false'}`);
let chokidarWatcher: chokidar.FSWatcher | null = chokidar.watch(realBasePath, watcherOpts);
this._watcherCount++;
@@ -297,6 +299,10 @@ export class ChokidarWatcherService extends Disposable implements IWatcherServic
this._onDidLogMessage.fire({ type: 'trace', message: `[File Watcher (chokidar)] ` + message });
}
private debug(message: string) {
this._onDidLogMessage.fire({ type: 'debug', message: `[File Watcher (chokidar)] ` + message });
}
private warn(message: string) {
this._onDidLogMessage.fire({ type: 'warn', message: `[File Watcher (chokidar)] ` + message });
}

View File

@@ -13,7 +13,7 @@ export interface IWatcherRequest {
export interface IWatcherOptions {
pollingInterval?: number;
usePolling?: boolean;
usePolling?: boolean | string[]; // boolean or a set of glob patterns matching folders that need polling
verboseLogging?: boolean;
}

View File

@@ -5,8 +5,8 @@
import { Server } from 'vs/base/parts/ipc/node/ipc.cp';
import { ChokidarWatcherService } from 'vs/platform/files/node/watcher/unix/chokidarWatcherService';
import { createChannelReceiver } from 'vs/base/parts/ipc/common/ipc';
import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc';
const server = new Server('watcher');
const service = new ChokidarWatcherService();
server.registerChannel('watcher', createChannelReceiver(service));
server.registerChannel('watcher', ProxyChannel.fromService(service));

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { createChannelSender, getNextTickChannel } from 'vs/base/parts/ipc/common/ipc';
import { ProxyChannel, getNextTickChannel } from 'vs/base/parts/ipc/common/ipc';
import { Client } from 'vs/base/parts/ipc/node/ipc.cp';
import { IDiskFileChange, ILogMessage } from 'vs/platform/files/node/watcher/watcher';
import { Disposable } from 'vs/base/common/lifecycle';
@@ -62,7 +62,7 @@ export class FileWatcher extends Disposable {
}));
// Initialize watcher
this.service = createChannelSender<IWatcherService>(getNextTickChannel(client.getChannel('watcher')));
this.service = ProxyChannel.toService<IWatcherService>(getNextTickChannel(client.getChannel('watcher')));
this.service.init({ ...this.watcherOptions, verboseLogging: this.verboseLogging });
this._register(this.service.onDidChangeFile(e => !this.isDisposed && this.onDidFilesChange(e)));
@@ -92,7 +92,7 @@ export class FileWatcher extends Disposable {
}
}
dispose(): void {
override dispose(): void {
this.isDisposed = true;
super.dispose();

View File

@@ -13,7 +13,7 @@ export interface IDiskFileChange {
}
export interface ILogMessage {
type: 'trace' | 'warn' | 'error';
type: 'trace' | 'warn' | 'error' | 'info' | 'debug';
message: string;
}