1

I have a custom schematic in which I want to add some files to the standard angular application schematic. I do this by running a mergeWith to add some of my own custom files. A bit later due to some setting, I wish to delete one of my own files. The delete action does not give any errors or warning and if I check the tree afterwards, it appears as if the file has been deleted. However, the file is still stored on the filesystem. I cannot figure out why it does not work. The relevant code below:

This is what is executed when 'ng new' with my collection is ran.

import {
    apply,
    chain,
    empty,
    externalSchematic,
    mergeWith,
    move,
    //noop,
    Rule,
    schematic, SchematicContext,
} from '@angular-devkit/schematics';
import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks';
import { Schema as AngularNgNewSchema, Style } from '@schematics/angular/ng-new/schema';
import { CamcoApplicationSchema } from '../camco-application/schema';
//import { CamcoLibrarySchema } from '../library/schema';
//import { CamcoPortalApplicationSchema } from '../portal-application/schema';
//import { CamcoVisualStudioSchema } from '../visual-studio/schema';
import { CamcoNewSchema } from './schema';

/**
 * This schematic generates a new application.
 * It wraps the Angular ng-new command and modifies the output and configuration to generate a Camco web application.
 *
 * @param options
 */
export default function run(options: CamcoNewSchema): Rule {
    if(options.library && options.portal)
        throw new Error(`Cannot scaffold both a library project and a portal module in the same project. Provide either 'library' or 'portal' as argument.`);
    const angularOptions: AngularNgNewSchema = {
        name: options.name, // Use the supplied name.
        directory: '.', // Generate in the "current" directory, this is because other schematics operate on "." and would otherwise have to traverse the tree.
        version: '9.0.1', // The version of the Angular CLI to set in the project, we use the version used to generate these schematics.
        minimal: true, // Generate absolutely minimal project, no testing, linting, ...
        style: Style.Scss, // Use SCSS for stylesheets
        routing: true, // Scaffold routing
        skipTests: true, // We don't want pesky "spec" files all over
        skipInstall: true, // Do not run "yarn install" since we change the directory of the project after it's generation, yarn would run in the wrong folder.
        skipGit: true, // Do not initialize Git, usually projects are scaffolded *inside* a Git repo, and you don't want them to nest.
    };  
    //let libraryName: string | undefined = options.library || options.portal;
    return chain([
        mergeWith(apply(empty(), [ // Start from an empty file structure
            externalSchematic('@schematics/angular', 'ng-new', angularOptions), // Generate a standard Angular project
            schematic<CamcoApplicationSchema>('camco-application', { name: options.name }, { interactive: true }), // Scaffold Camco boilerplate stuff
            //(libraryName !== undefined ? schematic<CamcoLibrarySchema>('library', { project: options.name, name: libraryName }, { interactive: true }) : noop()), // If a library or portal name was passed, run the library schematic. Otherwise run a noop()
            //(options.portal !== undefined ? schematic<CamcoPortalApplicationSchema>('portal-application', { project: options.name, name: options.portal }, { interactive: true }) : noop()), // If a portal name was passed, run the PortalApplication schematic. Otherwise run a noop()
            //schematic<CamcoVisualStudioSchema>('visual-studio', { name: options.name, type: options['project-type'] }, { interactive: true }), // Generate a Visual Studio project file
            move((options.directory || options.name)), // Move the files to the project folder instead of generating in the folder the command was ran in.
        ])),
        (_, context: SchematicContext) => {
            if (options.install !== false) {
                context.addTask(new NodePackageInstallTask({
                    packageManager: 'yarn',
                    workingDirectory: (options.directory || options.name),
                }));
            }
        },
    ]);
}

This is the custom code I want to run. Note that I already tried without the 'move' and the 'overwriteIfExists'. The 'overwriteIfExists' is copied to from an other SO to solve file already exists errors. See: How to overwrite file with angular schematics?

import {strings} from '@angular-devkit/core';
import {apply, chain, MergeStrategy, mergeWith, Rule, template, Tree, url, move} from '@angular-devkit/schematics';
//import { configureAngularJson } from './operations/angular-json';
//import { configurePackageJson } from './operations/package-json';
import { CamcoApplicationSchema } from './schema';
import {overwriteIfExists} from "../utils/filesystem";


/**
 * This schematic handles the Camco specific configuration of a standard Angular project.
 * It assumes the project was generated using the "minimal" flag of the Angular ng-new schematic.
 *
 * @param options
 */
