diff --git a/.eslintrc.js b/.eslintrc.js index 3d77b69..0eaca9f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,7 +6,7 @@ module.exports = { }, extends: ["eslint:recommended", "prettier"], parserOptions: { - ecmaVersion: 2017 + ecmaVersion: 2018 }, plugins: ["jest"], rules: { diff --git a/.gitignore b/.gitignore index debc521..cd76a6f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ coverage/ .vscode +.idea/ diff --git a/__tests__/fileSet.test.js b/__tests__/fileSet.test.js index 6b22f22..2720df1 100644 --- a/__tests__/fileSet.test.js +++ b/__tests__/fileSet.test.js @@ -178,6 +178,27 @@ describe("createFileSet", () => { "bar.js": {} }); }); + + it("should unify windows- and posix paths into posix paths", () => { + const result = createFileSet( + [ + { + filePath: "\\absolute\\path\\windows\\foo.js", + messages: [] + }, + { + filePath: "/absolute/path/posix/bar.js", + messages: [] + } + ], + [] + ); + + expect(result).toEqual({ + "windows/foo.js": {}, + "posix/bar.js": {} + }); + }); }); describe("cleanUpDeletedFilesInFileSet", () => { diff --git a/__tests__/integration/engine/run.test.js b/__tests__/integration/engine/run.test.js index d694773..f5ec2dd 100644 --- a/__tests__/integration/engine/run.test.js +++ b/__tests__/integration/engine/run.test.js @@ -134,6 +134,20 @@ describe("engine.run", () => { }) ); + it( + "should convert windows- to posix paths when reading a record", + setup("windows-paths-in-record", ({ fixturePath }) => { + const { run } = require("../../../lib/engine"); + const { results } = run({}, ["."]); + expect(results).toHaveLength(0); + + const rewrittenRecord = readRecord(fixturePath); + expect(rewrittenRecord.files).toEqual({ + "src/main.js": { "no-console": 1 } + }); + }) + ); + it( "ignores eslint rules not listed in config", setup("no-rules", () => { diff --git a/__tests__/integration/fixtures/windows-paths-in-record/.eslintrc.js b/__tests__/integration/fixtures/windows-paths-in-record/.eslintrc.js new file mode 100644 index 0000000..cadf14e --- /dev/null +++ b/__tests__/integration/fixtures/windows-paths-in-record/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + rules: { + "no-console": "warn" + } +}; diff --git a/__tests__/integration/fixtures/windows-paths-in-record/.esplint.rec.json b/__tests__/integration/fixtures/windows-paths-in-record/.esplint.rec.json new file mode 100644 index 0000000..685fedd --- /dev/null +++ b/__tests__/integration/fixtures/windows-paths-in-record/.esplint.rec.json @@ -0,0 +1,9 @@ +{ + "recordVersion": 1, + "configHash": "773a8b36f5d74ada1b0144c983a6d725c71c9413", + "files": { + "src\\main.js": { + "no-console": 1 + } + } +} diff --git a/__tests__/integration/fixtures/windows-paths-in-record/.esplintrc.js b/__tests__/integration/fixtures/windows-paths-in-record/.esplintrc.js new file mode 100644 index 0000000..6727cec --- /dev/null +++ b/__tests__/integration/fixtures/windows-paths-in-record/.esplintrc.js @@ -0,0 +1,4 @@ +module.exports = { + surfaceArea: ["."], + rules: ["no-console"] +}; diff --git a/__tests__/integration/fixtures/windows-paths-in-record/src/main.js b/__tests__/integration/fixtures/windows-paths-in-record/src/main.js new file mode 100644 index 0000000..f741f0b --- /dev/null +++ b/__tests__/integration/fixtures/windows-paths-in-record/src/main.js @@ -0,0 +1 @@ +console.log("this does nothing"); diff --git a/__tests__/pathUtils.test.js b/__tests__/pathUtils.test.js new file mode 100644 index 0000000..323b219 --- /dev/null +++ b/__tests__/pathUtils.test.js @@ -0,0 +1,31 @@ +const { toPosixPath, toSystemPath, toWinPath } = require("../lib/pathUtils"); +const helpers = require("../lib/helpers"); + +describe("toPosixPath", function() { + it("should convert windows to posix paths", () => { + expect(toPosixPath("\\windows\\path")).toEqual("/windows/path"); + }); + it("should not alter posix paths", () => { + expect(toPosixPath("/posix/path")).toEqual("/posix/path"); + }); +}); + +describe("toWinPath", function() { + it("should convert posix to windows path", () => { + expect(toWinPath("/posix/path")).toEqual("\\posix\\path"); + }); + it("not alter windows path", () => { + expect(toWinPath("\\windows\\path")).toEqual("\\windows\\path"); + }); +}); + +describe("toSystemPath", () => { + it("should convert posix to windows on windows", () => { + jest.spyOn(helpers, "isPosix").mockImplementation(() => false); + expect(toSystemPath("/posix/path")).toEqual("\\posix\\path"); + }); + it("should convert windows to posix on posix", () => { + jest.spyOn(helpers, "isPosix").mockImplementation(() => true); + expect(toSystemPath("\\windows\\path")).toEqual("/windows/path"); + }); +}); diff --git a/__tests__/record.test.js b/__tests__/record.test.js index d49b6c6..0187c5b 100644 --- a/__tests__/record.test.js +++ b/__tests__/record.test.js @@ -1,4 +1,4 @@ -const { createRecord } = require("../lib/record"); +const { createRecord, unifyFilePaths } = require("../lib/record"); jest.mock("../package.json", () => ({ version: "1.0.0" })); describe("createRecord", () => { @@ -28,3 +28,34 @@ describe("createRecord", () => { expect(Object.keys(files)).toEqual(["a/b/c", "b/b/c", "z/a/c"]); }); }); + +describe("unifyFilePaths", () => { + it("converts windows paths to posix", () => { + const record = { + hash: "aabbcc", + files: { + "\\windows\\path.js": {}, + "\\another\\windows\\path.js": {} + } + }; + const unifiedRecord = unifyFilePaths(record); + expect(unifiedRecord).toEqual({ + hash: "aabbcc", + files: { + "/windows/path.js": {}, + "/another/windows/path.js": {} + } + }); + }); + it("keeps posix paths as posix", () => { + const record = { + hash: "aabbcc", + files: { + "/windows/path.js": {}, + "/another/windows/path.js": {} + } + }; + const unifiedRecord = unifyFilePaths(record); + expect(unifiedRecord).toEqual(record); + }); +}); diff --git a/lib/fileSet.js b/lib/fileSet.js index 3c1f013..c35605a 100644 --- a/lib/fileSet.js +++ b/lib/fileSet.js @@ -1,13 +1,16 @@ const path = require("path"); const fs = require("fs"); const chalk = require("chalk"); +const { toPosixPath, toSystemPath } = require("./pathUtils"); function createFileSet(results, trackedRules, getWarnings) { const fileSet = {}; const trackedRuleSet = new Set(trackedRules); results.forEach(({ messages, filePath }) => { - const relativePath = path.relative(process.cwd(), filePath); + const relativePath = toPosixPath( + path.relative(process.cwd(), toSystemPath(filePath)) + ); const rules = {}; if (getWarnings) { diff --git a/lib/helpers.js b/lib/helpers.js new file mode 100644 index 0000000..80d8158 --- /dev/null +++ b/lib/helpers.js @@ -0,0 +1,9 @@ +const path = require("path"); + +function isPosix() { + return path.sep === path.posix.sep; +} + +module.exports = { + isPosix +}; diff --git a/lib/pathUtils.js b/lib/pathUtils.js new file mode 100644 index 0000000..1676d82 --- /dev/null +++ b/lib/pathUtils.js @@ -0,0 +1,24 @@ +const path = require("path"); +const helpers = require("./helpers"); + +function toPosixPath(filePath) { + return filePath.split(path.win32.sep).join(path.posix.sep); +} + +function toWinPath(filePath) { + return filePath.split(path.posix.sep).join(path.win32.sep); +} + +function toSystemPath(filePath) { + if (helpers.isPosix()) { + return toPosixPath(filePath); + } else { + return toWinPath(filePath); + } +} + +module.exports = { + toPosixPath, + toWinPath, + toSystemPath +}; diff --git a/lib/record.js b/lib/record.js index f7e8c27..b3f2306 100644 --- a/lib/record.js +++ b/lib/record.js @@ -9,6 +9,7 @@ const semver = require("semver"); const { hasGitConflict, resolveGitConflict } = require("./gitConflict"); const EsplintError = require("./EsplintError"); const git = require("simple-git/promise")(); +const { toPosixPath } = require("./pathUtils"); function getRecordPath() { const packageDir = pkgDir.sync(); @@ -38,6 +39,23 @@ function createRecord({ files, config }) { }; } +function unifyFilePaths(record) { + if (record === null) { + return record; + } + + return { + ...record, + files: Object.entries(record.files).reduce( + (result, [filePath, warnings]) => { + result[toPosixPath(filePath)] = warnings; + return result; + }, + {} + ) + }; +} + function getRecord(config) { const { overwrite } = config; @@ -47,7 +65,7 @@ function getRecord(config) { } const configHash = getConfigHash(config); - const record = readRecord(); + const record = unifyFilePaths(readRecord()); if (record === null) { return {}; @@ -165,5 +183,6 @@ module.exports = { getRecord, writeRecord, readRecord, - stageRecord + stageRecord, + unifyFilePaths };