mirror of
https://github.com/Microsoft/vscode
synced 2024-10-30 19:12:57 +00:00
files - cleanup & remove obsolete importFile action
This commit is contained in:
parent
fe9d9532ea
commit
84ce87420b
8 changed files with 81 additions and 204 deletions
|
@ -125,11 +125,6 @@ export interface IFileService {
|
|||
*/
|
||||
del(resource: URI, useTrash?: boolean): TPromise<void>;
|
||||
|
||||
/**
|
||||
* Imports the file to the parent identified by the resource.
|
||||
*/
|
||||
importFile(source: URI, targetFolder: URI): TPromise<IImportResult>;
|
||||
|
||||
/**
|
||||
* Allows to start a watcher that reports file change events on the provided resource.
|
||||
*/
|
||||
|
@ -178,8 +173,7 @@ export enum FileOperation {
|
|||
CREATE,
|
||||
DELETE,
|
||||
MOVE,
|
||||
COPY,
|
||||
IMPORT
|
||||
COPY
|
||||
}
|
||||
|
||||
export class FileOperationEvent {
|
||||
|
@ -546,11 +540,6 @@ export interface ICreateFileOptions {
|
|||
overwrite?: boolean;
|
||||
}
|
||||
|
||||
export interface IImportResult {
|
||||
stat: IFileStat;
|
||||
isNew: boolean;
|
||||
}
|
||||
|
||||
export class FileOperationError extends Error {
|
||||
constructor(message: string, public fileOperationResult: FileOperationResult, public options?: IResolveContentOptions & IUpdateContentOptions & ICreateFileOptions) {
|
||||
super(message);
|
||||
|
|
|
@ -13,6 +13,7 @@ import { sequence, ITask, always } from 'vs/base/common/async';
|
|||
import * as paths from 'vs/base/common/paths';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { posix } from 'path';
|
||||
import * as errors from 'vs/base/common/errors';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
|
@ -725,8 +726,8 @@ class BaseDeleteFileAction extends BaseFileAction {
|
|||
}
|
||||
}
|
||||
|
||||
/* Import File */
|
||||
export class ImportFileAction extends BaseFileAction {
|
||||
/* Add File */
|
||||
export class AddFilesAction extends BaseFileAction {
|
||||
|
||||
private tree: ITree;
|
||||
|
||||
|
@ -740,7 +741,7 @@ export class ImportFileAction extends BaseFileAction {
|
|||
@INotificationService notificationService: INotificationService,
|
||||
@ITextFileService textFileService: ITextFileService
|
||||
) {
|
||||
super('workbench.files.action.importFile', nls.localize('importFiles', "Import Files"), fileService, notificationService, textFileService);
|
||||
super('workbench.files.action.addFile', nls.localize('addFiles', "Add Files"), fileService, notificationService, textFileService);
|
||||
|
||||
this.tree = tree;
|
||||
this.element = element;
|
||||
|
@ -753,10 +754,10 @@ export class ImportFileAction extends BaseFileAction {
|
|||
}
|
||||
|
||||
public run(resources: URI[]): TPromise<any> {
|
||||
const importPromise = TPromise.as(null).then(() => {
|
||||
const addPromise = TPromise.as(null).then(() => {
|
||||
if (resources && resources.length > 0) {
|
||||
|
||||
// Find parent for import
|
||||
// Find parent to add to
|
||||
let targetElement: ExplorerItem;
|
||||
if (this.element) {
|
||||
targetElement = this.element;
|
||||
|
@ -797,15 +798,15 @@ export class ImportFileAction extends BaseFileAction {
|
|||
return void 0;
|
||||
}
|
||||
|
||||
// Run import in sequence
|
||||
const importPromisesFactory: ITask<TPromise<void>>[] = [];
|
||||
// Run add in sequence
|
||||
const addPromisesFactory: ITask<TPromise<void>>[] = [];
|
||||
resources.forEach(resource => {
|
||||
importPromisesFactory.push(() => {
|
||||
addPromisesFactory.push(() => {
|
||||
const sourceFile = resource;
|
||||
const targetFile = targetElement.resource.with({ path: paths.join(targetElement.resource.path, paths.basename(sourceFile.path)) });
|
||||
|
||||
// if the target exists and is dirty, make sure to revert it. otherwise the dirty contents
|
||||
// of the target file would replace the contents of the imported file. since we already
|
||||
// of the target file would replace the contents of the added file. since we already
|
||||
// confirmed the overwrite before, this is OK.
|
||||
let revertPromise = TPromise.wrap(null);
|
||||
if (this.textFileService.isDirty(targetFile)) {
|
||||
|
@ -813,18 +814,19 @@ export class ImportFileAction extends BaseFileAction {
|
|||
}
|
||||
|
||||
return revertPromise.then(() => {
|
||||
return this.fileService.importFile(sourceFile, targetElement.resource).then(res => {
|
||||
const target = targetElement.resource.with({ path: posix.join(targetElement.resource.path, posix.basename(sourceFile.path)) });
|
||||
return this.fileService.copyFile(sourceFile, target, true).then(stat => {
|
||||
|
||||
// if we only import one file, just open it directly
|
||||
// if we only add one file, just open it directly
|
||||
if (resources.length === 1) {
|
||||
this.editorService.openEditor({ resource: res.stat.resource, options: { pinned: true } }).done(null, errors.onUnexpectedError);
|
||||
this.editorService.openEditor({ resource: stat.resource, options: { pinned: true } }).done(null, errors.onUnexpectedError);
|
||||
}
|
||||
}, error => this.onError(error));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return sequence(importPromisesFactory);
|
||||
return sequence(addPromisesFactory);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -832,7 +834,7 @@ export class ImportFileAction extends BaseFileAction {
|
|||
return void 0;
|
||||
});
|
||||
|
||||
return importPromise.then(() => {
|
||||
return addPromise.then(() => {
|
||||
this.tree.clearHighlight();
|
||||
}, (error: any) => {
|
||||
this.onError(error);
|
||||
|
|
|
@ -470,7 +470,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView
|
|||
}
|
||||
|
||||
// Add
|
||||
if (e.operation === FileOperation.CREATE || e.operation === FileOperation.IMPORT || e.operation === FileOperation.COPY) {
|
||||
if (e.operation === FileOperation.CREATE || e.operation === FileOperation.COPY) {
|
||||
const addedElement = e.target;
|
||||
const parentResource = resources.dirname(addedElement.resource);
|
||||
const parents = this.model.findAll(parentResource);
|
||||
|
|
|
@ -24,7 +24,7 @@ import { IFilesConfiguration, SortOrder } from 'vs/workbench/parts/files/common/
|
|||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { FileOperationError, FileOperationResult, IFileService, FileKind } from 'vs/platform/files/common/files';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { DuplicateFileAction, ImportFileAction, IEditableData, IFileViewletState, FileCopiedContext } from 'vs/workbench/parts/files/electron-browser/fileActions';
|
||||
import { DuplicateFileAction, AddFilesAction, IEditableData, IFileViewletState, FileCopiedContext } from 'vs/workbench/parts/files/electron-browser/fileActions';
|
||||
import { IDataSource, ITree, IAccessibilityProvider, IRenderer, ContextMenuEvent, ISorter, IFilter, IDragAndDropData, IDragOverReaction, DRAG_OVER_ACCEPT_BUBBLE_DOWN, DRAG_OVER_ACCEPT_BUBBLE_DOWN_COPY, DRAG_OVER_ACCEPT_BUBBLE_UP, DRAG_OVER_ACCEPT_BUBBLE_UP_COPY, DRAG_OVER_REJECT } from 'vs/base/parts/tree/browser/tree';
|
||||
import { DesktopDragAndDropData, ExternalElementsDragAndDropData } from 'vs/base/parts/tree/browser/treeDnd';
|
||||
import { ClickBehavior } from 'vs/base/parts/tree/browser/treeDefaults';
|
||||
|
@ -921,9 +921,9 @@ export class FileDragAndDrop extends SimpleFileResourceDragAndDrop {
|
|||
|
||||
// Handle dropped files (only support FileStat as target)
|
||||
else if (target instanceof ExplorerItem) {
|
||||
const importAction = this.instantiationService.createInstance(ImportFileAction, tree, target, null);
|
||||
const addFilesAction = this.instantiationService.createInstance(AddFilesAction, tree, target, null);
|
||||
|
||||
return importAction.run(droppedResources.map(res => res.resource));
|
||||
return addFilesAction.run(droppedResources.map(res => res.resource));
|
||||
}
|
||||
|
||||
return void 0;
|
||||
|
|
|
@ -10,7 +10,7 @@ import * as fs from 'fs';
|
|||
import * as os from 'os';
|
||||
import * as crypto from 'crypto';
|
||||
import * as assert from 'assert';
|
||||
import { isParent, FileOperation, FileOperationEvent, IContent, IFileService, IResolveFileOptions, IResolveFileResult, IResolveContentOptions, IFileStat, IStreamContent, FileOperationError, FileOperationResult, IUpdateContentOptions, FileChangeType, IImportResult, FileChangesEvent, ICreateFileOptions, IContentData, ITextSnapshot, IFilesConfiguration } from 'vs/platform/files/common/files';
|
||||
import { isParent, FileOperation, FileOperationEvent, IContent, IFileService, IResolveFileOptions, IResolveFileResult, IResolveContentOptions, IFileStat, IStreamContent, FileOperationError, FileOperationResult, IUpdateContentOptions, FileChangeType, FileChangesEvent, ICreateFileOptions, IContentData, ITextSnapshot, IFilesConfiguration } from 'vs/platform/files/common/files';
|
||||
import { MAX_FILE_SIZE, MAX_HEAP_SIZE } from 'vs/platform/files/node/files';
|
||||
import { isEqualOrParent } from 'vs/base/common/paths';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
|
@ -47,6 +47,42 @@ import product from 'vs/platform/node/product';
|
|||
import { WORKSPACE_EXTENSION } from 'vs/platform/workspaces/common/workspaces';
|
||||
import { shell } from 'electron';
|
||||
|
||||
class BufferPool {
|
||||
|
||||
static _64K = new BufferPool(64 * 1024, 5);
|
||||
|
||||
constructor(
|
||||
readonly bufferSize: number,
|
||||
private readonly _capacity: number,
|
||||
private readonly _free: Buffer[] = [],
|
||||
) { }
|
||||
|
||||
acquire(): Buffer {
|
||||
if (this._free.length === 0) {
|
||||
return Buffer.allocUnsafe(this.bufferSize);
|
||||
} else {
|
||||
return this._free.shift();
|
||||
}
|
||||
}
|
||||
|
||||
release(buf: Buffer): void {
|
||||
if (this._free.length <= this._capacity) {
|
||||
this._free.push(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface IEncodingOverride {
|
||||
parent?: uri;
|
||||
extension?: string;
|
||||
encoding: string;
|
||||
}
|
||||
|
||||
export interface IFileServiceTestOptions {
|
||||
disableWatcher?: boolean;
|
||||
encodingOverride?: IEncodingOverride[];
|
||||
}
|
||||
|
||||
export class FileService implements IFileService {
|
||||
|
||||
public _serviceBrand: any;
|
||||
|
@ -191,12 +227,6 @@ export class FileService implements IFileService {
|
|||
return this._onAfterOperation.event;
|
||||
}
|
||||
|
||||
public updateOptions(options: IFileServiceTestOptions): void {
|
||||
if (options) {
|
||||
objects.mixin(this.options, options); // overwrite current options
|
||||
}
|
||||
}
|
||||
|
||||
private setupFileWatching(): void {
|
||||
|
||||
// dispose old if any
|
||||
|
@ -213,10 +243,11 @@ export class FileService implements IFileService {
|
|||
// new watcher: use it if setting tells us so or we run in multi-root environment
|
||||
const configuration = this.configurationService.getValue<IFilesConfiguration>();
|
||||
if ((configuration.files && configuration.files.useExperimentalFileWatcher) || workbenchState === WorkbenchState.WORKSPACE) {
|
||||
this.activeWorkspaceFileChangeWatcher = toDisposable(this.setupNsfwWorkspaceWatching().startWatching());
|
||||
const multiRootWatcher = new NsfwWatcherService(this.contextService, this.configurationService, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose);
|
||||
this.activeWorkspaceFileChangeWatcher = toDisposable(multiRootWatcher.startWatching());
|
||||
}
|
||||
|
||||
// old watcher
|
||||
// legacy watcher
|
||||
else {
|
||||
let watcherIgnoredPatterns: string[] = [];
|
||||
if (configuration.files && configuration.files.watcherExclude) {
|
||||
|
@ -224,25 +255,15 @@ export class FileService implements IFileService {
|
|||
}
|
||||
|
||||
if (isWindows) {
|
||||
this.activeWorkspaceFileChangeWatcher = toDisposable(this.setupWin32WorkspaceWatching(watcherIgnoredPatterns).startWatching());
|
||||
const legacyWindowsWatcher = new WindowsWatcherService(this.contextService, watcherIgnoredPatterns, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose);
|
||||
this.activeWorkspaceFileChangeWatcher = toDisposable(legacyWindowsWatcher.startWatching());
|
||||
} else {
|
||||
this.activeWorkspaceFileChangeWatcher = toDisposable(this.setupUnixWorkspaceWatching(watcherIgnoredPatterns).startWatching());
|
||||
const legacyUnixWatcher = new UnixWatcherService(this.contextService, watcherIgnoredPatterns, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose);
|
||||
this.activeWorkspaceFileChangeWatcher = toDisposable(legacyUnixWatcher.startWatching());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private setupWin32WorkspaceWatching(watcherIgnoredPatterns: string[]): WindowsWatcherService {
|
||||
return new WindowsWatcherService(this.contextService, watcherIgnoredPatterns, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose);
|
||||
}
|
||||
|
||||
private setupUnixWorkspaceWatching(watcherIgnoredPatterns: string[]): UnixWatcherService {
|
||||
return new UnixWatcherService(this.contextService, watcherIgnoredPatterns, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose);
|
||||
}
|
||||
|
||||
private setupNsfwWorkspaceWatching(): NsfwWatcherService {
|
||||
return new NsfwWatcherService(this.contextService, this.configurationService, e => this._onFileChanges.fire(e), err => this.handleError(err), this.environmentService.verbose);
|
||||
}
|
||||
|
||||
public resolveFile(resource: uri, options?: IResolveFileOptions): TPromise<IFileStat> {
|
||||
return this.resolve(resource, options);
|
||||
}
|
||||
|
@ -512,9 +533,10 @@ export class FileService implements IFileService {
|
|||
} else {
|
||||
// when receiving the first chunk of data we need to create the
|
||||
// decoding stream which is then used to drive the string stream.
|
||||
const autoGuessEncoding = (options && options.autoGuessEncoding) || this.textResourceConfigurationService.getValue(resource, 'files.autoGuessEncoding');
|
||||
TPromise.as(encoding.detectEncodingFromBuffer(
|
||||
{ buffer: chunkBuffer, bytesRead },
|
||||
options && options.autoGuessEncoding || this.configuredAutoGuessEncoding(resource)
|
||||
autoGuessEncoding
|
||||
)).then(detected => {
|
||||
|
||||
if (options && options.acceptTextOnly && detected.seemsBinary) {
|
||||
|
@ -920,32 +942,6 @@ export class FileService implements IFileService {
|
|||
});
|
||||
}
|
||||
|
||||
public importFile(source: uri, targetFolder: uri): TPromise<IImportResult> {
|
||||
const sourcePath = this.toAbsolutePath(source);
|
||||
const targetResource = uri.file(paths.join(targetFolder.fsPath, paths.basename(source.fsPath)));
|
||||
const targetPath = this.toAbsolutePath(targetResource);
|
||||
|
||||
// 1.) resolve
|
||||
return pfs.stat(sourcePath).then(stat => {
|
||||
if (stat.isDirectory()) {
|
||||
return TPromise.wrapError<IImportResult>(new Error(nls.localize('foldersCopyError', "Folders cannot be copied into the workspace. Please select individual files to copy them."))); // for now we do not allow to import a folder into a workspace
|
||||
}
|
||||
|
||||
// 2.) copy
|
||||
return this.doMoveOrCopyFile(sourcePath, targetPath, true, true).then(exists => {
|
||||
|
||||
// 3.) resolve
|
||||
return this.resolve(targetResource).then(stat => {
|
||||
|
||||
// Events
|
||||
this._onAfterOperation.fire(new FileOperationEvent(source, FileOperation.IMPORT, stat));
|
||||
|
||||
return <IImportResult>{ isNew: !exists, stat };
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public del(resource: uri, useTrash?: boolean): TPromise<void> {
|
||||
if (useTrash) {
|
||||
return this.doMoveItemToTrash(resource);
|
||||
|
@ -992,8 +988,7 @@ export class FileService implements IFileService {
|
|||
}
|
||||
|
||||
private resolve(resource: uri, options: IResolveFileOptions = Object.create(null)): TPromise<IFileStat> {
|
||||
return this.toStatResolver(resource)
|
||||
.then(model => model.resolve(options));
|
||||
return this.toStatResolver(resource).then(model => model.resolve(options));
|
||||
}
|
||||
|
||||
private toStatResolver(resource: uri): TPromise<StatResolver> {
|
||||
|
@ -1043,10 +1038,6 @@ export class FileService implements IFileService {
|
|||
return fileEncoding;
|
||||
}
|
||||
|
||||
private configuredAutoGuessEncoding(resource: uri): boolean {
|
||||
return this.textResourceConfigurationService.getValue(resource, 'files.autoGuessEncoding');
|
||||
}
|
||||
|
||||
private configuredEncoding(resource: uri): string {
|
||||
return this.textResourceConfigurationService.getValue(resource, 'files.encoding');
|
||||
}
|
||||
|
@ -1181,17 +1172,6 @@ export class FileService implements IFileService {
|
|||
}
|
||||
}
|
||||
|
||||
export interface IEncodingOverride {
|
||||
parent?: uri;
|
||||
extension?: string;
|
||||
encoding: string;
|
||||
}
|
||||
|
||||
export interface IFileServiceTestOptions {
|
||||
disableWatcher?: boolean;
|
||||
encodingOverride?: IEncodingOverride[];
|
||||
}
|
||||
|
||||
function etag(stat: fs.Stats): string;
|
||||
function etag(size: number, mtime: number): string;
|
||||
function etag(arg1: any, arg2?: any): string {
|
||||
|
@ -1208,33 +1188,6 @@ function etag(arg1: any, arg2?: any): string {
|
|||
return `"${crypto.createHash('sha1').update(String(size) + String(mtime)).digest('hex')}"`;
|
||||
}
|
||||
|
||||
class BufferPool {
|
||||
|
||||
static _64K = new BufferPool(64 * 1024, 5);
|
||||
|
||||
constructor(
|
||||
readonly bufferSize: number,
|
||||
private readonly _capacity: number,
|
||||
private readonly _free: Buffer[] = [],
|
||||
) {
|
||||
//
|
||||
}
|
||||
|
||||
acquire(): Buffer {
|
||||
if (this._free.length === 0) {
|
||||
return Buffer.allocUnsafe(this.bufferSize);
|
||||
} else {
|
||||
return this._free.shift();
|
||||
}
|
||||
}
|
||||
|
||||
release(buf: Buffer): void {
|
||||
if (this._free.length <= this._capacity) {
|
||||
this._free.push(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class StatResolver {
|
||||
private name: string;
|
||||
private etag: string;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
import URI from 'vs/base/common/uri';
|
||||
import { FileService } from 'vs/workbench/services/files/electron-browser/fileService';
|
||||
import { IContent, IStreamContent, IFileStat, IResolveContentOptions, IUpdateContentOptions, IResolveFileOptions, IResolveFileResult, FileOperationEvent, FileOperation, IFileSystemProvider, IStat, FileType2, IImportResult, FileChangesEvent, ICreateFileOptions, FileOperationError, FileOperationResult, ITextSnapshot, snapshotToString } from 'vs/platform/files/common/files';
|
||||
import { IContent, IStreamContent, IFileStat, IResolveContentOptions, IUpdateContentOptions, IResolveFileOptions, IResolveFileResult, FileOperationEvent, FileOperation, IFileSystemProvider, IStat, FileType2, FileChangesEvent, ICreateFileOptions, FileOperationError, FileOperationResult, ITextSnapshot, snapshotToString } from 'vs/platform/files/common/files';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { posix } from 'path';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
@ -430,15 +430,6 @@ export class RemoteFileService extends FileService {
|
|||
});
|
||||
}
|
||||
|
||||
importFile(source: URI, targetFolder: URI): TPromise<IImportResult> {
|
||||
if (source.scheme === targetFolder.scheme && source.scheme === Schemas.file) {
|
||||
return super.importFile(source, targetFolder);
|
||||
} else {
|
||||
const target = targetFolder.with({ path: posix.join(targetFolder.path, posix.basename(source.path)) });
|
||||
return this.copyFile(source, target, false).then(stat => ({ stat, isNew: false }));
|
||||
}
|
||||
}
|
||||
|
||||
copyFile(source: URI, target: URI, overwrite?: boolean): TPromise<IFileStat> {
|
||||
if (source.scheme === target.scheme && source.scheme === Schemas.file) {
|
||||
return super.copyFile(source, target, overwrite);
|
||||
|
|
|
@ -426,36 +426,18 @@ suite('FileService', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('importFile', function () {
|
||||
let event: FileOperationEvent;
|
||||
const toDispose = service.onAfterOperation(e => {
|
||||
event = e;
|
||||
});
|
||||
|
||||
return service.resolveFile(uri.file(path.join(testDir, 'deep'))).then(target => {
|
||||
const resource = uri.file(require.toUrl('./fixtures/service/index.html'));
|
||||
return service.importFile(resource, target.resource).then(res => {
|
||||
assert.equal(res.isNew, true);
|
||||
assert.equal(fs.existsSync(res.stat.resource.fsPath), true);
|
||||
|
||||
assert.ok(event);
|
||||
assert.equal(event.resource.fsPath, resource.fsPath);
|
||||
assert.equal(event.operation, FileOperation.IMPORT);
|
||||
assert.equal(event.target.resource.fsPath, res.stat.resource.fsPath);
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('importFile - MIX CASE', function () {
|
||||
test('copyFile - MIX CASE', function () {
|
||||
return service.resolveFile(uri.file(path.join(testDir, 'index.html'))).then(source => {
|
||||
return service.rename(source.resource, 'CONWAY.js').then(renamed => { // index.html => CONWAY.js
|
||||
assert.equal(fs.existsSync(renamed.resource.fsPath), true);
|
||||
assert.ok(fs.readdirSync(testDir).some(f => f === 'CONWAY.js'));
|
||||
|
||||
return service.resolveFile(uri.file(path.join(testDir, 'deep', 'conway.js'))).then(source => {
|
||||
return service.importFile(source.resource, uri.file(testDir)).then(res => { // CONWAY.js => conway.js
|
||||
assert.equal(fs.existsSync(res.stat.resource.fsPath), true);
|
||||
const targetParent = uri.file(testDir);
|
||||
const target = targetParent.with({ path: path.posix.join(targetParent.path, path.posix.basename(source.resource.path)) });
|
||||
|
||||
return service.copyFile(source.resource, target, true).then(res => { // CONWAY.js => conway.js
|
||||
assert.equal(fs.existsSync(res.resource.fsPath), true);
|
||||
assert.ok(fs.readdirSync(testDir).some(f => f === 'conway.js'));
|
||||
});
|
||||
});
|
||||
|
@ -463,48 +445,12 @@ suite('FileService', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('importFile - overwrite folder with file', function () {
|
||||
let createEvent: FileOperationEvent;
|
||||
let importEvent: FileOperationEvent;
|
||||
let deleteEvent: FileOperationEvent;
|
||||
const toDispose = service.onAfterOperation(e => {
|
||||
if (e.operation === FileOperation.CREATE) {
|
||||
createEvent = e;
|
||||
} else if (e.operation === FileOperation.DELETE) {
|
||||
deleteEvent = e;
|
||||
} else if (e.operation === FileOperation.IMPORT) {
|
||||
importEvent = e;
|
||||
}
|
||||
});
|
||||
|
||||
return service.resolveFile(uri.file(testDir)).then(parent => {
|
||||
const folderResource = uri.file(path.join(parent.resource.fsPath, 'conway.js'));
|
||||
return service.createFolder(folderResource).then(f => {
|
||||
const resource = uri.file(path.join(testDir, 'deep', 'conway.js'));
|
||||
return service.importFile(resource, uri.file(testDir)).then(res => {
|
||||
assert.equal(fs.existsSync(res.stat.resource.fsPath), true);
|
||||
assert.ok(fs.readdirSync(testDir).some(f => f === 'conway.js'));
|
||||
assert.ok(fs.statSync(res.stat.resource.fsPath).isFile);
|
||||
|
||||
assert.ok(createEvent);
|
||||
assert.ok(deleteEvent);
|
||||
assert.ok(importEvent);
|
||||
|
||||
assert.equal(importEvent.resource.fsPath, resource.fsPath);
|
||||
assert.equal(importEvent.target.resource.fsPath, res.stat.resource.fsPath);
|
||||
|
||||
assert.equal(deleteEvent.resource.fsPath, folderResource.fsPath);
|
||||
|
||||
toDispose.dispose();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('importFile - same file', function () {
|
||||
test('copyFile - same file', function () {
|
||||
return service.resolveFile(uri.file(path.join(testDir, 'index.html'))).then(source => {
|
||||
return service.importFile(source.resource, uri.file(path.dirname(source.resource.fsPath))).then(imported => {
|
||||
assert.equal(imported.stat.size, source.size);
|
||||
const targetParent = uri.file(path.dirname(source.resource.fsPath));
|
||||
const target = targetParent.with({ path: path.posix.join(targetParent.path, path.posix.basename(source.resource.path)) });
|
||||
return service.copyFile(source.resource, target, true).then(copied => {
|
||||
assert.equal(copied.size, source.size);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -32,7 +32,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
|
|||
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
|
||||
import { IEditorGroupService, GroupArrangement, GroupOrientation, IEditorTabOptions, IMoveOptions } from 'vs/workbench/services/group/common/groupService';
|
||||
import { TextFileService } from 'vs/workbench/services/textfile/common/textFileService';
|
||||
import { FileOperationEvent, IFileService, IResolveContentOptions, FileOperationError, IFileStat, IResolveFileResult, IImportResult, FileChangesEvent, IResolveFileOptions, IContent, IUpdateContentOptions, IStreamContent, ICreateFileOptions, ITextSnapshot } from 'vs/platform/files/common/files';
|
||||
import { FileOperationEvent, IFileService, IResolveContentOptions, FileOperationError, IFileStat, IResolveFileResult, FileChangesEvent, IResolveFileOptions, IContent, IUpdateContentOptions, IStreamContent, ICreateFileOptions, ITextSnapshot } from 'vs/platform/files/common/files';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl';
|
||||
import { ModelServiceImpl } from 'vs/editor/common/services/modelServiceImpl';
|
||||
|
@ -805,10 +805,6 @@ export class TestFileService implements IFileService {
|
|||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
importFile(source: URI, targetFolder: URI): TPromise<IImportResult> {
|
||||
return TPromise.as(null);
|
||||
}
|
||||
|
||||
watchFileChanges(resource: URI): void {
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue