Skip to content

Commit

Permalink
fix(workspace): avoid workspace watcher crashing if folder is deleted (
Browse files Browse the repository at this point in the history
…#2359)

* chore: avoid workspace watcher crashing if folder is deleted

* fix build errors

* remove deprecated isPathInWorkspace

* Merge 'origin/master'

* remove new? use after merge & test fix & import

* fix circular dependency
  • Loading branch information
Kaan Genç committed Feb 9, 2022
1 parent f9ca064 commit 9d0325f
Show file tree
Hide file tree
Showing 18 changed files with 159 additions and 154 deletions.
11 changes: 0 additions & 11 deletions packages/engine-server/src/workspace/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ import {
removeCache,
writeWSMetaFile,
} from "../utils";
import { WorkspaceUtils } from "./utils";
import { WorkspaceConfig } from "./vscode";
import {
IWorkspaceService,
Expand Down Expand Up @@ -849,16 +848,6 @@ export class WorkspaceService implements Disposable, IWorkspaceService {
return [...(await this.getAllReposVaults()).keys()];
}

/**
* Check if a path belongs to a workspace
@deprecated - use {@link WorkspaceUtils.isPathInWorkspace}
*/
isPathInWorkspace(fpath: string) {
const vaults = ConfigUtils.getVaults(this.config);
const wsRoot = this.wsRoot;
return WorkspaceUtils.isPathInWorkspace({ fpath, vaults, wsRoot });
}

async pullVault(opts: { vault: DVault }) {
const { vault } = _.defaults(opts, {
urlTransformer: _.identity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ export type SyncActionResult = {
};

export interface IWorkspaceService {
/**
* Check if a path belongs to a workspace
@deprecated - use {@link WorkspaceUtils.isPathInWorkspace}
*/
isPathInWorkspace(fpath: string): boolean;

get config(): IntermediateDendronConfig;

commitAndAddAll(opts: { engine: DEngineClient }): Promise<SyncActionResult[]>;
Expand Down
8 changes: 7 additions & 1 deletion packages/plugin-core/src/WSUtilsV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { Logger } from "./logger";
import { VSCodeUtils } from "./vsCodeUtils";
import { ExtensionProvider } from "./ExtensionProvider";
import { isInsidePath, vault2Path } from "@dendronhq/common-server";
import { WorkspaceUtils } from "@dendronhq/engine-server";

let WS_UTILS: IWSUtilsV2 | undefined;

Expand Down Expand Up @@ -174,8 +175,13 @@ export class WSUtilsV2 implements IWSUtilsV2 {
}

tryGetNoteFromDocument(document: vscode.TextDocument): NoteProps | undefined {
const { wsRoot, vaults } = this.extension.getDWorkspace();
if (
!this.extension.workspaceService?.isPathInWorkspace(document.uri.fsPath)
!WorkspaceUtils.isPathInWorkspace({
wsRoot,
vaults,
fpath: document.uri.fsPath,
})
) {
Logger.info({
uri: document.uri.fsPath,
Expand Down
60 changes: 35 additions & 25 deletions packages/plugin-core/src/WorkspaceWatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
Wrap,
} from "@dendronhq/common-all";
import { file2Note, vault2Path } from "@dendronhq/common-server";
import { RemarkUtils } from "@dendronhq/engine-server";
import { RemarkUtils, WorkspaceUtils } from "@dendronhq/engine-server";
import * as Sentry from "@sentry/node";
import _ from "lodash";
import path from "path";
Expand All @@ -29,17 +29,14 @@ import {
window,
workspace,
} from "vscode";
import { IDendronExtension } from "./dendronExtensionInterface";
import { FileWatcher } from "./fileWatcher";
import { Logger } from "./logger";
import { ISchemaSyncService } from "./services/SchemaSyncServiceInterface";
import { AnalyticsUtils, sentryReportingCallback } from "./utils/analytics";
import { VSCodeUtils } from "./vsCodeUtils";
import {
DendronExtension,
getDWorkspace,
getExtension,
getVaultFromUri,
} from "./workspace";
import { WindowWatcher } from "./windowWatcher";
import { DendronExtension, getVaultFromUri } from "./workspace";

const MOVE_CURSOR_PAST_FRONTMATTER_DELAY = 50; /* ms */

Expand All @@ -50,21 +47,21 @@ interface DebouncedFunc<T extends (...args: any[]) => any> {
* If the debounced function can be run immediately, this calls it and returns its return
* value.
*
* Otherwise, it returns the return value of the last invokation, or undefined if the debounced
* Otherwise, it returns the return value of the last invocation, or undefined if the debounced
* function was not invoked yet.
*/
(...args: Parameters<T>): ReturnType<T> | undefined;

/**
* Throw away any pending invokation of the debounced function.
* Throw away any pending invocation of the debounced function.
*/
cancel(): void;

/**
* If there is a pending invokation of the debounced function, invoke it immediately and return
* If there is a pending invocation of the debounced function, invoke it immediately and return
* its return value.
*
* Otherwise, return the value from the last invokation, or undefined if the debounced function
* Otherwise, return the value from the last invocation, or undefined if the debounced function
* was never invoked.
*/
flush(): ReturnType<T> | undefined;
Expand All @@ -85,12 +82,16 @@ export class WorkspaceWatcher {
(event: TextDocumentChangeEvent) => Promise<void>
>;
private _schemaSyncService: ISchemaSyncService;
private _extension: IDendronExtension;

constructor({
schemaSyncService,
extension,
}: {
schemaSyncService: ISchemaSyncService;
extension: IDendronExtension;
}) {
this._extension = extension;
this._schemaSyncService = schemaSyncService;
this._openedDocuments = new Map();
this._quickDebouncedOnDidChangeTextDocument = _.debounce(
Expand All @@ -100,7 +101,7 @@ export class WorkspaceWatcher {
}

activate(context: ExtensionContext) {
const extension = getExtension();
const extension = this._extension;

extension.addDisposable(
workspace.onWillSaveTextDocument(
Expand Down Expand Up @@ -193,14 +194,21 @@ export class WorkspaceWatcher {
Logger.debug({ ...ctx, state: "enter" });
this._quickDebouncedOnDidChangeTextDocument.cancel();
const uri = event.document.uri;
if (!getExtension().workspaceService?.isPathInWorkspace(uri.fsPath)) {
const { wsRoot, vaults } = this._extension.getDWorkspace();
if (
!WorkspaceUtils.isPathInWorkspace({
wsRoot,
vaults,
fpath: uri.fsPath,
})
) {
Logger.debug({ ...ctx, state: "uri not in workspace" });
return;
}
Logger.debug({ ...ctx, state: "trigger change handlers" });
const activeEditor = window.activeTextEditor;
if (activeEditor?.document.uri.fsPath === event.document.uri.fsPath) {
getExtension().windowWatcher?.triggerUpdateDecorations(activeEditor);
WindowWatcher.triggerUpdateDecorations(activeEditor);
}
Logger.debug({ ...ctx, state: "exit" });
return;
Expand Down Expand Up @@ -235,7 +243,10 @@ export class WorkspaceWatcher {
reason: TextDocumentSaveReason[event.reason],
msg: "enter",
});
if (!getExtension().workspaceService?.isPathInWorkspace(uri.fsPath)) {
const { wsRoot, vaults } = this._extension.getDWorkspace();
if (
!WorkspaceUtils.isPathInWorkspace({ fpath: uri.fsPath, wsRoot, vaults })
) {
Logger.debug({
ctx,
uri: uri.fsPath,
Expand Down Expand Up @@ -263,15 +274,14 @@ export class WorkspaceWatcher {
private onWillSaveNote(event: TextDocumentWillSaveEvent) {
const ctx = "WorkspaceWatcher:onWillSaveNote";
const uri = event.document.uri;
const engineClient = getDWorkspace().engine;
const engine = this._extension.getDWorkspace().engine;
const fname = path.basename(uri.fsPath, ".md");
const now = Time.now().toMillis();

const note = NoteUtils.getNoteByFnameV5({
const note = NoteUtils.getNoteByFnameFromEngine({
fname,
vault: getVaultFromUri(uri),
notes: engineClient.notes,
wsRoot: getDWorkspace().wsRoot,
engine,
}) as NoteProps;

const content = event.document.getText();
Expand All @@ -293,7 +303,7 @@ export class WorkspaceWatcher {
// eslint-disable-next-line no-async-promise-executor
const p = new Promise(async (resolve) => {
note.updated = now;
await engineClient.updateNote(note);
await engine.updateNote(note);
return resolve(changes);
});
event.waitUntil(p);
Expand Down Expand Up @@ -336,7 +346,7 @@ export class WorkspaceWatcher {
}
try {
const files = args.files[0];
const { vaults, wsRoot } = getDWorkspace();
const { vaults, wsRoot } = this._extension.getDWorkspace();
const { oldUri, newUri } = files;
const oldVault = VaultUtils.getVaultByFilePath({
vaults,
Expand All @@ -363,7 +373,7 @@ export class WorkspaceWatcher {
isEventSourceEngine: false,
};
AnalyticsUtils.track(ContextualUIEvents.ContextualUIRename);
const engine = getExtension().getEngine();
const engine = this._extension.getEngine();
const updateNoteReferences = engine.renameNote(opts);
args.waitUntil(updateNoteReferences);
} catch (error: any) {
Expand All @@ -385,8 +395,8 @@ export class WorkspaceWatcher {
const files = args.files[0];
const { newUri } = files;
const fname = DNodeUtils.fname(newUri.fsPath);
const engine = getExtension().getEngine();
const { vaults, wsRoot } = getDWorkspace();
const engine = this._extension.getEngine();
const { vaults, wsRoot } = this._extension.getDWorkspace();
const newVault = VaultUtils.getVaultByFilePath({
vaults,
wsRoot,
Expand Down Expand Up @@ -418,7 +428,7 @@ export class WorkspaceWatcher {
fname: NoteUtils.uri2Fname(editor.document.uri),
});
WorkspaceWatcher.moveCursorPastFrontmatter(editor);
const config = getExtension().getDWorkspace().config;
const config = this._extension.getDWorkspace().config;
if (ConfigUtils.getWorkspace(config).enableAutoFoldFrontmatter) {
await this.foldFrontmatter();
}
Expand Down
11 changes: 7 additions & 4 deletions packages/plugin-core/src/commands/PasteFile.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { DendronError, ERROR_STATUS, VaultUtils } from "@dendronhq/common-all";
import { vault2Path } from "@dendronhq/common-server";
import { WorkspaceUtils } from "@dendronhq/engine-server";
import fs from "fs-extra";
import _ from "lodash";
import path from "path";
import { Selection, window } from "vscode";
import { PickerUtilsV2 } from "../components/lookup/utils";
import { DENDRON_COMMANDS } from "../constants";
import { ExtensionProvider } from "../ExtensionProvider";
import { Logger } from "../logger";
import { clipboard } from "../utils";
import { VSCodeUtils } from "../vsCodeUtils";
import { getExtension, getDWorkspace } from "../workspace";
import { BasicCommand } from "./base";

type CommandInput = {
Expand Down Expand Up @@ -59,9 +60,11 @@ export class PasteFileCommand extends BasicCommand<CommandOpts, CommandOutput> {
}

const uri = editor.document.uri;
const ext = getExtension();
const { vaults, wsRoot } = getDWorkspace();
if (!ext.workspaceService?.isPathInWorkspace(uri.fsPath)) {
const ext = ExtensionProvider.getExtension();
const { vaults, wsRoot } = ext.getDWorkspace();
if (
!WorkspaceUtils.isPathInWorkspace({ vaults, wsRoot, fpath: uri.fsPath })
) {
const error = DendronError.createFromStatus({
status: ERROR_STATUS.INVALID_STATE,
message: "not in a vault",
Expand Down
12 changes: 5 additions & 7 deletions packages/plugin-core/src/components/lookup/LookupControllerV3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@ import {
} from "./buttons";
import { ILookupProviderV3 } from "./LookupProviderV3Interface";
import { DendronQuickPickerV2, LookupControllerState } from "./types";
import {
CreateQuickPickOpts,
PickerUtilsV2,
PrepareQuickPickOpts,
ShowQuickPickOpts,
} from "./utils";
import {
import { PickerUtilsV2 } from "./utils";
import type {
ILookupControllerV3,
LookupControllerV3CreateOpts,
PrepareQuickPickOpts,
ShowQuickPickOpts,
CreateQuickPickOpts,
} from "./LookupControllerV3Interface";
import { ExtensionProvider } from "../../ExtensionProvider";
import { VersionProvider } from "../../versionProvider";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,40 @@ import { DendronQuickPickerV2, LookupControllerState } from "./types";
import { ILookupProviderV3 } from "./LookupProviderV3Interface";
import { CancellationTokenSource, QuickInputButton } from "vscode";
import { DNodeType } from "@dendronhq/common-all";
import {
CreateQuickPickOpts,
PrepareQuickPickOpts,
ShowQuickPickOpts,
} from "./utils";

export type CreateQuickPickOpts = {
title?: string;
placeholder: string;
/**
* QuickPick.ignoreFocusOut prop
*/
ignoreFocusOut?: boolean;
/**
* Initial value for quickpick
*/
initialValue?: string;
nonInteractive?: boolean;
/**
* See {@link DendronQuickPickerV2["alwaysShow"]}
*/
alwaysShow?: boolean;
/**
* if canSelectMany and items from selection, select all items at creation
*/
selectAll?: boolean;
};

export type PrepareQuickPickOpts = CreateQuickPickOpts & {
provider: ILookupProviderV3;
onDidHide?: () => void;
};

export type ShowQuickPickOpts = {
quickpick: DendronQuickPickerV2;
provider: ILookupProviderV3;
nonInteractive?: boolean;
fuzzThreshold?: number;
};

export interface ILookupControllerV3 {
readonly quickpick: DendronQuickPickerV2;
Expand Down
10 changes: 9 additions & 1 deletion packages/plugin-core/src/components/lookup/buttons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
NoteUtils,
TaskNoteUtils,
} from "@dendronhq/common-all";
import { WorkspaceUtils } from "@dendronhq/engine-server";
import _ from "lodash";
import * as vscode from "vscode";
import { DendronClientUtilsV2 } from "../../clientUtils";
Expand Down Expand Up @@ -112,8 +113,15 @@ const selectionToNoteProps = async (opts: {
const leaveTrace = noteLookupConfig.leaveTrace || false;
const body = "\n" + document.getText(range).trim();
note.body = body;
const { wsRoot, vaults } = ext.getDWorkspace();
// don't delete if original file is not in workspace
if (!ext.workspaceService?.isPathInWorkspace(document.uri.fsPath)) {
if (
!WorkspaceUtils.isPathInWorkspace({
wsRoot,
vaults,
fpath: document.uri.fsPath,
})
) {
return note;
}
if (leaveTrace) {
Expand Down

0 comments on commit 9d0325f

Please sign in to comment.