diff --git a/packages/cli/lib/commands/upgrade.ts b/packages/cli/lib/commands/upgrade.ts index 873b96a2b..4683e2cde 100644 --- a/packages/cli/lib/commands/upgrade.ts +++ b/packages/cli/lib/commands/upgrade.ts @@ -1,7 +1,14 @@ -import { App, BaseTemplateManager, GoogleAnalytics, ProjectConfig, TEMPLATE_MANAGER, type ProjectTemplate, Util } from "@igniteui/cli-core"; +import { App, BaseTemplateManager, detectFrameworkFromPackageJson, GoogleAnalytics, ProjectConfig, TEMPLATE_MANAGER, + type ProjectTemplate, Util } from "@igniteui/cli-core"; import { PositionalArgs, UpgradeCommandType } from "./types"; import { ArgumentsCamelCase } from "yargs"; +const FRAMEWORK_PROJECT_TYPE_MAP: Record = { + angular: "igx-ts", + react: "igr-ts", + webcomponents: "igc-ts" +}; + const command: UpgradeCommandType = { command: "upgrade-packages", aliases: ["upgrade"], @@ -25,8 +32,23 @@ const command: UpgradeCommandType = { }, async upgrade(argv: ArgumentsCamelCase) { const config = ProjectConfig.getConfig(); - const framework = config.project.framework; - const projectType = config.project.projectType; + let framework = config.project?.framework; + let projectType = config.project?.projectType; + + if (!framework) { + const detected = detectFrameworkFromPackageJson(); + if (!detected) { + Util.log("Unable to determine the project framework. " + + "Please ensure you are running this command in a project directory with a package.json file, " + + "or create an ignite-ui-cli.json configuration file.", "yellow"); + return; + } + framework = detected; + } + + if (!projectType) { + projectType = FRAMEWORK_PROJECT_TYPE_MAP[framework.toLowerCase()] || ""; + } switch (framework.toLowerCase()) { case "jquery": @@ -39,7 +61,7 @@ const command: UpgradeCommandType = { const templateManager = App.container.get(TEMPLATE_MANAGER); const projectLibrary = templateManager.getProjectLibrary(framework, projectType); let project: ProjectTemplate; - if (!config.project.projectTemplate || !projectLibrary.hasProject(config.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]); } else { diff --git a/spec/unit/upgrade-spec.ts b/spec/unit/upgrade-spec.ts index 051b7ee15..8b1cc4964 100644 --- a/spec/unit/upgrade-spec.ts +++ b/spec/unit/upgrade-spec.ts @@ -2,6 +2,7 @@ import { App, BaseTemplate, BaseTemplateManager, Config, GoogleAnalytics, PackageManager, ProjectConfig, ProjectLibrary, ProjectTemplate, Template, TEMPLATE_MANAGER, Util } from "@igniteui/cli-core"; +import * as detectFrameworkModule from "../../packages/core/util/detect-framework"; import { default as upgradeCmd } from "../../packages/cli/lib/commands/upgrade"; @@ -144,4 +145,54 @@ describe("Unit - Upgrade command", () => { await upgradeCmd.handler({ _: ["upgrade"], $0: "upgrade" }); expect(Util.log).toHaveBeenCalledTimes(1); }); + + it("Should auto-detect framework from package.json when config has no project", async () => { + const config = {} as Config; + spyOn(ProjectConfig, "getConfig").and.returnValue(config); + spyOn(detectFrameworkModule, "detectFrameworkFromPackageJson").and.returnValue("react"); + + const mockProjTemplate: ProjectTemplate = { + id: "mock", + name: "mock", + description: "mock", + delimiters: { content: { start: "{{", end: "}}" }, path: { start: "[[", end: "]]" } }, + dependencies: [], + framework: "react", + projectType: "igr-ts", + hasExtraConfiguration: false, + isHidden: false, + templatePaths: [], + generateConfig: jasmine.createSpy().and.returnValue({}), + getExtraConfiguration: jasmine.createSpy().and.returnValue([]), + setExtraConfiguration: jasmine.createSpy(), + installModules: jasmine.createSpy(), + upgradeIgniteUIPackages: jasmine.createSpy().and.returnValue(Promise.resolve(true)) + }; + + const mockProjLib: Partial = { + projectIds: ["default-project"], + getProject: jasmine.createSpy().and.returnValue(mockProjTemplate), + hasProject: jasmine.createSpy().and.returnValue(false) + }; + + const mockTemplateManager: Partial = { getProjectLibrary: () => null }; + App.container.set(TEMPLATE_MANAGER, mockTemplateManager); + spyOn(mockTemplateManager, "getProjectLibrary").and.returnValue(mockProjLib as ProjectLibrary); + + await upgradeCmd.handler({ skipInstall: true, _: ["upgrade"], $0: "upgrade" }); + expect(detectFrameworkModule.detectFrameworkFromPackageJson).toHaveBeenCalled(); + expect(mockTemplateManager.getProjectLibrary).toHaveBeenCalledWith("react", "igr-ts"); + expect(mockProjTemplate.upgradeIgniteUIPackages).toHaveBeenCalledWith(process.cwd(), ""); + }); + + it("Should log a message when no framework can be detected", async () => { + const config = {} as Config; + spyOn(ProjectConfig, "getConfig").and.returnValue(config); + spyOn(detectFrameworkModule, "detectFrameworkFromPackageJson").and.returnValue(null); + + await upgradeCmd.handler({ _: ["upgrade"], $0: "upgrade" }); + expect(Util.log).toHaveBeenCalledWith( + jasmine.stringMatching(/Unable to determine the project framework/), "yellow" + ); + }); });