1

在多个目标上运行./pants idea时,生成的 IntelliJ 项目允许我引用我的目标实际上并不依赖的代码。

这是裤子的一个例子

./pants idea  examples/tests/java/com/pants/examples/hello/greet:: \
    examples/tests/java/com/pants/examples/useproto::

在 Greeting.java 中,我添加了一个对 hello 项目实际上并不依赖的东西的依赖:

  public static String greet(String greetee) {  
    // These two lines added to illustrate question
    Distance proto = Distance.getDefaultInstance();
    System.out.println("Proto: " + proto.toString());
    return "Hello, " + greetee + "!";
  }

但是该GreetingTest项目在 IntelliJ 下运行良好!

但是,当我尝试从命令行运行 GreetingTest 时,它失败了。

$ ./pants test examples/tests/java/com/pants/examples/hello/greet
INFO] Detected git repository at /Users/zundel/Src/pants on branch master

11:24:20 00:00 [main]
               (To run a reporting server: ./pants server)
11:24:20 00:00   [bootstrap]
11:24:20 00:00   [setup]
11:24:20 00:00     [parse]
               Executing tasks in goals: bootstrap -> imports -> unpack-jars -> deferred-sources -> gen -> resolve -> compile -> resources -> test
11:24:20 00:00   [bootstrap]
11:24:20 00:00     [bootstrap-jvm-tools]
11:24:20 00:00   [imports]
11:24:20 00:00     [ivy-imports]
11:24:20 00:00   [unpack-jars]
11:24:20 00:00     [unpack-jars]
11:24:20 00:00   [deferred-sources]
11:24:20 00:00     [deferred-sources]
11:24:20 00:00   [gen]
11:24:20 00:00     [thrift]
11:24:20 00:00     [protoc]
11:24:20 00:00     [antlr]
11:24:20 00:00     [ragel]
11:24:20 00:00     [jaxb]
11:24:21 00:01     [wire]
11:24:21 00:01     [aapt]
11:24:21 00:01     [scrooge]
11:24:21 00:01   [resolve]
11:24:21 00:01     [ivy]
                   Invalidated 2 targets.
11:24:21 00:01       [ivy-resolve]
11:24:21 00:01   [compile]
11:24:21 00:01     [compile]
11:24:21 00:01     [jvm]
11:24:21 00:01       [jvm-compilers]
11:24:21 00:01         [find-deleted-sources]
                     Invalidated 2 targets.
11:24:21 00:01         [partition-analysis]
                     Compiling 2 java sources in 2 targets (partition 1 of 1).
11:24:21 00:01         [compile]
11:24:21 00:01           [jmake]
                         Jmake version 1.3.8-10
                         Opening project database...  Done.
                         Recompiling source files:
                         /Users/zundel/Src/pants/examples/src/java/com/pants/examples/hello/greet/Greeting.java
                         /Users/zundel/Src/pants/examples/src/java/com/pants/examples/hello/greet/Greeting.java:6: error: package com.pants.examples.distance.Distances does not exist
                         import com.pants.examples.distance.Distances.Distance;
                                                                     ^
                         /Users/zundel/Src/pants/examples/src/java/com/pants/examples/hello/greet/Greeting.java:37: error: cannot find symbol
                           symbol:   class Distance
                           location: class com.pants.examples.hello.greet.Greeting
                             Distance proto = Distance.getDefaultInstance();
                             ^
                         /Users/zundel/Src/pants/examples/src/java/com/pants/examples/hello/greet/Greeting.java:37: error: cannot find symbol
                           symbol:   variable Distance
                           location: class com.pants.examples.hello.greet.Greeting
                             Distance proto = Distance.getDefaultInstance();
                                              ^
                         Reading existing dependency file at /Users/zundel/Src/pants/.pants.d/compile/jvm/java/jmake-depfiles/global_depfile
                         Writing class dependency file to /Users/zundel/Src/pants/.pants.d/compile/jvm/java/jmake-depfiles/global_depfile
                         Writing project database...  Done.

FAILURE: compilation error


               Waiting for background workers to finish.
               FAILURE
4

1 回答 1

2

首先要注意的是,测试在 IntelliJ IDEA 项目中运行绿色的事实是:

$ ./pants idea \
  examples/tests/java/com/pants/examples/hello/greet:: \
  examples/tests/java/com/pants/examples/useproto::

是您在命令行中选择的目标的结果,而不是您在 IDEA 中运行测试的事实。

例如,如果您像这样从命令行运行测试,它们也会通过:

$ ./pants test \
  examples/tests/java/com/pants/examples/hello/greet:: \
  examples/tests/java/com/pants/examples/useproto::`

正如您所指出的,根本原因是裤子让examples/tests/java/com/pants/examples/hello/greet目标引用它没有声明依赖的代码。简而言之,这是当今裤子ideatest目标中的一个错误。

  1. idea漏洞

    IDEA 目标当前为命令行上指定的所有目标生成一个模块,这使得所有目标对彼此可见,以用于 IDEA 的编译方案。相反,idea 目标应该真正为每个目标生成一个模块。您可以尝试使用 IDEA Pants Support插件作为./pants idea命令行目标的替代方案。

  2. test漏洞

    这实际上是隐式运行的compile目标中的一个错误。test就目前情况而言,对 jvm 编译的裤子处理在概念上是批处理的。如果您像处理::递归目标 glob 一样向它传递许多目标,则出于类路径和源路径的目的,它会将生成的目标传递闭包视为一个编译单元。现在这是一个善意的谎言,在某些情况下,裤子被迫将编译分解成几个块,在这种情况下,具有未声明依赖关系的目标对象也可能会失败。

    正在进行的工作是让裤子从概念批处理转移到真正的每个目标隔离编译。一旦这项工作完成,默认情况下或通过 repo 的pants.ini 配置,上面的全局测试命令和单独的目标测试命令都将在编译阶段失败。

于 2015-04-03T19:38:36.870 回答