Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions packages/cli/lib/commands/upgrade.ts
Original file line number Diff line number Diff line change
@@ -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<string, string> = {
angular: "igx-ts",
react: "igr-ts",
webcomponents: "igc-ts"
};
Copy link
Copy Markdown
Member

@damyanpetev damyanpetev May 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth to add default project type per framework (bit out of scope), even though those are currently singular IIRC and templateManager.getProjectLibrary will return the first if type is not supplied, so this can possibly even be dropped. Need to check tho.


const command: UpgradeCommandType = {
command: "upgrade-packages",
aliases: ["upgrade"],
Expand All @@ -25,8 +32,23 @@ const command: UpgradeCommandType = {
},
async upgrade(argv: ArgumentsCamelCase<PositionalArgs>) {
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.warn("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;
Comment on lines 34 to +44
}
framework = detected;
}

if (!projectType) {
projectType = FRAMEWORK_PROJECT_TYPE_MAP[framework.toLowerCase()] || "";
}

switch (framework.toLowerCase()) {
case "jquery":
Expand All @@ -39,7 +61,7 @@ const command: UpgradeCommandType = {
const templateManager = App.container.get<BaseTemplateManager>(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 {
Comment on lines 62 to 67
Expand Down
52 changes: 52 additions & 0 deletions spec/unit/upgrade-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -144,4 +145,55 @@ 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");

Comment on lines +149 to +153
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<ProjectLibrary> = {
projectIds: ["default-project"],
getProject: jasmine.createSpy().and.returnValue(mockProjTemplate),
hasProject: jasmine.createSpy().and.returnValue(false)
};

const mockTemplateManager: Partial<BaseTemplateManager> = { 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);

spyOn(Util, "warn");
await upgradeCmd.handler({ _: ["upgrade"], $0: "upgrade" });
expect(Util.warn).toHaveBeenCalledWith(
jasmine.stringMatching(/Unable to determine the project framework/), "yellow"
);
});
});
Loading