Skip to content

Commit

Permalink
fix(get/set): Add support for global configuration. (#4074)
Browse files Browse the repository at this point in the history
If we dont find the local one, we error now. If we get/set with --global, we properly do the right thing.
  • Loading branch information
hansl authored Jan 18, 2017
1 parent e91552f commit 088ebf0
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 31 deletions.
3 changes: 2 additions & 1 deletion packages/angular-cli/addon/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ module.exports = {

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

blueprintsPath: function () {
Expand Down
26 changes: 20 additions & 6 deletions packages/angular-cli/commands/get.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
import * as chalk from 'chalk';
import {CliConfig} from '../models/config';

const SilentError = require('silent-error');
const Command = require('../ember-cli/lib/models/command');


export interface GetOptions {
global?: boolean;
}


const GetCommand = Command.extend({
name: 'get',
description: 'Get a value from the configuration.',
works: 'everywhere',

availableOptions: [],
availableOptions: [
{ name: 'global', type: Boolean, 'default': false }
],

run: function (commandOptions: any, rawArgs: string[]): Promise<void> {
run: function (commandOptions: GetOptions, rawArgs: string[]): Promise<void> {
return new Promise<void>(resolve => {
const config = CliConfig.fromProject();
const config = commandOptions.global ? CliConfig.fromGlobal() : CliConfig.fromProject();

if (config === null) {
throw new SilentError('No config found. If you want to use global configuration, '
+ 'you need the --global argument.');
}

const value = config.get(rawArgs[0]);

if (value === null) {
console.error(chalk.red('Value cannot be found.'));
if (value === null || value === undefined) {
throw new SilentError('Value cannot be found.');
} else if (typeof value == 'object') {
console.log(JSON.stringify(value));
} else {
Expand Down
30 changes: 24 additions & 6 deletions packages/angular-cli/commands/set.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import {CliConfig} from '../models/config';

const SilentError = require('silent-error');
const Command = require('../ember-cli/lib/models/command');
import {CliConfig} from '../models/config';


export interface SetOptions {
global?: boolean;
}


const SetCommand = Command.extend({
Expand All @@ -9,7 +15,7 @@ const SetCommand = Command.extend({
works: 'everywhere',

availableOptions: [
{ name: 'global', type: Boolean, default: false, aliases: ['g'] },
{ name: 'global', type: Boolean, 'default': false, aliases: ['g'] },
],

asBoolean: function (raw: string): boolean {
Expand All @@ -28,13 +34,25 @@ const SetCommand = Command.extend({
return +raw;
},

run: function (commandOptions: any, rawArgs: string[]): Promise<void> {
run: function (commandOptions: SetOptions, rawArgs: string[]): Promise<void> {
return new Promise<void>(resolve => {
const [jsonPath, rawValue] = rawArgs;
const config = CliConfig.fromProject();
const config = commandOptions.global ? CliConfig.fromGlobal() : CliConfig.fromProject();
if (config === null) {
throw new SilentError('No config found. If you want to use global configuration, '
+ 'you need the --global argument.');
}

let [jsonPath, rawValue] = rawArgs;

if (rawValue === undefined) {
[jsonPath, rawValue] = jsonPath.split('=', 2);
if (rawValue === undefined) {
throw new SilentError('Must specify a value.');
}
}

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;
Expand Down
1 change: 0 additions & 1 deletion packages/angular-cli/ember-cli/lib/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ module.exports = {
InstallBlueprint: require('./tasks/install-blueprint'),
NpmInstall: require('./tasks/npm-install'),
NpmTask: require('./tasks/npm-task'),
NpmUninstall: require('./tasks/npm-uninstall'),
};
11 changes: 0 additions & 11 deletions packages/angular-cli/ember-cli/lib/tasks/npm-uninstall.js

This file was deleted.

30 changes: 28 additions & 2 deletions packages/angular-cli/models/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ function _findUp(name: string, from: string) {
return p;
}

const nodeModuleP = path.join(currentDir, 'node_modules');
if (fs.existsSync(nodeModuleP)) {
return null;
}

currentDir = path.dirname(currentDir);
}

Expand All @@ -24,7 +29,7 @@ function _findUp(name: string, from: string) {


function getUserHome() {
return process.env[(process.platform == 'win32') ? 'USERPROFILE' : 'HOME'];
return process.env[(process.platform.startsWith('win')) ? 'USERPROFILE' : 'HOME'];
}


Expand All @@ -37,13 +42,34 @@ export class CliConfig extends CliConfigBase<ConfigInterface> {
|| _findUp(CLI_CONFIG_FILE_NAME, __dirname);
}

static fromGlobal(): CliConfig {
const globalConfigPath = path.join(getUserHome(), CLI_CONFIG_FILE_NAME);

const cliConfig = CliConfigBase.fromConfigPath<ConfigInterface>(globalConfigPath);

const aliases = [
cliConfig.alias('apps.0.root', 'defaults.sourceDir'),
cliConfig.alias('apps.0.prefix', 'defaults.prefix')
];

// If any of them returned true, output a deprecation warning.
if (aliases.some(x => !!x)) {
console.error(chalk.yellow(oneLine`
The "defaults.prefix" and "defaults.sourceDir" properties of angular-cli.json
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 cliConfig;
}

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

if (!configPath) {
return CliConfigBase.fromJson<ConfigInterface>({});
return null;
}

const cliConfig = CliConfigBase.fromConfigPath<ConfigInterface>(
Expand Down
4 changes: 3 additions & 1 deletion packages/angular-cli/models/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ export class CliConfig<JsonType> {
}

static fromConfigPath<T>(configPath: string, otherPath: string[] = []): CliConfig<T> {
const configContent = fs.readFileSync(configPath, 'utf-8');
const configContent = fs.existsSync(configPath)
? fs.readFileSync(configPath, 'utf-8')
: '{}';
const schemaContent = fs.readFileSync(DEFAULT_CONFIG_SCHEMA_PATH, 'utf-8');
const otherContents = otherPath
.map(path => fs.existsSync(path) && fs.readFileSync(path, 'utf-8'))
Expand Down
26 changes: 26 additions & 0 deletions tests/e2e/tests/commands/config/get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {ng, silentNg} from '../../../utils/process';
import {expectToFail} from '../../../utils/utils';


export default function() {
return Promise.resolve()
.then(() => process.chdir('/'))
.then(() => expectToFail(() => ng('get', 'defaults.inline.style')))
.then(() => ng('get', '--global', 'defaults.inline.style'))
.then(output => {
if (!output.match(/false\n?/)) {
throw new Error(`Expected "false", received "${JSON.stringify(output)}".`);
}
})
.then(() => expectToFail(() => {
return ng('set', '--global', 'defaults.inline.style', 'INVALID_BOOLEAN');
}))
.then(() => ng('set', '--global', 'defaults.inline.style', 'true'))
.then(() => ng('get', '--global', 'defaults.inline.style'))
.then(output => {
if (!output.match(/true\n?/)) {
throw new Error(`Expected "true", received "${JSON.stringify(output)}".`);
}
})
.then(() => ng('set', '--global', 'defaults.inline.style', 'false'));
}
9 changes: 6 additions & 3 deletions tests/e2e_runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ testsToRun.reduce((previous, relativeName) => {
.then(() => fn(() => clean = false))
.then(() => ConsoleLoggerStack.pop(), (err: any) => { ConsoleLoggerStack.pop(); throw err; })
.then(() => console.log('----'))
.then(() => { ConsoleLoggerStack.push(NullLogger); })
.then(() => {
// If we're not in a setup, change the directory back to where it was before the test.
// This allows tests to chdir without worrying about keeping the original directory.
Expand All @@ -145,10 +144,14 @@ testsToRun.reduce((previous, relativeName) => {
// Only clean after a real test, not a setup step. Also skip cleaning if the test
// requested an exception.
if (allSetups.indexOf(relativeName) == -1 && clean) {
return gitClean();
ConsoleLoggerStack.push(NullLogger);
return gitClean()
.then(() => ConsoleLoggerStack.pop(), (err: any) => {
ConsoleLoggerStack.pop();
throw err;
});
}
})
.then(() => ConsoleLoggerStack.pop(), (err: any) => { ConsoleLoggerStack.pop(); throw err; })
.then(() => printFooter(currentFileName, start),
(err) => {
printFooter(currentFileName, start);
Expand Down

0 comments on commit 088ebf0

Please sign in to comment.