Follow the steps mentioned in the angular docs
You will run into a bit of issues. For example
1) const workspaceConfig = tree.read('/angular.json');
// will be null when using the 'schematics' command but will work when using the 'ng g' commad.
2) Similarly 'options.path' will be undefined when using the 'schematics' command but will work when using the 'ng g' command.
You need to add path to schema.json file and then in your function, you should be able to use 'options.path' to get the current location. However as I mentioned I was not able to get it to work when using the 'schematics' command. I was only able to get it to work when using the 'ng g' command.
So as an example here are my files
1) ..schematics/ng-generate/customComponent/schema.json
{
"$schema": "http://json-schema.org/schema",
"id": "GenerateCustomComponent",
"title": "Generate Custom Component",
"type": "object",
"properties": {
"name": {
"description": "The name for the custom component.",
"type": "string",
"x-prompt": "What is the name for the custom component?"
},
"path": {
"type": "string",
"format": "path",
"description": "The path at which to create the component file, relative to the current workspace. Default is a folder with the same name as the component in the project root.",
"visible": false
}
},
"required": [
"name"
]
}
2) ..schematics/ng-generate/customComponent/schema.ts
import { Schema as ComponentSChema } from '@schematics/angular/component/schema';
export interface Schema extends ComponentSChema {
// The name of the custom component
name: string;
}
2) ..schematics/ng-generate/customComponent/index.ts
import {
Rule, Tree, SchematicsException,
apply, url, applyTemplates, move,
chain, mergeWith
} from '@angular-devkit/schematics';
import { strings, experimental, normalize } from '@angular-devkit/core';
import { Schema as CustomSchema } from './schema';
export function generate(options: CustomSchema): Rule {
return (tree: Tree) => {
const workspaceConfig = tree.read('/angular.json'); // will return null when using schematics command but will work when using ng g
console.log('workspaceConfig::', workspaceConfig);
console.log('path:', options.path); // will be undefined when using schematics command but will work when using ng g
// from now following along with angular docs with slight modifications.
if (workspaceConfig && !options.path) {
const workspaceContent = workspaceConfig.toString();
console.log('workspaceContent::', workspaceContent);
const workspace: experimental.workspace.WorkspaceSchema = JSON.parse(workspaceContent);
console.log('workspace', workspace);
options.project = workspace.defaultProject;
const projectName = options.project as string;
const project = workspace.projects[projectName];
const projectType = project.projectType === 'application' ? 'app' : 'lib';
console.log('projectType::', projectType);
options.path = `${project.sourceRoot}/${projectType}`;
}
if (options.path) {
// this will be used by the ng g command
const templateSource = apply(url('./files'), [
applyTemplates({
classify: strings.classify,
dasherize: strings.dasherize,
name: options.name
}),
move(normalize(options.path as string))
]);
return chain([
mergeWith(templateSource)
]);
} else {
// this will be used by the schematics command
const templateSource = apply(url('./files'), [
applyTemplates({
classify: strings.classify,
dasherize: strings.dasherize,
name: options.name
})
]);
return chain([
mergeWith(templateSource)
]);
}
};
}