bre*_*dan 9 bash gradle kotlin ros gradle-kotlin-dsl
我需要在shell环境中运行Gradle任务,该环境必须在启动任务之前创建.使用commandLine
或executable
不合适,因为我需要在与shell脚本相同的进程中运行任务.最初,我直接在里面调用了脚本gradlew
,但后来我决定从中获取源代码build.gradle.kts
并通过gradlew
以下方式调用后续任务:
val setupRosEnv by tasks.creating(Exec::class) {
executable = "bash"
args("-c", "source $rosPath/setup.sh && source gradlew myTask")
}
Run Code Online (Sandbox Code Playgroud)
我可以通过./gradlew setupRosEnv
CLI 运行来构建所有内容.除了运行脚本然后运行gradlew
,有没有办法使用Gradle API实现这一点?当前的解决方案看起来有点笨拙,而且依赖于其他任务很笨拙setupRosEnv
,因为这将导致无限循环或必须明确处理以防止任务多次运行.
由于shell脚本本身是由ROS生成的,因此无法将其转换为Gradle或轻松解析.
这取决于您的gradle任务如何myTask
使用环境.如果它使用环境System.getenv
,则可以使用以下步骤.
env.sh
并将所有变量加载到Properties
java.lang.ProcessEnvironment
通过反射将环境变量附加到当前进程下面只是从Java复制的一个示例代码,稍作修改,但它在gradle构建任务中工作正常.
task myEnvironInjected << {
println("task with injected enviroment")
}
task myBuildTask(dependsOn: myEnvironInjected) << {
def v1 = System.getenv("V1")
println("my build task running V1=${v1}")
}
myEnvironInjected.doFirst {
final Map<String, String> bashEnvMap = new HashMap<>();
try {
// a simple simulation of bash command source env.sh
// use it carefully
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream
("/path/to/env.sh")));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream));
String line;
while ((line = reader.readLine()) != null) {
if (line.length() > 0 && line.startsWith("export ")) {
String newLine = line.trim().replaceFirst("^export ", "");
// remove single or double quote from the value if it has
int quoteIndex = newLine.indexOf('=')+1;
if (quoteIndex < newLine.length() && (newLine.charAt(quoteIndex) == ('"' as char) ||
newLine.charAt(quoteIndex) == ('\'' as char))) {
newLine = newLine.substring(0, quoteIndex) + newLine.substring(quoteIndex+1, newLine.length()-1);
}
writer.write(newLine);
writer.newLine();
}
}
writer.flush();
writer.close();
InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
Properties properties = new Properties();
properties.load(inputStream);
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
bashEnvMap.put(((String) entry.getKey()), ((String) entry.getValue()));
}
outputStream.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
for (Class<?> aClass : Collections.class.getDeclaredClasses()) {
if ("java.util.Collections\$UnmodifiableMap".equals(aClass.getName())) {
try {
Field mapField = aClass.getDeclaredField("m");
mapField.setAccessible(true);
Object mapObject = mapField.get(System.getenv());
Map<String, String> environMap = ((Map<String, String>) mapObject);
environMap.putAll(bashEnvMap);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
for (Map.Entry<String, String> envEntry : System.getenv().entrySet()) {
System.out.println(envEntry.getKey() + "=" + envEntry.getValue());
}
}
Run Code Online (Sandbox Code Playgroud)
我的测试文件env.sh
看起来像这样.
export V1="v1 vvv"
export V2='v 2222'
export V3=v33333
Run Code Online (Sandbox Code Playgroud)
如果您的构建任务不使用环境变量System.getenv
,那么您的黑客方法可能是最佳解决方案.
task myBuildTaskWithSourceEnv(type: Exec) {
commandLine '/bin/bash'
setArgs(['-c', 'source ../env.sh;set;../gradlew :app:assembleDebug'])
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
987 次 |
最近记录: |