Skip to content

Commit 1aed823

Browse files
committed
refactor(commands): move three commands to the class form
platform|clean, update and device|*list are written as Command() classes, with their services as inject() fields and the constructor doing the initializeProjectData() work setup did. The per-platform device listings stay in the object form: they are generated from one function, which is what that form is for.
1 parent 2ffeb51 commit 1aed823

7 files changed

Lines changed: 140 additions & 174 deletions

File tree

lib/bootstrap.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -527,10 +527,10 @@ injector.require("androidToolsInfo", "./android-tools-info");
527527
injector.require("devicePathProvider", "./device-path-provider");
528528

529529
registerBuiltInCommand<
530-
typeof import("./commands/platform-clean").platformCleanCommandDefinition
530+
typeof import("./commands/platform-clean").PlatformCleanCommand
531531
>(
532532
"platform|clean",
533-
() => require("./commands/platform-clean").platformCleanCommandDefinition,
533+
() => require("./commands/platform-clean").PlatformCleanCommand,
534534
);
535535

536536
injector.require(
@@ -583,9 +583,10 @@ registerBuiltInCommand<
583583
registerBuiltInCommand<
584584
typeof import("./commands/migrate").migrateCommandDefinition
585585
>("migrate", () => require("./commands/migrate").migrateCommandDefinition);
586-
registerBuiltInCommand<
587-
typeof import("./commands/update").updateCommandDefinition
588-
>("update", () => require("./commands/update").updateCommandDefinition);
586+
registerBuiltInCommand<typeof import("./commands/update").UpdateCommand>(
587+
"update",
588+
() => require("./commands/update").UpdateCommand,
589+
);
589590

590591
injector.require("iOSLogFilter", "./services/ios-log-filter");
591592
injector.require("logSourceMapService", "./services/log-source-map-service");

lib/commands/platform-clean.ts

Lines changed: 57 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ import {
88
import { IPlatformEnvironmentRequirements } from "../definitions/platform";
99
import { IErrors } from "../common/declarations";
1010
import {
11-
CommandContext,
11+
Command,
1212
CommandOptionsSchema,
13-
defineCommand,
1413
stringOption,
1514
} from "../common/define-command";
1615
import { inject } from "../common/di";
@@ -19,93 +18,71 @@ const platformCleanCommandOptions = {
1918
frameworkPath: stringOption(),
2019
} satisfies CommandOptionsSchema;
2120

22-
export type PlatformCleanCommandContext = CommandContext<
23-
typeof platformCleanCommandOptions
24-
>;
25-
26-
export function setupPlatformCleanCommand() {
27-
const services = {
28-
$errors: inject<IErrors>("errors"),
29-
$options: inject<IOptions>("options"),
30-
$platformCommandHelper: inject<IPlatformCommandHelper>(
31-
"platformCommandHelper",
32-
),
33-
$platformValidationService: inject<IPlatformValidationService>(
34-
"platformValidationService",
35-
),
36-
$platformEnvironmentRequirements: inject<IPlatformEnvironmentRequirements>(
37-
"platformEnvironmentRequirements",
38-
),
39-
$projectData: inject<IProjectData>("projectData"),
40-
};
41-
services.$projectData.initializeProjectData();
42-
43-
return services;
44-
}
45-
46-
export type IPlatformCleanCommandServices = ReturnType<
47-
typeof setupPlatformCleanCommand
48-
>;
21+
export class PlatformCleanCommand extends Command({
22+
name: "platform|clean",
23+
description: "Removes and adds again the selected platform.",
24+
options: platformCleanCommandOptions,
25+
arguments: "any",
26+
}) {
27+
private $errors = inject<IErrors>("errors");
28+
private $options = inject<IOptions>("options");
29+
private $platformCommandHelper = inject<IPlatformCommandHelper>(
30+
"platformCommandHelper",
31+
);
32+
private $platformValidationService = inject<IPlatformValidationService>(
33+
"platformValidationService",
34+
);
35+
private $platformEnvironmentRequirements =
36+
inject<IPlatformEnvironmentRequirements>("platformEnvironmentRequirements");
37+
private $projectData = inject<IProjectData>("projectData");
4938

50-
export async function canExecutePlatformCleanCommand(
51-
context: PlatformCleanCommandContext,
52-
services: IPlatformCleanCommandServices,
53-
): Promise<boolean> {
54-
const args = context.args;
55-
if (!args || args.length === 0) {
56-
services.$errors.failWithHelp(
57-
"No platform specified. Please specify a platform to clean.",
58-
);
39+
constructor() {
40+
super();
41+
this.$projectData.initializeProjectData();
5942
}
6043

61-
_.each(args, (platform) => {
62-
services.$platformValidationService.validatePlatform(
63-
platform,
64-
services.$projectData,
65-
);
66-
});
44+
public async canExecute(): Promise<boolean> {
45+
const args = this.args;
46+
if (!args || args.length === 0) {
47+
this.$errors.failWithHelp(
48+
"No platform specified. Please specify a platform to clean.",
49+
);
50+
}
6751

68-
for (const platform of args) {
69-
services.$platformValidationService.validatePlatformInstalled(
70-
platform,
71-
services.$projectData,
72-
);
52+
_.each(args, (platform) => {
53+
this.$platformValidationService.validatePlatform(
54+
platform,
55+
this.$projectData,
56+
);
57+
});
7358

74-
const currentRuntimeVersion =
75-
services.$platformCommandHelper.getCurrentPlatformVersion(
59+
for (const platform of args) {
60+
this.$platformValidationService.validatePlatformInstalled(
7661
platform,
77-
services.$projectData,
62+
this.$projectData,
7863
);
79-
await services.$platformEnvironmentRequirements.checkEnvironmentRequirements(
80-
{
64+
65+
const currentRuntimeVersion =
66+
this.$platformCommandHelper.getCurrentPlatformVersion(
67+
platform,
68+
this.$projectData,
69+
);
70+
await this.$platformEnvironmentRequirements.checkEnvironmentRequirements({
8171
platform,
82-
projectDir: services.$projectData.projectDir,
72+
projectDir: this.$projectData.projectDir,
8373
runtimeVersion: currentRuntimeVersion,
84-
options: services.$options,
85-
},
86-
);
87-
}
74+
options: this.$options,
75+
});
76+
}
8877

89-
return true;
90-
}
78+
return true;
79+
}
9180

92-
export async function runPlatformCleanCommand(
93-
context: PlatformCleanCommandContext,
94-
services: IPlatformCleanCommandServices,
95-
): Promise<void> {
96-
await services.$platformCommandHelper.cleanPlatforms(
97-
context.args,
98-
services.$projectData,
99-
context.options.frameworkPath,
100-
);
81+
public async run(): Promise<void> {
82+
await this.$platformCommandHelper.cleanPlatforms(
83+
this.args,
84+
this.$projectData,
85+
this.options.frameworkPath,
86+
);
87+
}
10188
}
102-
103-
export const platformCleanCommandDefinition = defineCommand({
104-
name: "platform|clean",
105-
description: "Removes and adds again the selected platform.",
106-
options: platformCleanCommandOptions,
107-
arguments: "any",
108-
setup: setupPlatformCleanCommand,
109-
canExecute: canExecutePlatformCleanCommand,
110-
run: runPlatformCleanCommand,
111-
});

lib/commands/update.ts

Lines changed: 58 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ import { IMigrateController } from "../definitions/migrate";
33
import { IErrors } from "../common/declarations";
44
import {
55
booleanOption,
6-
CommandContext,
6+
Command,
77
CommandOptionsSchema,
8-
defineCommand,
98
stringOption,
109
} from "../common/define-command";
1110
import { inject } from "../common/di";
@@ -19,84 +18,70 @@ const updateCommandOptions = {
1918
frameworkPath: stringOption(),
2019
} satisfies CommandOptionsSchema;
2120

22-
export type UpdateCommandContext = CommandContext<typeof updateCommandOptions>;
23-
24-
export function setupUpdateCommand() {
25-
const services = {
26-
$devicePlatformsConstants: inject<Mobile.IDevicePlatformsConstants>(
27-
"devicePlatformsConstants",
28-
),
29-
$updateController: inject<IUpdateController>("updateController"),
30-
$migrateController: inject<IMigrateController>("migrateController"),
31-
$errors: inject<IErrors>("errors"),
32-
$logger: inject<ILogger>("logger"),
33-
$projectData: inject<IProjectData>("projectData"),
34-
$markingModeService: inject<IMarkingModeService>("markingModeService"),
35-
};
36-
services.$projectData.initializeProjectData();
21+
export class UpdateCommand extends Command({
22+
name: "update",
23+
description:
24+
"Updates the project with the latest versions of its NativeScript dependencies.",
25+
options: updateCommandOptions,
26+
arguments: "any",
27+
}) {
28+
private $devicePlatformsConstants = inject<Mobile.IDevicePlatformsConstants>(
29+
"devicePlatformsConstants",
30+
);
31+
private $updateController = inject<IUpdateController>("updateController");
32+
private $migrateController = inject<IMigrateController>("migrateController");
33+
private $errors = inject<IErrors>("errors");
34+
private $logger = inject<ILogger>("logger");
35+
private $projectData = inject<IProjectData>("projectData");
36+
private $markingModeService =
37+
inject<IMarkingModeService>("markingModeService");
3738

38-
return services;
39-
}
39+
constructor() {
40+
super();
41+
this.$projectData.initializeProjectData();
42+
}
4043

41-
export type IUpdateCommandServices = ReturnType<typeof setupUpdateCommand>;
44+
public async canExecute(): Promise<boolean> {
45+
const shouldMigrate = await this.$migrateController.shouldMigrate({
46+
projectDir: this.$projectData.projectDir,
47+
platforms: [
48+
this.$devicePlatformsConstants.Android,
49+
this.$devicePlatformsConstants.iOS,
50+
],
51+
loose: true,
52+
});
4253

43-
export async function canExecuteUpdateCommand(
44-
context: UpdateCommandContext,
45-
services: IUpdateCommandServices,
46-
): Promise<boolean> {
47-
const shouldMigrate = await services.$migrateController.shouldMigrate({
48-
projectDir: services.$projectData.projectDir,
49-
platforms: [
50-
services.$devicePlatformsConstants.Android,
51-
services.$devicePlatformsConstants.iOS,
52-
],
53-
loose: true,
54-
});
54+
if (shouldMigrate) {
55+
this.$errors.fail(SHOULD_MIGRATE_PROJECT_MESSAGE);
56+
}
5557

56-
if (shouldMigrate) {
57-
services.$errors.fail(SHOULD_MIGRATE_PROJECT_MESSAGE);
58+
return this.args.length < 2 && this.$projectData.projectDir !== "";
5859
}
5960

60-
return context.args.length < 2 && services.$projectData.projectDir !== "";
61-
}
61+
public async run(): Promise<void> {
62+
if (this.options.markingMode) {
63+
// ns update --markingMode
64+
await this.$markingModeService.handleMarkingModeFullDeprecation({
65+
projectDir: this.$projectData.projectDir,
66+
forceSwitch: true,
67+
});
68+
return;
69+
}
6270

63-
export async function runUpdateCommand(
64-
context: UpdateCommandContext,
65-
services: IUpdateCommandServices,
66-
): Promise<void> {
67-
if (context.options.markingMode) {
68-
// ns update --markingMode
69-
await services.$markingModeService.handleMarkingModeFullDeprecation({
70-
projectDir: services.$projectData.projectDir,
71-
forceSwitch: true,
72-
});
73-
return;
74-
}
71+
if (
72+
!(await this.$updateController.shouldUpdate({
73+
projectDir: this.$projectData.projectDir,
74+
version: this.args[0],
75+
}))
76+
) {
77+
this.$logger.printMarkdown(`__${PROJECT_UP_TO_DATE_MESSAGE}__`);
78+
return;
79+
}
7580

76-
if (
77-
!(await services.$updateController.shouldUpdate({
78-
projectDir: services.$projectData.projectDir,
79-
version: context.args[0],
80-
}))
81-
) {
82-
services.$logger.printMarkdown(`__${PROJECT_UP_TO_DATE_MESSAGE}__`);
83-
return;
81+
await this.$updateController.update({
82+
projectDir: this.$projectData.projectDir,
83+
version: this.args[0],
84+
frameworkPath: this.options.frameworkPath,
85+
});
8486
}
85-
86-
await services.$updateController.update({
87-
projectDir: services.$projectData.projectDir,
88-
version: context.args[0],
89-
frameworkPath: context.options.frameworkPath,
90-
});
9187
}
92-
93-
export const updateCommandDefinition = defineCommand({
94-
name: "update",
95-
description:
96-
"Updates the project with the latest versions of its NativeScript dependencies.",
97-
options: updateCommandOptions,
98-
arguments: "any",
99-
setup: setupUpdateCommand,
100-
canExecute: canExecuteUpdateCommand,
101-
run: runUpdateCommand,
102-
});

lib/common/bootstrap.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,16 @@ registerBuiltInCommand<
9191
);
9292

9393
registerBuiltInCommand<
94-
typeof import("./commands/device/list-devices").listDevicesCommandDefinition
94+
typeof import("./commands/device/list-devices").ListDevicesCommand
9595
>(
9696
"device|*list",
97-
() => require("./commands/device/list-devices").listDevicesCommandDefinition,
97+
() => require("./commands/device/list-devices").ListDevicesCommand,
9898
);
9999
registerBuiltInCommand<
100-
typeof import("./commands/device/list-devices").listDevicesCommandDefinition
100+
typeof import("./commands/device/list-devices").ListDevicesCommand
101101
>(
102102
"devices|*list",
103-
() => require("./commands/device/list-devices").listDevicesCommandDefinition,
103+
() => require("./commands/device/list-devices").ListDevicesCommand,
104104
);
105105
registerBuiltInCommand<
106106
typeof import("./commands/device/list-devices").androidListDevicesCommand

lib/common/commands/device/list-devices.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { DeviceConnectionType } from "../../../constants";
33
import { IErrors } from "../../declarations";
44
import {
55
booleanOption,
6+
Command,
67
CommandContext,
78
CommandName,
89
CommandOptionsSchema,
@@ -160,17 +161,21 @@ export async function runListDevicesCommand(
160161
}
161162
}
162163

163-
export const listDevicesCommandDefinition = defineCommand({
164+
export class ListDevicesCommand extends Command({
164165
name: ["device|*list", "devices|*list"],
165166
description: "Lists the connected devices and emulators.",
166167
options: listDevicesCommandOptions,
167168
arguments: [{ name: "platform" }],
168-
setup: setupListDevicesCommand,
169-
run(context, services): Promise<void> {
170-
return runListDevicesCommand(context, services, context.args[0]);
171-
},
172-
});
169+
}) {
170+
private services = setupListDevicesCommand();
173171

172+
public run(): Promise<void> {
173+
return runListDevicesCommand(this.context, this.services, this.args[0]);
174+
}
175+
}
176+
177+
// One definition per platform, generated: the object form is what a family of
178+
// commands needs, where the class form fits a single named command.
174179
const defineListPlatformDevicesCommand = <const TName extends CommandName>(
175180
name: TName,
176181
listedPlatform: "iOS" | "Android",

0 commit comments

Comments
 (0)