Skip to content

Commit

Permalink
fix(schematics): add module import to root module
Browse files Browse the repository at this point in the history
fix #3638
  • Loading branch information
aitboudad committed May 6, 2023
1 parent 7d02313 commit ea959be
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 34 deletions.
3 changes: 2 additions & 1 deletion src/schematics/src/ng-add/index.ts
@@ -1,6 +1,7 @@
import { chain, noop, Rule, Tree, SchematicContext } from '@angular-devkit/schematics';
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
import { findModuleFromOptions, addModuleImportToModule } from '../../utils/ast';
import { findModuleFromOptions } from '../../utils/ast';
import { addModuleImportToModule } from '@angular/cdk/schematics';
import { angularVersion, ngxFormlyVersion } from '../../utils/lib-versions';
import { addPackageToPackageJson } from '../../utils/package';
import { Schema } from './schema';
Expand Down
4 changes: 3 additions & 1 deletion src/schematics/src/ng-add/schema.ts
@@ -1,4 +1,6 @@
export interface Schema {
import {Schema as ComponentSchema} from '@schematics/angular/component/schema';

export interface Schema extends ComponentSchema {
/**
* Do not add @ngx-formly dependencies to package.json (e.g., --skipPackageJson)
*/
Expand Down
72 changes: 40 additions & 32 deletions src/schematics/utils/ast.ts
@@ -1,13 +1,19 @@
/**
* https://github.com/angular/components/tree/main/src/cdk/schematics
*/

import { normalize } from '@angular-devkit/core';
import { SchematicsException, Tree } from '@angular-devkit/schematics';
import * as ts from 'typescript';
import { addImportToModule } from '@schematics/angular/utility/ast-utils';
import { InsertChange } from '@schematics/angular/utility/change';
import { getAppModulePath } from '@schematics/angular/utility/ng-ast-utils';
import { findModuleFromOptions as internalFindModule } from '@schematics/angular/utility/find-module';
import { WorkspaceProject } from '@schematics/angular/utility/workspace-models';
import { getWorkspace } from '@schematics/angular/utility/workspace';

import {Schema as ComponentOptions} from '@schematics/angular/component/schema';
import {Path} from '@angular-devkit/core';
import {JsonValue} from '@angular-devkit/core';
import {ProjectDefinition} from '@angular-devkit/core/src/workspace';
import { addModuleImportToModule } from '@angular/cdk/schematics';
/** Reads file given path and returns TypeScript source file. */
export function parseSourceFile(host: Tree, path: string): ts.SourceFile {
const buffer = host.read(path);
Expand All @@ -18,37 +24,11 @@ export function parseSourceFile(host: Tree, path: string): ts.SourceFile {
}

/** Import and add module to root app module. */
export function addModuleImportToRootModule(host: Tree, moduleName: string, src: string, project: WorkspaceProject) {
const modulePath = getAppModulePath(host, project.architect.build.options.main);
export function addModuleImportToRootModule(host: Tree, moduleName: string, src: string, project: ProjectDefinition) {
const modulePath = getAppModulePath(host, getProjectMainFile(project));
addModuleImportToModule(host, modulePath, moduleName, src);
}

/**
* Import and add module to specific module path.
* @param host the tree we are updating
* @param modulePath src location of the module to import
* @param moduleName name of module to import
* @param src src location to import
*/
export function addModuleImportToModule(host: Tree, modulePath: string, moduleName: string, src: string) {
const moduleSource = parseSourceFile(host, modulePath);

if (!moduleSource) {
throw new SchematicsException(`Module not found: ${modulePath}`);
}

const changes = addImportToModule(moduleSource, modulePath, moduleName, src);
const recorder = host.beginUpdate(modulePath);

changes.forEach((change) => {
if (change instanceof InsertChange) {
recorder.insertLeft(change.pos, change.toAdd);
}
});

host.commitUpdate(recorder);
}

/** Gets the app index.html file */
export function getIndexHtmlPath(host: Tree, project: WorkspaceProject): string {
const buildTarget = project.architect.build.options;
Expand Down Expand Up @@ -87,7 +67,7 @@ export function getStylesPath(host: Tree, project: WorkspaceProject): string {
/** Wraps the internal find module from options with undefined path handling */
export async function findModuleFromOptions(
host: Tree,
options: any,
options: ComponentOptions,
): Promise<string | undefined> {
const workspace = await getWorkspace(host);

Expand All @@ -103,3 +83,31 @@ export async function findModuleFromOptions(

return internalFindModule(host, options);
}

export function getProjectMainFile(project: ProjectDefinition): Path {
const buildOptions = getProjectTargetOptions(project, 'build');

if (!buildOptions.main) {
throw new SchematicsException(
`Could not find the project main file inside of the ` +
`workspace config (${project.sourceRoot})`,
);
}

return buildOptions.main as Path;
}

export function getProjectTargetOptions(
project: ProjectDefinition,
buildTarget: string,
): Record<string, JsonValue | undefined> {
const options = project.targets?.get(buildTarget)?.options;

if (!options) {
throw new SchematicsException(
`Cannot determine project target configuration for: ${buildTarget}.`,
);
}

return options;
}

0 comments on commit ea959be

Please sign in to comment.