@pmate/cli 0.25.2 → 0.25.3

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.
Files changed (2) hide show
  1. package/dist/index.js +51 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -22375,13 +22375,14 @@ var AndroidApkReleaseService = class {
22375
22375
  if (!gradlew) {
22376
22376
  throw new Error(`Gradle wrapper not found in ${appDir} or ${repoRoot}`);
22377
22377
  }
22378
+ const gradleCwd = import_node_path24.default.dirname(gradlew);
22378
22379
  const normalizedVariant = variant.toLowerCase();
22379
22380
  const taskSuffix = `assemble${capitalize(normalizedVariant)}`;
22380
22381
  const tasks = [`:app:${taskSuffix}`, taskSuffix];
22381
22382
  let lastError;
22382
22383
  for (const task of tasks) {
22383
22384
  try {
22384
- await runCommand(gradlew, [task], repoRoot);
22385
+ await runCommand(gradlew, [task], gradleCwd);
22385
22386
  return findLatestApk(repoRoot, appDir, normalizedVariant);
22386
22387
  } catch (error) {
22387
22388
  lastError = error;
@@ -22391,8 +22392,11 @@ var AndroidApkReleaseService = class {
22391
22392
  }
22392
22393
  async readApkMetadata(apkPath) {
22393
22394
  const readers = [
22395
+ async () => readGradleOutputMetadata(apkPath),
22394
22396
  async () => parseAaptBadging(await runCommandCapture("aapt", ["dump", "badging", apkPath])),
22395
- async () => parseApkAnalyzerManifest(await runCommandCapture("apkanalyzer", ["manifest", "print", apkPath]))
22397
+ async () => parseApkAnalyzerManifest(await runCommandCapture("apkanalyzer", ["manifest", "print", apkPath])),
22398
+ async () => parseAaptBadging(await runAndroidSdkToolCapture("aapt", ["dump", "badging", apkPath])),
22399
+ async () => parseApkAnalyzerManifest(await runAndroidSdkToolCapture("apkanalyzer", ["manifest", "print", apkPath]))
22396
22400
  ];
22397
22401
  const errors = [];
22398
22402
  for (const reader of readers) {
@@ -22402,7 +22406,9 @@ var AndroidApkReleaseService = class {
22402
22406
  errors.push(error instanceof Error ? error.message : String(error));
22403
22407
  }
22404
22408
  }
22405
- throw new Error(`Cannot read APK metadata. Install Android SDK build-tools. ${errors.join(" | ")}`);
22409
+ throw new Error(
22410
+ `Cannot read APK metadata. Expected Gradle output-metadata.json or Android SDK tools aapt/apkanalyzer. ${errors.join(" | ")}`
22411
+ );
22406
22412
  }
22407
22413
  async findExistingObject(objectKey) {
22408
22414
  const parentPrefix = objectKey.split("/").slice(0, -1).join("/");
@@ -22473,6 +22479,17 @@ function parseApkAnalyzerManifest(output) {
22473
22479
  }
22474
22480
  return { applicationId, versionName, versionCode };
22475
22481
  }
22482
+ function parseGradleOutputMetadata(source, apkFileName) {
22483
+ const payload = JSON.parse(source);
22484
+ const element = (apkFileName ? payload.elements?.find((item) => item.outputFile === apkFileName) : void 0) ?? payload.elements?.find((item) => item.versionName != null && item.versionCode != null);
22485
+ const applicationId = payload.applicationId;
22486
+ const versionName = element?.versionName;
22487
+ const versionCode = Number(element?.versionCode);
22488
+ if (!applicationId || !versionName || !Number.isFinite(versionCode)) {
22489
+ throw new Error("Gradle output metadata is missing applicationId, versionName, or versionCode");
22490
+ }
22491
+ return { applicationId, versionName, versionCode };
22492
+ }
22476
22493
  function bumpAndroidProjectVersion(appDir, bump) {
22477
22494
  const candidates = [
22478
22495
  import_node_path24.default.join(appDir, "app", "build.gradle.kts"),
@@ -22501,6 +22518,13 @@ function findLatestApk(repoRoot, appDir, variant) {
22501
22518
  files.sort((a, b) => (0, import_node_fs20.statSync)(b).mtimeMs - (0, import_node_fs20.statSync)(a).mtimeMs);
22502
22519
  return files[0];
22503
22520
  }
22521
+ function readGradleOutputMetadata(apkPath) {
22522
+ const metadataPath = import_node_path24.default.join(import_node_path24.default.dirname(apkPath), "output-metadata.json");
22523
+ if (!(0, import_node_fs20.existsSync)(metadataPath)) {
22524
+ throw new Error(`Gradle output metadata not found: ${metadataPath}`);
22525
+ }
22526
+ return parseGradleOutputMetadata((0, import_node_fs20.readFileSync)(metadataPath, "utf8"), import_node_path24.default.basename(apkPath));
22527
+ }
22504
22528
  function listApks(dir) {
22505
22529
  if (!(0, import_node_fs20.existsSync)(dir)) return [];
22506
22530
  return (0, import_node_fs20.readdirSync)(dir).filter((entry) => entry.endsWith(".apk")).map((entry) => import_node_path24.default.join(dir, entry)).filter((entry) => (0, import_node_fs20.statSync)(entry).isFile());
@@ -22529,6 +22553,30 @@ function runCommandCapture(command, args, cwd) {
22529
22553
  });
22530
22554
  });
22531
22555
  }
22556
+ async function runAndroidSdkToolCapture(toolName, args) {
22557
+ const toolPath = findAndroidSdkTool(toolName);
22558
+ if (!toolPath) {
22559
+ throw new Error(`Android SDK tool not found: ${toolName}`);
22560
+ }
22561
+ return runCommandCapture(toolPath, args);
22562
+ }
22563
+ function findAndroidSdkTool(toolName) {
22564
+ const sdkRoots = [process.env.ANDROID_HOME, process.env.ANDROID_SDK_ROOT].filter((item) => Boolean(item)).map((item) => import_node_path24.default.resolve(item));
22565
+ for (const sdkRoot of sdkRoots) {
22566
+ const candidates = toolName === "aapt" ? listVersionedToolCandidates(import_node_path24.default.join(sdkRoot, "build-tools"), toolName) : [
22567
+ import_node_path24.default.join(sdkRoot, "cmdline-tools", "latest", "bin", toolName),
22568
+ ...listVersionedToolCandidates(import_node_path24.default.join(sdkRoot, "cmdline-tools"), import_node_path24.default.join("bin", toolName)),
22569
+ import_node_path24.default.join(sdkRoot, "tools", "bin", toolName)
22570
+ ];
22571
+ const match = candidates.find((candidate) => (0, import_node_fs20.existsSync)(candidate));
22572
+ if (match) return match;
22573
+ }
22574
+ return void 0;
22575
+ }
22576
+ function listVersionedToolCandidates(parentDir, relativeToolPath) {
22577
+ if (!(0, import_node_fs20.existsSync)(parentDir)) return [];
22578
+ return (0, import_node_fs20.readdirSync)(parentDir).map((entry) => import_node_path24.default.join(parentDir, entry)).filter((entry) => (0, import_node_fs20.statSync)(entry).isDirectory()).sort((a, b) => import_node_path24.default.basename(b).localeCompare(import_node_path24.default.basename(a), void 0, { numeric: true })).map((entry) => import_node_path24.default.join(entry, relativeToolPath));
22579
+ }
22532
22580
  function sha256File(filePath) {
22533
22581
  return new Promise((resolve, reject) => {
22534
22582
  const hash = (0, import_node_crypto4.createHash)("sha256");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmate/cli",
3
- "version": "0.25.2",
3
+ "version": "0.25.3",
4
4
  "description": "CLI utilities for the pMate project",
5
5
  "license": "MIT",
6
6
  "bin": {