Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(commands): lazy load commands #3805

Merged
merged 2 commits into from
Dec 31, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
39 changes: 39 additions & 0 deletions packages/angular-cli/commands/build.run.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Version } from '../upgrade/version';
import WebpackBuild from '../tasks/build-webpack';
import WebpackBuildWatch from '../tasks/build-webpack-watch';
import { BuildOptions } from './build';

export default function buildRun(commandOptions: BuildOptions) {
if (commandOptions.environment === '') {
if (commandOptions.target === 'development') {
commandOptions.environment = 'dev';
}
if (commandOptions.target === 'production') {
commandOptions.environment = 'prod';
}
}

const project = this.project;

// Check angular version.
Version.assertAngularVersionIs2_3_1OrHigher(project.root);

const ui = this.ui;
const buildTask = commandOptions.watch ?
new WebpackBuildWatch({
cliProject: project,
ui: ui,
outputPath: commandOptions.outputPath,
target: commandOptions.target,
environment: commandOptions.environment
}) :
new WebpackBuild({
cliProject: project,
ui: ui,
outputPath: commandOptions.outputPath,
target: commandOptions.target,
environment: commandOptions.environment,
});

return buildTask.run(commandOptions);
}
36 changes: 1 addition & 35 deletions packages/angular-cli/commands/build.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import {Version} from '../upgrade/version';
const Command = require('../ember-cli/lib/models/command');
import WebpackBuild from '../tasks/build-webpack';
import WebpackBuildWatch from '../tasks/build-webpack-watch';

export interface BuildOptions {
target?: string;
Expand Down Expand Up @@ -52,38 +49,7 @@ const BuildCommand = Command.extend({
],

run: function (commandOptions: BuildOptions) {
if (commandOptions.environment === '') {
if (commandOptions.target === 'development') {
commandOptions.environment = 'dev';
}
if (commandOptions.target === 'production') {
commandOptions.environment = 'prod';
}
}

const project = this.project;

// Check angular version.
Version.assertAngularVersionIs2_3_1OrHigher(project.root);

const ui = this.ui;
const buildTask = commandOptions.watch ?
new WebpackBuildWatch({
cliProject: project,
ui: ui,
outputPath: commandOptions.outputPath,
target: commandOptions.target,
environment: commandOptions.environment
}) :
new WebpackBuild({
cliProject: project,
ui: ui,
outputPath: commandOptions.outputPath,
target: commandOptions.target,
environment: commandOptions.environment,
});

return buildTask.run(commandOptions);
return require('./build.run').default.call(this, commandOptions);
}
});

Expand Down
4 changes: 2 additions & 2 deletions packages/angular-cli/commands/e2e.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const Command = require('../ember-cli/lib/models/command');
import {E2eTask} from '../tasks/e2e';
import {CliConfig} from '../models/config';
import { CliConfig } from '../models/config';

