Skip to content

Commit 9969509

Browse files
committed
feat: allow for configurable source diretory location and selector prefix at app creation
1 parent 5b08965 commit 9969509

30 files changed

+178
-169
lines changed

addon/ng2/blueprints/component/index.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,8 @@ module.exports = {
8888
dir = dirParts.join(path.sep);
8989
}
9090
}
91-
this.appDir = dir.replace(`src${path.sep}client${path.sep}`, '');
91+
var srcDir = this.project.ngConfig.defaults.sourceDir;
92+
this.appDir = dir.substr(dir.indexOf(srcDir) + srcDir.length);
9293
this.generatePath = dir;
9394
return dir;
9495
},
@@ -100,8 +101,11 @@ module.exports = {
100101

101102
afterInstall: function(options) {
102103
if (!options.flat) {
103-
var filePath = path.join('src', 'client', 'system-config.ts');
104-
var barrelUrl = this.appDir.replace(path.sep, '/');
104+
var filePath = path.join(this.project.ngConfig.defaults.sourceDir, 'system-config.ts');
105+
var barrelUrl = this.appDir.replace(/\\/g, '/');
106+
if (barrelUrl[0] === '/') {
107+
barrelUrl = barrelUrl.substr(1);
108+
}
105109

106110
return addBarrelRegistration(this, this.generatePath)
107111
.then(() => {
@@ -110,7 +114,7 @@ module.exports = {
110114
` '${barrelUrl}',`,
111115
{ before: ' /** @cli-barrel */' }
112116
);
113-
})
117+
});
114118
} else {
115119
return addBarrelRegistration(
116120
this,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
/// <reference path="<%= refToTypings %>/typings/browser.d.ts" />
2+
3+
declare var __moduleName: string;

addon/ng2/blueprints/ng2/files/angular-cli.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"name": "<%= htmlComponentName %>"
55
},
66
"apps": [
7-
{"main": "src/client/main.ts", "tsconfig": "src/client/tsconfig.json"}
7+
{"main": "<%= sourceDir %>/main.ts", "tsconfig": "<%= sourceDir %>/tsconfig.json"}
88
],
99
"addons": [],
1010
"packages": [],
@@ -19,6 +19,7 @@
1919
}
2020
},
2121
"defaults": {
22-
"prefix": "app"
22+
"prefix": "<%= prefix %>",
23+
"sourceDir": "<%= sourceDir %>"
2324
}
2425
}

addon/ng2/blueprints/ng2/files/src/client/typings.d.ts

-3
This file was deleted.

addon/ng2/blueprints/ng2/index.js

+14-1
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,36 @@ const stringUtils = require('ember-cli-string-utils');
33

