Skip to content

Commit

Permalink
Merge branch 'master' into remove_travis_custom_launcher
Browse files Browse the repository at this point in the history
  • Loading branch information
andyskw authored Aug 24, 2016
2 parents e6e8744 + 1ecd72d commit ffbec3e
Show file tree
Hide file tree
Showing 25 changed files with 1,094 additions and 236 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,8 @@ Simply install your library via `npm install lib-name --save` and import it in y
If the library does not include typings, you can install them using npm:

```bash
npm install moment --save
npm install @types/moment --save-dev
npm install d3 --save
npm install @types/d3 --save-dev
```

### Global Library Installation
Expand Down
4 changes: 3 additions & 1 deletion addon/ng2/commands/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ const GetCommand = Command.extend({

run: function (commandOptions, rawArgs): Promise<void> {
return new Promise(resolve => {
const value = new CliConfig().get(rawArgs[0]);
const config = CliConfig.fromProject();
const value = config.get(rawArgs[0]);

if (value === null) {
console.error(chalk.red('Value cannot be found.'));
} else if (typeof value == 'object') {
Expand Down
10 changes: 5 additions & 5 deletions addon/ng2/commands/github-pages-deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ module.exports = Command.extend({
type: String,
default: 'new gh-pages version',
description: 'The commit message to include with the build, must be wrapped in quotes.'
}, {
}, {
name: 'target',
type: String,
default: 'production',
default: 'production',
aliases: ['t', { 'dev': 'development' }, { 'prod': 'production' }]
}, {
}, {
name: 'environment',
type: String,
default: '',
Expand Down Expand Up @@ -72,12 +72,12 @@ module.exports = Command.extend({
}
if (options.target === 'production') {
options.environment = 'prod';
}
}
}

var projectName = this.project.pkg.name;

const outDir = CliConfig.fromProject().apps[0].outDir;
const outDir = CliConfig.fromProject().config.apps[0].outDir;

let ghPagesBranch = 'gh-pages';
let destinationBranch = options.userPage ? 'master' : ghPagesBranch;
Expand Down
33 changes: 31 additions & 2 deletions addon/ng2/commands/set.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as SilentError from 'silent-error';
import * as Command from 'ember-cli/lib/models/command';
import {CliConfig} from '../models/config';

Expand All @@ -11,10 +12,38 @@ const SetCommand = Command.extend({
{ name: 'global', type: Boolean, default: false, aliases: ['g'] },
],

asBoolean: function (raw: string): boolean {
if (raw == 'true' || raw == '1') {
return true;
} else if (raw == 'false' || raw == '' || raw == '0') {
return false;
} else {
throw new SilentError(`Invalid boolean value: "${raw}"`);
}
},
asNumber: function (raw: string): number {
if (Number.isNaN(+raw)) {
throw new SilentError(`Invalid number value: "${raw}"`);
}
return +raw;
},

run: function (commandOptions, rawArgs): Promise<void> {
return new Promise(resolve => {
const config = new CliConfig();
config.set(rawArgs[0], rawArgs[1], commandOptions.force);
const [jsonPath, rawValue] = rawArgs;
const config = CliConfig.fromProject();
const type = config.typeOf(jsonPath);
let value: any = rawValue;

switch (type) {
case 'boolean': value = this.asBoolean(rawValue); break;
case 'number': value = this.asNumber(rawValue); break;
case 'string': value = rawValue; break;

default: value = JSON.parse(rawValue);
}

config.set(jsonPath, value);
config.save();
resolve();
});
Expand Down
4 changes: 2 additions & 2 deletions addon/ng2/commands/test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as TestCommand from 'ember-cli/lib/commands/test';
import * as config from '../models/config';
import * as TestTask from '../tasks/test';
import {CliConfig} from '../models/config';

module.exports = TestCommand.extend({
availableOptions: [
Expand All @@ -14,7 +14,7 @@ module.exports = TestCommand.extend({
],

run: function (commandOptions) {
this.project.ngConfig = this.project.ngConfig || config.CliConfig.fromProject();
this.project.ngConfig = this.project.ngConfig || CliConfig.fromProject();

var testTask = new TestTask({
ui: this.ui,
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion addon/ng2/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {
name: 'ng2',

config: function () {
this.project.ngConfig = this.project.ngConfig || config.CliConfig.fromProject();
this.project.ngConfig = this.project.ngConfig || config.CliConfig.fromProject().config;
},

includedCommands: function () {
Expand Down
169 changes: 21 additions & 148 deletions addon/ng2/models/config.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import {CliConfig as CliConfigBase} from './config/config';
import {CliConfig as ConfigInterface} from '../../../lib/config/schema';
import * as chalk from 'chalk';
import * as fs from 'fs';
import * as path from 'path';
import * as chalk from 'chalk';

const schemaPath = path.resolve(process.env.CLI_ROOT, 'lib/config/schema.json');
const schema = require(schemaPath);

export const CLI_CONFIG_FILE_NAME = 'angular-cli.json';
export const ARRAY_METHODS = ['push', 'splice', 'sort', 'reverse', 'pop', 'shift'];


function _findUp(name: string, from: string) {
let currentDir = from;
Expand All @@ -16,175 +18,46 @@ function _findUp(name: string, from: string) {
return p;
}

currentDir = path.resolve(currentDir, '..');
currentDir = path.dirname(currentDir);
}

return null;
}


export class CliConfig {
private _config: any;

constructor(path?: string) {
if (path) {
try {
fs.accessSync(path);
this._config = require(path);
} catch (e) {
throw new Error(`Config file does not exits.`);
}
} else {
this._config = CliConfig.fromProject();
}
}

save(path: string = CliConfig._configFilePath()) {
if (!path) {
throw new Error('Could not find config path.');
}

fs.writeFileSync(path, JSON.stringify(this._config, null, 2), { encoding: 'utf-8' });
}

set(jsonPath: string, value: any, force: boolean = false): boolean {
let method: any = null;
let splittedPath = jsonPath.split('.');
if (ARRAY_METHODS.indexOf(splittedPath[splittedPath.length - 1]) != -1) {
method = splittedPath[splittedPath.length - 1];
splittedPath.splice(splittedPath.length - 1, 1);
jsonPath = splittedPath.join('.');
}

let { parent, name, remaining } = this._findParent(jsonPath);
let properties: any;
let additionalProperties: boolean;

const checkPath = jsonPath.split('.').reduce((o, i) => {
if (!o || !o.properties) {
throw new Error(`Invalid config path.`);
}
properties = o.properties;
additionalProperties = o.additionalProperties;

return o.properties[i];
}, schema);
const configPath = jsonPath.split('.').reduce((o, i) => o[i], this._config);

if (!properties[name] && !additionalProperties) {
throw new Error(`${name} is not a known property.`);
}

if (method) {
if (Array.isArray(configPath) && checkPath.type === 'array') {
[][method].call(configPath, value);
return true;
} else {
throw new Error(`Trying to use array method on non-array property type.`);
}
}

if (typeof checkPath.type === 'string' && isNaN(value)) {
parent[name] = value;
return true;
}

if (typeof checkPath.type === 'number' && !isNaN(value)) {
parent[name] = value;
return true;
}

if (typeof value != checkPath.type) {
throw new Error(`Invalid value type. Trying to set ${typeof value} to ${path.type}`);
}
}

get(jsonPath: string): any {
let { parent, name, remaining } = this._findParent(jsonPath);
if (remaining || !(name in parent)) {
return null;
} else {
return parent[name];
}
}

private _validatePath(jsonPath: string) {
if (!jsonPath.match(/^(?:[-_\w\d]+(?:\[\d+\])*\.)*(?:[-_\w\d]+(?:\[\d+\])*)$/)) {
throw `Invalid JSON path: "${jsonPath}"`;
}
}

private _findParent(jsonPath: string): { parent: any, name: string | number, remaining?: string } {
this._validatePath(jsonPath);

let parent: any = null;
let current: any = this._config;

const splitPath = jsonPath.split('.');
let name: string | number = '';

while (splitPath.length > 0) {
const m = splitPath.shift().match(/^(.*?)(?:\[(\d+)\])*$/);

name = m[1];
const index: string = m[2];
parent = current;
current = current[name];

if (current === null || current === undefined) {
return {
parent,
name,
remaining: (!isNaN(index) ? `[${index}]` : '') + splitPath.join('.')
};
}

if (!isNaN(index)) {
name = index;
parent = current;
current = current[index];

if (current === null || current === undefined) {
return {
parent,
name,
remaining: splitPath.join('.')
};
}
}
}
function getUserHome() {
return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
}

return { parent, name };
}

export class CliConfig extends CliConfigBase<ConfigInterface> {
private static _configFilePath(projectPath?: string): string {
// Find the configuration, either where specified, in the angular-cli project
// (if it's in node_modules) or from the current process.
return (projectPath && _findUp(CLI_CONFIG_FILE_NAME, projectPath))
|| _findUp(CLI_CONFIG_FILE_NAME, __dirname)
|| _findUp(CLI_CONFIG_FILE_NAME, process.cwd());
|| _findUp(CLI_CONFIG_FILE_NAME, process.cwd())
|| _findUp(CLI_CONFIG_FILE_NAME, __dirname);
}

public static fromProject(): any {
const configPath = CliConfig._configFilePath();

static fromProject(): CliConfig {
const configPath = this._configFilePath();
const globalConfigPath = path.join(getUserHome(), CLI_CONFIG_FILE_NAME);

if (!configPath) {
return {};
}

let config = require(configPath);

if (config.defaults.sourceDir || config.defaults.prefix) {
config.apps[0].root = config.apps[0].root || config.defaults.sourceDir;
config.apps[0].prefix = config.apps[0].prefix || config.defaults.prefix;

const cliConfig = CliConfigBase.fromConfigPath(CliConfig._configFilePath(), [globalConfigPath]);
if (cliConfig.alias('apps.0.root', 'defaults.sourceDir')
+ cliConfig.alias('apps.0.prefix', 'defaults.prefix')) {
console.error(chalk.yellow(
'The "defaults.prefix" and "defaults.sourceDir" properties of angular-cli.json '
'The "defaults.prefix" and "defaults.sourceDir" properties of angular-cli.json\n'
+ 'are deprecated in favor of "apps[0].root" and "apps[0].prefix".\n'
+ 'Please update in order to avoid errors in future versions of angular-cli.'
));
}
return config;

return cliConfig as CliConfig;
}
}
Loading

0 comments on commit ffbec3e

Please sign in to comment.