Skip to content

Commit

Permalink
feat(cli): add hooks to capacitor commands for custom platforms (#3091)
Browse files Browse the repository at this point in the history
Co-authored-by: Dan Imhoff <[email protected]>
Co-authored-by: IT-MikeS <[email protected]>
  • Loading branch information
3 people committed Jul 1, 2020
1 parent 34730d5 commit c2133c5
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 95 deletions.
38 changes: 36 additions & 2 deletions cli/src/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Config } from './config';
import { exec } from 'child_process';
import { exec, spawn } from 'child_process';
import { setTimeout } from 'timers';
import { basename, dirname, join, parse, resolve } from 'path';
import { copyAsync, existsAsync, readFileAsync, renameAsync, writeFileAsync } from './util/fs';
Expand Down Expand Up @@ -252,6 +252,21 @@ export function wait(time: number) {
return new Promise((resolve) => setTimeout(resolve, time));
}

export function runPlatformHook(command: string): Promise<string> {
return new Promise((resolve, reject) => {
const cmd = spawn(command, {
stdio: 'inherit',
shell: true
});
cmd.on('close', (code) => {
resolve('');
});
cmd.on('error', (err) => {
reject(err);
});
});
}

export function runCommand(command: string): Promise<string> {
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
Expand Down Expand Up @@ -420,7 +435,26 @@ export async function checkPlatformVersions(config: Config, platform: string) {
}
}

