fix: playbook 支持 python 脚本

This commit is contained in:
zhangshuai
2024-11-26 10:08:24 +08:00
parent 35eebd7beb
commit 83b17b5f5e
5 changed files with 135 additions and 32 deletions

View File

@@ -268,11 +268,12 @@ public class APIController {
public R execPlaybook(@RequestParam("file") MultipartFile file,
@RequestParam("packageName") String packageName,
@RequestParam("id") String id,
@RequestParam("type") String type,
@RequestParam("reInstall") Boolean reInstall,
@RequestParam("clearCache") Boolean clearCache,
@RequestParam("unInstall") Boolean unInstall) {
File apkFile = null;
File playbookAirDir = null;
File scriptPath = null;
File destination = null;
try {
File playbookDir = T.FileUtil.file(Constant.TEMP_PATH, id);
@@ -299,14 +300,24 @@ public class APIController {
})).findFirst().get();
// unzip playbook zip
T.ZipUtil.unzip(playbook, playbookDir);
playbookAirDir = Arrays.stream(playbookDir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".air");
}
})).findFirst().get();
if (T.StrUtil.equals(type, "python")){
playbookDir = T.FileUtil.file(Constant.TEMP_PATH, id, "main");
T.ZipUtil.unzip(playbook, playbookDir);
scriptPath = Arrays.stream(playbookDir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().equals("main.py");
}
})).findFirst().get();
}else {
T.ZipUtil.unzip(playbook, playbookDir);
scriptPath = Arrays.stream(playbookDir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".air");
}
})).findFirst().get();
}
} catch (Exception e) {
log.error(e.getMessage());
throw new APIException(RCode.ERROR);
@@ -314,7 +325,7 @@ public class APIController {
T.FileUtil.del(destination);
}
PlaybookRunnable playbookRunnable = new PlaybookRunnable(apiYml, apkFile, playbookAirDir, id, packageName, reInstall, clearCache, unInstall);
PlaybookRunnable playbookRunnable = new PlaybookRunnable(apiYml, apkFile, scriptPath, id, packageName, type, reInstall, clearCache, unInstall);
ThreadUtil.execAsync(playbookRunnable);
return R.ok();
}
@@ -391,7 +402,7 @@ public class APIController {
File playbookDir = Arrays.stream(jobResult.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".air");
return name.endsWith(".air") || name.equals("main");
}
})).toList().getFirst();

View File

