diff --git a/packages/cli/lib/commands/upgrade.ts b/packages/cli/lib/commands/upgrade.ts index 1a8551b84..e1166156e 100644 --- a/packages/cli/lib/commands/upgrade.ts +++ b/packages/cli/lib/commands/upgrade.ts @@ -1,4 +1,4 @@ -import { GoogleAnalytics, ProjectConfig, Util } from "@igniteui/cli-core"; +import { GoogleAnalytics, ProjectConfig, type ProjectTemplate, Util } from "@igniteui/cli-core"; import { PositionalArgs, UpgradeCommandType } from "./types"; import { ArgumentsCamelCase } from "yargs"; @@ -38,7 +38,7 @@ const command: UpgradeCommandType = { case "webcomponents": if (projectType === "igx-ts" || projectType === "igr-ts" || projectType === "igc-ts") { const projectLibrary = command.templateManager.getProjectLibrary(framework, projectType); - let project; + let project: ProjectTemplate; if (!config.project.projectTemplate || !projectLibrary.hasProject(config.project.projectTemplate)) { // in case project template is missing from the config we provide backward. project = projectLibrary.getProject(projectLibrary.projectIds[0]); diff --git a/packages/core/util/FileSystem.ts b/packages/core/util/FileSystem.ts index 5457b1b17..ddce66d24 100644 --- a/packages/core/util/FileSystem.ts +++ b/packages/core/util/FileSystem.ts @@ -2,7 +2,7 @@ import * as fs from "fs"; import * as glob from "glob"; import * as path from "path"; -import { IFileSystem } from "../types/FileSystem"; +import type { IFileSystem } from "../types/FileSystem"; export class FsFileSystem implements IFileSystem { public fileExists(filePath: string): boolean { @@ -30,7 +30,8 @@ export class FsFileSystem implements IFileSystem { } public glob(dirPath: string, pattern: string): string[] { - return glob.sync(path.join(dirPath, pattern), { nodir: true }) - .map(filePath => filePath.replace(/\\/g, "/")); + // NB!: glob 8+ patterns use `\` as escape only, so ensure posix-style: + const globPattern = path.join(dirPath, pattern).replace(/\\/g, "/"); + return glob.sync(globPattern, { nodir: true }); } } diff --git a/spec/unit/FsFileSystem-spec.ts b/spec/unit/FsFileSystem-spec.ts new file mode 100644 index 000000000..a9c991031 --- /dev/null +++ b/spec/unit/FsFileSystem-spec.ts @@ -0,0 +1,43 @@ +import * as glob from "glob"; +import { FsFileSystem } from "../../packages/core/util/FileSystem"; + +describe("Unit - FsFileSystem", () => { + let fileSystem: FsFileSystem; + + beforeEach(() => { + fileSystem = new FsFileSystem(); + }); + + describe("glob", () => { + it("should pass a forward-slash pattern to glob even when dirPath uses backslashes", () => { + spyOn(glob, "sync").and.returnValue([]); + const windowsDirPath = "C:\\Work\\git\\project\\src"; + fileSystem.glob(windowsDirPath, "**/*.ts"); + expect(glob.sync).toHaveBeenCalledWith( + "C:/Work/git/project/src/**/*.ts", + jasmine.objectContaining({ nodir: true }) + ); + }); + + it("should pass a forward-slash pattern to glob even when pattern contains backslashes", () => { + spyOn(glob, "sync").and.returnValue([]); + fileSystem.glob("C:\\Work\\project", "sub\\**\\*.ts"); + expect(glob.sync).toHaveBeenCalledWith( + "C:/Work/project/sub/**/*.ts", + jasmine.objectContaining({ nodir: true }) + ); + }); + + it("should work correctly with forward-slash paths (non-Windows)", () => { + spyOn(glob, "sync").and.returnValue([ + "/home/user/project/src/app.ts" + ] as any); + const result = fileSystem.glob("/home/user/project", "src/**/*.ts"); + expect(glob.sync).toHaveBeenCalledWith( + "/home/user/project/src/**/*.ts", + jasmine.objectContaining({ nodir: true }) + ); + expect(result).toEqual(["/home/user/project/src/app.ts"]); + }); + }); +});