From 5e7da6086db3db78927e568c877933e519eccc19 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Wed, 21 Feb 2024 16:47:07 -0800 Subject: [PATCH] Fix Windows, test it in CI (#961) --- .changeset/twenty-eyes-matter.md | 8 ++++++++ .gitattributes | 1 + .github/workflows/ci.yml | 9 ++++++++- .../src/get-affected-packages.ts | 6 ++++-- packages/dtslint-runner/src/main.ts | 2 ++ .../eslint-plugin/src/rules/no-bad-reference.ts | 8 ++++---- packages/eslint-plugin/src/util.ts | 1 + packages/eslint-plugin/test/eslint.test.ts | 17 +++++++++++++++-- packages/utils/src/fs.ts | 12 ++++++------ tsconfig.test.json | 12 ++++++++++-- 10 files changed, 59 insertions(+), 17 deletions(-) create mode 100644 .changeset/twenty-eyes-matter.md create mode 100644 .gitattributes diff --git a/.changeset/twenty-eyes-matter.md b/.changeset/twenty-eyes-matter.md new file mode 100644 index 0000000000..08389920cf --- /dev/null +++ b/.changeset/twenty-eyes-matter.md @@ -0,0 +1,8 @@ +--- +"@definitelytyped/definitions-parser": patch +"@definitelytyped/dtslint-runner": patch +"@definitelytyped/eslint-plugin": patch +"@definitelytyped/utils": patch +--- + +Fix compatibility with Windows diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..fa1385d99a --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* -text diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c3d6280d0e..05cdf9bb60 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,14 @@ defaults: jobs: build_and_test: name: build and test - runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + - windows-latest + # - macos-latest # OOMs + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 diff --git a/packages/definitions-parser/src/get-affected-packages.ts b/packages/definitions-parser/src/get-affected-packages.ts index 701c66bc7a..cd8be93663 100644 --- a/packages/definitions-parser/src/get-affected-packages.ts +++ b/packages/definitions-parser/src/get-affected-packages.ts @@ -1,7 +1,8 @@ import { assertDefined, execAndThrowErrors, mapDefined, normalizeSlashes, withoutStart } from "@definitelytyped/utils"; import { AllPackages, PackageId, formatTypingVersion, getDependencyFromFile } from "./packages"; -import { resolve } from "path"; +import { isAbsolute } from "path"; import { satisfies } from "semver"; +import assert from "assert"; export interface PreparePackagesResult { readonly packageNames: Set; readonly dependents: Set; @@ -77,7 +78,8 @@ export async function getAffectedPackagesWorker( dependentOutputs: string[], definitelyTypedPath: string, ): Promise { - const dt = resolve(definitelyTypedPath); + assert(isAbsolute(definitelyTypedPath), "definitelyTypedPath should be absolute"); + const dt = definitelyTypedPath; const changedDirs = mapDefined(changedOutput.split("\n"), getDirectoryName(dt)); const dependentDirs = mapDefined(dependentOutputs.join("\n").split("\n"), getDirectoryName(dt)); const packageNames = new Set([ diff --git a/packages/dtslint-runner/src/main.ts b/packages/dtslint-runner/src/main.ts index ff74d49247..d1ce81ac41 100644 --- a/packages/dtslint-runner/src/main.ts +++ b/packages/dtslint-runner/src/main.ts @@ -9,6 +9,7 @@ import fs from "fs"; import { RunDTSLintOptions } from "./types"; import { prepareAllPackages } from "./prepareAllPackages"; import { prepareAffectedPackages } from "./prepareAffectedPackages"; +import { resolve } from "path"; export async function runDTSLint({ definitelyTypedAcquisition, @@ -36,6 +37,7 @@ export async function runDTSLint({ } else { definitelyTypedPath = definitelyTypedAcquisition.path; } + definitelyTypedPath = resolve(definitelyTypedPath); if (!fs.existsSync(definitelyTypedPath)) { throw new Error(`Path '${definitelyTypedPath}' does not exist.`); diff --git a/packages/eslint-plugin/src/rules/no-bad-reference.ts b/packages/eslint-plugin/src/rules/no-bad-reference.ts index 90ac5e2533..d4dc4ff5bb 100644 --- a/packages/eslint-plugin/src/rules/no-bad-reference.ts +++ b/packages/eslint-plugin/src/rules/no-bad-reference.ts @@ -79,6 +79,7 @@ const rule = createRule({ messageId: "backslashes", loc: tsRangeToESLintLocation(ref.range), }); + continue; } const p = ref.text.startsWith(realNamePlusSlash) @@ -88,8 +89,7 @@ const rule = createRule({ ) : ref.text; - const resolved = path.resolve(containingDirectory, p); - const otherPackage = findTypesPackage(resolved); + const otherPackage = findTypesPackage(path.resolve(containingDirectory, p)); if (otherPackage && otherPackage.dir === typesPackage.dir) { // Perf trick; if a path doesn't have ".." anywhere, then it can't have resolved @@ -105,9 +105,9 @@ const rule = createRule({ continue; } if (part === "..") { - cwd = path.posix.dirname(cwd); + cwd = path.dirname(cwd); } else { - cwd = path.posix.join(cwd, part); + cwd = path.join(cwd, part); } const otherPackage = findTypesPackage(cwd); if (otherPackage && otherPackage.dir === typesPackage.dir) { diff --git a/packages/eslint-plugin/src/util.ts b/packages/eslint-plugin/src/util.ts index cf37f16d34..6297f0899c 100644 --- a/packages/eslint-plugin/src/util.ts +++ b/packages/eslint-plugin/src/util.ts @@ -53,6 +53,7 @@ export function findUp(p: string, fn: (p: string) => T | undefined } export interface TypesPackageInfo { + /** directory containing package json; this is a OS-specific path */ dir: string; /** package.json with name="@types/foo__bar-baz" */ packageJson: PackageJSON; diff --git a/packages/eslint-plugin/test/eslint.test.ts b/packages/eslint-plugin/test/eslint.test.ts index ec624c4e42..38e725c123 100644 --- a/packages/eslint-plugin/test/eslint.test.ts +++ b/packages/eslint-plugin/test/eslint.test.ts @@ -6,6 +6,7 @@ import { fixtureRoot } from "./util"; import { toMatchFile } from "jest-file-snapshot"; import * as plugin from "../src/index"; import fs from "fs"; +import { normalizeSlashes } from "@definitelytyped/utils"; expect.extend({ toMatchFile }); const snapshotDir = path.join(__dirname, "__file_snapshots__"); @@ -50,11 +51,23 @@ for (const fixture of allFixtures) { const resultText = stripAnsi(formatted).trim() || "No errors"; expect(resultText).not.toContain("Parsing error"); const newOutput = formatResultsWithInlineErrors(results); - expect(resultText + "\n\n" + newOutput).toMatchFile(getLintSnapshotPath(fixture)); + expect(normalizeSnapshot(resultText + "\n\n" + newOutput)).toMatchFile(getLintSnapshotPath(fixture)); }); }); } +function normalizeSnapshot(snapshot: string): string { + return snapshot + .split(/\r?\n/g) + .map((line) => { + if (line.startsWith("types\\")) { + return normalizeSlashes(line); + } + return line; + }) + .join("\n"); +} + function formatResultsWithInlineErrors(results: ESLint.LintResult[]): string { const output: string[] = []; @@ -74,7 +87,7 @@ function formatResultsWithInlineErrors(results: ESLint.LintResult[]): string { const indent = " "; for (const result of results) { - output.push(`==== ${result.filePath} ====`); + output.push(`==== ${normalizeSlashes(result.filePath)} ====`); output.push(""); const sourceText = fs.readFileSync(path.join(fixtureRoot, result.filePath), "utf-8"); diff --git a/packages/utils/src/fs.ts b/packages/utils/src/fs.ts index 4d69779f45..6b8e87ec19 100644 --- a/packages/utils/src/fs.ts +++ b/packages/utils/src/fs.ts @@ -1,12 +1,12 @@ import assert from "assert"; -import { join, relative, resolve, isAbsolute } from "path"; +import systemPath, { posix as posixPath } from "path"; import getCacheDir = require("cachedir"); import { assertDefined } from "./assertions"; import fs from "fs"; import { readFileSync, readJsonSync } from "./io"; /** The directory to read/write suggestsions from */ -export const suggestionsDir = join(getCacheDir("dts"), "suggestions"); +export const suggestionsDir = systemPath.join(getCacheDir("dts"), "suggestions"); /** Convert a path to use "/" instead of "\\" for consistency. (This affects content hash.) */ export function normalizeSlashes(path: string): string { @@ -91,7 +91,7 @@ export class InMemoryFS implements FS { private tryGetEntry(path: string): ReadonlyDir | string | undefined { if (path[0] === "/") { - path = relative(this.rootPrefix, path); + path = posixPath.relative(this.rootPrefix, path); } if (path === "") { return this.curDir; @@ -162,7 +162,7 @@ export class InMemoryFS implements FS { subDir(path: string): FS { assert(path[0] !== "/", "Cannot use absolute paths with InMemoryFS.subDir"); - return new InMemoryFS(this.getDir(path), resolve(this.rootPrefix, path)); + return new InMemoryFS(this.getDir(path), posixPath.join(this.rootPrefix, path)); } debugPath(): string { @@ -179,12 +179,12 @@ export class InMemoryFS implements FS { export class DiskFS implements FS { constructor(private readonly rootPrefix: string) { - assert(isAbsolute(rootPrefix), "DiskFS must use absolute paths"); + assert(systemPath.isAbsolute(rootPrefix), "DiskFS must use absolute paths"); this.rootPrefix = ensureTrailingSlash(rootPrefix); } private getPath(path: string | undefined): string { - return resolve(this.rootPrefix, path ?? ""); + return systemPath.resolve(this.rootPrefix, path ?? ""); } readdir(dirPath?: string): readonly string[] { diff --git a/tsconfig.test.json b/tsconfig.test.json index 4da564fa2f..7d094e189b 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -7,9 +7,17 @@ }, "files": [], "references": [ - { "path": "packages/header-parser/test" }, { "path": "packages/definitions-parser/test" }, + { "path": "packages/dts-critic" }, + { "path": "packages/dts-gen" }, + { "path": "packages/dtslint/test" }, + { "path": "packages/dtslint-runner" }, + { "path": "packages/eslint-plugin/test" }, + { "path": "packages/header-parser/test" }, { "path": "packages/publisher/test" }, - { "path": "packages/utils/test" } + { "path": "packages/retag" }, + { "path": "packages/typescript-packages/test" }, + { "path": "packages/typescript-versions/test" }, + { "path": "packages/utils/test" }, ] }