I'm trying to make a very simple implementation with Starlark:
greeting.bzl
def greet():
print ("Hello World!")
test.bzl
load (":greeting.bzl", "greet")
greet()
And execute it with:
java -jar Starlark_deploy.jar test.bzl
The result of the above call is:
file ':greeting.bzl' was not correctly loaded. Make sure the 'load' statement appears in the global scope in your file
My end goal is to have my own Starlark engine, which depends on Starlark_deploy.jar
. I'll then leverage the existence of Bazel rules (such as htt_archive
and http_file
) and define my own Starlark superset.
I'm using Bazel java implementation for Starlark described in the official documentation. It was obtained by:
bazel build //src/main/java/com/google/devtools/starlark:Starlark_deploy.jar
Starlark_deploy.jar
It's not documented because it's not a clean or stable API. Expect API changes in the future. To embed in another tool, the Go implementation is much more mature.
That being said, if you want to experiment, you can:
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;
}
The returns the environment after execution, so you can inspect the variables or functions that have been defined.
In the example above, modules are loaded one by one in the for
loop. You may do the evaluation in parallel, like Bazel does.
As I said before, expect breaking changes in the API.