@produtype/core 0.29.1 → 0.29.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,7 +37,21 @@ const textSearch_1 = require("../utils/textSearch");
37
37
  */
38
38
  /** Files that say which platform this is, without reading their contents. */
39
39
  const IOS_MARKERS = [/(^|\/)Info\.plist$/i, /(^|\/)Podfile$/, /\.xcodeproj\//, /(^|\/)Package\.swift$/];
40
- const ANDROID_MARKERS = [/(^|\/)AndroidManifest\.xml$/i, /(^|\/)build\.gradle(\.kts)?$/];
40
+ /**
41
+ * `AndroidManifest.xml` says Android. `build.gradle` says the JVM.
42
+ *
43
+ * Gradle builds Android applications, Spring services, Kotlin libraries and most of the
44
+ * Java world. Treating its presence as a platform made spring-petclinic — the canonical
45
+ * Spring web application — a mobile app at high confidence, and it would do the same to
46
+ * every JVM server ever written.
47
+ *
48
+ * A Gradle file earns the label by applying the Android plugin, which is the line that
49
+ * makes a build an Android build. That has to be read rather than matched on a path,
50
+ * which is why the two lists are separate.
51
+ */
52
+ const ANDROID_MARKERS = [/(^|\/)AndroidManifest\.xml$/i];
53
+ const GRADLE_FILES = /(^|\/)build\.gradle(\.kts)?$/;
54
+ const ANDROID_GRADLE_PLUGIN = /com\.android\.(application|library)|(^|\s)android\s*\{/m;
41
55
  /** Gradle coordinates that put a secret in the Android keystore rather than in a file. */
42
56
  const SECURE_STORAGE_GRADLE = ['androidx.security:security-crypto', 'com.scottyab:secure-preferences'];
43
57
  /**
@@ -110,9 +124,18 @@ function matchesAny(files, patterns) {
110
124
  .filter((file) => !GENERATED_OR_VENDORED.test(file))
111
125
  .filter((file) => patterns.some((pattern) => pattern.test(file)));
112
126
  }
127
+ async function androidGradleFiles(ctx) {
128
+ const found = [];
129
+ for (const file of ctx.files.all.filter((candidate) => GRADLE_FILES.test(candidate))) {
130
+ const text = await (0, readTextFileSafe_1.readTextFileSafe)(ctx.root, file);
131
+ if (text && ANDROID_GRADLE_PLUGIN.test(text))
132
+ found.push(file);
133
+ }
134
+ return found;
135
+ }
113
136
  async function detectMobile(ctx) {
114
137
  const iosFiles = matchesAny(ctx.files.all, IOS_MARKERS);
115
- const androidFiles = matchesAny(ctx.files.all, ANDROID_MARKERS);
138
+ const androidFiles = [...matchesAny(ctx.files.all, ANDROID_MARKERS), ...(await androidGradleFiles(ctx))];
116
139
  const flutterDeps = (0, detectContext_1.hasAnyDartDep)(ctx, ['flutter']);
117
140
  const reactNativeDeps = (0, detectContext_1.hasAnyDep)(ctx, ['react-native', 'expo']);
118
141
  const platforms = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@produtype/core",
3
- "version": "0.29.1",
3
+ "version": "0.29.2",
4
4
  "description": "Deterministic CLI and library that analyzes a web application repository and reports how far it is from production-ready for the kind of product it is meant to be.",
5
5
  "license": "MIT",
6
6
  "bin": {