mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-09 15:59:30 +00:00
fix(android): auto-detect the Android SDK when fresh worktrees lack local.properties (#101273)
This commit is contained in:
parent
6e7ef631d2
commit
bc5a82b26d
2 changed files with 84 additions and 4 deletions
|
|
@ -1,5 +1,7 @@
|
|||
#!/usr/bin/env node
|
||||
import { spawn } from "node:child_process";
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
|
|
@ -39,11 +41,35 @@ export function linuxArmAndroidGradleSkipMessage(platform = process.platform, ar
|
|||
);
|
||||
}
|
||||
|
||||
export function run(command, args, cwd) {
|
||||
// Fresh git worktrees do not carry the gitignored apps/android/local.properties,
|
||||
// so AGP tasks fail with "SDK location not found" even when an SDK is installed.
|
||||
// Fall back to the Android Studio default install path when nothing names one.
|
||||
export function resolveAndroidSdkEnv(options = {}) {
|
||||
const env = options.env ?? process.env;
|
||||
if (env.ANDROID_HOME || env.ANDROID_SDK_ROOT) {
|
||||
return env;
|
||||
}
|
||||
const existsSync = options.existsSync ?? fs.existsSync;
|
||||
if (existsSync(path.join(androidDir, "local.properties"))) {
|
||||
return env;
|
||||
}
|
||||
const homeDir = options.homeDir ?? os.homedir();
|
||||
const platform = options.platform ?? process.platform;
|
||||
const defaultSdkDir =
|
||||
platform === "darwin"
|
||||
? path.join(homeDir, "Library", "Android", "sdk")
|
||||
: path.join(homeDir, "Android", "Sdk");
|
||||
if (!existsSync(defaultSdkDir)) {
|
||||
return env;
|
||||
}
|
||||
return { ...env, ANDROID_HOME: defaultSdkDir };
|
||||
}
|
||||
|
||||
export function run(command, args, cwd, env = process.env) {
|
||||
return new Promise((resolve) => {
|
||||
const child = spawn(command, args, {
|
||||
cwd,
|
||||
env: process.env,
|
||||
env,
|
||||
stdio: "inherit",
|
||||
});
|
||||
child.on("close", (status, signal) => {
|
||||
|
|
@ -78,12 +104,13 @@ export async function main(argv = process.argv.slice(2)) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
const gradleStatus = await run("./gradlew", gradleArgs, androidDir);
|
||||
const env = resolveAndroidSdkEnv();
|
||||
const gradleStatus = await run("./gradlew", gradleArgs, androidDir, env);
|
||||
if (gradleStatus !== 0 || postArgs.length === 0) {
|
||||
return gradleStatus;
|
||||
}
|
||||
|
||||
return await run(postArgs[0], postArgs.slice(1), repoRoot);
|
||||
return await run(postArgs[0], postArgs.slice(1), repoRoot, env);
|
||||
}
|
||||
|
||||
if (isMain) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
linuxArmAndroidGradleSkipMessage,
|
||||
resolveAndroidSdkEnv,
|
||||
shouldSkipLinuxArmAndroidGradle,
|
||||
splitAndroidGradleArgs,
|
||||
} from "../../scripts/run-android-gradle.mjs";
|
||||
|
|
@ -37,4 +39,55 @@ describe("run-android-gradle", () => {
|
|||
"OPENCLAW_ANDROID_GRADLE_ALLOW_LINUX_ARM=1",
|
||||
);
|
||||
});
|
||||
|
||||
describe("resolveAndroidSdkEnv", () => {
|
||||
const macSdk = path.join("/Users/dev", "Library", "Android", "sdk");
|
||||
const linuxSdk = path.join("/home/dev", "Android", "Sdk");
|
||||
|
||||
it("keeps env untouched when ANDROID_HOME or ANDROID_SDK_ROOT is set", () => {
|
||||
const env = { ANDROID_HOME: "/opt/sdk" };
|
||||
expect(resolveAndroidSdkEnv({ env, existsSync: () => true })).toBe(env);
|
||||
const rootEnv = { ANDROID_SDK_ROOT: "/opt/sdk" };
|
||||
expect(resolveAndroidSdkEnv({ env: rootEnv, existsSync: () => true })).toBe(rootEnv);
|
||||
});
|
||||
|
||||
it("keeps env untouched when local.properties exists", () => {
|
||||
const env = {};
|
||||
const result = resolveAndroidSdkEnv({
|
||||
env,
|
||||
existsSync: (p: string) => p.endsWith("local.properties"),
|
||||
homeDir: "/Users/dev",
|
||||
platform: "darwin",
|
||||
});
|
||||
expect(result).toBe(env);
|
||||
});
|
||||
|
||||
it("falls back to the Android Studio default SDK path per platform", () => {
|
||||
const darwin = resolveAndroidSdkEnv({
|
||||
env: {},
|
||||
existsSync: (p: string) => p === macSdk,
|
||||
homeDir: "/Users/dev",
|
||||
platform: "darwin",
|
||||
});
|
||||
expect(darwin.ANDROID_HOME).toBe(macSdk);
|
||||
const linux = resolveAndroidSdkEnv({
|
||||
env: {},
|
||||
existsSync: (p: string) => p === linuxSdk,
|
||||
homeDir: "/home/dev",
|
||||
platform: "linux",
|
||||
});
|
||||
expect(linux.ANDROID_HOME).toBe(linuxSdk);
|
||||
});
|
||||
|
||||
it("keeps env untouched when no default SDK install exists", () => {
|
||||
const env = {};
|
||||
const result = resolveAndroidSdkEnv({
|
||||
env,
|
||||
existsSync: () => false,
|
||||
homeDir: "/Users/dev",
|
||||
platform: "darwin",
|
||||
});
|
||||
expect(result).toBe(env);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue