如何正确地将 Starlark 脚本加载到另一个脚本中?
How to properly load a Starlark script into another?
我试图用 Starlark:
做一个非常简单的实现
greeting.bzl
def greet():
print ("Hello World!")
test.bzl
load (":greeting.bzl", "greet")
greet()
并执行:
java -jar Starlark_deploy.jar test.bzl
以上调用的结果为:
file ':greeting.bzl' was not correctly loaded. Make sure the 'load' statement appears in the global scope in your file
我的最终目标是拥有自己的 Starlark 引擎,这取决于 Starlark_deploy.jar
。然后,我将利用现有的 Bazel 规则(例如 htt_archive
和 http_file
)并定义我自己的 Starlark 超集。
我正在为 Starlark described in the official documentation 使用 Bazel java 实现。获得方式:
- 克隆Bazel repository
- 运行
bazel build //src/main/java/com/google/devtools/starlark:Starlark_deploy.jar
- 上面命令的输出是
Starlark_deploy.jar
它没有记录在案,因为它不是干净或稳定的 API。预计未来会发生 API 变化。要嵌入另一个工具,Go implementation 成熟得多。
话虽如此,如果您想进行实验,您可以:
import com.google.devtools.build.lib.syntax.ParserInputSource;
import com.google.devtools.build.lib.syntax.ParserInputSource;
import com.google.devtools.build.lib.syntax.StringLiteral;
import java.util.HashMap;
import java.util.Map;
public Environment newEnvironment(Map<String, Environment.Extension> imports) {
return Environment.builder(mutability)
.useDefaultSemantics()
.setGlobals(Environment.DEFAULT_GLOBALS)
.setEventHandler(PRINT_HANDLER)
.setImportedExtensions(imports)
.build();
}
public Environment execute(String path)
throws InterruptedException, IOException, EvalException {
String content = new String(Files.readAllBytes(Paths.get(path)), CHARSET);
ParserInputSource input = ParserInputSource.create(content, PathFragment.EMPTY_FRAGMENT);
BuildFileAST ast = BuildFileAST.parseSkylarkFileWithoutImports(input, PRINT_HANDLER);
Map<String, Environment.Extension> imports = new HashMap<>();
for (StringLiteral imp : ast.getRawImports()) {
imports.put(
imp.getValue(),
new Environment.Extension(execute(imp.getValue())));
}
Environment env = newEnvironment(imports);
ast.eval(env);
return env;
}
returns执行后的环境,可以检查已定义的变量或函数。
在上面的示例中,模块在 for
循环中一个接一个地加载。您可以像 Bazel 那样并行进行评估。
正如我之前所说,期待 API 中的突破性变化。
我试图用 Starlark:
做一个非常简单的实现greeting.bzl
def greet():
print ("Hello World!")
test.bzl
load (":greeting.bzl", "greet")
greet()
并执行:
java -jar Starlark_deploy.jar test.bzl
以上调用的结果为:
file ':greeting.bzl' was not correctly loaded. Make sure the 'load' statement appears in the global scope in your file
我的最终目标是拥有自己的 Starlark 引擎,这取决于 Starlark_deploy.jar
。然后,我将利用现有的 Bazel 规则(例如 htt_archive
和 http_file
)并定义我自己的 Starlark 超集。
我正在为 Starlark described in the official documentation 使用 Bazel java 实现。获得方式:
- 克隆Bazel repository
- 运行
bazel build //src/main/java/com/google/devtools/starlark:Starlark_deploy.jar
- 上面命令的输出是
Starlark_deploy.jar
它没有记录在案,因为它不是干净或稳定的 API。预计未来会发生 API 变化。要嵌入另一个工具,Go implementation 成熟得多。
话虽如此,如果您想进行实验,您可以:
import com.google.devtools.build.lib.syntax.ParserInputSource;
import com.google.devtools.build.lib.syntax.ParserInputSource;
import com.google.devtools.build.lib.syntax.StringLiteral;
import java.util.HashMap;
import java.util.Map;
public Environment newEnvironment(Map<String, Environment.Extension> imports) {
return Environment.builder(mutability)
.useDefaultSemantics()
.setGlobals(Environment.DEFAULT_GLOBALS)
.setEventHandler(PRINT_HANDLER)
.setImportedExtensions(imports)
.build();
}
public Environment execute(String path)
throws InterruptedException, IOException, EvalException {
String content = new String(Files.readAllBytes(Paths.get(path)), CHARSET);
ParserInputSource input = ParserInputSource.create(content, PathFragment.EMPTY_FRAGMENT);
BuildFileAST ast = BuildFileAST.parseSkylarkFileWithoutImports(input, PRINT_HANDLER);
Map<String, Environment.Extension> imports = new HashMap<>();
for (StringLiteral imp : ast.getRawImports()) {
imports.put(
imp.getValue(),
new Environment.Extension(execute(imp.getValue())));
}
Environment env = newEnvironment(imports);
ast.eval(env);
return env;
}
returns执行后的环境,可以检查已定义的变量或函数。
在上面的示例中,模块在 for
循环中一个接一个地加载。您可以像 Bazel 那样并行进行评估。
正如我之前所说,期待 API 中的突破性变化。