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

View File

@@ -229,19 +229,6 @@ public class AdbCommandBuilder {
return this; 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() { public List<String> build() {
return this.command; return this.command;

View File

@@ -10,6 +10,7 @@ import net.geedge.common.RCode;
import net.geedge.common.T; import net.geedge.common.T;
import java.io.*; import java.io.*;
import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.*; import java.util.*;
import java.util.concurrent.*; 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()); log.info("[execPlaybook] [begin!] [serial:{}]", this.getSerial());
List<String> command = new AdbCommandBuilder("python") List<String> command;
.buildRunPlaybook(ANDROID_LAUNCHER, playbookPath, tid, packageName, this.getSerial()) File environment = null;
.build(); 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); Process process = commandExec.execForProcess(command);
T.FileUtil.appendString(T.StrUtil.concat(true, "$ ", command.stream().collect(Collectors.joining(" ")), "\n"), logFile, "UTF-8"); 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(); process.destroyForcibly();
throw new APIException(RCode.ERROR); throw new APIException(RCode.ERROR);
}finally { }finally {
T.FileUtil.del(environment);
T.IoUtil.close(inputStreamReader); T.IoUtil.close(inputStreamReader);
T.IoUtil.close(bufferedReader); T.IoUtil.close(bufferedReader);
} }

View File

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