diff --git a/lib/commands.ts b/lib/commands.ts index dd9c283f..ff5163f2 100644 --- a/lib/commands.ts +++ b/lib/commands.ts @@ -80,7 +80,7 @@ export class Commands { } } -export function showDebug(standardLinters: Array, indieLinters: Array, uiProviders: Array) { +export async function showDebug(standardLinters: Array, indieLinters: Array, uiProviders: Array) { if (!manifest) { manifest = require('../package.json') } @@ -104,7 +104,7 @@ export function showDebug(standardLinters: Array, indieLinters: Array { } let minimatch: typeof import('minimatch') -export function isPathIgnored(filePath: string | null | undefined, ignoredGlob: string, ignoredVCS: boolean): boolean { +export async function isPathIgnored( + filePath: string | null | undefined, + ignoredGlob: string, + ignoredVCS: boolean, +): Promise { if (!filePath) { return true } if (ignoredVCS) { - let repository = null - const projectPaths = atom.project.getPaths() - for (let i = 0, { length } = projectPaths; i < length; ++i) { - const projectPath = projectPaths[i] - if (filePath.indexOf(projectPath) === 0) { - repository = atom.project.getRepositories()[i] - break - } - } + const directory = new Directory(filePath) + const repository = await atom.project.repositoryForDirectory(directory) if (repository && repository.isPathIgnored(filePath)) { return true } diff --git a/lib/linter-registry.ts b/lib/linter-registry.ts index 33b1b085..21722fc7 100644 --- a/lib/linter-registry.ts +++ b/lib/linter-registry.ts @@ -70,8 +70,8 @@ export default class LinterRegistry { if ( (onChange && !this.lintOnChange) || // Lint-on-change mismatch // Ignored by VCS, Glob, or simply not saved anywhere yet - Helpers.isPathIgnored(editor.getPath(), this.ignoreGlob, this.ignoreVCS) || - (!this.lintPreviewTabs && atom.workspace.getActivePane().getPendingItem() === editor) // Ignore Preview tabs + (!this.lintPreviewTabs && atom.workspace.getActivePane().getPendingItem() === editor) || // Ignore Preview tabs + (await Helpers.isPathIgnored(editor.getPath(), this.ignoreGlob, this.ignoreVCS)) ) { return false } diff --git a/lib/main.ts b/lib/main.ts index 27bb90ec..a33e0770 100644 --- a/lib/main.ts +++ b/lib/main.ts @@ -50,7 +50,7 @@ class Linter { this.registryUIInit() this.registryIndieInit() this.registryLintersInit() - showDebug( + await showDebug( // this.registryLinters becomes valid inside registryLintersInit this.registryLinters!.getProviders(), // this.registryIndie becomes valid inside registryIndieInit diff --git a/package.json b/package.json index 091ad5a4..3fee82e7 100644 --- a/package.json +++ b/package.json @@ -69,11 +69,13 @@ "eslint": "^7.17.0", "eslint-config-atomic": "^1.5.1", "eslint-plugin-react": "^7.22.0", + "fs-plus": "^3.1.1", "jasmine-fix": "^1.3.1", "prettier": "^2", "rollup": "^2.35.1", "rollup-plugin-atomic": "^1.6.4", "shx": "^0.3.3", + "temp": "^0.9.4", "typescript": "^4.1.3" }, "package-deps": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d7d2a05e..a52af5d9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,11 +14,13 @@ devDependencies: eslint: 7.18.0 eslint-config-atomic: 1.5.1_eslint@7.18.0 eslint-plugin-react: 7.22.0_eslint@7.18.0 + fs-plus: 3.1.1 jasmine-fix: 1.3.1 prettier: 2.2.1 rollup: 2.38.0 rollup-plugin-atomic: 1.9.0_22ce2c661feed355c62fbac9a707e4f9 shx: 0.3.3 + temp: 0.9.4 typescript: 4.1.3 lockfileVersion: 5.2 packages: @@ -666,6 +668,10 @@ packages: node: '>=8' resolution: integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + /async/1.5.2: + dev: true + resolution: + integrity: sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= /atob/2.1.2: dev: true engines: @@ -1721,6 +1727,15 @@ packages: dev: true resolution: integrity: sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA== + /fs-plus/3.1.1: + dependencies: + async: 1.5.2 + mkdirp: 0.5.5 + rimraf: 2.7.1 + underscore-plus: 1.7.0 + dev: true + resolution: + integrity: sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA== /fs.realpath/1.0.0: dev: true resolution: @@ -2286,6 +2301,13 @@ packages: dev: true resolution: integrity: sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + /mkdirp/0.5.5: + dependencies: + minimist: 1.2.5 + dev: true + hasBin: true + resolution: + integrity: sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== /ms/2.0.0: dev: true resolution: @@ -2677,6 +2699,20 @@ packages: node: '>=0.10.0' resolution: integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + /rimraf/2.6.3: + dependencies: + glob: 7.1.6 + dev: true + hasBin: true + resolution: + integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + /rimraf/2.7.1: + dependencies: + glob: 7.1.6 + dev: true + hasBin: true + resolution: + integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== /rimraf/3.0.2: dependencies: glob: 7.1.6 @@ -3124,6 +3160,15 @@ packages: node: '>=10.0.0' resolution: integrity: sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g== + /temp/0.9.4: + dependencies: + mkdirp: 0.5.5 + rimraf: 2.6.3 + dev: true + engines: + node: '>=6.0.0' + resolution: + integrity: sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA== /terser/5.5.1: dependencies: commander: 2.20.3 @@ -3208,6 +3253,16 @@ packages: hasBin: true resolution: integrity: sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg== + /underscore-plus/1.7.0: + dependencies: + underscore: 1.12.0 + dev: true + resolution: + integrity: sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA== + /underscore/1.12.0: + dev: true + resolution: + integrity: sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ== /uri-js/4.4.1: dependencies: punycode: 2.1.1 @@ -3322,6 +3377,7 @@ specifiers: eslint: ^7.17.0 eslint-config-atomic: ^1.5.1 eslint-plugin-react: ^7.22.0 + fs-plus: ^3.1.1 jasmine-fix: ^1.3.1 lodash: ^4.17.20 minimatch: ^3.0.4 @@ -3329,4 +3385,5 @@ specifiers: rollup: ^2.35.1 rollup-plugin-atomic: ^1.6.4 shx: ^0.3.3 + temp: ^0.9.4 typescript: ^4.1.3 diff --git a/spec/fixtures/git-dir/.gitignore b/spec/fixtures/git-dir/.gitignore new file mode 100644 index 00000000..8ea087a8 --- /dev/null +++ b/spec/fixtures/git-dir/.gitignore @@ -0,0 +1 @@ +ignore.txt diff --git a/spec/fixtures/file.txt b/spec/fixtures/git-dir/file.txt similarity index 100% rename from spec/fixtures/file.txt rename to spec/fixtures/git-dir/file.txt diff --git a/spec/fixtures/git-dir/git.git/HEAD b/spec/fixtures/git-dir/git.git/HEAD new file mode 100644 index 00000000..b870d826 --- /dev/null +++ b/spec/fixtures/git-dir/git.git/HEAD @@ -0,0 +1 @@ +ref: refs/heads/main diff --git a/spec/fixtures/git-dir/git.git/index b/spec/fixtures/git-dir/git.git/index new file mode 100644 index 00000000..6937c818 Binary files /dev/null and b/spec/fixtures/git-dir/git.git/index differ diff --git a/spec/fixtures/git-dir/git.git/objects/23/6eb3ec15b651a9aa9b681c8f1769ec997ffe3f b/spec/fixtures/git-dir/git.git/objects/23/6eb3ec15b651a9aa9b681c8f1769ec997ffe3f new file mode 100644 index 00000000..7565067f Binary files /dev/null and b/spec/fixtures/git-dir/git.git/objects/23/6eb3ec15b651a9aa9b681c8f1769ec997ffe3f differ diff --git a/spec/fixtures/git-dir/git.git/objects/52/c5f46c008e6eaf3dc121df85a81ee0bef44a7e b/spec/fixtures/git-dir/git.git/objects/52/c5f46c008e6eaf3dc121df85a81ee0bef44a7e new file mode 100644 index 00000000..9063b1ed Binary files /dev/null and b/spec/fixtures/git-dir/git.git/objects/52/c5f46c008e6eaf3dc121df85a81ee0bef44a7e differ diff --git a/spec/fixtures/git-dir/git.git/objects/7d/aa0e7af415143fa3def5f9265a108de0c280c4 b/spec/fixtures/git-dir/git.git/objects/7d/aa0e7af415143fa3def5f9265a108de0c280c4 new file mode 100644 index 00000000..14eb7bd0 Binary files /dev/null and b/spec/fixtures/git-dir/git.git/objects/7d/aa0e7af415143fa3def5f9265a108de0c280c4 differ diff --git a/spec/fixtures/git-dir/git.git/objects/8e/a087a8938ad653e37d518b7d95b7145736c678 b/spec/fixtures/git-dir/git.git/objects/8e/a087a8938ad653e37d518b7d95b7145736c678 new file mode 100644 index 00000000..99e6d9ef Binary files /dev/null and b/spec/fixtures/git-dir/git.git/objects/8e/a087a8938ad653e37d518b7d95b7145736c678 differ diff --git a/spec/fixtures/git-dir/git.git/refs/heads/main b/spec/fixtures/git-dir/git.git/refs/heads/main new file mode 100644 index 00000000..bdd506d1 --- /dev/null +++ b/spec/fixtures/git-dir/git.git/refs/heads/main @@ -0,0 +1 @@ +52c5f46c008e6eaf3dc121df85a81ee0bef44a7e diff --git a/spec/fixtures/git-dir/ignore.txt b/spec/fixtures/git-dir/ignore.txt new file mode 100644 index 00000000..7daa0e7a --- /dev/null +++ b/spec/fixtures/git-dir/ignore.txt @@ -0,0 +1 @@ +Beep Boop diff --git a/spec/helpers-spec.js b/spec/helpers-spec.js index 1c6ee37d..2bb2e314 100644 --- a/spec/helpers-spec.js +++ b/spec/helpers-spec.js @@ -1,8 +1,12 @@ /* @flow */ +import fs from 'fs-plus' import { it } from 'jasmine-fix' +import * as path from 'path' +import * as temp from 'temp' + import * as Helpers from '../dist/helpers' -import { getFixturesPath, getMessage } from './common' +import { getMessage } from './common' describe('Helpers', function () { // NOTE: Did *not* add specs for messageKey and messageKeyLegacy on purpose @@ -90,55 +94,71 @@ describe('Helpers', function () { ).toBe(false) }) }) - describe('isPathIgnored', function () { + describe('isPathIgnored: ignoredGlob', function () { function isPathIgnored(a: any, b: any, c: any) { return Helpers.isPathIgnored(a, b || '**/*.min.{js,css}', c || false) } - it('returns false if path does not match glob', function () { - expect(isPathIgnored('a.js')).toBe(false) - expect(isPathIgnored('a.css')).toBe(false) - expect(isPathIgnored('/a.js')).toBe(false) - expect(isPathIgnored('/a.css')).toBe(false) - }) - it('returns false correctly for windows styled paths', function () { - expect(isPathIgnored('a.js')).toBe(false) - expect(isPathIgnored('a.css')).toBe(false) - expect(isPathIgnored('\\a.js')).toBe(false) - expect(isPathIgnored('\\a.css')).toBe(false) - }) - it('returns true if path matches glob', function () { - expect(isPathIgnored('a.min.js')).toBe(true) - expect(isPathIgnored('a.min.css')).toBe(true) - expect(isPathIgnored('/a.min.js')).toBe(true) - expect(isPathIgnored('/a.min.css')).toBe(true) - }) - it('returns true correctly for windows styled paths', function () { - expect(isPathIgnored('a.min.js')).toBe(true) - expect(isPathIgnored('a.min.css')).toBe(true) - expect(isPathIgnored('\\a.min.js')).toBe(true) - expect(isPathIgnored('\\a.min.css')).toBe(true) - }) - it('returns true if the path is ignored by VCS', async function () { - try { - await atom.workspace.open(__filename) - expect(isPathIgnored(getFixturesPath('ignored.txt'), null, true)).toBe(true) - } finally { - atom.workspace.destroyActivePane() - } - }) - it('returns false if the path is not ignored by VCS', async function () { - try { - await atom.workspace.open(__filename) - expect(isPathIgnored(getFixturesPath('file.txt'), null, true)).toBe(false) - } finally { - atom.workspace.destroyActivePane() - } - }) - it('returns true if no path is given', function () { - expect(isPathIgnored(undefined)).toBe(true) - expect(isPathIgnored(null)).toBe(true) - expect(isPathIgnored('')).toBe(true) + it('returns false if path does not match glob', async function () { + expect(await isPathIgnored('a.js')).toBe(false) + expect(await isPathIgnored('a.css')).toBe(false) + expect(await isPathIgnored('/a.js')).toBe(false) + expect(await isPathIgnored('/a.css')).toBe(false) + }) + it('returns false correctly for windows styled paths', async function () { + expect(await isPathIgnored('a.js')).toBe(false) + expect(await isPathIgnored('a.css')).toBe(false) + expect(await isPathIgnored('\\a.js')).toBe(false) + expect(await isPathIgnored('\\a.css')).toBe(false) + }) + it('returns true if path matches glob', async function () { + expect(await isPathIgnored('a.min.js')).toBe(true) + expect(await isPathIgnored('a.min.css')).toBe(true) + expect(await isPathIgnored('/a.min.js')).toBe(true) + expect(await isPathIgnored('/a.min.css')).toBe(true) + }) + it('returns true correctly for windows styled paths', async function () { + expect(await isPathIgnored('a.min.js')).toBe(true) + expect(await isPathIgnored('a.min.css')).toBe(true) + expect(await isPathIgnored('\\a.min.js')).toBe(true) + expect(await isPathIgnored('\\a.min.css')).toBe(true) + }) + it('returns true if no path is given', async function () { + expect(await isPathIgnored(undefined)).toBe(true) + expect(await isPathIgnored(null)).toBe(true) + expect(await isPathIgnored('')).toBe(true) + }) + }) + + describe('isPathIgnored: ignoredVCS', function () { + function isPathIgnored(a: any, b: any, c: any) { + return Helpers.isPathIgnored(a, b || '**/*.min.{js,css}', c || true) + } + + let workingDir + beforeEach(() => { + workingDir = temp.mkdirSync('helpers-spec') + fs.copySync(path.join(__dirname, 'fixtures'), workingDir) + fs.moveSync(path.join(workingDir, 'git-dir', 'git.git'), path.join(workingDir, 'git-dir', '.git')) + + waitsForPromise(() => atom.workspace.open(path.join(workingDir, 'git-dir', 'file.txt'))) + }) + + it('returns true if the path is ignored by VCS', async () => { + atom.project.setPaths([path.join(workingDir, 'git-dir')]) + expect(await isPathIgnored(path.join(workingDir, 'git-dir', 'ignore.txt'))).toBe(true) + }) + it('returns false if the path is not ignored by VCS', async () => { + atom.project.setPaths([path.join(workingDir, 'git-dir')]) + expect(await isPathIgnored(path.join(workingDir, 'git-dir', 'file.txt'))).toBe(false) + }) + it('returns true if the path is ignored by VCS with the git directory in a subfolder', async () => { + atom.project.setPaths([workingDir]) + expect(await isPathIgnored(path.join(workingDir, 'git-dir', 'ignore.txt'))).toBe(true) + }) + it('returns false if the path is not ignored by VCS with the git directory in a subfolder', async () => { + atom.project.setPaths([workingDir]) + expect(await isPathIgnored(path.join(workingDir, 'git-dir', 'file.txt'))).toBe(false) }) })