Skip to content

Commit

Permalink
feat(@angular/cli): Add options for third party package manager (#4321)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `--skip-npm` flag is now named `--skip-install`
  • Loading branch information
sumitarora authored and hansl committed Feb 9, 2017
1 parent 4e06612 commit d2849c7
Show file tree
Hide file tree
Showing 22 changed files with 126 additions and 55 deletions.
2 changes: 1 addition & 1 deletion docs/documentation/new.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Default applications are created in a directory of the same name, with an initia
## Options
`--dry-run` (`-d`) run through without making any changes

`--skip-npm` (`-sn`) skip installing npm packages
`--skip-install` (`-si`) skip installing packages

`--skip-git` (`-sg`) skip initializing a git repository

Expand Down
2 changes: 1 addition & 1 deletion docs/documentation/update.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Initialization is done in-place, meaning that the generated application is initi
## Options
`--dry-run` (`-d`) run through without making any changes

`--skip-npm` (`-sn`) skip installing npm packages
`--skip-install` (`-si`) skip installing packages

`--skip-git` (`-sg`) skip initializing a git repository

Expand Down
2 changes: 1 addition & 1 deletion packages/@angular/cli/commands/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const InitCommand: any = Command.extend({
{ name: 'verbose', type: Boolean, default: false, aliases: ['v'] },
{ name: 'link-cli', type: Boolean, default: false, aliases: ['lc'] },
{ name: 'ng4', type: Boolean, default: false },
{ name: 'skip-npm', type: Boolean, default: false, aliases: ['sn'] },
{ name: 'skip-install', type: Boolean, default: false, aliases: ['si'] },
{ name: 'skip-git', type: Boolean, default: false, aliases: ['sg'] },
{ name: 'skip-tests', type: Boolean, default: false, aliases: ['st'] },
{ name: 'skip-commit', type: Boolean, default: false, aliases: ['sc'] },
Expand Down
2 changes: 1 addition & 1 deletion packages/@angular/cli/commands/new.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const NewCommand = Command.extend({
{ name: 'verbose', type: Boolean, default: false, aliases: ['v'] },
{ name: 'link-cli', type: Boolean, default: false, aliases: ['lc'] },
{ name: 'ng4', type: Boolean, default: false },
{ name: 'skip-npm', type: Boolean, default: false, aliases: ['sn'] },
{ name: 'skip-install', type: Boolean, default: false, aliases: ['si'] },
{ name: 'skip-git', type: Boolean, default: false, aliases: ['sg'] },
{ name: 'skip-tests', type: Boolean, default: false, aliases: ['st'] },
{ name: 'skip-commit', type: Boolean, default: false, aliases: ['sc'] },
Expand Down
5 changes: 5 additions & 0 deletions packages/@angular/cli/lib/config/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,11 @@
},
"additionalProperties": false
},
"packageManager": {
"enum": [ "npm", "cnpm", "yarn", "default" ],
"default": "default",
"type": "string"
},
"warnings": {
"description": "Allow people to disable console warnings.",
"type": "object",
Expand Down
13 changes: 9 additions & 4 deletions packages/@angular/cli/tasks/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import * as chalk from 'chalk';
import LinkCli from '../tasks/link-cli';
import NpmInstall from '../tasks/npm-install';
import { validateProjectName } from '../utilities/validate-project-name';
import {checkYarnOrCNPM} from '../utilities/check-package-manager';
import {CliConfig} from '../models/config';

const Task = require('../ember-cli/lib/models/task');
const Promise = require('../ember-cli/lib/ext/promise');
Expand All @@ -13,7 +15,7 @@ const GitInit = require('../tasks/git-init');
export default Task.extend({
run: function (commandOptions: any, rawArgs: string[]) {
if (commandOptions.dryRun) {
commandOptions.skipNpm = true;
commandOptions.skipInstall = true;
}

const installBlueprint = new this.tasks.InstallBlueprint({
Expand All @@ -32,10 +34,12 @@ export default Task.extend({
}

let npmInstall: any;
if (!commandOptions.skipNpm) {
if (!commandOptions.skipInstall) {
const packageManager = CliConfig.fromGlobal().get('packageManager');
npmInstall = new NpmInstall({
ui: this.ui,
project: this.project
project: this.project,
packageManager
});
}

Expand Down Expand Up @@ -87,7 +91,7 @@ export default Task.extend({
}
})
.then(function () {
if (!commandOptions.skipNpm) {
if (!commandOptions.skipInstall) {
return npmInstall.run();
}
})
Expand All @@ -96,6 +100,7 @@ export default Task.extend({
return linkCli.run();
}
})
.then(checkYarnOrCNPM)
.then(() => {
this.ui.writeLine(chalk.green(`Project '${packageName}' successfully created.`));
});
Expand Down
10 changes: 7 additions & 3 deletions packages/@angular/cli/tasks/npm-install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@ import {exec} from 'child_process';
export default Task.extend({
run: function() {
const ui = this.ui;
let packageManager = this.packageManager;
if (packageManager === 'default') {
packageManager = 'npm';
}

return new Promise(function(resolve, reject) {
ui.writeLine(chalk.green('Installing packages for tooling via npm.'));
exec('npm install',
ui.writeLine(chalk.green(`Installing packages for tooling via ${packageManager}.`));
exec(`${packageManager} install`,
(err: NodeJS.ErrnoException, stdout: string, stderr: string) => {
if (err) {
ui.writeLine(stderr);
ui.writeLine(chalk.red('Package install failed, see above.'));
reject();
} else {
ui.writeLine(chalk.green('Installed packages for tooling via npm.'));
ui.writeLine(chalk.green(`Installed packages for tooling via ${packageManager}.`));
resolve();
}
});
Expand Down
38 changes: 38 additions & 0 deletions packages/@angular/cli/utilities/check-package-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import * as chalk from 'chalk';
import {exec} from 'child_process';
import {CliConfig} from '../models/config';

const Promise = require('../ember-cli/lib/ext/promise');
const execPromise = Promise.denodeify(exec);
const packageManager = CliConfig.fromGlobal().get('packageManager');


export function checkYarnOrCNPM() {
if (packageManager !== 'default') {
return Promise.resolve();
}

return Promise
.all([checkYarn(), checkCNPM()])
.then((data: Array<boolean>) => {
const [isYarnInstalled, isCNPMInstalled] = data;
if (isYarnInstalled && isCNPMInstalled) {
console.log(chalk.yellow('You can `ng set --global packageManager=yarn` '
+ 'or `ng set --global packageManager=cnpm`.'));
} else if (isYarnInstalled) {
console.log(chalk.yellow('You can `ng set --global packageManager=yarn`.'));
} else if (isCNPMInstalled) {
console.log(chalk.yellow('You can `ng set --global packageManager=cnpm`.'));
}
});
}

function checkYarn() {
return execPromise('yarn --version')
.then(() => true, () => false);
}

function checkCNPM() {
return execPromise('cnpm --version')
.then(() => true, () => false);
}
4 changes: 3 additions & 1 deletion packages/@ngtools/json-schema/src/schema-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,9 @@ class EnumSchemaTreeNode extends LeafSchemaTreeNode<any> {
return v;
}

get type() { return 'any'; }
get type() {
return this._schema['type'] || 'any';
}
get tsType(): null { return null; }
serialize(serializer: Serializer) { serializer.outputEnum(this); }
}
Expand Down
2 changes: 1 addition & 1 deletion tests/acceptance/destroy.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe('Acceptance: ng destroy', function () {
return tmp.setup('./tmp').then(function () {
process.chdir('./tmp');
}).then(function () {
return ng(['new', 'foo', '--skip-npm']);
return ng(['new', 'foo', '--skip-install']);
});
});

Expand Down
2 changes: 1 addition & 1 deletion tests/acceptance/generate-class.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('Acceptance: ng generate class', function () {
return tmp.setup('./tmp').then(function () {
process.chdir('./tmp');
}).then(function () {
return ng(['new', 'foo', '--skip-npm']);
return ng(['new', 'foo', '--skip-install']);
});
});

Expand Down
2 changes: 1 addition & 1 deletion tests/acceptance/generate-component.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('Acceptance: ng generate component', function () {
return tmp.setup('./tmp').then(function () {
process.chdir('./tmp');
}).then(function () {
return ng(['new', 'foo', '--skip-npm']);
return ng(['new', 'foo', '--skip-install']);
});
});

Expand Down
2 changes: 1 addition & 1 deletion tests/acceptance/generate-directive.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('Acceptance: ng generate directive', function () {
return tmp.setup('./tmp').then(function () {
process.chdir('./tmp');
}).then(function () {
return ng(['new', 'foo', '--skip-npm']);
return ng(['new', 'foo', '--skip-install']);
});
});

Expand Down
2 changes: 1 addition & 1 deletion tests/acceptance/generate-module.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ describe('Acceptance: ng generate module', function () {
return tmp.setup('./tmp').then(function () {
process.chdir('./tmp');
}).then(function () {
return ng(['new', 'foo', '--skip-npm']);
return ng(['new', 'foo', '--skip-install']);
});
});

Expand Down
2 changes: 1 addition & 1 deletion tests/acceptance/generate-pipe.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ describe('Acceptance: ng generate pipe', function () {
return tmp.setup('./tmp').then(function () {
process.chdir('./tmp');
}).then(function () {
return ng(['new', 'foo', '--skip-npm']);
return ng(['new', 'foo', '--skip-install']);
});
});

Expand Down
2 changes: 1 addition & 1 deletion tests/acceptance/generate-route.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ xdescribe('Acceptance: ng generate route', function () {
return tmp.setup('./tmp').then(function () {
process.chdir('./tmp');
}).then(function () {
return ng(['new', 'foo', '--skip-npm']);
return ng(['new', 'foo', '--skip-install']);
});
});

Expand Down
2 changes: 1 addition & 1 deletion tests/acceptance/generate-service.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('Acceptance: ng generate service', function () {
return tmp.setup('./tmp').then(function () {
process.chdir('./tmp');
}).then(function () {
return ng(['new', 'foo', '--skip-npm']);
return ng(['new', 'foo', '--skip-install']);
});
});

Expand Down
32 changes: 16 additions & 16 deletions tests/acceptance/init.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ describe('Acceptance: ng update', function () {
it('ng init does the same as ng update', function () {
return ng([
'init',
'--skip-npm'
'--skip-install'
]).then(confirmBlueprinted);
});

Expand All @@ -109,7 +109,7 @@ describe('Acceptance: ng update', function () {
.then(function () {
return ng([
'init',
'--skip-npm',
'--skip-install',
'--name',
'tmp'
]);
Expand All @@ -121,79 +121,79 @@ describe('Acceptance: ng update', function () {
});

it('init an already init\'d folder', function () {
return ng(['init', '--skip-npm'])
return ng(['init', '--skip-install'])
.then(function () {
return ng(['init', '--skip-npm']);
return ng(['init', '--skip-install']);
})
.then(confirmBlueprinted);
});

it('init a single file', function () {
return ng(['init', 'package.json', '--skip-npm'])
return ng(['init', 'package.json', '--skip-install'])
.then(function () {
return 'package.json';
})
.then(confirmGlobBlueprinted);
});

it('init a single file on already init\'d folder', function () {
return ng(['init', '--skip-npm'])
return ng(['init', '--skip-install'])
.then(function () {
return ng(['init', 'package.json', '--skip-npm']);
return ng(['init', 'package.json', '--skip-install']);
})
.then(confirmBlueprinted);
});

it('init multiple files by glob pattern', function () {
return ng(['init', 'src/**', '--skip-npm'])
return ng(['init', 'src/**', '--skip-install'])
.then(function () {
return 'src/**';
})
.then(confirmGlobBlueprinted);
});

it('init multiple files by glob pattern on already init\'d folder', function () {
return ng(['init', '--skip-npm'])
return ng(['init', '--skip-install'])
.then(function () {
return ng(['init', 'src/**', '--skip-npm']);
return ng(['init', 'src/**', '--skip-install']);
})
.then(confirmBlueprinted);
});

it('init multiple files by glob patterns', function () {
return ng(['init', 'src/**', 'package.json', '--skip-npm'])
return ng(['init', 'src/**', 'package.json', '--skip-install'])
.then(function () {
return '{src/**,package.json}';
})
.then(confirmGlobBlueprinted);
});

it('init multiple files by glob patterns on already init\'d folder', function () {
return ng(['init', '--skip-npm'])
return ng(['init', '--skip-install'])
.then(function () {
return ng(['init', 'src/**', 'package.json', '--skip-npm']);
return ng(['init', 'src/**', 'package.json', '--skip-install']);
})
.then(confirmBlueprinted);
});

it('ng update --inline-template does not generate a template file', () => {
return ng(['init', '--skip-npm', '--skip-git', '--inline-template'])
return ng(['init', '--skip-install', '--skip-git', '--inline-template'])
.then(() => {
const templateFile = path.join('src', 'app', 'app.component.html');
expect(existsSync(templateFile)).to.equal(false);
});
});

it('ng update --inline-style does not gener a style file', () => {
return ng(['init', '--skip-npm', '--skip-git', '--inline-style'])
return ng(['init', '--skip-install', '--skip-git', '--inline-style'])
.then(() => {
const styleFile = path.join('src', 'app', 'app.component.css');
expect(existsSync(styleFile)).to.equal(false);
});
});

it('should skip spec files when passed --skip-tests', () => {
return ng(['init', '--skip-npm', '--skip-git', '--skip-tests'])
return ng(['init', '--skip-install', '--skip-git', '--skip-tests'])
.then(() => {
const specFile = path.join('src', 'app', 'app.component.spec.ts');
expect(existsSync(specFile)).to.equal(false);
Expand Down
Loading

0 comments on commit d2849c7

Please sign in to comment.