From ac78af2aa00e4cd86ad71798036ab84f4def0db5 Mon Sep 17 00:00:00 2001 From: Blake Dietz Date: Thu, 14 Feb 2019 16:22:56 -0700 Subject: [PATCH] fix(File tree): Only allow markdown files in the tree (#27) * perf(tag-tree-data-provider.ts): Scan files asynchronously (#24) * Scan files asynchronously * Only include markdown files * docs(CHANGELOG.md): Automatically publish changes to CHANGELOG.md (#25) Automatically publish changes to CHANGELOG.md --- .circleci/CHANGELOG.md | 0 package-lock.json | 21 ++++++++ package.json | 33 ++++++------- src/tag-tree-data-provider.ts | 93 ++++++++++++++--------------------- 4 files changed, 74 insertions(+), 73 deletions(-) create mode 100644 .circleci/CHANGELOG.md diff --git a/.circleci/CHANGELOG.md b/.circleci/CHANGELOG.md new file mode 100644 index 0000000..e69de29 diff --git a/package-lock.json b/package-lock.json index d8e4e80..18cdfcc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -165,6 +165,18 @@ "any-observable": "^0.3.0" } }, + "@semantic-release/changelog": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/@semantic-release/changelog/-/changelog-3.0.2.tgz", + "integrity": "sha1-sJqODQcu9U0rx6XIL2ES3DyK6F0=", + "dev": true, + "requires": { + "@semantic-release/error": "^2.1.0", + "aggregate-error": "^2.0.0", + "fs-extra": "^7.0.0", + "lodash": "^4.17.4" + } + }, "@semantic-release/commit-analyzer": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-6.1.0.tgz", @@ -450,6 +462,15 @@ "integrity": "sha512-9spv6SklidqxevvZyOUGjZVz4QRXGu2dNaLyXIFzFYZW0AGDykzPRIUFJXTlQXyfzAucddwTcGtJNim8zqSOPA==", "dev": true }, + "@types/recursive-readdir": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.intuit.com:443/artifactory/api/npm/npm-intuit/@types/recursive-readdir/-/recursive-readdir-2.2.0.tgz", + "integrity": "sha1-s5zVR0/Vjqcn/kNNXGi3ogupEhw=", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/shelljs": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.2.tgz", diff --git a/package.json b/package.json index d211b8b..a848c69 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "watch": "tsc -watch -p ./" }, "devDependencies": { + "@semantic-release/changelog": "^3.0.2", "@semantic-release/commit-analyzer": "^6.1.0", "@semantic-release/exec": "^3.3.2", "@semantic-release/git": "^7.0.8", @@ -34,6 +35,7 @@ "@types/debounce": "^1.2.0", "@types/jest": "^23.3.12", "@types/node": "^10.12.18", + "@types/recursive-readdir": "2.2.0", "commitizen": "^3.0.5", "cz-conventional-changelog": "^2.1.0", "husky": "^1.3.1", @@ -67,10 +69,10 @@ } }, "icon": "images/icon.png", - "galleryBanner": { - "color": "#073642", - "theme": "dark" - }, + "galleryBanner": { + "color": "#073642", + "theme": "dark" + }, "publisher": "vscode-nested-tags", "config": { "loglevel": "verbose", @@ -91,20 +93,15 @@ ] }, "release": { - "verifyConditions": [ - "semantic-release-vsce", - "@semantic-release/github" - ], - "prepare": { - "path": "semantic-release-vsce", - "packageVsix": "vscode-nested-tags.vsix" - }, - "publish": [ - "semantic-release-vsce", - { - "path": "@semantic-release/github", - "assets": "vscode-nested-tags.vsix" - } + "plugins": [ + ["semantic-release-vsce", { + "path": "@semantic-release/github", + "assets": "vscode-nested-tags.vsix" + }], + "@semantic-release/github", + ["@semantic-release/changelog", { + "changelogFile": "./CHANGELOG.md" + }] ] } } diff --git a/src/tag-tree-data-provider.ts b/src/tag-tree-data-provider.ts index fdab08c..6b2dc02 100644 --- a/src/tag-tree-data-provider.ts +++ b/src/tag-tree-data-provider.ts @@ -1,6 +1,6 @@ import { debounce } from "debounce"; import * as fs from "fs"; -import * as path from "path"; +import * as recursiveReadDir from "recursive-readdir"; import * as vscode from "vscode"; import { setsAreEqual } from "./sets"; import { FileNode, fileNodeSort } from "./tag-tree/file-node"; @@ -25,13 +25,9 @@ class TagTreeDataProvider readonly onDidChangeTreeData: vscode.Event< TagNode | FileNode | null> = this._onDidChangeTreeData.event; constructor() { - // vscode.window.onDidChangeActiveTextEditor(() => this.onActiveEditorChanged()); - // vscode.workspace.onDidSaveTextDocument((e) => { - // console.log(e); - // }); - - // Register the extension to events of interest - // Debounce to improve performance. Otherwise a file read would occur during each of the user's change to the document. + /* Register the extension to events of interest + * Debounce to improve performance. Otherwise a file read would occur during each of the user's change to the document. + */ vscode.workspace.onDidChangeTextDocument(debounce((e: vscode.TextDocumentChangeEvent) => this.onDocumentChanged(e), 500)); vscode.workspace.onWillSaveTextDocument((e) => { this.onWillSaveTextDocument(e); @@ -39,21 +35,23 @@ class TagTreeDataProvider this.tagTree = new TagTree(); - // Add all files in the current workspace folder to the tag tree - // @ts-ignore - const workspaceFolder = vscode.workspace.workspaceFolders[0].uri.fsPath; - const files = []; - - // TODO: (bdietz) - this is probably going to be pretty slow - for(const filePath of this.walkFileSystemSync(workspaceFolder)) { - const fileInfo = this.getTagsFromFileOnFileSystem(filePath); - if (fileInfo.tags.size > 0) { - files.push(fileInfo); - } - } - - for (const fileInfo of files) { - this.tagTree.addFile(fileInfo.filePath, [...fileInfo.tags], fileInfo.filePath); + /* Add all files in the current workspace folder to the tag tree + * @ts-ignore + */ + if (vscode.workspace.workspaceFolders!.length > 0) { + vscode.workspace.workspaceFolders!.forEach(workspaceFolder => { + const { fsPath } = workspaceFolder.uri; + recursiveReadDir(fsPath, ["!*.md"], (error: any, files: any) => { + for (const filePath of files) { + const fileInfo = this.getTagsFromFileOnFileSystem(filePath); + if (fileInfo.tags.size > 0) { + this.tagTree.addFile(fileInfo.filePath, [...fileInfo.tags], fileInfo.filePath); + } + } + + this._onDidChangeTreeData.fire(); + }); + }); } } @@ -114,7 +112,7 @@ class TagTreeDataProvider * @param changeEvent */ private onWillSaveTextDocument(changeEvent: vscode.TextDocumentWillSaveEvent) { - if (changeEvent.document.isDirty) { + if (changeEvent.document.isDirty && changeEvent.document.languageId === "markdown") { const filePath = changeEvent.document.fileName; const fileInfo = this.getTagsFromFileOnFileSystem(filePath); const tagsInTreeForFile = this.tagTree.getTagsForFile(filePath); @@ -132,37 +130,21 @@ class TagTreeDataProvider */ private onDocumentChanged(changeEvent: vscode.TextDocumentChangeEvent): void { const filePath = changeEvent.document.fileName; - const fileInfo = this.getTagsFromFileText(changeEvent.document.getText(), filePath); - const tagsInTreeForFile = this.tagTree.getTagsForFile(filePath); - const isUpdateNeeded = !setsAreEqual(fileInfo.tags, tagsInTreeForFile); - /* - * This could be potentially performance intensive due to the number of changes that could - * be made to a document and how large the document is. There will definitely need to be some - * work done around TagTree to make sure that the code - */ - if (isUpdateNeeded) { - this.tagTree.deleteFile(filePath); - this.tagTree.addFile(filePath, [...fileInfo.tags.values()], filePath); - // TODO: (bdietz) - this._onDidChangeTreeData.fire(specificNode?) - this._onDidChangeTreeData.fire(); - } - } - - /** - * NOTE: Stole this from https://gist.github.com/luciopaiva/4ba78a124704007c702d0293e7ff58dd. - * - * Recursively walk through the file system synchronously. - */ - private *walkFileSystemSync(dir: string): IterableIterator { - const files = fs.readdirSync(dir); - - for (const file of files) { - const pathToFile = path.join(dir, file); - const isDirectory = fs.statSync(pathToFile).isDirectory(); - if (isDirectory) { - yield* this.walkFileSystemSync(pathToFile); - } else { - yield pathToFile; + // If the file has been saved and the file is a markdown file allow for making changes to the tag tree + if (filePath !== undefined && changeEvent.document.languageId === "markdown") { + const fileInfo = this.getTagsFromFileText(changeEvent.document.getText(), filePath); + const tagsInTreeForFile = this.tagTree.getTagsForFile(filePath); + const isUpdateNeeded = !setsAreEqual(fileInfo.tags, tagsInTreeForFile); + /* + * This could be potentially performance intensive due to the number of changes that could + * be made to a document and how large the document is. There will definitely need to be some + * work done around TagTree to make sure that the code + */ + if (isUpdateNeeded) { + this.tagTree.deleteFile(filePath); + this.tagTree.addFile(filePath, [...fileInfo.tags.values()], filePath); + // TODO: (bdietz) - this._onDidChangeTreeData.fire(specificNode?) + this._onDidChangeTreeData.fire(); } } } @@ -210,6 +192,7 @@ class TagTreeDataProvider .split(','); return {...accumulator, tags: new Set([...accumulator.tags,...tagsToAdd])}; } + return accumulator; }, { tags: new Set(), filePath }); }