【问题标题】:How to properly load a Starlark script into another?如何将 Starlark 脚本正确加载到另一个脚本中?
【发布时间】:2019-04-13 14:44:15
【问题描述】:

我正在尝试用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_archivehttp_file)并定义我自己的 Starlark 超集。


我正在为 Starlark described in the official documentation 使用 Bazel java 实现。它是通过以下方式获得的:

  1. 克隆Bazel repository
  2. 正在运行bazel build //src/main/java/com/google/devtools/starlark:Starlark_deploy.jar
  3. 上面命令的输出是Starlark_deploy.jar

【问题讨论】:

    标签: bazel buck skylark starlark


    【解决方案1】:

    它没有被记录,因为它不是一个干净或稳定的 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;
      }
    

    执行后返回环境,可以查看已定义的变量或函数。

    在上面的示例中,模块在for 循环中被一一加载。您可以像 Bazel 那样并行进行评估。

    正如我之前所说,预计 API 会发生重大变化。

    【讨论】:

    • 太好了。我会谨慎地在产品中使用它,但我绝对想测试它。我会试一试,然后回来接受答案!非常感谢您的帮助:)
    猜你喜欢
    • 1970-01-01
    • 2021-08-28
    • 2017-01-20
    • 1970-01-01
    • 2019-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多