Skip to content

Commit

Permalink
refactor(upgrade): handle multiple licensed packages, #741 (#743)
Browse files Browse the repository at this point in the history
  • Loading branch information
ViktorSlavov authored Jun 3, 2020
1 parent 2e042a4 commit 3ab63f9
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 84 deletions.
4 changes: 2 additions & 2 deletions packages/igx-templates/IgniteUIForAngularTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
ControlExtraConfiguration, FS_TOKEN, IFileSystem, Template, TemplateDependency, TypeScriptFileUpdate, Util
} from "@igniteui/cli-core";
import * as path from "path";
import { resolvePackage } from "./package-resolve";
import { resolveIgxPackage } from "./package-resolve";

export class IgniteUIForAngularTemplate implements Template {
public components: string[];
Expand Down Expand Up @@ -113,7 +113,7 @@ export class IgniteUIForAngularTemplate implements Template {
config["description"] = this.description;
config["cliVersion"] = Util.version();
config["camelCaseName"] = Util.camelCase(name);
config["igxPackage"] = resolvePackage();
config["igxPackage"] = resolveIgxPackage();

/** 'nameMerged' is never used igx templates, removed */
return config;
Expand Down
36 changes: 14 additions & 22 deletions packages/igx-templates/Update.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { App, IFileSystem, PackageManager, ProjectConfig, Util } from "@igniteui/cli-core";
import * as path from "path";
import * as pkgResolve from "./package-resolve";
import { updateWorkspace } from "./Update";

Expand All @@ -19,21 +18,12 @@ describe("updateWorkspace - Unit tests", () => {
spyOn(ProjectConfig, "getConfig").and.returnValue({});
});
it("Should fail if current used package is registry package", async () => {
spyOn(pkgResolve, "resolvePackage").and.returnValue(pkgResolve.FEED_PACKAGE);
spyOn(pkgResolve, "getUpgradeablePackages").and.returnValue([]);
expect(await updateWorkspace("")).toEqual(false);
});

it("Should fail if '@infragistics' node modules are installed", async () => {
spyOn(pkgResolve, "resolvePackage").and.returnValue(pkgResolve.NPM_PACKAGE);
(fsSpy.directoryExists as jasmine.Spy).and.returnValue(true);
spyOn(Util, "log");
expect(await updateWorkspace("root")).toEqual(false);
expect(fsSpy.directoryExists).toHaveBeenCalledWith(path.join("mockDir", "root", "node_modules", "@infragistics"));
expect(Util.log).toHaveBeenCalledWith("@infragistics module already exists. Nothing to do here.");
});

it("Should fail if no packages.json is found", async () => {
spyOn(pkgResolve, "resolvePackage").and.returnValue(pkgResolve.NPM_PACKAGE);
spyOn(pkgResolve, "getUpgradeablePackages").and.returnValue([pkgResolve.UPGRADEABLE_PACKAGES[0]]);
(fsSpy.directoryExists as jasmine.Spy).and.returnValue(false);
(fsSpy.readFile as jasmine.Spy).and.returnValue("");
spyOn(Util, "log");
Expand All @@ -45,7 +35,7 @@ describe("updateWorkspace - Unit tests", () => {
const mockJSONInput = {
someName: "testValue"
};
spyOn(pkgResolve, "resolvePackage").and.returnValue(pkgResolve.NPM_PACKAGE);
spyOn(pkgResolve, "getUpgradeablePackages").and.returnValue([pkgResolve.UPGRADEABLE_PACKAGES[0]]);
(fsSpy.directoryExists as jasmine.Spy).and.returnValue(false);
(fsSpy.readFile as jasmine.Spy).and.returnValue(JSON.stringify(mockJSONInput, null, 4));
spyOn(PackageManager, "ensureRegistryUser").and.returnValue(false);
Expand All @@ -62,36 +52,38 @@ describe("updateWorkspace - Unit tests", () => {
"some-package": "^0.0.0"
}
};
(fsSpy.fileExists as jasmine.Spy).and.returnValue(false);
(fsSpy.fileExists as jasmine.Spy).and.returnValue(true);
(fsSpy.readFile as jasmine.Spy).and.callFake((filePath: string) => {
if (filePath.indexOf("package.json") > -1) {
return JSON.stringify(mockPackageJSON);
}
if (filePath === "angular.json") {
if (filePath.indexOf("angular.json") > -1) {
return JSON.stringify({
projects: {}
});
}
});
spyOn(PackageManager, "ensureRegistryUser").and.returnValue(true);
spyOn(Util, "log");
expect(await updateWorkspace("")).toEqual(false);
expect(fsSpy.writeFile).toHaveBeenCalledWith("package.json", JSON.stringify({
expect(await updateWorkspace("")).toEqual(true);
expect(fsSpy.writeFile).toHaveBeenCalledWith("package.json", Util.formatPackageJson({
dependencies: {
"@alphabetically-sorted-scope/package": "^0.0.0",
"@infragistics/igniteui-angular": "^9.1.0",
"@infragistics/igniteui-dockmanager": "^1.0.0",
"alphabetically-second-package": "^0.0.0",
"some-package": "^0.0.0"
}
}, null, 2));
}));
expect(fsSpy.writeFile).toHaveBeenCalledTimes(1);
});

it("Should update import paths in files correctly", async () => {
const mockPackageJSON = {
dependencies: {
"some-package": "^0.0.0",
"igniteui-angular": "^9.1.0"
"igniteui-angular": "^9.1.0",
"igniteui-dockmanager": "^1.0.0"
}
};
const mockFileArray: MockFile[] = [{
Expand Down Expand Up @@ -179,8 +171,8 @@ import { dockManagerLoader } from '@infragistics/igniteui-dockmanager/loader';
export class HomeComponent {
title = 'igniteui-angular example';
}`}];
(fsSpy.glob as jasmine.Spy).and.returnValue(
["src/home.component.ts", "src/home.component.scss", "src/app.module.ts"]);
(fsSpy.glob as jasmine.Spy).and.returnValues(
["src/home.component.ts", "src/app.module.ts"], ["src/home.component.scss"], [], []);
(fsSpy.readFile as jasmine.Spy).and.callFake((filePath: string) => {
if (filePath.indexOf("package.json") > -1) {
return JSON.stringify(mockPackageJSON);
Expand All @@ -192,7 +184,7 @@ title = 'igniteui-angular example';
spyOn(PackageManager, "ensureRegistryUser").and.returnValue(true);
expect(await updateWorkspace("")).toEqual(true);
for (const fileEntry of mockFileArray) {
expect(fsSpy.writeFile).toHaveBeenCalledWith(fileEntry.path, fileEntry.expected);
expect((fsSpy.writeFile as jasmine.Spy)).toHaveBeenCalledWith(fileEntry.path, fileEntry.expected);
}
expect(fsSpy.glob).toHaveBeenCalledTimes(4);
});
Expand Down
91 changes: 41 additions & 50 deletions packages/igx-templates/Update.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
import { App, FS_TOKEN, IFileSystem, PackageManager, ProjectConfig, Util } from "@igniteui/cli-core";
import * as path from "path";
import { FEED_DOCK_MANAGER, FEED_PACKAGE, NPM_DOCK_MANAGER, NPM_PACKAGE, resolvePackage } from "./package-resolve";
import { getUpgradeablePackages, PackageDefinition } from "./package-resolve";

const styleExtension = ["css", "scss", "sass"];
enum RegularExpressionType {
STYLE,
LOGIC
}

// tslint:disable: object-literal-sort-keys
const packages: { [key: string]: { trial: string, licensed: string, styleExp: string, logicExp: string } } = {
base: {
trial: NPM_PACKAGE,
licensed: FEED_PACKAGE,
styleExp: createExpression(RegularExpressionType.STYLE, NPM_PACKAGE),
logicExp: createExpression(RegularExpressionType.LOGIC, NPM_PACKAGE)
},
dockManager: {
trial: NPM_DOCK_MANAGER,
licensed: FEED_DOCK_MANAGER,
styleExp: createExpression(RegularExpressionType.STYLE, NPM_DOCK_MANAGER),
logicExp: createExpression(RegularExpressionType.LOGIC, NPM_DOCK_MANAGER)
}
};

function createExpression(expressionType: RegularExpressionType, packageName: string): string {
if (expressionType === RegularExpressionType.LOGIC) {
return String.raw`(from ["'])${packageName}(?<submodules>\/.*?)?(["'])`;
Expand All @@ -33,35 +17,29 @@ function createExpression(expressionType: RegularExpressionType, packageName: st
}

export async function updateWorkspace(rootPath: string): Promise<boolean> {
if (resolvePackage() === FEED_PACKAGE) {
const fs: IFileSystem = App.container.get(FS_TOKEN);
const upgradeable = getUpgradeablePackages();
if (!upgradeable.length) {
// log "no change needed"
return false;
}
const fs: IFileSystem = App.container.get(FS_TOKEN);

const packageJsonPath = path.join(rootPath, "package.json");
const fileString = fs.readFile(packageJsonPath);
if (fs.directoryExists(path.join(App.workDir, rootPath, "node_modules", "@infragistics"))) {
Util.log("@infragistics module already exists. Nothing to do here.");
return false;
}

// check for registry user in npm
const config = ProjectConfig.getConfig();
if (fileString) {
const pkgJSON = JSON.parse(fileString);
const errorMsg = "Something went wrong, " +
"please follow the steps in this guide: https://www.infragistics.com/products/ignite-ui-angular/angular/components/general/ignite-ui-licensing.html";
if (PackageManager.ensureRegistryUser(config, errorMsg)) {
updatePackageJSON(NPM_PACKAGE, FEED_PACKAGE, pkgJSON);
updatePackageJSON(NPM_DOCK_MANAGER, FEED_DOCK_MANAGER, pkgJSON);
fs.writeFile(packageJsonPath, JSON.stringify(pkgJSON, null, 2));
} else {
return false;
}
} else {
if (!fileString) {
Util.log("Package.json not found!");
return false;
}
const pkgJSON = JSON.parse(fileString);

const errorMsg = "Something went wrong, " +
"please follow the steps in this guide: https://www.infragistics.com/products/ignite-ui-angular/angular/components/general/ignite-ui-licensing.html";
if (!PackageManager.ensureRegistryUser(config, errorMsg)) {
return false;
}

// get all workspace roots
const workspaces = [];
Expand Down Expand Up @@ -90,9 +68,11 @@ export async function updateWorkspace(rootPath: string): Promise<boolean> {
}
}
styleFiles.push(workspacePath);

updateFileImports(logicFiles, styleFiles, fs);

for (const packageDef of upgradeable) {
updatePackageJSON(packageDef.trial, packageDef.licensed, pkgJSON);
}
fs.writeFile(packageJsonPath, Util.formatPackageJson(pkgJSON));
updateFileImports(logicFiles, styleFiles, upgradeable, fs);
return true;
}

Expand All @@ -108,24 +88,39 @@ function updateFileContent(fileContent: string, regexString: string, replaceWith
function updateFileImports(
logicFiles: string[],
styleFiles: string[],
packageDefs: PackageDefinition[],
fs: IFileSystem
): void {

for (const file of logicFiles) {
let fileContent = fs.readFile(file);
// tslint:disable-next-line: forin
for (const key in packages) {
fileContent = updateFileContent(fileContent, packages[key].logicExp, packages[key].licensed);
let fileChange = false;
for (const packageDef of packageDefs) {
if (fileContent.includes(packageDef.trial)) {
const newContent = updateFileContent(fileContent,
createExpression(RegularExpressionType.LOGIC, packageDef.trial), packageDef.licensed);
fileChange = fileContent !== newContent;
fileContent = newContent;
}
}
if (fileChange) {
fs.writeFile(file, fileContent);
}
fs.writeFile(file, fileContent);
}
for (const file of styleFiles) {
let fileContent = fs.readFile(file);
// tslint:disable-next-line: forin
for (const key in packages) {
fileContent = updateFileContent(fileContent, packages[key].styleExp, packages[key].licensed);
let fileChange = false;
for (const packageDef of packageDefs) {
if (fileContent.includes(packageDef.trial)) {
const newContent = updateFileContent(fileContent,
createExpression(RegularExpressionType.STYLE, packageDef.trial), packageDef.licensed);
fileChange = fileContent !== newContent;
fileContent = newContent;
}
}
if (fileChange) {
fs.writeFile(file, fileContent);
}
fs.writeFile(file, fileContent);
}
}

Expand All @@ -139,8 +134,4 @@ function updatePackageJSON(
}
pkgJSON.dependencies[replaceWith] = pkgJSON.dependencies[initName];
delete pkgJSON.dependencies[initName];
pkgJSON.dependencies =
Object.keys(pkgJSON.dependencies)
.sort()
.reduce((result, key) => (result[key] = pkgJSON.dependencies[key]) && result, {});
}
8 changes: 4 additions & 4 deletions packages/igx-templates/package-resolve.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { App, FS_TOKEN, IFileSystem } from "@igniteui/cli-core";
import { FEED_PACKAGE, NPM_PACKAGE, resolvePackage } from "./package-resolve";
import { FEED_PACKAGE, NPM_PACKAGE, resolveIgxPackage } from "./package-resolve";

class MockFileSystem implements IFileSystem {
public fileExists(filePath: string): boolean {
Expand All @@ -25,7 +25,7 @@ describe("cli-config schematic", () => {
spyOn(mockFs, "fileExists").and.returnValue(false);
App.container.set(FS_TOKEN, mockFs);

const result = resolvePackage();
const result = resolveIgxPackage();
expect(result).toEqual(NPM_PACKAGE);
expect(mockFs.fileExists).toHaveBeenCalledWith("./package.json");
});
Expand All @@ -36,7 +36,7 @@ describe("cli-config schematic", () => {
spyOn(mockFs, "readFile").and.returnValue(`{ "dependencies": { "${NPM_PACKAGE}": "*" } }`);
App.container.set(FS_TOKEN, mockFs);

const result = resolvePackage();
const result = resolveIgxPackage();
expect(result).toEqual(NPM_PACKAGE);
expect(mockFs.fileExists).toHaveBeenCalledWith("./package.json");
expect(mockFs.readFile).toHaveBeenCalledWith("./package.json");
Expand All @@ -48,7 +48,7 @@ describe("cli-config schematic", () => {
spyOn(mockFs, "readFile").and.returnValue(`{ "dependencies": { "${FEED_PACKAGE}": "*" } }`);
App.container.set(FS_TOKEN, mockFs);

const result = resolvePackage();
const result = resolveIgxPackage();
expect(result).toEqual(FEED_PACKAGE);
expect(mockFs.fileExists).toHaveBeenCalledWith("./package.json");
expect(mockFs.readFile).toHaveBeenCalledWith("./package.json");
Expand Down
35 changes: 34 additions & 1 deletion packages/igx-templates/package-resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,24 @@ export const FEED_PACKAGE = "@infragistics/igniteui-angular";
export const NPM_DOCK_MANAGER = "igniteui-dockmanager";
export const FEED_DOCK_MANAGER = "@infragistics/igniteui-dockmanager";

export function resolvePackage() {
export interface PackageDefinition {
trial: string;
licensed: string;
}

// packages that have both a trial AND licensed definition
export const UPGRADEABLE_PACKAGES: PackageDefinition[] = [
{
trial: NPM_PACKAGE,
licensed: FEED_PACKAGE
},
{
trial: NPM_DOCK_MANAGER,
licensed: FEED_DOCK_MANAGER
}
];

export function resolveIgxPackage() {
const fs = App.container.get<IFileSystem>(FS_TOKEN);

// read project package JSON
Expand All @@ -19,3 +36,19 @@ export function resolvePackage() {

return NPM_PACKAGE;
}

export function getUpgradeablePackages(): PackageDefinition[] {
const fs = App.container.get<IFileSystem>(FS_TOKEN);
const upgradeable: PackageDefinition[] = [];

if (fs.fileExists("./package.json")) {
const packageJson = JSON.parse(fs.readFile("./package.json"));
const dependencies = packageJson["dependencies"];
for (const packageEntry of UPGRADEABLE_PACKAGES) {
if (dependencies[packageEntry.trial]) {
upgradeable.push(packageEntry);
}
}
}
return upgradeable;
}
4 changes: 2 additions & 2 deletions packages/ng-schematics/src/cli-config/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DependencyNotFoundException } from "@angular-devkit/core";
import { yellow } from "@angular-devkit/core/src/terminal";
import { chain, FileDoesNotExistException, Rule, Tree } from "@angular-devkit/schematics";
import { resolvePackage } from "@igniteui/angular-templates";
import { resolveIgxPackage } from "@igniteui/angular-templates";
import { addTypography, TypeScriptFileUpdate } from "@igniteui/cli-core";
import { createCliConfig } from "../utils/cli-config";
import { setVirtual } from "../utils/NgFileSystem";
Expand Down Expand Up @@ -33,7 +33,7 @@ function getDependencyVersion(pkg: string, tree: Tree): string {

function displayVersionMismatch(): Rule {
return (tree: Tree) => {
const igxPackage = resolvePackage();
const igxPackage = resolveIgxPackage();
const pkgJson = JSON.parse(tree.read(`/node_modules/${igxPackage}/package.json`)!.toString());
const ngKey = "@angular/core";
const ngCommonKey = "@angular/common";
Expand Down
6 changes: 3 additions & 3 deletions packages/ng-schematics/src/utils/theme-import.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SchematicsException } from "@angular-devkit/schematics";
import { Tree } from "@angular-devkit/schematics/src/tree/interface";
import { resolvePackage } from "@igniteui/angular-templates";
import { resolveIgxPackage } from "@igniteui/angular-templates";
import { getWorkspace } from "@schematics/angular/utility/config";
import { ProjectType, WorkspaceProject, WorkspaceSchema } from "@schematics/angular/utility/workspace-models";
import * as path from "path";
Expand Down Expand Up @@ -39,7 +39,7 @@ export function addFontsToIndexHtml(tree: Tree) {
}

function importDefaultThemeSass(tree: Tree, ext: string): Tree {
const igxPackage = resolvePackage();
const igxPackage = resolveIgxPackage();
const sassImports =
`
@import "~${igxPackage}/lib/core/styles/themes/index";
Expand Down Expand Up @@ -104,7 +104,7 @@ export function getDefaultProjectBuildOptions(tree: Tree) {
}

function importDefaultThemeToAngularWorkspace(workspace: WorkspaceSchema, key: string) {
const igxPackage = resolvePackage();
const igxPackage = resolveIgxPackage();
const cssImport = `node_modules/${igxPackage}/styles/igniteui-angular.css`;
const projectName = workspace.defaultProject;
if (projectName) {
Expand Down

0 comments on commit 3ab63f9

Please sign in to comment.