microsoft/vscode-react-native

Public

mirrored from https://github.com/microsoft/vscode-react-nativeAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
timeout-constant-configuration-file

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

src/extension/android/packageNameResolver.ts

98lines · modecode

1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for details.
3
4import * as path from "path";
5import { FileSystem } from "../../common/node/fileSystem";
6
7export class PackageNameResolver {
8 private static PackageNameRegexp: RegExp = /package="(.+?)"/;
9 private static ApplicationIdRegexp: RegExp = /applicationId\s+(=)?\s*["'](.+?)["']/;
10 private static ManifestName = "AndroidManifest.xml";
11 private static GradleBuildName = "build.gradle";
12 private static DefaultPackagePrefix = "com.";
13 private static SourceRootRelPath: string[] = ["android", "app", "src", "main"];
14 private static DefaultManifestLocation: string[] = PackageNameResolver.SourceRootRelPath.concat(
15 PackageNameResolver.ManifestName,
16 );
17 private static DefaultGradleBuildLocation: string[] = [
18 "android",
19 "app",
20 PackageNameResolver.GradleBuildName,
21 ];
22 private applicationName: string;
23
24 constructor(applicationName: string) {
25 this.applicationName = applicationName;
26 }
27
28 /**
29 * Tries to find the package name in AndroidManifest.xml. If not found, it returns the default package name,
30 * which is the application name prefixed with the default prefix.
31 */
32 public async resolvePackageName(projectRoot: string): Promise<string> {
33 const expectedGradleBuildPath = path.join.apply(
34 this,
35 [projectRoot].concat(PackageNameResolver.DefaultGradleBuildLocation),
36 );
37 const gradlePackageName = await this.readApplicationId(expectedGradleBuildPath);
38 if (gradlePackageName) {
39 return gradlePackageName;
40 }
41
42 const expectedAndroidManifestPath = path.join.apply(
43 this,
44 [projectRoot].concat(PackageNameResolver.DefaultManifestLocation),
45 );
46 return this.readPackageName(expectedAndroidManifestPath);
47 }
48
49 private async readApplicationId(gradlePath: string): Promise<string | null> {
50 if (gradlePath) {
51 const fs = new FileSystem();
52 if (await fs.exists(gradlePath)) {
53 const content = await fs.readFile(gradlePath);
54 const match = content.toString().match(PackageNameResolver.ApplicationIdRegexp);
55 return match ? match[2] : null;
56 }
57 }
58 return null;
59 }
60
61 /**
62 * Given a manifest file path, it parses the file and returns the package name.
63 * If the package name cannot be parsed, the default packge name is returned.
64 */
65 private async readPackageName(manifestPath: string): Promise<string> {
66 if (manifestPath) {
67 const fs = new FileSystem();
68 const exists = await fs.exists(manifestPath);
69 if (exists) {
70 const manifestContent = await fs.readFile(manifestPath);
71 let packageName = this.parsePackageName(manifestContent.toString());
72 if (!packageName) {
73 packageName = this.getDefaultPackageName(this.applicationName);
74 }
75 return packageName;
76 }
77 return this.getDefaultPackageName(this.applicationName);
78 }
79 return this.getDefaultPackageName(this.applicationName);
80 }
81
82 /**
83 * Gets the default package name, based on the application name.
84 */
85 private getDefaultPackageName(applicationName: string): string {
86 return (PackageNameResolver.DefaultPackagePrefix + applicationName).toLowerCase();
87 }
88
89 /**
90 * Parses the application package name from the contents of an Android manifest file.
91 * If a match was found, it is returned. Otherwise null is returned.
92 */
93 private parsePackageName(manifestContents: string) {
94 // first we remove all the comments from the file
95 const match = manifestContents.match(PackageNameResolver.PackageNameRegexp);
96 return match ? match[1] : null;
97 }
98}
99