@@ -229,19 +229,6 @@ public class AdbCommandBuilder {
return this;
}
public AdbCommandBuilder buildRunPlaybook(String launcher, String path, String jobId, String packageName, String serial) {
this.command.add(launcher);
this.command.add(path);
this.command.add("--device");
this.command.add(T.StrUtil.concat(true,"Android://127.0.0.1:5037/", serial));
this.command.add("--job_id");
this.command.add(jobId);
this.command.add("--job_path");
this.command.add(path);
this.command.add("--package_name");
this.command.add(packageName);
return this;
}
public List<String> build() {
return this.command;

View File

@@ -10,6 +10,7 @@ import net.geedge.common.RCode;
import net.geedge.common.T;
import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.*;
@@ -901,11 +902,32 @@ public class AdbUtil {
}
public CommandResult execPlaybook(String playbookPath, String tid, String packageName, File logFile) {
public CommandResult execPlaybook(String scriptPath, String tid, String packageName, String type, File logFile) {
log.info("[execPlaybook] [begin!] [serial:{}]", this.getSerial());
List<String> command = new AdbCommandBuilder("python")
.buildRunPlaybook(ANDROID_LAUNCHER, playbookPath, tid, packageName, this.getSerial())
.build();
List<String> command;
File environment = null;
if (T.StrUtil.equals(type, "python")){
// check requirements.txt
Path parent = Paths.get(scriptPath).getParent();
Path resolve = parent.resolve("requirements.txt");
command = new PythonCommandBuilder("python")
.buildRunPythonScript(scriptPath, tid, packageName, this.getSerial())
.build();
if (T.FileUtil.exist(resolve.toString())){
// create venv
environment = T.FileUtil.file(parent.toString(), "environment");
commandExec.exec(new PythonCommandBuilder("python").buildCreateVenv(environment.getAbsolutePath()).build());
commandExec.exec(new PythonCommandBuilder(T.StrUtil.concat(true, environment.getAbsolutePath(), "/bin/pip")).buildUpgradePip().build());
commandExec.exec(new PythonCommandBuilder(T.StrUtil.concat(true, environment.getAbsolutePath(), "/bin/pip")).buildInstallRequirements(resolve.toString()).build());
command = new PythonCommandBuilder(T.StrUtil.concat(true, environment.getAbsolutePath(), "/bin/python"))
.buildRunPythonScript(scriptPath, tid, packageName, this.getSerial())
.build();
}
}else {
command = new PythonCommandBuilder("python")
.buildRunAirScript(ANDROID_LAUNCHER, scriptPath, tid, packageName, this.getSerial())
.build();
}
Process process = commandExec.execForProcess(command);
T.FileUtil.appendString(T.StrUtil.concat(true, "$ ", command.stream().collect(Collectors.joining(" ")), "\n"), logFile, "UTF-8");
@@ -929,6 +951,7 @@ public class AdbUtil {
process.destroyForcibly();
throw new APIException(RCode.ERROR);
}finally {
T.FileUtil.del(environment);
T.IoUtil.close(inputStreamReader);
T.IoUtil.close(bufferedReader);
}

View File

@@ -22,18 +22,20 @@ public class PlaybookRunnable implements Runnable {
private String tid;
private File apkFile;
private String packageName;
private File playbookDir;
private File scriptPath;
private String type;
private boolean reInstall;
private boolean clearCache;
private boolean unInstall;
private boolean interrupt;
public PlaybookRunnable(EnvApiYml envApiYml, File apkFile, File playbookDir, String tid, String packageName, Boolean reInstall, Boolean clearCache, Boolean unInstall) {
public PlaybookRunnable(EnvApiYml envApiYml, File apkFile, File scriptPath, String tid, String packageName, String type, Boolean reInstall, Boolean clearCache, Boolean unInstall) {
this.envApiYml = envApiYml;
this.tid = tid;
this.apkFile = apkFile;
this.packageName = packageName;
this.playbookDir = playbookDir;
this.scriptPath = scriptPath;
this.type = type;
this.reInstall = reInstall;
this.clearCache = clearCache;
this.unInstall = unInstall;
@@ -118,7 +120,7 @@ public class PlaybookRunnable implements Runnable {
// exec playbook
if (interrupt) return;
AdbUtil.CommandResult airtestResult = adbUtil.execPlaybook(playbookDir.getPath(), tid, packageName, logFile);
AdbUtil.CommandResult airtestResult = adbUtil.execPlaybook(scriptPath.getPath(), tid, packageName, type, logFile);
if (0 != airtestResult.exitCode()) {
T.FileUtil.appendString(String.format("ERROR: Exec playbook failed: exit code %s \n", airtestResult.exitCode()), logFile, "UTF-8");
throw new APIException("playbook exec error");

View File

@@ -0,0 +1,80 @@
package net.geedge.api.util;
import net.geedge.common.T;
import java.util.LinkedList;
import java.util.List;
public class PythonCommandBuilder {
private final String pythonPath;
private final List<String> command;
public PythonCommandBuilder(String pythonPath) {
this.pythonPath = pythonPath;
this.command = new LinkedList<>();
this.command.add(pythonPath);
}
public static PythonCommandBuilder builder() {
return new PythonCommandBuilder("python");
}
public static PythonCommandBuilder builder(String pythonPath) {
return new PythonCommandBuilder(pythonPath);
}
public PythonCommandBuilder buildRunAirScript(String launcher, String path, String jobId, String packageName, String serial) {
this.command.add(launcher);
this.command.add(path);
this.command.add("--device");
this.command.add(T.StrUtil.concat(true,"Android://127.0.0.1:5037/", serial));
this.command.add("--job_id");
this.command.add(jobId);
this.command.add("--job_path");
this.command.add(path);
this.command.add("--package_name");
this.command.add(packageName);
return this;
}
public PythonCommandBuilder buildRunPythonScript(String path, String jobId, String packageName, String serial) {
this.command.add(path);
this.command.add("--device");
this.command.add(T.StrUtil.concat(true,"Android://127.0.0.1:5037/", serial));
this.command.add("--serial");
this.command.add(serial);
this.command.add("--job_id");
this.command.add(jobId);
this.command.add("--job_path");
this.command.add(path);
this.command.add("--package_name");
this.command.add(packageName);
return this;
}
public PythonCommandBuilder buildCreateVenv(String path) {
this.command.add("-m");
this.command.add("venv");
this.command.add(path);
this.command.add("--system-site-packages");
return this;
}
public PythonCommandBuilder buildUpgradePip() {
this.command.add("install");
this.command.add("--upgrade");
this.command.add("pip");
return this;
}
public PythonCommandBuilder buildInstallRequirements(String path) {
this.command.add("install");
this.command.add("-r");
this.command.add(path);
return this;
}
public List<String> build() {
return this.command;
}
}