diff --git a/apps/angular-console-e2e/src/integration/local-collection.spec.ts b/apps/angular-console-e2e/src/integration/local-collection.spec.ts new file mode 100644 index 0000000000..61a02b23a7 --- /dev/null +++ b/apps/angular-console-e2e/src/integration/local-collection.spec.ts @@ -0,0 +1,71 @@ +import { + checkDisplayedCommand, + clickOnTask, + goBack, + goToGenerate, + openProject, + projectPath, + taskListHeaders, + tasks, + texts, + uniqName, + whitelistGraphql +} from './utils'; +import { clearRecentTask } from './tasks.utils'; + +describe('Project with local collection', () => { + beforeEach(() => { + whitelistGraphql(); + cy.visit('/workspaces'); + openProject(projectPath('proj-local-collection')); + goToGenerate(); + cy.get('div.title').contains('Generate Code'); + }); + + it('shows the local schematics', () => { + taskListHeaders($p => { + expect($p.length).to.equal(3); + expect(texts($p)[0]).to.equal('.proj-local-collection'); + }); + + tasks($p => { + const t = texts($p); + expect(t.indexOf('my-full-schematic') > -1).to.equal(true); + }); + }); + + it('runs a local schematic', () => { + clickOnTask('.proj-local-collection', 'my-full-schematic'); + cy.get('div.context-title').contains( + 'A schematic using a source and a schema to validate options' + ); + + const name = uniqName('example'); + cy.get('input[name="name"]').type(name); + + cy.wait(100); + + cy.get('button') + .contains('Generate') + .click(); + + cy.wait(100); + + checkDisplayedCommand(`$ ng generate .:my-full-schematic --name=${name}`); + cy.readFile('./../../tmp/proj-local-collection/hola'); + cy.readFile('./../../tmp/proj-local-collection/allo'); + + goBack(); + + cy.get('div.title').contains('Generate Code'); + taskListHeaders($p => { + expect(texts($p)[0]).to.equal('.proj-local-collection'); + }); + }); + + after(() => { + cy.visit('/workspaces'); + openProject(projectPath('proj-local-collection')); + clearRecentTask(); + }); +}); diff --git a/libs/feature-generate/src/lib/schematic/schematic.component.ts b/libs/feature-generate/src/lib/schematic/schematic.component.ts index afc6cfa886..a55307a01b 100644 --- a/libs/feature-generate/src/lib/schematic/schematic.component.ts +++ b/libs/feature-generate/src/lib/schematic/schematic.component.ts @@ -235,7 +235,11 @@ export class SchematicComponent implements OnInit { } getPrefix(schematic: Schematic) { - return [`${schematic.collection}:${schematic.name}`]; + return [ + `${schematic.collection.startsWith('.') ? '.' : schematic.collection}:${ + schematic.name + }` + ]; } path() { diff --git a/server/src/api/read-schematic-collections.ts b/server/src/api/read-schematic-collections.ts index 011f200cbc..36ecc118cb 100644 --- a/server/src/api/read-schematic-collections.ts +++ b/server/src/api/read-schematic-collections.ts @@ -30,7 +30,8 @@ interface Schematic { export function readAllSchematicCollections(basedir: string) { const nodeModulesDir = path.join(basedir, 'node_modules'); const packages = listOfUnnestedNpmPackages(nodeModulesDir); - const schematicCollections = packages.filter(p => { + const relativeRootPath = './..'; + const schematicCollections = [relativeRootPath, ...packages].filter(p => { try { return !!readJsonFile(path.join(p, 'package.json'), nodeModulesDir).json .schematics; @@ -47,12 +48,13 @@ export function readAllSchematicCollections(basedir: string) { } }); return schematicCollections - .map(c => readSchematicCollections(nodeModulesDir, c)) + .map(c => readSchematicCollections(nodeModulesDir, relativeRootPath, c)) .filter(collection => !!collection && collection.schematics.length > 0); } function readSchematicCollections( basedir: string, + rootCollection: string, collectionName: string ): SchematicCollection { try { @@ -64,8 +66,12 @@ function readSchematicCollections( packageJson.json.schematics, path.dirname(packageJson.path) ); + const name = + collectionName === rootCollection + ? `.${packageJson.json.name}` + : collectionName; const schematicCollection = { - name: collectionName, + name, schematics: [] as Schematic[] }; Object.entries(collection.json.schematics).forEach(([k, v]: [any, any]) => { @@ -77,7 +83,7 @@ function readSchematicCollections( schematicCollection.schematics.push({ name: k, - collection: collectionName, + collection: name, schema: normalizeSchema(schematicSchema.json), description: v.description }); diff --git a/tools/scripts/set-up-e2e-fixtures.js b/tools/scripts/set-up-e2e-fixtures.js index c729a24e45..9521ee9ac2 100644 --- a/tools/scripts/set-up-e2e-fixtures.js +++ b/tools/scripts/set-up-e2e-fixtures.js @@ -14,10 +14,14 @@ shell.rm('-rf', path.join(tmp, 'proj-extensions')); shell.mkdir(path.join(tmp, 'proj-extensions')); shell.rm('-rf', path.join(tmp, 'proj-no-node-modules')); shell.mkdir(path.join(tmp, 'proj-no-node-modules')); +shell.rm('-rf', path.join(tmp, 'proj-local-collection')); +shell.mkdir(path.join(tmp, 'proj-local-collection')); shell.rm('-rf', path.join(tmp, 'ng')); shell.mkdir(path.join(tmp, 'ng')); cp.execSync('yarn add @angular/cli@7.0.4', {cwd: path.join(tmp, 'ng')}); +cp.execSync('yarn add @angular-devkit/schematics-cli @schematics/schematics', {cwd: path.join(tmp, 'ng')}); +cp.execSync('yarn add json', {cwd: path.join(tmp, 'ng')}); cp.execSync('ng config -g cli.packageManager yarn'); cp.execSync(`${path.join(tmp, 'ng')}/node_modules/.bin/ng new proj --collection=@schematics/angular --directory=proj --skip-git --no-interactive`, { cwd: tmp, stdio: [0, 1, 2] }); @@ -28,3 +32,12 @@ shell.mv(path.join(tmp, 'proj-extensions'), './tmp/proj-extensions'); cp.execSync(`${path.join(tmp, 'ng')}/node_modules/.bin/ng new proj-no-node-modules --collection=@schematics/angular --directory=proj-no-node-modules --skip-install --skip-git --no-interactive`, { cwd: tmp, stdio: [0, 1, 2] }); shell.mv(path.join(tmp, 'proj-no-node-modules'), './tmp/proj-no-node-modules'); + +cp.execSync(`${path.join(tmp, 'ng')}/node_modules/.bin/ng new proj-local-collection --collection=@schematics/angular --directory=proj-local-collection --skip-git --no-interactive`, { cwd: tmp, stdio: [0, 1, 2] }); +shell.mv(path.join(tmp, 'proj-local-collection'), './tmp/proj-local-collection'); +shell.cd('./tmp/proj-local-collection'); +cp.execSync(`${path.join(tmp, 'ng')}/node_modules/.bin/schematics schematic --name=schematics .`); +cp.execSync(`${path.join(tmp, 'ng')}/node_modules/.bin/json -I -f package.json -e 'this.schematics="./schematics/src/collection.json"'`); +cp.execSync('ng config cli.defaultCollection schematics') +shell.cd('schematics'); +cp.execSync(`${path.join(tmp, 'ng')}/node_modules/.bin/tsc`);