feat(bin): add pm.uninstall

This commit is contained in:
Simon Chan 2023-09-07 11:45:58 +08:00
parent 023492fb75
commit 2743a9088f
No known key found for this signature in database
GPG key ID: A8B69F750B9BCEDD

View file

@ -1,6 +1,7 @@
// cspell:ignore dont // cspell:ignore dont
// cspell:ignore instantapp // cspell:ignore instantapp
// cspell:ignore apks // cspell:ignore apks
// cspell:ignore versioncode
import type { Adb } from "@yume-chan/adb"; import type { Adb } from "@yume-chan/adb";
import { import {
@ -9,7 +10,11 @@ import {
escapeArg, escapeArg,
} from "@yume-chan/adb"; } from "@yume-chan/adb";
import type { Consumable, ReadableStream } from "@yume-chan/stream-extra"; import type { Consumable, ReadableStream } from "@yume-chan/stream-extra";
import { ConcatStringStream, DecodeUtf8Stream } from "@yume-chan/stream-extra"; import {
ConcatStringStream,
DecodeUtf8Stream,
SplitStringStream,
} from "@yume-chan/stream-extra";
import { Cmd } from "./cmd.js"; import { Cmd } from "./cmd.js";
@ -218,6 +223,23 @@ export interface PackageManagerListPackagesResult {
uid?: number | undefined; uid?: number | undefined;
} }
export interface PackageManagerUninstallOptions {
keepData: boolean;
user: "all" | "current" | number;
versionCode: number;
splitNames: string[];
}
const PACKAGE_MANAGER_UNINSTALL_OPTIONS_MAP: Record<
keyof PackageManagerUninstallOptions,
string
> = {
keepData: "-k",
user: "--user",
versionCode: "--versionCode",
splitNames: "",
};
export class PackageManager extends AdbCommandBase { export class PackageManager extends AdbCommandBase {
#cmd: Cmd; #cmd: Cmd;
@ -297,10 +319,9 @@ export class PackageManager extends AdbCommandBase {
// so installing a file must use `pm`. // so installing a file must use `pm`.
const args = this.#buildInstallArguments(options); const args = this.#buildInstallArguments(options);
args.push(filePath); args.push(filePath);
const process = await AdbSubprocessNoneProtocol.raw( const process = await this.adb.subprocess.spawn(args.map(escapeArg), {
this.adb, protocols: [AdbSubprocessNoneProtocol],
args.map(escapeArg).join(" "), });
);
const output = await process.stdout const output = await process.stdout
.pipeThrough(new DecodeUtf8Stream()) .pipeThrough(new DecodeUtf8Stream())
@ -348,6 +369,8 @@ export class PackageManager extends AdbCommandBase {
]); ]);
} }
// TODO: install: support split apk formats (`adb install-multiple`)
static parsePackageListItem( static parsePackageListItem(
line: string, line: string,
): PackageManagerListPackagesResult { ): PackageManagerListPackagesResult {
@ -399,9 +422,18 @@ export class PackageManager extends AdbCommandBase {
}; };
} }
async listPackages( async #cmdOrSubprocess(args: string[]) {
if (this.#cmd.supportsCmd) {
args.shift();
return await this.#cmd.spawn(false, "package", ...args);
}
return this.adb.subprocess.spawn(args);
}
async *listPackages(
options?: Partial<PackageManagerListPackagesOptions>, options?: Partial<PackageManagerListPackagesOptions>,
): Promise<PackageManagerListPackagesResult[]> { ): AsyncGenerator<PackageManagerListPackagesResult, void, void> {
const args = this.#buildArguments( const args = this.#buildArguments(
["list", "packages"], ["list", "packages"],
options, options,
@ -410,12 +442,42 @@ export class PackageManager extends AdbCommandBase {
if (options?.filter) { if (options?.filter) {
args.push(options.filter); args.push(options.filter);
} }
const output = await this.adb.subprocess.spawnAndWaitLegacy(args);
return output const process = await this.#cmdOrSubprocess(args);
.split("\n") const reader = process.stdout
.filter((line) => !!line) .pipeThrough(new DecodeUtf8Stream())
.map((line) => PackageManager.parsePackageListItem(line)); .pipeThrough(new SplitStringStream("\n"))
.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
yield PackageManager.parsePackageListItem(value);
}
} }
// TODO: install: support split apk formats (`adb install-multiple`) async uninstall(
packageName: string,
options?: Partial<PackageManagerUninstallOptions>,
): Promise<void> {
const args = this.#buildArguments(
["uninstall"],
options,
PACKAGE_MANAGER_UNINSTALL_OPTIONS_MAP,
);
args.push(packageName);
if (options?.splitNames) {
args.push(...options.splitNames);
}
const process = await this.#cmdOrSubprocess(args);
const output = await process.stdout
.pipeThrough(new DecodeUtf8Stream())
.pipeThrough(new ConcatStringStream())
.then((output) => output.trim());
if (output !== "Success") {
throw new Error(output);
}
}
} }