44
module.exports = {
55
description: '',
6+
7+
availableOptions: [
8+
{ name: 'source-dir', type: String, default: 'src', aliases: ['sd'] },
9+
{ name: 'prefix', type: String, default: 'app', aliases: ['p'] }
10+
],
611

712
locals: function(options) {
813
//TODO: pull value from config
914
this.styleExt = 'css';
1015
this.version = require(path.resolve(__dirname, '..', '..', '..', '..', 'package.json')).version;
1116

17+
// Join with / not path.sep as reference to typings require forward slashes.
18+
const refToTypings = options.sourceDir.split(path.sep).map(() => '..').join('/');
1219
return {
1320
htmlComponentName: stringUtils.dasherize(options.entity.name),
1421
jsComponentName: stringUtils.classify(options.entity.name),
1522
styleExt: this.styleExt,
16-
version: this.version
23+
version: this.version,
24+
sourceDir: options.sourceDir,
25+
prefix: options.prefix,
26+
refToTypings: refToTypings
1727
};
1828
},
1929

2030
fileMapTokens: function (options) {
2131
// Return custom template variables here.
2232
return {
33+
__path__: () => {
34+
return options.locals.sourceDir;
35+
},
2336
__styleext__: () => {
2437
return options.locals.styleExt;
2538
}

addon/ng2/commands/init.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ module.exports = Command.extend({
1919
{ name: 'blueprint', type: String, aliases: ['b'] },
2020
{ name: 'skip-npm', type: Boolean, default: false, aliases: ['sn'] },
2121
{ name: 'skip-bower', type: Boolean, default: true, aliases: ['sb'] },
22-
{ name: 'name', type: String, default: '', aliases: ['n'] }
22+
{ name: 'name', type: String, default: '', aliases: ['n'] },
23+
{ name: 'source-dir', type: String, default: 'src', aliases: ['sd'] },
24+
{ name: 'prefix', type: String, default: 'app', aliases: ['p'] }
2325
],
2426

2527
anonymousOptions: ['<glob-pattern>'],
@@ -79,13 +81,15 @@ module.exports = Command.extend({
7981

8082
return Promise.reject(new SilentError(message));
8183
}
82-
84+
8385
var blueprintOpts = {
8486
dryRun: commandOptions.dryRun,
8587
blueprint: commandOptions.blueprint || this._defaultBlueprint(),
8688
rawName: packageName,
8789
targetFiles: rawArgs || '',
88-
rawArgs: rawArgs.toString()
90+
rawArgs: rawArgs.toString(),
91+
sourceDir: commandOptions.sourceDir,
92+
prefix: commandOptions.prefix
8993
};
9094

9195
if (!validProjectName(packageName)) {

addon/ng2/commands/new.ts

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ const NewCommand = Command.extend({
2020
{ name: 'skip-bower', type: Boolean, default: true, aliases: ['sb'] },
2121
{ name: 'skip-git', type: Boolean, default: false, aliases: ['sg'] },
2222
{ name: 'directory', type: String, aliases: ['dir'] },
23+
{ name: 'source-dir', type: String, default: 'src', aliases: ['sd'] },
24+
{ name: 'prefix', type: String, default: 'app', aliases: ['p'] }
2325
],
2426

2527
run: function (commandOptions, rawArgs) {

addon/ng2/utilities/dynamic-path-parser.js

+2-16
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,17 @@ var fs = require('fs');
44

55
module.exports = function dynamicPathParser(project, entityName) {
66
var projectRoot = project.root;
7-
var appRoot = path.join('src', 'client', 'app');
7+
var appRoot = path.join(project.ngConfig.defaults.sourceDir, 'app');
88
var cwd = process.env.PWD;
99

1010
var rootPath = path.join(projectRoot, appRoot);
1111

1212
var outputPath = path.join(rootPath, entityName);
13-
13+
1414
if (entityName.indexOf(path.sep) === 0) {
1515
outputPath = path.join(rootPath, entityName.substr(1));
1616
} else if (cwd.indexOf(rootPath) >= 0) {
1717
outputPath = path.join(cwd, entityName);
18-
} else if (cwd.indexOf(path.join(projectRoot, 'src', 'client')) >= 0) {
19-
if (entityName.indexOf('app') === 0) {
20-
outputPath = path.join(cwd, entityName);
21-
} else {
22-
outputPath = path.join(cwd, 'app', entityName);
23-
}
24-
} else if (cwd.indexOf(path.join(projectRoot, 'src')) >= 0) {
25-
if (entityName.indexOf(path.join('client', 'app')) === 0) {
26-
outputPath = path.join(cwd, entityName);
27-
} else if (entityName.indexOf('client') === 0) {
28-
outputPath = path.join(cwd, 'app', entityName);
29-
} else {
30-
outputPath = path.join(cwd, 'client', 'app', entityName);
31-
}
3218
}
3319

3420
if (!fs.existsSync(outputPath)) {

lib/broccoli/angular2-app.js

+17-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@ const BroccoliFunnel = require('broccoli-funnel');
1010
const BroccoliMergeTrees = require('broccoli-merge-trees');
1111
const BroccoliUglify = require('broccoli-uglify-js');
1212
const Project = require('ember-cli/lib/models/project');
13+
const config = require('../../addon/ng2/models/config');
1314

1415

1516
class Angular2App extends BroccoliPlugin {
1617
constructor(project, inputNode, options) {
18+
const ngConfig = config.CliConfig.fromProject();
19+
1720
if (!options) {
1821
options = inputNode;
1922
inputNode = null;
@@ -23,7 +26,7 @@ class Angular2App extends BroccoliPlugin {
2326
options = options || {};
2427

2528
this._options = options;
26-
this._sourceDir = options.sourceDir || 'src/client';
29+
this._sourceDir = ngConfig.defaults.sourceDir || 'src';
2730
this._inputNode = inputNode || this._buildInputTree();
2831
this._destDir = options.destDir || '';
2932

@@ -95,6 +98,7 @@ class Angular2App extends BroccoliPlugin {
9598

9699
var buildTrees = [assetTree, tsTree, indexTree, vendorNpmTree];
97100

101+
// Add available and supported CSS plugins.
98102
for (const suffix of ['sass', 'less', 'stylus', 'compass']) {
99103
const plugin = require(`./angular-broccoli-${suffix}`);
100104
const tree = plugin.makeBroccoliTree(this._inputNode, this._options[`${suffix}Compiler`]);
@@ -113,6 +117,18 @@ class Angular2App extends BroccoliPlugin {
113117
}
114118
}));
115119
}
120+
121+
// Add the public folder in.
122+
buildTrees.push(new BroccoliFunnel(this._inputNode, {
123+
include: ['public/**/*'],
124+
getDestinationPath: (n) => {
125+
if (n.startsWith('public')) {
126+
return n.substr(6);
127+
}
128+
return n;
129+
},
130+
name: 'PublicFolderFunnel'
131+
}));
116132

117133
var merged = new BroccoliMergeTrees(buildTrees, { overwrite: true });
118134
merged = new BroccoliMergeTrees([merged, new BroccoliSwManifest([merged])]);

lib/config/schema.json

+3
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@
8282
"properties": {
8383
"prefix": {
8484
"type": "string"
85+
},
86+
"sourceDir": {
87+
"type": "string"
8588
}
8689
},
8790
"additionalProperties": false

tests/acceptance/dynamic-path-parser.spec.js

+32-34
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,28 @@ var path = require('path');
55
var dynamicPathParser = require('../../addon/ng2/utilities/dynamic-path-parser');
66
var mockFs = require('mock-fs');
77

8-
var appDir = `src${path.sep}client${path.sep}app`;
8+
var appDir = `src${path.sep}app`;
99

1010
describe('dynamic path parser', () => {
1111
var project;
1212
var entityName = 'temp-name';
1313
var rootName = path.parse(process.cwd()).root + 'project';
14+
var sourceDir = 'src';
1415
beforeEach(() => {
15-
project = { root: rootName };
16+
project = {
17+
root: rootName,
18+
ngConfig: {
19+
defaults: {
20+
sourceDir: sourceDir
21+
}
22+
}
23+
};
1624
var mockFolder = {};
1725
mockFolder[rootName] = {
1826
src: {
19-
client: {
20-
app: {
21-
'index.html': '<html></html>',
22-
'temp-name': {}
23-
}
27+
app: {
28+
'index.html': '<html></html>',
29+
'temp-name': {}
2430
}
2531
}
2632
};
@@ -63,18 +69,16 @@ describe('dynamic path parser', () => {
6369
var mockFolder = {};
6470
mockFolder[rootName] = {
6571
src: {
66-
client: {
67-
app: {
68-
'index.html': '<html></html>',
69-
'child-dir': {
70-
'temp-name': {}
71-
}
72+
app: {
73+
'index.html': '<html></html>',
74+
'child-dir': {
75+
'temp-name': {}
7276
}
7377
}
7478
}
7579
};
7680
mockFs(mockFolder);
77-
process.env.PWD = path.join(project.root, 'src', 'client', 'app', 'child-dir');
81+
process.env.PWD = path.join(project.root, 'src', 'app', 'child-dir');
7882
var result = dynamicPathParser(project, entityName);
7983
expect(result.dir).to.equal(`${appDir}${path.sep}child-dir`);
8084
expect(result.name).to.equal(entityName);
@@ -84,17 +88,15 @@ describe('dynamic path parser', () => {
8488
var mockFolder = {};
8589
mockFolder[rootName] = {
8690
src: {
87-
client: {
88-
app: {
89-
'index.html': '<html></html>',
90-
'child-dir': {},
91-
'temp-name': {}
92-
}
91+
app: {
92+
'index.html': '<html></html>',
93+
'child-dir': {},
94+
'temp-name': {}
9395
}
9496
}
9597
};
9698
mockFs(mockFolder);
97-
process.env.PWD = path.join(project.root, 'src', 'client', 'app', 'child-dir');
99+
process.env.PWD = path.join(project.root, 'src', 'app', 'child-dir');
98100
var result = dynamicPathParser(project, '..' + path.sep + entityName);
99101
expect(result.dir).to.equal(appDir);
100102
expect(result.name).to.equal(entityName);
@@ -105,19 +107,17 @@ describe('dynamic path parser', () => {
105107
var mockFolder = {};
106108
mockFolder[rootName] = {
107109
src: {
108-
client: {
109-
app: {
110-
'index.html': '<html></html>',
111-
'child-dir': {
112-
'grand-child-dir': {},
113-
'temp-name': {}
114-
}
110+
app: {
111+
'index.html': '<html></html>',
112+
'child-dir': {
113+
'grand-child-dir': {},
114+
'temp-name': {}
115115
}
116116
}
117117
}
118118
};
119119
mockFs(mockFolder);
120-
process.env.PWD = path.join(project.root, 'src', 'client', 'app', 'child-dir', 'grand-child-dir');
120+
process.env.PWD = path.join(project.root, 'src', 'app', 'child-dir', 'grand-child-dir');
121121
var result = dynamicPathParser(project, '..' + path.sep + entityName);
122122
expect(result.dir).to.equal(`${appDir}${path.sep}child-dir`);
123123
expect(result.name).to.equal(entityName);
@@ -127,15 +127,13 @@ describe('dynamic path parser', () => {
127127
var mockFolder = {};
128128
mockFolder[rootName] = {
129129
src: {
130-
client: {
131-
app: {
132-
'+my-route': {}
133-
}
130+
app: {
131+
'+my-route': {}
134132
}
135133
}
136134
};
137135
mockFs(mockFolder);
138-
process.env.PWD = path.join(project.root, 'src', 'client', 'app', 'my-route');
136+
process.env.PWD = path.join(project.root, 'src', 'app', 'my-route');
139137
var result = dynamicPathParser(project, entityName);
140138
expect(result.dir).to.equal(`${appDir}${path.sep}+my-route`);
141139
expect(result.name).to.equal(entityName);

tests/acceptance/generate-class.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const expect = require('chai').expect;
99
const path = require('path');
1010
const root = process.cwd();
1111

12-
const testPath = path.join(root, 'tmp', 'foo', 'src', 'client', 'app');
12+
const testPath = path.join(root, 'tmp', 'foo', 'src', 'app');
1313

1414
describe('Acceptance: ng generate class', function () {
1515
before(conf.setup);

0 commit comments

Comments
 (0)