当 运行 ./pants idea 有多个目标时,为什么 IntelliJ 不尊重我的依赖项?
When running ./pants idea with multiple targets, why doesn't IntelliJ respect my dependencies?
在多个目标上 运行 宁 ./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
首先要注意的是,在生成的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
目标引用它尚未声明依赖的代码。简而言之,这是今天裤子 idea
和 test
目标中的一个错误。
idea
错误
idea 目标当前为命令行上指定的所有目标生成一个模块,这使得所有目标对于 IDEA 的编译方案而言彼此可见。相反,idea 目标应该真正为每个目标生成一个模块。您可以尝试使用 IDEA Pants Support 插件来替代 ./pants idea
命令行目标。
test
错误
这确实是 compile
目标中的一个错误,test
隐含地 运行s。就目前而言,jvm 编译的裤子处理在概念上是批处理的。如果像处理 ::
递归目标 glob 一样将许多目标交给它,它会将生成的 t运行sitive 目标闭包视为一个编译单元,用于类路径和源路径。现在这是一个善意的谎言,在某些情况下 pants 被迫将编译分成几个块,在这些情况下,具有未声明依赖项的目标团也可能会失败。
正在进行的工作是让裤子从概念批处理转移到真正的每个目标独立编译。一旦这项工作完成,默认情况下或通过配置你的 repo pants.ini,上面的 globbed 测试命令和单独的目标测试命令都将在编译阶段失败。
在多个目标上 运行 宁 ./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
首先要注意的是,在生成的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
目标引用它尚未声明依赖的代码。简而言之,这是今天裤子 idea
和 test
目标中的一个错误。
idea
错误idea 目标当前为命令行上指定的所有目标生成一个模块,这使得所有目标对于 IDEA 的编译方案而言彼此可见。相反,idea 目标应该真正为每个目标生成一个模块。您可以尝试使用 IDEA Pants Support 插件来替代
./pants idea
命令行目标。test
错误这确实是
compile
目标中的一个错误,test
隐含地 运行s。就目前而言,jvm 编译的裤子处理在概念上是批处理的。如果像处理::
递归目标 glob 一样将许多目标交给它,它会将生成的 t运行sitive 目标闭包视为一个编译单元,用于类路径和源路径。现在这是一个善意的谎言,在某些情况下 pants 被迫将编译分成几个块,在这些情况下,具有未声明依赖项的目标团也可能会失败。正在进行的工作是让裤子从概念批处理转移到真正的每个目标独立编译。一旦这项工作完成,默认情况下或通过配置你的 repo pants.ini,上面的 globbed 测试命令和单独的目标测试命令都将在编译阶段失败。