Skip to content

Commit

Permalink
fix(@angular/cli): honor global config command option
Browse files Browse the repository at this point in the history
  • Loading branch information
clydin authored and hansl committed Mar 29, 2018
1 parent 2955462 commit c34db58
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 31 deletions.
19 changes: 10 additions & 9 deletions packages/@angular/cli/commands/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,17 +120,18 @@ export default class ConfigCommand extends Command {
public readonly description = 'Get/set configuration values.';
public readonly arguments = ['jsonPath', 'value'];
public readonly options: Option[] = [
// {
// name: 'global',
// type: Boolean,
// 'default': false,
// aliases: ['g'],
// description: 'Get/set the value in the global configuration (in your home directory).'
// }
{
name: 'global',
type: Boolean,
'default': false,
aliases: ['g'],
description: 'Get/set the value in the global configuration (in your home directory).'
}
];

public run(options: ConfigOptions) {
const config = (getWorkspace() as {} as { _workspace: WorkspaceJson});
const level = options.global ? 'global' : 'local';
const config = (getWorkspace(level) as {} as { _workspace: WorkspaceJson});

if (!config) {
throw new SilentError('No config found.');
Expand All @@ -156,7 +157,7 @@ export default class ConfigCommand extends Command {
}

private set(options: ConfigOptions) {
const [config, configPath] = getWorkspaceRaw();
const [config, configPath] = getWorkspaceRaw(options.global ? 'global' : 'local');

// TODO: Modify & save without destroying comments
const configValue = config.value;
Expand Down
152 changes: 131 additions & 21 deletions packages/@angular/cli/utilities/config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { existsSync, writeFileSync } from 'fs';
import * as os from 'os';
import * as path from 'path';
import {
JsonAstObject,
Expand All @@ -19,44 +21,88 @@ function getSchemaLocation(): string {

export const workspaceSchemaPath = getSchemaLocation();

function configFilePath(projectPath?: string): string | null {
const configNames = [ 'angular.json', '.angular.json' ];
const configNames = [ 'angular.json', '.angular.json' ];

function projectFilePath(projectPath?: string): string | null {
// 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(configNames, projectPath))
|| findUp(configNames, process.cwd())
|| findUp(configNames, __dirname);
}

let cachedWorkspace: experimental.workspace.Workspace | null | undefined = undefined;
export function getWorkspace(): experimental.workspace.Workspace | null {
if (cachedWorkspace != undefined) {
return cachedWorkspace;
function globalFilePath(): string | null {
const home = os.homedir();
if (!home) {
return null;
}

for (const name of configNames) {
const p = path.join(home, name);
if (existsSync(p)) {
return p;
}
}

return null;
}

const cachedWorkspaces = new Map<string, experimental.workspace.Workspace | null>();

export function getWorkspace(
level: 'local' | 'global' = 'local',
): experimental.workspace.Workspace | null {
const cached = cachedWorkspaces.get(level);
if (cached != undefined) {
return cached;
}

const configPath = configFilePath();
let configPath = level === 'local' ? projectFilePath() : globalFilePath();

if (!configPath) {
cachedWorkspace = null;
return null;
if (level === 'global') {
configPath = createGlobalSettings();
} else {
cachedWorkspaces.set(level, null);
return null;
}
}

const root = path.dirname(configPath);
const root = normalize(path.dirname(configPath));
const file = normalize(path.basename(configPath));
const workspace = new experimental.workspace.Workspace(
normalize(root),
root,
new NodeJsSyncHost(),
);

workspace.loadWorkspaceFromHost(normalize(path.basename(configPath))).subscribe();
cachedWorkspace = workspace;
workspace.loadWorkspaceFromHost(file).subscribe();
cachedWorkspaces.set(level, workspace);
return workspace;
}

export function getWorkspaceRaw(): [JsonAstObject | null, string] {
const configPath = configFilePath();
function createGlobalSettings(): string {
const home = os.homedir();
if (!home) {
throw new Error('No home directory found.');
}

const globalPath = path.join(home, configNames[1]);
writeFileSync(globalPath, JSON.stringify({ version: 1 }));

return globalPath;
}

export function getWorkspaceRaw(
level: 'local' | 'global' = 'local',
): [JsonAstObject | null, string | null] {
let configPath = level === 'local' ? projectFilePath() : globalFilePath();

if (!configPath) {
return null;
if (level === 'global') {
configPath = createGlobalSettings();
} else {
return [null, null];
}
}

let content;
Expand Down Expand Up @@ -89,19 +135,60 @@ export function validateWorkspace(json: JsonValue) {
return true;
}

export function getProjectByCwd(_workspace: experimental.workspace.Workspace): string | null {
// const cwd = process.cwd();
// TOOD: Implement project location logic
return null;
}

export function getPackageManager(): string {
const workspace = getWorkspace();
let workspace = getWorkspace();

if (workspace) {
const project = getProjectByCwd(workspace);
if (project && workspace.getProject(project).cli) {
const value = workspace.getProject(project).cli['packageManager'];
if (typeof value == 'string') {
return value;
}
} else if (workspace.getCli()) {
const value = workspace.getCli()['packageManager'];
if (typeof value == 'string') {
return value;
}
}
}

workspace = getWorkspace('global');
if (workspace && workspace.getCli()) {
const value = workspace.getCli()['packageManager'];
if (typeof value == 'string') {
return value;
}
}

return 'npm';
}

export function getDefaultSchematicCollection(): string {
const workspace = getWorkspace();
let workspace = getWorkspace('local');

if (workspace) {
const project = getProjectByCwd(workspace);
if (project && workspace.getProject(project).schematics) {
const value = workspace.getProject(project).schematics['defaultCollection'];
if (typeof value == 'string') {
return value;
}
} else if (workspace.getSchematics()) {
const value = workspace.getSchematics()['defaultCollection'];
if (typeof value == 'string') {
return value;
}
}
}

workspace = getWorkspace('global');
if (workspace && workspace.getSchematics()) {
const value = workspace.getSchematics()['defaultCollection'];
if (typeof value == 'string') {
Expand All @@ -113,13 +200,36 @@ export function getDefaultSchematicCollection(): string {
}

export function isWarningEnabled(warning: string): boolean {
const workspace = getWorkspace();
let workspace = getWorkspace('local');

if (workspace) {
const project = getProjectByCwd(workspace);
if (project && workspace.getProject(project).cli) {
const warnings = workspace.getProject(project).cli['warnings'];
if (typeof warnings == 'object' && !Array.isArray(warnings)) {
const value = warnings[warning];
if (typeof value == 'boolean') {
return value;
}
}
} else if (workspace.getCli()) {
const warnings = workspace.getCli()['warnings'];
if (typeof warnings == 'object' && !Array.isArray(warnings)) {
const value = warnings[warning];
if (typeof value == 'boolean') {
return value;
}
}
}
}

workspace = getWorkspace('global');
if (workspace && workspace.getCli()) {
const warnings = workspace.getCli()['warnings'];
if (typeof warnings == 'object' && !Array.isArray(warnings)) {
const value = warnings[warning];
if (value === false) {
return false;
if (typeof value == 'boolean') {
return value;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/tests/commands/config/config-get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {expectToFail} from '../../../utils/utils';

export default function() {
return Promise.resolve()
.then(() => expectToFail(() => ng('config', 'schematics.@schematics/angular.component.inlineStyle'))
.then(() => expectToFail(() => ng('config', 'schematics.@schematics/angular.component.inlineStyle')))
.then(() => ng('config', 'schematics.@schematics/angular.component.inlineStyle', 'false'))
.then(() => ng('config', 'schematics.@schematics/angular.component.inlineStyle'))
.then(({ stdout }) => {
Expand Down
30 changes: 30 additions & 0 deletions tests/e2e/tests/commands/config/config-global.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {ng} from '../../../utils/process';
import {expectToFail} from '../../../utils/utils';
import { expectFileToExist } from '../../../utils/fs';
import * as path from 'path';
import { homedir } from 'os';


export default function() {
return Promise.resolve()
.then(() => expectToFail(() => ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle')))
.then(() => ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle', 'false'))
.then(() => ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle'))
.then(({ stdout }) => {
if (!stdout.match(/false\n?/)) {
throw new Error(`Expected "false", received "${JSON.stringify(stdout)}".`);
}
})
.then(() => expectToFail(() => {
return ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle', 'INVALID_BOOLEAN');
}))
.then(() => ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle', 'true'))
.then(() => ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle'))
.then(({ stdout }) => {
if (!stdout.match(/true\n?/)) {
throw new Error(`Expected "true", received "${JSON.stringify(stdout)}".`);
}
})
.then(() => ng('config', '--global', 'schematics.@schematics/angular.component.inlineStyle', 'false'))
.then(() => expectFileToExist(path.join(homedir(), '.angular.json')));
}

0 comments on commit c34db58

Please sign in to comment.