const E2eCommand = Command.extend({
name: 'e2e',
description: 'Run e2e tests in existing project',
works: 'insideProject',
run: function () {
const E2eTask = require('../tasks/e2e').E2eTask;
this.project.ngConfig = this.project.ngConfig || CliConfig.fromProject();

const e2eTask = new E2eTask({
Expand Down
220 changes: 220 additions & 0 deletions packages/angular-cli/commands/github-pages-deploy.run.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
const SilentError = require('silent-error');
import denodeify = require('denodeify');

import { exec } from 'child_process';
import * as chalk from 'chalk';
import * as fs from 'fs';
import * as fse from 'fs-extra';
import * as path from 'path';
import WebpackBuild from '../tasks/build-webpack';
import CreateGithubRepo from '../tasks/create-github-repo';
import { CliConfig } from '../models/config';
import { GithubPagesDeployOptions } from './github-pages-deploy';

const fsReadDir = <any>denodeify(fs.readdir);
const fsCopy = <any>denodeify(fse.copy);

export default function githubPagesDeployRun(options: GithubPagesDeployOptions, rawArgs: string[]) {
const ui = this.ui;
const root = this.project.root;
const execOptions = {
cwd: root
};

if (options.environment === '') {
if (options.target === 'development') {
options.environment = 'dev';
}
if (options.target === 'production') {
options.environment = 'prod';
}
}

const projectName = this.project.pkg.name;

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

let ghPagesBranch = 'gh-pages';
let destinationBranch = options.userPage ? 'master' : ghPagesBranch;
let initialBranch: string;
let branchErrMsg = ' You might also need to return to the initial branch manually.';

// declared here so that tests can stub exec
const execPromise = <(cmd: string, options?: any) => Promise<string>>denodeify(exec);

const buildTask = new WebpackBuild({
ui: this.ui,
cliProject: this.project,
target: options.target,
environment: options.environment,
outputPath: outDir
});

/**
* BaseHref tag setting logic:
* First, use --base-href flag value if provided.
* Else if --user-page is true, then keep baseHref default as declared in index.html.
* Otherwise auto-replace with `/${projectName}/`.
*/
const baseHref = options.baseHref || (options.userPage ? null : `/${projectName}/`);

const buildOptions = {
target: options.target,
environment: options.environment,
outputPath: outDir,
baseHref: baseHref,
};

const createGithubRepoTask = new CreateGithubRepo({
ui: this.ui,
project: this.project
});

const createGithubRepoOptions = {
projectName,
ghUsername: options.ghUsername,
ghToken: options.ghToken
};

return checkForPendingChanges()
.then(build)
.then(saveStartingBranchName)
.then(createGitHubRepoIfNeeded)
.then(checkoutGhPages)
.then(cleanGhPagesBranch)
.then(copyFiles)
.then(createNotFoundPage)
.then(addAndCommit)
.then(returnStartingBranch)
.then(pushToGitRepo)
.then(printProjectUrl)
.catch(failGracefully);

function checkForPendingChanges() {
return execPromise('git status --porcelain')
.then((stdout: string) => {
if (/\w+/m.test(stdout)) {
let msg = 'Uncommitted file changes found! Please commit all changes before deploying.';
return Promise.reject(new SilentError(msg));
}
});
}

function build() {
if (options.skipBuild) { return Promise.resolve(); }
return buildTask.run(buildOptions);
}

function saveStartingBranchName() {
return execPromise('git rev-parse --abbrev-ref HEAD')
.then((stdout: string) => initialBranch = stdout.replace(/\s/g, ''));
}

function createGitHubRepoIfNeeded() {
return execPromise('git remote -v')
.then(function (stdout) {
if (!/origin\s+(https:\/\/|git@)github\.com/m.test(stdout)) {
return createGithubRepoTask.run(createGithubRepoOptions)
.then(() => {
// only push starting branch if it's not the destinationBranch
// this happens commonly when using github user pages, since
// they require the destination branch to be 'master'
if (destinationBranch !== initialBranch) {
execPromise(`git push -u origin ${initialBranch}`);
}
});
}
});
}

function checkoutGhPages() {
return execPromise(`git checkout ${ghPagesBranch}`)
.catch(createGhPagesBranch);
}

function createGhPagesBranch() {
return execPromise(`git checkout --orphan ${ghPagesBranch}`)
.then(() => execPromise('git rm --cached -r .', execOptions))
.then(() => execPromise('git add .gitignore', execOptions))
.then(() => execPromise('git clean -f -d', execOptions))
.then(() => execPromise(`git commit -m \"initial ${ghPagesBranch} commit\"`));
}

function cleanGhPagesBranch() {
return execPromise('git ls-files')
.then(function (stdout) {
let files = '';
stdout.split(/\n/).forEach(function (f) {
// skip .gitignore & 404.html
if ((f != '') && (f != '.gitignore') && (f != '404.html')) {
files = files.concat(`"${f}" `);
}
});
return execPromise(`git rm -r ${files}`)
.catch(() => {
// Ignoring errors when trying to erase files.
});
});
}

function copyFiles() {
return fsReadDir(outDir)
.then((files: string[]) => Promise.all(files.map((file) => {
if (file === '.gitignore') {
// don't overwrite the .gitignore file
return Promise.resolve();
}
return fsCopy(path.join(outDir, file), path.join('.', file));
})));
}

function createNotFoundPage() {
const indexHtml = path.join(root, indexFilename);
const notFoundPage = path.join(root, '404.html');
return fsCopy(indexHtml, notFoundPage);
}

function addAndCommit() {
return execPromise('git add .', execOptions)
.then(() => execPromise(`git commit -m "${options.message}"`))
.catch(() => {
let msg = 'No changes found. Deployment skipped.';
return returnStartingBranch()
.then(() => Promise.reject(new SilentError(msg)))
.catch(() => Promise.reject(new SilentError(msg.concat(branchErrMsg))));
});
}

function returnStartingBranch() {
return execPromise(`git checkout ${initialBranch}`);
}

function pushToGitRepo() {
return execPromise(`git push origin ${ghPagesBranch}:${destinationBranch}`)
.catch((err) => returnStartingBranch()
.catch(() => Promise.reject(err)));
}

function printProjectUrl() {
return execPromise('git remote -v')
.then((stdout) => {
let match = stdout.match(/origin\s+(?:https:\/\/|git@)github\.com(?:\:|\/)([^\/]+)/m);
let userName = match[1].toLowerCase();
let url = `https://${userName}.github.io/${options.userPage ? '' : (baseHref + '/')}`;
ui.writeLine(chalk.green(`Deployed! Visit ${url}`));
ui.writeLine('Github pages might take a few minutes to show the deployed site.');
});
}

function failGracefully(error: Error) {
if (error && (/git clean/.test(error.message) || /Permission denied/.test(error.message))) {
ui.writeLine(error.message);
let msg = 'There was a permissions error during git file operations, ' +
'please close any open project files/folders and try again.';
return Promise.reject(new SilentError(msg.concat(branchErrMsg)));
} else {
return Promise.reject(error);
}
}
}