mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-27 01:25:36 -05:00
* 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>
110 lines
3.4 KiB
TypeScript
110 lines
3.4 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import { URI as uri } from 'vs/base/common/uri';
|
|
import { FileChangeType, isParent, IFileChange } from 'vs/platform/files/common/files';
|
|
import { isLinux } from 'vs/base/common/platform';
|
|
|
|
export interface IDiskFileChange {
|
|
type: FileChangeType;
|
|
path: string;
|
|
}
|
|
|
|
export interface ILogMessage {
|
|
type: 'trace' | 'warn' | 'error' | 'info' | 'debug';
|
|
message: string;
|
|
}
|
|
|
|
export function toFileChanges(changes: IDiskFileChange[]): IFileChange[] {
|
|
return changes.map(change => ({
|
|
type: change.type,
|
|
resource: uri.file(change.path)
|
|
}));
|
|
}
|
|
|
|
export function normalizeFileChanges(changes: IDiskFileChange[]): IDiskFileChange[] {
|
|
|
|
// Build deltas
|
|
const normalizer = new EventNormalizer();
|
|
for (const event of changes) {
|
|
normalizer.processEvent(event);
|
|
}
|
|
|
|
return normalizer.normalize();
|
|
}
|
|
|
|
class EventNormalizer {
|
|
private normalized: IDiskFileChange[] = [];
|
|
private mapPathToChange: Map<string, IDiskFileChange> = new Map();
|
|
|
|
processEvent(event: IDiskFileChange): void {
|
|
const existingEvent = this.mapPathToChange.get(event.path);
|
|
|
|
// Event path already exists
|
|
if (existingEvent) {
|
|
const currentChangeType = existingEvent.type;
|
|
const newChangeType = event.type;
|
|
|
|
// ignore CREATE followed by DELETE in one go
|
|
if (currentChangeType === FileChangeType.ADDED && newChangeType === FileChangeType.DELETED) {
|
|
this.mapPathToChange.delete(event.path);
|
|
this.normalized.splice(this.normalized.indexOf(existingEvent), 1);
|
|
}
|
|
|
|
// flatten DELETE followed by CREATE into CHANGE
|
|
else if (currentChangeType === FileChangeType.DELETED && newChangeType === FileChangeType.ADDED) {
|
|
existingEvent.type = FileChangeType.UPDATED;
|
|
}
|
|
|
|
// Do nothing. Keep the created event
|
|
else if (currentChangeType === FileChangeType.ADDED && newChangeType === FileChangeType.UPDATED) { }
|
|
|
|
// Otherwise apply change type
|
|
else {
|
|
existingEvent.type = newChangeType;
|
|
}
|
|
}
|
|
|
|
// Otherwise store new
|
|
else {
|
|
this.normalized.push(event);
|
|
this.mapPathToChange.set(event.path, event);
|
|
}
|
|
}
|
|
|
|
normalize(): IDiskFileChange[] {
|
|
const addedChangeEvents: IDiskFileChange[] = [];
|
|
const deletedPaths: string[] = [];
|
|
|
|
// This algorithm will remove all DELETE events up to the root folder
|
|
// that got deleted if any. This ensures that we are not producing
|
|
// DELETE events for each file inside a folder that gets deleted.
|
|
//
|
|
// 1.) split ADD/CHANGE and DELETED events
|
|
// 2.) sort short deleted paths to the top
|
|
// 3.) for each DELETE, check if there is a deleted parent and ignore the event in that case
|
|
return this.normalized.filter(e => {
|
|
if (e.type !== FileChangeType.DELETED) {
|
|
addedChangeEvents.push(e);
|
|
|
|
return false; // remove ADD / CHANGE
|
|
}
|
|
|
|
return true; // keep DELETE
|
|
}).sort((e1, e2) => {
|
|
return e1.path.length - e2.path.length; // shortest path first
|
|
}).filter(e => {
|
|
if (deletedPaths.some(d => isParent(e.path, d, !isLinux /* ignorecase */))) {
|
|
return false; // DELETE is ignored if parent is deleted already
|
|
}
|
|
|
|
// otherwise mark as deleted
|
|
deletedPaths.push(e.path);
|
|
|
|
return true;
|
|
}).concat(addedChangeEvents);
|
|
}
|
|
}
|