export function resolveNode(config: Config, ...pathSegments: any[]): string | null {
export function resolvePlatform(config: Config, platform: string): string | null {
if (platform[0] !== '@') {
const core = resolveNode(config, `@capacitor/${platform}`);

if (core) {
return core;
}

const community = resolveNode(config, `@capacitor-community/${platform}`);

if (community) {
return community;
}
}

// third-party
return resolveNode(config, platform);
}

export function resolveNode(config: Config, ...pathSegments: string[]): string | null {
const id = pathSegments[0];
const path = pathSegments.slice(1);

Expand Down
73 changes: 41 additions & 32 deletions cli/src/tasks/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,59 @@ import { addElectron } from '../electron/add';
import { addIOS, addIOSChecks } from '../ios/add';
import { editProjectSettingsAndroid } from '../android/common';
import { editProjectSettingsIOS } from '../ios/common';
import { check, checkAppConfig, checkPackage, checkWebDir, log, logError, logFatal, logInfo, runTask, writePrettyJSON } from '../common';
import { check, checkAppConfig, checkPackage, checkWebDir, hasYarn, log, logError, logFatal, logInfo, resolvePlatform, runCommand, runPlatformHook, runTask, writePrettyJSON } from '../common';
import { sync } from './sync';

import chalk from 'chalk';
import { resolve } from 'path';

export async function addCommand(config: Config, selectedPlatformName: string) {
if (selectedPlatformName && !config.isValidPlatform(selectedPlatformName)) {
const platformFolder = resolvePlatform(config, selectedPlatformName);
if (platformFolder) {
const result = await runPlatformHook(`cd "${platformFolder}" && ${await hasYarn(config) ? 'yarn' : 'npm'} run capacitor:add`);
log(result);
} else {
logError(`platform ${selectedPlatformName} not found`);
}
} else {
const platformName = await config.askPlatform(
selectedPlatformName,
`Please choose a platform to add:`
);

const platformName = await config.askPlatform(
selectedPlatformName,
`Please choose a platform to add:`
);

if (platformName === config.web.name) {
webWarning();
return;
}
if (platformName === config.web.name) {
webWarning();
return;
}

const existingPlatformDir = config.platformDirExists(platformName);
if (existingPlatformDir) {
logFatal(`"${platformName}" platform already exists.
To add a new "${platformName}" platform, please remove "${existingPlatformDir}" and run this command again.
WARNING! your native IDE project will be completely removed.`);
}
const existingPlatformDir = config.platformDirExists(platformName);
if (existingPlatformDir) {
logFatal(`"${platformName}" platform already exists.
To add a new "${platformName}" platform, please remove "${existingPlatformDir}" and run this command again.
WARNING! your native IDE project will be completely removed.`);
}

try {
await check(
config,
[checkPackage, checkAppConfig, ...addChecks(config, platformName)]
);
await generateCapacitorConfig(config);
await check(config, [checkWebDir]);
await doAdd(config, platformName);
await editPlatforms(config, platformName);
try {
await check(
config,
[checkPackage, checkAppConfig, ...addChecks(config, platformName)]
);
await generateCapacitorConfig(config);
await check(config, [checkWebDir]);
await doAdd(config, platformName);
await editPlatforms(config, platformName);

if (shouldSync(config, platformName)) {
await sync(config, platformName, false);
}
if (shouldSync(config, platformName)) {
await sync(config, platformName, false);
}

if (platformName === config.ios.name || platformName === config.android.name) {
log(chalk`\nNow you can run {green {bold npx cap open ${platformName}}} to launch ${platformName === config.ios.name ? 'Xcode' : 'Android Studio'}`);
if (platformName === config.ios.name || platformName === config.android.name) {
log(chalk`\nNow you can run {green {bold npx cap open ${platformName}}} to launch ${platformName === config.ios.name ? 'Xcode' : 'Android Studio'}`);
}
} catch (e) {
logFatal(e);
}
} catch (e) {
logFatal(e);
}
}

Expand Down
30 changes: 20 additions & 10 deletions cli/src/tasks/copy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Config } from '../config';
import { checkWebDir, logError, logFatal, logInfo, resolveNode, runTask } from '../common';
import { checkWebDir, hasYarn, log, logError, logFatal, logInfo, resolveNode, resolvePlatform, runCommand, runPlatformHook, runTask } from '../common';
import { existsAsync } from '../util/fs';
import { allSerial } from '../util/promise';
import { copyWeb } from '../web/copy';
Expand All @@ -10,15 +10,25 @@ import { getCordovaPlugins, handleCordovaPluginsJS, writeCordovaAndroidManifest
import chalk from 'chalk';

export async function copyCommand(config: Config, selectedPlatformName: string) {
const platforms = config.selectPlatforms(selectedPlatformName);
if (platforms.length === 0) {
logInfo(`There are no platforms to copy yet. Create one with \`capacitor create\`.`);
return;
}
try {
await allSerial(platforms.map(platformName => () => copy(config, platformName)));
} catch (e) {
logError(e);
if (selectedPlatformName && !config.isValidPlatform(selectedPlatformName)) {
const platformFolder = resolvePlatform(config, selectedPlatformName);
if (platformFolder) {
const result = await runPlatformHook(`cd "${platformFolder}" && ${await hasYarn(config) ? 'yarn' : 'npm'} run capacitor:copy`);
log(result);
} else {
logError(`platform ${selectedPlatformName} not found`);
}
} else {
const platforms = config.selectPlatforms(selectedPlatformName);
if (platforms.length === 0) {
logInfo(`There are no platforms to copy yet. Create one with \`capacitor create\`.`);
return;
}
try {
await allSerial(platforms.map(platformName => () => copy(config, platformName)));
} catch (e) {
logError(e);
}
}
}

Expand Down
41 changes: 25 additions & 16 deletions cli/src/tasks/open.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
import { Config } from '../config';
import { logFatal, logInfo, runTask } from '../common';
import { hasYarn, log, logError, logFatal, logInfo, resolvePlatform, runPlatformHook, runTask } from '../common';
import { openAndroid } from '../android/open';
import { openElectron } from '../electron/open';
import { openIOS } from '../ios/open';

export async function openCommand(config: Config, selectedPlatform: string) {
const platforms = config.selectPlatforms(selectedPlatform);
let platformName: string;
if (platforms.length === 0) {
logInfo(`There are no platforms to open yet. Create one with "capacitor add".`);
return;
} else if (platforms.length === 1) {
platformName = platforms[0];
export async function openCommand(config: Config, selectedPlatformName: string) {
if (selectedPlatformName && !config.isValidPlatform(selectedPlatformName)) {
const platformFolder = resolvePlatform(config, selectedPlatformName);
if (platformFolder) {
const result = await runPlatformHook(`cd "${platformFolder}" && ${await hasYarn(config) ? 'yarn' : 'npm'} run capacitor:open`);
log(result);
} else {
logError(`platform ${selectedPlatformName} not found`);
}
} else {
platformName = await config.askPlatform('', `Please choose a platform to open:`);
}

try {
await open(config, platformName);
const platforms = config.selectPlatforms(selectedPlatformName);
let platformName: string;
if (platforms.length === 0) {
logInfo(`There are no platforms to open yet. Create one with "capacitor add".`);
return;
} else if (platforms.length === 1) {
platformName = platforms[0];
} else {
platformName = await config.askPlatform('', `Please choose a platform to open:`);
}

} catch (e) {
logFatal(e);
try {
await open(config, platformName);
} catch (e) {
logFatal(e);
}
}
}

Expand Down
43 changes: 26 additions & 17 deletions cli/src/tasks/sync.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,37 @@
import { Config } from '../config';
import { copy } from './copy';
import { update, updateChecks } from './update';
import { copy, copyCommand } from './copy';
import { update, updateChecks, updateCommand } from './update';
import { check, checkPackage, checkWebDir, log, logError, logFatal, logInfo } from '../common';

import { allSerial } from '../util/promise';

/**
* Sync is a copy and an update in one.
*/
export async function syncCommand(config: Config, selectedPlatform: string, deployment: boolean) {
const then = +new Date;
const platforms = config.selectPlatforms(selectedPlatform);
if (platforms.length === 0) {
logInfo(`There are no platforms to sync yet. Create one with "capacitor create".`);
return;
}
try {
await check(config, [checkPackage, checkWebDir, ...updateChecks(config, platforms)]);
await allSerial(platforms.map(platformName => () => sync(config, platformName, deployment)));
const now = +new Date;
const diff = (now - then) / 1000;
log(`Sync finished in ${diff}s`);
} catch (e)  {
logFatal(e);
export async function syncCommand(config: Config, selectedPlatformName: string, deployment: boolean) {
if (selectedPlatformName && !config.isValidPlatform(selectedPlatformName)) {
try {
await copyCommand(config, selectedPlatformName);
} catch (e) {
logError(e);
}
await updateCommand(config, selectedPlatformName, deployment);
} else {
const then = +new Date;
const platforms = config.selectPlatforms(selectedPlatformName);
if (platforms.length === 0) {
logInfo(`There are no platforms to sync yet. Create one with "capacitor create".`);
return;
}
try {
await check(config, [checkPackage, checkWebDir, ...updateChecks(config, platforms)]);
await allSerial(platforms.map(platformName => () => sync(config, platformName, deployment)));
const now = +new Date;
const diff = (now - then) / 1000;
log(`Sync finished in ${diff}s`);
} catch (e)  {
logFatal(e);
}
}
}

Expand Down
46 changes: 28 additions & 18 deletions cli/src/tasks/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,39 @@ import { Config } from '../config';
import { updateAndroid } from '../android/update';
import { updateIOS, updateIOSChecks } from '../ios/update';
import { allSerial } from '../util/promise';
import { CheckFunction, check, checkPackage, log, logError, logFatal, logInfo, runTask } from '../common';
import { CheckFunction, check, checkPackage, hasYarn, log, logError, logFatal, logInfo, resolvePlatform, runCommand, runPlatformHook, runTask } from '../common';

import chalk from 'chalk';

export async function updateCommand(config: Config, selectedPlatformName: string, deployment: boolean) {
const then = +new Date;
const platforms = config.selectPlatforms(selectedPlatformName);
if (platforms.length === 0) {
logInfo(`There are no platforms to update yet. Create one with "capacitor create".`);
return;
}
try {
await check(
config,
[checkPackage, ...updateChecks(config, platforms)]
);
if (selectedPlatformName && !config.isValidPlatform(selectedPlatformName)) {
const platformFolder = resolvePlatform(config, selectedPlatformName);
if (platformFolder) {
const result = await runPlatformHook(`cd "${platformFolder}" && ${await hasYarn(config) ? 'yarn' : 'npm'} run capacitor:update`);
log(result);
} else {
logError(`platform ${selectedPlatformName} not found`);
}
} else {
const then = +new Date;
const platforms = config.selectPlatforms(selectedPlatformName);
if (platforms.length === 0) {
logInfo(`There are no platforms to update yet. Create one with "capacitor create".`);
return;
}
try {
await check(
config,
[checkPackage, ...updateChecks(config, platforms)]
);

await allSerial(platforms.map(platformName => async () => await update(config, platformName, deployment)));
const now = +new Date;
const diff = (now - then) / 1000;
log(`Update finished in ${diff}s`);
} catch (e) {
logFatal(e);
await allSerial(platforms.map(platformName => async () => await update(config, platformName, deployment)));
const now = +new Date;
const diff = (now - then) / 1000;
log(`Update finished in ${diff}s`);
} catch (e) {
logFatal(e);
}
}
}

Expand Down

0 comments on commit c2133c5

Please sign in to comment.