Skip to content

Commit 6146296

Browse files
giocalitriimhoffd
authored andcommitted
fix(deploy): support custom Capacitor build directory (#4065)
1 parent 5a035ad commit 6146296

File tree

3 files changed

+46
-25
lines changed

3 files changed

+46
-25
lines changed

packages/ionic/src/commands/deploy/core.ts

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,7 @@ import { input, strong } from '../../lib/color';
77
import { Command } from '../../lib/command';
88
import { FatalException } from '../../lib/errors';
99

10-
export abstract class DeployConfCommand extends Command {
11-
12-
protected readonly optionsToPlistKeys = {
13-
'app-id': 'IonAppId',
14-
'channel-name': 'IonChannelName',
15-
'update-method': 'IonUpdateMethod',
16-
'max-store': 'IonMaxVersions',
17-
'min-background-duration': 'IonMinBackgroundDuration',
18-
'update-api': 'IonApi',
19-
};
20-
protected readonly optionsToStringXmlKeys = {
21-
'app-id': 'ionic_app_id',
22-
'channel-name': 'ionic_channel_name',
23-
'update-method': 'ionic_update_method',
24-
'max-store': 'ionic_max_versions',
25-
'min-background-duration': 'ionic_min_background_duration',
26-
'update-api': 'ionic_update_api',
27-
};
28-
10+
export abstract class DeployCoreCommand extends Command {
2911
protected async getAppIntegration(): Promise<string | undefined> {
3012
if (this.project) {
3113
if (this.project.getIntegration('capacitor') !== undefined) {
@@ -44,12 +26,32 @@ export abstract class DeployConfCommand extends Command {
4426
if (!integration) {
4527
throw new FatalException(
4628
`It looks like your app isn't integrated with Capacitor or Cordova.\n` +
47-
`In order to add the Appflow Deploy plugin, you will need to integrate your app with Capacitor or Cordova. See the docs for setting up native projects:\n\n` +
29+
`In order to use the Appflow Deploy plugin, you will need to integrate your app with Capacitor or Cordova. See the docs for setting up native projects:\n\n` +
4830
`iOS: ${strong('https://ionicframework.com/docs/building/ios')}\n` +
4931
`Android: ${strong('https://ionicframework.com/docs/building/android')}\n`
5032
);
5133
}
5234
}
35+
}
36+
37+
export abstract class DeployConfCommand extends DeployCoreCommand {
38+
39+
protected readonly optionsToPlistKeys = {
40+
'app-id': 'IonAppId',
41+
'channel-name': 'IonChannelName',
42+
'update-method': 'IonUpdateMethod',
43+
'max-store': 'IonMaxVersions',
44+
'min-background-duration': 'IonMinBackgroundDuration',
45+
'update-api': 'IonApi',
46+
};
47+
protected readonly optionsToStringXmlKeys = {
48+
'app-id': 'ionic_app_id',
49+
'channel-name': 'ionic_channel_name',
50+
'update-method': 'ionic_update_method',
51+
'max-store': 'ionic_max_versions',
52+
'min-background-duration': 'ionic_min_background_duration',
53+
'update-api': 'ionic_update_api',
54+
};
5355

5456
protected async getAppId(): Promise<string | undefined> {
5557
if (this.project) {

packages/ionic/src/commands/deploy/manifest.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { MetadataGroup } from '@ionic/cli-framework';
2+
import { prettyPath } from '@ionic/cli-framework/utils/format';
23
import { map } from '@ionic/utils-array';
34
import { readdirp, stat, writeFile } from '@ionic/utils-fs';
45
import * as crypto from 'crypto';
@@ -7,16 +8,17 @@ import * as path from 'path';
78

89
import { CommandMetadata } from '../../definitions';
910
import { input } from '../../lib/color';
10-
import { Command } from '../../lib/command';
1111
import { FatalException } from '../../lib/errors';
1212

13+
import { DeployCoreCommand } from './core';
14+
1315
interface DeployManifestItem {
1416
href: string;
1517
size: number;
1618
integrity: string;
1719
}
1820

19-
export class DeployManifestCommand extends Command {
21+
export class DeployManifestCommand extends DeployCoreCommand {
2022
async getMetadata(): Promise<CommandMetadata> {
2123
return {
2224
name: 'manifest',
@@ -30,11 +32,14 @@ export class DeployManifestCommand extends Command {
3032
if (!this.project) {
3133
throw new FatalException(`Cannot run ${input('ionic deploy manifest')} outside a project directory.`);
3234
}
35+
await this.requireNativeIntegration();
3336

34-
const buildDir = path.resolve(this.project.directory, 'www'); // TODO: this is hard-coded
37+
const buildDir = await this.project.getDistDir();
3538
const manifest = await this.getFilesAndSizesAndHashesForGlobPattern(buildDir);
3639

37-
await writeFile(path.resolve(buildDir, 'pro-manifest.json'), JSON.stringify(manifest, undefined, 2), { encoding: 'utf8' });
40+
const manifestPath = path.resolve(buildDir, 'pro-manifest.json');
41+
await writeFile(manifestPath, JSON.stringify(manifest, undefined, 2), { encoding: 'utf8' });
42+
this.env.log.ok(`Appflow Deploy manifest written to ${input(prettyPath(manifestPath))}!`);
3843
}
3944

4045
private async getFilesAndSizesAndHashesForGlobPattern(buildDir: string): Promise<DeployManifestItem[]> {

packages/ionic/src/lib/project/index.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { isMultiProjectConfig, isProjectConfig } from '../../guards';
1313
import { ancillary, failure, input, strong } from '../color';
1414
import { BaseException, FatalException, IntegrationNotFoundException, RunnerNotFoundException } from '../errors';
1515
import { BaseIntegration } from '../integrations';
16+
import { CAPACITOR_CONFIG_FILE, CapacitorConfig } from '../integrations/capacitor/config';
1617

1718
const debug = Debug('ionic:lib:project');
1819

@@ -520,7 +521,20 @@ export abstract class Project implements IProject {
520521
}
521522

522523
async getDistDir(): Promise<string> {
523-
return path.resolve(this.directory, 'www');
524+
if (this.getIntegration('capacitor') !== undefined) {
525+
const conf = new CapacitorConfig(path.resolve(this.directory, CAPACITOR_CONFIG_FILE));
526+
const webDir = conf.get('webDir');
527+
if (webDir) {
528+
return path.resolve(this.directory, webDir);
529+
} else {
530+
throw new FatalException(
531+
`The ${input('webDir')} property must be set in the Capacitor configuration file (${input(CAPACITOR_CONFIG_FILE)}). \n` +
532+
`See the Capacitor docs for more information: ${strong('https://capacitor.ionicframework.com/docs/basics/configuring-your-app')}`
533+
);
534+
}
535+
} else {
536+
return path.resolve(this.directory, 'www');
537+
}
524538
}
525539

526540
async getInfo(): Promise<InfoItem[]> {

0 commit comments

Comments
 (0)