Skip to content

Commit be6d70c

Browse files
committed
feat(resources-update-command): introduce resources-update command
Introduce the 'tns resources-update android' command. By design, upon execution it should migrate the directory structure of App_Resources/Android to the new v4 structure - the one that supports inclusion of java source files, arbitrary assets, and any resource files in the App_Resources/Android/src/main directory structure. Additional, user-defined flavors can also be created taking advantage of the new dir structure.
1 parent 64a973d commit be6d70c

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed

lib/bootstrap.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ $injector.requireCommand("init", "./commands/init");
102102
$injector.require("infoService", "./services/info-service");
103103
$injector.requireCommand("info", "./commands/info");
104104

105+
$injector.require("projectV4MigrationService", "./services/project-v4-migration-service");
106+
$injector.requireCommand("resources-update", "./commands/resources-update");
107+
105108
$injector.require("androidToolsInfo", "./android-tools-info");
106109
$injector.require("devicePathProvider", "./device-path-provider");
107110

lib/commands/resources-update.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
export class ResourcesUpdateCommand implements ICommand {
2+
public allowedParameters: ICommandParameter[] = [];
3+
4+
constructor(private $projectData: IProjectData,
5+
private $errors: IErrors,
6+
private $projectV4MigrationService: IProjectV4MigrationService) {
7+
this.$projectData.initializeProjectData();
8+
}
9+
10+
public async execute(args: string[]): Promise<void> {
11+
await this.$projectV4MigrationService.migrate(this.$projectData.getAppResourcesDirectoryPath());
12+
}
13+
14+
public async canExecute(args: string[]): Promise<boolean> {
15+
if (!args || args.length === 0) {
16+
this.$errors.failWithoutHelp("No platform specified. Please specify a platform to update. Valid platforms are: 'android'");
17+
}
18+
19+
for (const platform of args) {
20+
if (!this.$projectV4MigrationService.canMigrate(platform)) {
21+
this.$errors.failWithoutHelp("The iOS platform does not need to have its resources updated.");
22+
}
23+
24+
if (this.$projectV4MigrationService.hasMigrated(this.$projectData.getAppResourcesDirectoryPath())) {
25+
this.$errors.failWithoutHelp("The App_Resources have already been updated for the Android platform.");
26+
}
27+
}
28+
29+
return true;
30+
}
31+
}
32+
33+
$injector.registerCommand("resources-update", ResourcesUpdateCommand);

lib/declarations.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,12 @@ interface IInfoService {
432432
printComponentsInfo(): Promise<void>;
433433
}
434434

435+
interface IProjectV4MigrationService {
436+
canMigrate(platformString: string): boolean;
437+
hasMigrated(appResourcesDir: string): boolean;
438+
migrate(appResourcesDir: string): Promise<void>;
439+
}
440+
435441
/**
436442
* Describes properties needed for uploading a package to iTunes Connect
437443
*/
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import * as path from "path";
2+
import * as shell from "shelljs";
3+
4+
export class ProjectV4MigrationService implements IProjectV4MigrationService {
5+
private static ANDROID_DIR = "Android";
6+
private static ANDROID_DIR_TEMP = "Android-Updated";
7+
private static ANDROID_DIR_OLD = "Android-Pre-v4";
8+
9+
constructor(
10+
private $fs: IFileSystem,
11+
private $logger: ILogger,
12+
private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants
13+
) { }
14+
15+
canMigrate(platformString: string): boolean {
16+
if (platformString.toLowerCase() === this.$devicePlatformsConstants.iOS.toLowerCase()) {
17+
return false;
18+
}
19+
20+
return true;
21+
}
22+
23+
hasMigrated(appResourcesDir: string): boolean {
24+
return this.$fs.exists(path.join(appResourcesDir, ProjectV4MigrationService.ANDROID_DIR, "src", "main"));
25+
}
26+
27+
async migrate(appResourcesDir: string): Promise<void> {
28+
const originalAppResources = path.join(appResourcesDir, ProjectV4MigrationService.ANDROID_DIR);
29+
const appResourcesDestination = path.join(appResourcesDir, ProjectV4MigrationService.ANDROID_DIR_TEMP);
30+
const appMainSourceSet = path.join(appResourcesDestination, "src", "main");
31+
const appResourcesMainSourceSetResourcesDestination = path.join(appMainSourceSet, "res");
32+
33+
this.$fs.ensureDirectoryExists(appResourcesDestination);
34+
this.$fs.ensureDirectoryExists(appMainSourceSet);
35+
// create /java, /res and /assets in the App_Resources/Android/src/main directory
36+
this.$fs.ensureDirectoryExists(appResourcesMainSourceSetResourcesDestination);
37+
this.$fs.ensureDirectoryExists(path.join(appMainSourceSet, "java"));
38+
this.$fs.ensureDirectoryExists(path.join(appMainSourceSet, "assets"));
39+
40+
const isDirectory = (source: string) => this.$fs.getLsStats(source).isDirectory()
41+
const getDirectories = (source: string) =>
42+
this.$fs.readDirectory(source).map(name => path.join(source, name)).filter(isDirectory)
43+
44+
shell.cp(path.join(originalAppResources, "app.gradle"), path.join(appResourcesDestination, "app.gradle"));
45+
shell.cp(path.join(originalAppResources, "AndroidManifest.xml"), path.join(appMainSourceSet, "AndroidManifest.xml"));
46+
47+
let resourceDirectories = getDirectories(originalAppResources);
48+
49+
resourceDirectories.forEach(dir => {
50+
shell.cp("-Rf", dir, appResourcesMainSourceSetResourcesDestination);
51+
});
52+
53+
// move the pre-v4 app_resources in ANDROID_DIR_OLD
54+
shell.mv(originalAppResources, path.join(appResourcesDir, ProjectV4MigrationService.ANDROID_DIR_OLD));
55+
// move the new, updated app_resources to App_Resources/Android, as the de facto resources
56+
shell.mv(appResourcesDestination, originalAppResources)
57+
58+
this.$logger.out(`Successfully updated your project's App_Resources/Android directory structure. The previous version of App_Resources/Android has been renamed to App_Resources/${ProjectV4MigrationService.ANDROID_DIR_OLD}`);
59+
}
60+
61+
}
62+
63+
$injector.register("projectV4MigrationService", ProjectV4MigrationService);

0 commit comments

Comments
 (0)