From 7454dca9d1d69c86d5fc6600eadf6ad6242302ac Mon Sep 17 00:00:00 2001 From: Russell Bicknell Date: Fri, 13 Apr 2018 16:55:47 -0700 Subject: [PATCH 1/6] Call `npm install` if the `--npm` flag is passed or set in the config file. --- packages/cli/src/commands/install.ts | 8 +++++++- packages/cli/src/install/install.ts | 29 +++++++++++++++++++++------- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/packages/cli/src/commands/install.ts b/packages/cli/src/commands/install.ts index 873d0ea6f..3ed64d4e8 100644 --- a/packages/cli/src/commands/install.ts +++ b/packages/cli/src/commands/install.ts @@ -45,10 +45,16 @@ export class InstallCommand implements Command { }, ]; - async run(options: CommandOptions, _config: ProjectConfig): Promise { + async run(options: CommandOptions, config: ProjectConfig): Promise { // Defer dependency loading until this specific command is run const install = require('../install/install').install as typeof installTypeOnly; + + // Use `npm` from the config, if available and not passed as a CLI arg. + if (options.npm === undefined && config.npm !== undefined) { + options.npm = config.npm; + } + await install(options); } } diff --git a/packages/cli/src/install/install.ts b/packages/cli/src/install/install.ts index 973207750..86d644608 100644 --- a/packages/cli/src/install/install.ts +++ b/packages/cli/src/install/install.ts @@ -14,14 +14,17 @@ import * as bower from 'bower'; import {read as readBowerJson} from 'bower-json'; +import * as child_process from 'child_process'; import * as path from 'path'; import * as logging from 'plylog'; +import * as util from 'util'; import defaultBowerConfig = require('bower/lib/config'); import BowerLogger = require('bower-logger'); import StandardRenderer = require('bower/lib/renderers/StandardRenderer'); import BowerProject = require('bower/lib/core/Project'); +const exec = util.promisify(child_process.exec); const logger = logging.getLogger('cli.install'); type JsonValue = string|number|boolean|null|JsonObject|JsonArray; @@ -35,25 +38,37 @@ interface JsonArray extends Array {} export interface Options { variants?: boolean; offline?: boolean; + npm?: boolean; } export async function install(options?: Options): Promise { + if (options && options.npm) { + await npmInstall(); + return; + } + // default to false const offline = options == null ? false : options.offline === true; // default to false const variants = options == null ? false : options.variants === true; await Promise.all([ - installDefault(offline), - variants ? installVariants(offline) : Promise.resolve(), + bowerInstallDefault(offline), + variants ? bowerInstallVariants(offline) : Promise.resolve(), ]); } +async function npmInstall() { + logger.info('Installing npm dependencies...'); + await exec('npm install', {cwd: process.cwd()}); + logger.info('Finished installing npm dependencies.'); +} + /** * Performs a Bower install, optionally with a specific JSON configuration and * output directory. */ -async function _install( +async function _bowerInstall( offline: boolean, bowerJson?: JsonObject, componentDirectory?: string, @@ -90,13 +105,13 @@ async function _install( await project.install([], {save: false, offline}, config); } -async function installDefault(offline: boolean): Promise { +async function bowerInstallDefault(offline: boolean): Promise { logger.info(`Installing default Bower components...`); - await _install(offline); + await _bowerInstall(offline); logger.info(`Finished installing default Bower components`); } -async function installVariants(offline: boolean): Promise { +async function bowerInstallVariants(offline: boolean): Promise { const bowerJson = await new Promise((resolve, reject) => { const config = defaultBowerConfig({ save: false, @@ -120,7 +135,7 @@ async function installVariants(offline: boolean): Promise { const variantDirectory = `bower_components-${variantName}`; logger.info( `Installing variant ${variantName} to ${variantDirectory}...`); - await _install(offline, variantBowerJson, variantDirectory, variantName); + await _bowerInstall(offline, variantBowerJson, variantDirectory, variantName); logger.info(`Finished installing variant ${variantName}`); })); } From 3439242a3ecd6cf39ac935d8dc47139e625d7e05 Mon Sep 17 00:00:00 2001 From: Russell Bicknell Date: Fri, 13 Apr 2018 17:01:03 -0700 Subject: [PATCH 2/6] Update descriptions. --- packages/cli/src/args.ts | 5 +++-- packages/cli/src/commands/install.ts | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/cli/src/args.ts b/packages/cli/src/args.ts index f75dda67b..d20457cf8 100644 --- a/packages/cli/src/args.ts +++ b/packages/cli/src/args.ts @@ -70,8 +70,9 @@ export const globalArguments: ArgDescriptor[] = [ { name: 'npm', type: Boolean, - description: 'Sets npm mode: component directory is "node_modules" ' + - 'and the package name is read from package.json', + description: 'Sets npm mode: dependencies are installed from npm, ' + + 'component directory is "node_modules" and the package name is read ' + + 'from package.json', }, { name: 'module-resolution', diff --git a/packages/cli/src/commands/install.ts b/packages/cli/src/commands/install.ts index 3ed64d4e8..7b92d61ac 100644 --- a/packages/cli/src/commands/install.ts +++ b/packages/cli/src/commands/install.ts @@ -28,20 +28,21 @@ export class InstallCommand implements Command { aliases = ['i']; // TODO(justinfagnani): Expand and link to eventual doc on variants. - description = 'installs Bower dependencies, optionally installing "variants"'; + description = 'Installs project dependencies from npm or Bower (optionally ' + + 'installing "variants").'; args = [ { name: 'variants', type: Boolean, defaultValue: false, - description: 'Whether to install variants' + description: 'Whether to install Bower variants' }, { name: 'offline', type: Boolean, defaultValue: false, - description: 'Don\'t hit the network' + description: 'Don\'t hit the network when installing Bower dependencies' }, ]; From 059521b78855c0e8224d6e1d80844ad182e5e60a Mon Sep 17 00:00:00 2001 From: Russell Bicknell Date: Fri, 13 Apr 2018 17:04:02 -0700 Subject: [PATCH 3/6] Update old integration test that assumed `polymer install` didn't support npm. --- packages/cli/src/test/integration/integration_test.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/cli/src/test/integration/integration_test.ts b/packages/cli/src/test/integration/integration_test.ts index 4498861f1..6d5e27877 100644 --- a/packages/cli/src/test/integration/integration_test.ts +++ b/packages/cli/src/test/integration/integration_test.ts @@ -16,9 +16,6 @@ import {createApplicationGenerator} from '../../init/application/application'; import {runCommand} from './run-command'; import {createElementGenerator} from '../../init/element/element'; import {createGithubGenerator} from '../../init/github'; -import * as child_process from 'child_process'; -import * as util from 'util'; -const exec = util.promisify(child_process.exec); // A zero priveledge github token of a nonce account, used for quota. const githubToken = '8d8622bf09bb1d85cb411b5e475a35e742a7ce35'; @@ -42,9 +39,7 @@ suite('integration tests', function() { await runGenerator(createElementGenerator('polymer-3.x')) .withPrompts({name: 'my-element'}) // Mock the prompt answers .toPromise(); - // TODO(#118): Use `polymer install` once it supports installing npm - // packages. - await exec('npm install', {cwd: dir}); + await runCommand(binPath, ['install'], {cwd: dir}); // TODO(#130): Add this back in when `polymer lint` has a Polymer 3 // option. From b8ba2c22455e0c94d14af67cb6e4a397314379f1 Mon Sep 17 00:00:00 2001 From: Russell Bicknell Date: Mon, 16 Apr 2018 14:01:07 -0700 Subject: [PATCH 4/6] Remove `util.promisify` use (not available in Node.js 6). --- packages/cli/src/install/install.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/cli/src/install/install.ts b/packages/cli/src/install/install.ts index 86d644608..4df6d6304 100644 --- a/packages/cli/src/install/install.ts +++ b/packages/cli/src/install/install.ts @@ -17,14 +17,12 @@ import {read as readBowerJson} from 'bower-json'; import * as child_process from 'child_process'; import * as path from 'path'; import * as logging from 'plylog'; -import * as util from 'util'; import defaultBowerConfig = require('bower/lib/config'); import BowerLogger = require('bower-logger'); import StandardRenderer = require('bower/lib/renderers/StandardRenderer'); import BowerProject = require('bower/lib/core/Project'); -const exec = util.promisify(child_process.exec); const logger = logging.getLogger('cli.install'); type JsonValue = string|number|boolean|null|JsonObject|JsonArray; @@ -43,8 +41,7 @@ export interface Options { export async function install(options?: Options): Promise { if (options && options.npm) { - await npmInstall(); - return; + return npmInstall(); } // default to false @@ -60,7 +57,11 @@ export async function install(options?: Options): Promise { async function npmInstall() { logger.info('Installing npm dependencies...'); - await exec('npm install', {cwd: process.cwd()}); + await new Promise((resolve, reject) => { + child_process.exec('npm install', {cwd: process.cwd()}, (error, stdout, stderr) => { + error ? reject(error) : resolve([stdout, stderr]); + }); + }); logger.info('Finished installing npm dependencies.'); } From 58b7467e9fcbba30b92ceab3b26a70147d725701 Mon Sep 17 00:00:00 2001 From: Russell Bicknell Date: Mon, 16 Apr 2018 14:18:10 -0700 Subject: [PATCH 5/6] Copy `--npm` description from cli to polyserve. --- packages/polyserve/src/args.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/polyserve/src/args.ts b/packages/polyserve/src/args.ts index 4d12904f8..9bc02680d 100644 --- a/packages/polyserve/src/args.ts +++ b/packages/polyserve/src/args.ts @@ -91,8 +91,9 @@ export const args: ArgDescriptor[] = [ }, { name: 'npm', - description: 'Sets npm mode: component directory is "node_modules" and ' + - 'the package name is read from package.json', + description: 'Sets npm mode: dependencies are installed from npm, ' + + 'component directory is "node_modules" and the package name is read ' + + 'from package.json', type: Boolean, }, { From 76b2aad34bead278d2f548352d8d9d8b5d8d2476 Mon Sep 17 00:00:00 2001 From: Russell Bicknell Date: Mon, 16 Apr 2018 15:55:51 -0700 Subject: [PATCH 6/6] Move promisified `exec` to install command. --- packages/cli/src/install/install.ts | 14 +++++++++----- .../cli/src/test/integration/integration_test.ts | 9 --------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/packages/cli/src/install/install.ts b/packages/cli/src/install/install.ts index 4df6d6304..e5505fc78 100644 --- a/packages/cli/src/install/install.ts +++ b/packages/cli/src/install/install.ts @@ -25,6 +25,14 @@ import BowerProject = require('bower/lib/core/Project'); const logger = logging.getLogger('cli.install'); +async function exec(command: string, opts: child_process.ExecOptions) { + return new Promise<[string, string]>((resolve, reject) => { + child_process.exec(command, opts, (err, stdout, stderr) => { + err ? reject(err) : resolve([stdout, stderr]); + }); + }); +} + type JsonValue = string|number|boolean|null|JsonObject|JsonArray; interface JsonObject { @@ -57,11 +65,7 @@ export async function install(options?: Options): Promise { async function npmInstall() { logger.info('Installing npm dependencies...'); - await new Promise((resolve, reject) => { - child_process.exec('npm install', {cwd: process.cwd()}, (error, stdout, stderr) => { - error ? reject(error) : resolve([stdout, stderr]); - }); - }); + await exec('npm install', {cwd: process.cwd()}); logger.info('Finished installing npm dependencies.'); } diff --git a/packages/cli/src/test/integration/integration_test.ts b/packages/cli/src/test/integration/integration_test.ts index bc00a891b..6d5e27877 100644 --- a/packages/cli/src/test/integration/integration_test.ts +++ b/packages/cli/src/test/integration/integration_test.ts @@ -16,7 +16,6 @@ import {createApplicationGenerator} from '../../init/application/application'; import {runCommand} from './run-command'; import {createElementGenerator} from '../../init/element/element'; import {createGithubGenerator} from '../../init/github'; -import * as child_process from 'child_process'; // A zero priveledge github token of a nonce account, used for quota. const githubToken = '8d8622bf09bb1d85cb411b5e475a35e742a7ce35'; @@ -26,14 +25,6 @@ const githubToken = '8d8622bf09bb1d85cb411b5e475a35e742a7ce35'; const isWindows = process.platform === 'win32'; const skipOnWindows = isWindows ? test.skip : test; -async function exec(command: string, opts: child_process.ExecOptions) { - return new Promise<[string, string]>((resolve, reject) => { - child_process.exec(command, opts, (err, stdout, stderr) => { - err ? reject(err) : resolve([stdout, stderr]); - }); - }); -} - suite('integration tests', function() { const binPath = path.join(__dirname, '../../../', 'bin', 'polymer.js');