export default function run(options: CamcoApplicationSchema): Rule {
    return (host: Tree) => {
        return chain([
            // Scaffold Camco boilerplate in the project
            mergeWith(apply(url('./files'), [
                template({
                    ...strings,
                    name: options.name,
                }),
                overwriteIfExists(host),
                move('.')
            ]), MergeStrategy.Overwrite), // If there's a file already in the tree that we scaffold, scaffold gets priority
            //configurePackageJson(options), // Configure the package.json
            //configureAngularJson(options), // Configure the Angular.json
            deleteOneFile()
        ]);
    }   
}

export function  deleteOneFile(): Rule {
    return (host: Tree) => {
        console.log(host.exists('/src/app/app-routing.module.ts'));
        host.delete('/src/app/app-routing.module.ts');
        console.log(host.exists('/src/app/app-routing.module.ts'));
    }

}

It is curious because if I comment out the default angular schematics (externalSchematics), my file is removed. But with it I can't seem to get rid of my files!? It seems to be related to the 'move' method. The output of this is:

"C:\Program Files\nodejs\node.exe" F:\Git\Web\BuildTools\schematics\node_modules\@angular-devkit\schematics-cli\bin\schematics.js .:ng-new --directory F:\SCHEMATICS --name aNewHope
true
false
CREATE F:/SCHEMATICS/angular.json (3043 bytes)
CREATE F:/SCHEMATICS/package.json (908 bytes)
CREATE F:/SCHEMATICS/README.md (1025 bytes)
CREATE F:/SCHEMATICS/tsconfig.json (651 bytes)
CREATE F:/SCHEMATICS/.gitignore (549 bytes)
CREATE F:/SCHEMATICS/browserslist (429 bytes)
CREATE F:/SCHEMATICS/tsconfig.app.json (210 bytes)
CREATE F:/SCHEMATICS/.editorconfig (419 bytes)
CREATE F:/SCHEMATICS/CHANGELOG.md (508 bytes)
CREATE F:/SCHEMATICS/tslint.json (2183 bytes)
CREATE F:/SCHEMATICS/src/favicon.ico (5430 bytes)
CREATE F:/SCHEMATICS/src/index.html (6315 bytes)
CREATE F:/SCHEMATICS/src/main.ts (558 bytes)
CREATE F:/SCHEMATICS/src/polyfills.ts (3167 bytes)
CREATE F:/SCHEMATICS/src/styles.scss (80 bytes)
CREATE F:/SCHEMATICS/src/browserslist (396 bytes)
CREATE F:/SCHEMATICS/src/config.json (288 bytes)
CREATE F:/SCHEMATICS/src/assets/.gitkeep (0 bytes)
CREATE F:/SCHEMATICS/src/assets/logo-inverted.svg (7389 bytes)
CREATE F:/SCHEMATICS/src/assets/logo.svg (7343 bytes)
CREATE F:/SCHEMATICS/src/assets/icons/material-icons.eot (66816 bytes)
CREATE F:/SCHEMATICS/src/assets/icons/material-icons.ttf (170104 bytes)
CREATE F:/SCHEMATICS/src/assets/icons/material-icons.woff (77312 bytes)
CREATE F:/SCHEMATICS/src/assets/icons/material-icons.woff2 (59000 bytes)
CREATE F:/SCHEMATICS/src/environments/environment.prod.ts (51 bytes)
CREATE F:/SCHEMATICS/src/environments/environment.ts (662 bytes)
CREATE F:/SCHEMATICS/src/app/app-routing.module.ts (246 bytes)
CREATE F:/SCHEMATICS/src/app/app.module.ts (683 bytes)
CREATE F:/SCHEMATICS/src/app/app.component.ts (627 bytes)
CREATE F:/SCHEMATICS/src/app/app.component.html (534 bytes)
CREATE F:/SCHEMATICS/src/app/shared/services/configuration.service.ts (649 bytes)
CREATE F:/SCHEMATICS/src/styles/index.scss (91 bytes)
CREATE F:/SCHEMATICS/src/styles/_material-icons.scss (1023 bytes)
CREATE F:/SCHEMATICS/src/styles/_variables.scss (0 bytes)

Process finished with exit code 0

The file I try to remove: 'src/app/app-routing.module.ts'. But it does not work for any of my files. The folder structure:

enter image description here

Any help or suggestion would be appreciated! Thanks

1 Answers1

0

I think that you have to add the complete path:

camco-application/files/src/app/app-routing.module.ts

To do that you can use the rootDir information from the Tree:

${libsDir(tree)}/src/app/app-routing.module.ts
fcdt
  • 2,371
  • 5
  • 14
  • 26