1
0
Fork 0
mirror of https://github.com/ethauvin/kobalt.git synced 2025-04-28 17:18:13 -07:00

Compare commits

...

228 commits

Author SHA1 Message Date
37a89d206b Centralized versions in main Gradle build file. 2019-03-30 11:17:29 -07:00
bf68749d3e
Merge pull request #501 from ethauvin/master
Grade build
2019-03-30 00:25:51 -07:00
12a0618a90 Ignore build directories. 2019-03-30 00:08:00 -07:00
4a477f5563 Made gradew executable. 2019-03-29 23:53:42 -07:00
a5c0bd921f Added Gradle project based on the POM. 2019-03-29 23:52:02 -07:00
Cedric Beust
200a81b9fc
Merge pull request #500 from pabl0rg/fix-unsafe-dependency-fetching
Fix unsafe dependency fetching
2019-03-29 09:29:53 -07:00
Juan Liska
a38a7187e8 add maven build dirs to classpath in “dev mode”
dev mode = when requested kobalt version jar not found
2019-03-29 10:21:22 -06:00
Juan Liska
ae6258acb8 use https to fetch artifacts 2019-03-29 10:21:22 -06:00
Juan Liska
4644b66d79 create maven build files for kobalt 2019-03-29 10:21:22 -06:00
Cedric Beust
f96e349608
Merge pull request #498 from pabl0rg/upgrade-guava-27.0.1
upgrade guava to 27.0.1 to resolve multimap ordering
2019-03-12 10:49:03 -07:00
Juan Liska
935a866f52 upgrade guava to 27.0.1 to resolve multimap ordering 2019-03-12 11:43:20 -06:00
Cedric Beust
5f7efabe20
Merge pull request #497 from pabl0rg/upgrade-guice-4.2.2
upgrade guice to 4.2.2
2019-03-12 10:40:22 -07:00
Juan Liska
a09594ea06 upgrade guice to 4.2.2 2019-03-12 11:34:21 -06:00
Cedric Beust
e06fc29190 1.0.122. 2018-11-23 14:19:17 -08:00
Cedric Beust
e6b72c282f
Merge pull request #494 from pabl0rg/improve-external-compiler-invocation
Improve external compiler invocation
2018-11-23 07:15:34 -08:00
Juan Liska
a0d33fcaae bump version to 1.0.121 2018-11-23 06:04:54 -06:00
Juan Liska
6934dec51a only add stdlib to classpath when project does not specify a kotlin version
when the project specifies a kotlin version, that version’s stdlib will be added to the classpath by other means
2018-11-23 06:04:48 -06:00
Juan Liska
c33800b189 don’t add deprecated kotlin runtime jar to project templates 2018-11-23 06:04:43 -06:00
Juan Liska
1ff46b5842 don’t add deprecated kotlin runtime jar to classpath 2018-11-23 06:04:38 -06:00
Juan Liska
0cc2c23a32 extend timeout to 2 mins, log error when process times out 2018-11-23 06:04:24 -06:00
Cedric Beust
0f0a780b43 1.0.120. 2018-11-10 08:13:27 -08:00
Cedric Beust
7827aeeb43 Fix project directory. 2018-11-10 08:13:02 -08:00
Cedric Beust
a6097dc136 Better test results. 2018-11-10 08:11:08 -08:00
Cedric Beust
e22b5b77e6 1.0.119. 2018-11-06 10:37:50 -08:00
Cedric Beust
2e73ece52c Fix bad test directory. 2018-11-06 10:37:42 -08:00
Cedric Beust
5c3642b7d7 1.0.118. 2018-10-30 13:37:02 -07:00
Cedric Beust
71540a4426 Fix test results being read in the wrong directory. 2018-10-30 13:36:51 -07:00
Cedric Beust
61534e1e81 1.0.117. 2018-10-15 14:46:41 -07:00
Cedric Beust
b7dd3afde7 Warning. 2018-10-15 14:46:09 -07:00
Cedric Beust
43bb71b486 Better JUnit 5 detection. 2018-10-15 14:46:04 -07:00
Cedric Beust
55bba514b3 Bump kotlinc version. 2018-10-12 13:46:10 -07:00
Cedric Beust
58aae0bfe3 1.0.116. 2018-10-10 13:38:09 -07:00
Cedric Beust
7b902eb673
Merge pull request #488 from pabl0rg/improve-kotlin-compiler-version-tests
Improve kotlin compiler version tests, upgrade to kotlin 1.2.70
2018-09-17 09:22:05 -07:00
Juan Liska
65aedfebdc bump version to 1.0.115 2018-09-17 05:09:43 -06:00
Juan Liska
7cf19b3f95 fix test assertion, enable kobalt logging for tests 2018-09-17 05:00:28 -06:00
Juan Liska
39801a5a24 upgrade default compiler to 1.2.70 2018-09-17 04:55:10 -06:00
Juan Liska
42bd2ecdf1 extend timeout, add logging 2018-09-16 10:01:59 -06:00
Juan Liska
3475377185 add Args parameter to newReposityrSystemSession call 2018-09-16 09:57:37 -06:00
Juan Liska
e1adc87281 add a test for kotlinCompiler version setting 2018-09-16 09:48:37 -06:00
Cedric Beust
cdd30873d0 1.0.114. 2018-03-21 15:17:41 -07:00
Cedric Beust
b368aedef2 MetaArchive fix. 2018-03-21 15:17:20 -07:00
Cedric Beust
8d938bac2e 1.0.113. 2018-03-21 10:15:44 -07:00
Cedric Beust
50b31114f6 Remove warning when failing to parse the version number.
Fixes https://github.com/cbeust/kobalt/issues/475
2018-03-21 10:15:44 -07:00
Cedric Beust
c6b180dd71
Merge pull request #478 from avently/master
Added "offline" argument to prevent remote resolving of dependencies
2018-03-21 10:15:29 -07:00
Avently
f1a025036f Added "offline" argument to prevent remote resolving of dependencies 2018-03-21 18:25:44 +03:00
Cedric Beust
2241323498 Bump JUnit 5 versions. 2018-03-17 12:52:54 -07:00
Cedric Beust
6c031cd3c1 1.0.112. 2018-02-23 00:59:25 -08:00
Cedric Beust
a6f36de6a6 Create directories before actual entries in the jar file. 2018-02-23 00:59:13 -08:00
Cedric Beust
df89933cc8 1.0.111. 2018-02-21 16:50:30 -08:00
Cedric Beust
f95075c1ae Update KobaltClient to the correct WebSocket library. 2018-02-21 16:47:32 -08:00
Cedric Beust
49bc2b3a15 1.0.110. 2018-02-13 16:07:44 -08:00
Cedric Beust
03e94157c7 Revert. 2018-02-13 16:07:40 -08:00
Cedric Beust
700a8fbca8 1.0.108. 2018-02-13 13:58:25 -08:00
Cedric Beust
7df320b4c7 Reverting to Kotlin 1.2.10.
Until https://youtrack.jetbrains.com/issue/KT-22542 is fixed.

Fixes https://github.com/cbeust/kobalt/issues/472
2018-02-13 13:58:13 -08:00
Cedric Beust
82fa2081fc Unused. 2018-02-13 13:57:05 -08:00
Cedric Beust
ae82395fdf Bump bndlib. 2018-02-13 12:53:57 -08:00
Cedric Beust
4af7e2d36a 1.0.107. 2018-02-13 12:53:50 -08:00
Cedric Beust
645901d988 Fix build directory for the application plug-in.
Fixes https://github.com/cbeust/kobalt/issues/473
2018-02-13 12:53:32 -08:00
Cedric Beust
3d23f38239 1.0.105. 2018-02-05 09:17:24 -08:00
Cedric Beust
c2174fe1e7 Warnings. 2018-02-05 09:16:47 -08:00
Cedric Beust
11a1f427a0 1.0.106. 2018-02-04 04:42:56 -08:00
Cedric Beust
4281a1cad8 Fix empty new line in manifest. 2018-02-04 04:39:02 -08:00
Cedric Beust
d7a95d0c0c Warnings 2018-02-03 11:40:07 -08:00
Cedric Beust
7d27cd144d Exclude MANIFESTS from other jar files. 2018-02-03 11:17:44 -08:00
Cedric Beust
c1364c82a0 1.4.0. 2018-02-03 10:33:33 -08:00
Cedric Beust
52f5ceb3d6 Add MANIFEST.MF at the top of the jar file 2018-02-03 10:28:45 -08:00
Cedric Beust
7a2c4f34da Merge branch 'master' of github.com:cbeust/kobalt 2018-01-26 23:59:54 -08:00
Cedric Beust
32bf92e8c8
Merge pull request #470 from ethauvin/master
No longer create directories, etc. when --help or --version are used.
2018-01-26 23:59:16 -08:00
Cedric Beust
d2d0c7603d 1.0.103. 2018-01-26 23:23:34 -08:00
Cedric Beust
7d3549ec27 Kotlin 1.2.21. 2018-01-26 23:23:24 -08:00
Cedric Beust
026b0e209f Reverting back to Kotlin 1.2.10. 2018-01-26 23:15:16 -08:00
Cedric Beust
cce09756af 1.0.101. 2018-01-26 16:43:18 -08:00
Cedric Beust
323bfae756 Fix the Osgi plug-in. 2018-01-26 16:41:15 -08:00
22d983d559 Added --version argument to app. 2018-01-20 17:04:56 -08:00
41ba68c630 No longer create directories, etc. when --help or --version are used. 2018-01-20 16:15:31 -08:00
Cedric Beust
18c6f38948 Kotlin 1.2.20. 2018-01-17 13:52:26 -08:00
Cedric Beust
964fa3bc0f 1.0.100. 2018-01-08 15:17:13 -08:00
Cedric Beust
576cd56f88 No longer used. 2018-01-08 15:16:57 -08:00
Cedric Beust
2806f5e11b Revert to 1.0.94 while investigating issues with Kotlin 1.2.10. 2018-01-04 15:01:20 -08:00
Cedric Beust
cfbf0143f4 1.0.100. 2018-01-04 14:29:37 -08:00
Cedric Beust
126e7fb500 Bump Kotlin to 1.2.10. 2018-01-04 14:19:41 -08:00
Cedric Beust
0d0dcbbc54 1.0.94. 2018-01-02 16:43:38 -08:00
Cedric Beust
96d11d3dbf 1.0.93. 2017-12-09 09:07:05 -08:00
Cedric Beust
ae59e1d7ff Merge branch 'master' of github.com:cbeust/kobalt 2017-12-09 09:00:09 -08:00
Cedric Beust
84ee57a979 Sign artifacts. 2017-12-09 08:59:51 -08:00
Cedric Beust
fdee66ab93 For 'run', don't use the error stream as an error indicator. 2017-12-09 08:59:23 -08:00
Cedric Beust
6d7490a34d 1.0.92. 2017-11-20 13:42:48 -08:00
Cedric Beust
3d2e5b069d BuildConfig not being generated. (#464). 2017-11-20 13:41:36 -08:00
Cedric Beust
294799ee5d 1.0.91. 2017-11-08 10:50:34 -08:00
Cedric Beust
6ede80e9ce
Merge pull request #463 from ethauvin/master
Added ignore parameters to the application plugin.
2017-11-08 09:16:10 -08:00
20a01f8de0 Added ignoreInputStream, ignoreErrorStream and ignoreExitvalue to the application plugin. 2017-11-08 01:05:16 -08:00
Cedric Beust
72740079ce
Merge pull request #461 from ethauvin/master
Fixed finding tools.jar under Windows when JAVA_HOME is set to JRE.
2017-11-07 09:47:18 -08:00
Cedric Beust
e39be51cb8
Merge pull request #462 from McPringle/master
Code Review Changes
2017-11-06 11:38:57 -08:00
Marcus Fihlon
f4f3827fd1
💬 Adding trimming of line in format string
Before:
    ***** WARNING Old profile syntax detected for "                val debug = false", please update to "val debug by profile()"

    After:
    ***** WARNING Old profile syntax detected for "val debug = false", please update to "val debug by profile()
2017-11-06 19:54:54 +01:00
Marcus Fihlon
70f01fa691
Merge branch 'master' of github.com:cbeust/kobalt 2017-11-06 19:51:32 +01:00
Marcus Fihlon
2e2444c2bc
👌 Code review change
Thanks to @ethauvin for his very good hint!
2017-11-06 19:49:28 +01:00
be40f5c81d Fixed finding tools.jar under Windows when JAVA_HOME is set to JRE. 2017-11-05 17:11:11 -08:00
Cedric Beust
05f8e2f41a
Merge pull request #458 from McPringle/master
Fixing the WAR filename could contain a `null` version #456
2017-11-05 07:02:08 -08:00
Marcus Fihlon
5aef25a4a7
🐛 Fixing the WAR filename contains if version information is missing #456 2017-11-05 03:08:12 -06:00
Cedric Beust
e7ae50fe81
Merge pull request #454 from ethauvin/master
Java 9 initial compatibility
2017-11-04 13:36:08 -07:00
702a34dd4b Made executable in git index. 2017-11-04 12:14:30 -07:00
bd8ba4c497 Added kobatw-test wrapper to build the kobalt project using the jar in kobaltBuild/libs for testing. 2017-11-03 19:03:21 -07:00
a115111168 Added missing jaxb dependency for plugin API. 2017-11-03 19:01:38 -07:00
a431f4850b Syntax fix. 2017-11-03 13:15:15 -07:00
a1aa6d8eea Resolving merge conflict. 2017-11-02 17:47:40 -07:00
49db5a798e Fixed coroutinesSate syntax. 2017-11-02 17:40:14 -07:00
82b89edaee
Merge pull request #455 from pabl0rg/upgrade-to-kotlinc-1-1-51
upgrade to kotlinc 1.1.51
2017-11-02 17:26:42 -07:00
Juan Liska
f6de041fd8 bump kotlin compiler version string const 2017-11-02 17:35:49 -06:00
Juan Liska
629949edd4 upgrade to kotlinc 1.1.51 2017-11-02 17:26:29 -06:00
e8dcfc6d4b More syntax fix. 2017-11-01 10:13:39 -07:00
05d0ff04fb Fixed various syntax. 2017-10-31 23:17:42 -07:00
c99a9eb6cd First try at running under Java 9. 2017-10-31 21:44:57 -07:00
Cedric Beust
86e39cbb58 1.0.90. 2017-09-16 18:25:57 -07:00
Cedric Beust
f92ac752c1 1.0.89/ 2017-07-25 10:40:08 -07:00
Cedric Beust
084f4b5385 Silly oversight, 2017-07-25 10:39:53 -07:00
Cedric Beust
b109674f1a Merge branch 'master' of github.com:cbeust/kobalt 2017-07-25 10:31:29 -07:00
Cedric Beust
f782fa2236 1.0.88. 2017-07-25 10:23:52 -07:00
Cedric Beust
4405cf154c OsgiPlugin bug. 2017-07-25 10:23:17 -07:00
Cedric Beust
aac60fa0a3 Merge pull request #452 from MrTact/kotlin-template-deps
Fixes #451 -- add stdlib and runtime deps to the Kotlin project template
2017-07-19 20:21:01 -07:00
Tim Keating
be29f2c0b3 PR feedback: use version constant instead of hard-coded strings 2017-07-19 22:05:45 -05:00
Tim Keating
9e6b3d26db Fixes #451 -- add stdlib and runtime deps to the Kotlin project template 2017-07-18 00:26:01 -05:00
Cedric Beust
76bd010168 1.0.87. 2017-05-31 09:07:52 -07:00
Cedric Beust
c1c2057de4 Merge pull request #445 from albinekcom/patch-1
Update README
2017-05-21 06:32:07 -07:00
Albin "albinek" Sadowski
11cd3226e9 Update README 2017-05-21 09:51:03 +02:00
Cedric Beust
4efe8125d7 Merge pull request #444 from ethauvin/master
Added push parameter to autoGitTag
2017-05-10 12:44:17 -07:00
b944039fdc Added push parameter to autoGitTag. 2017-05-10 11:46:41 -07:00
Cedric Beust
a38b05fc92 Merge pull request #443 from ethauvin/master
Fixed repo name to use config param if available
2017-05-10 11:10:57 -07:00
bcb9cc4e87 Fixed repo name to use config param if available. 2017-05-10 11:08:15 -07:00
Cedric Beust
a1b952ca69 1.0.86. 2017-05-10 09:58:54 -07:00
Cedric Beust
a47b570d16 Fix the bogus default value for getProperty(). 2017-05-10 09:58:54 -07:00
Cedric Beust
75fbfb9613 Refactoring. 2017-05-09 13:12:22 -07:00
Cedric Beust
61af72e26d 1.0.85. 2017-05-09 10:56:06 -07:00
Cedric Beust
1d7f04bf47 Build fix. 2017-05-09 10:56:00 -07:00
Cedric Beust
d1039ce9af 1.0.84. 2017-05-08 15:47:59 -07:00
Cedric Beust
a95f8d91c1 Merge pull request #442 from ethauvin/master
Added support for configuring gpg's via local.properties
2017-05-08 15:47:50 -07:00
3b56122f92 Added support for configuring gpg's passphrase, key id and secret key ring location via local.properties. 2017-05-05 15:46:13 -07:00
Cedric Beust
91bb1b955c Warnings. 2017-05-05 12:47:29 -07:00
Cedric Beust
2227783905 Merge pull request #441 from ethauvin/master
Fixed vcs_tag
2017-05-05 11:20:00 -07:00
f43c186da1 Cleanup. 2017-05-05 10:33:21 -07:00
706f27de40 Added Bintray's package name and issue tracker URL. 2017-05-05 08:45:21 -07:00
62e1d55b53 Fixed vcs_tag.
Grab project description and url from pom, if not already specified.
2017-05-04 16:22:22 -07:00
Cedric Beust
686d98cdc9 Rename. 2017-05-04 09:39:52 -07:00
Cedric Beust
b74c4d65b2 Fix warnings. 2017-05-04 09:36:38 -07:00
Cedric Beust
4ff98d6d37 Merge pull request #440 from ethauvin/master
Removed sources directory from apt generated directory path
2017-05-04 09:32:17 -07:00
e468d1cb4d Removed sources directory from apt generated directory path. 2017-05-04 00:12:16 -07:00
Cedric Beust
2439da3545 Merge pull request #439 from ethauvin/master
Made doc run after clean
2017-05-03 20:43:31 -07:00
c69a41db66 Made doc run after clean. 2017-05-03 20:13:58 -07:00
407d2bb436 Cleanup. 2017-05-03 20:13:13 -07:00
Cedric Beust
74d6670882 1.0.83. 2017-05-03 11:32:55 -07:00
Cedric Beust
d095840121 Fix fixSlashes().
Fixes https://github.com/cbeust/kobalt/pull/438
2017-05-03 11:32:41 -07:00
Cedric Beust
8ea67e70cd Merge pull request #438 from ethauvin/master
Implemented javadoc options
2017-05-03 11:00:44 -07:00
e4650dd953 Implemented javadoc options. 2017-05-03 09:46:02 -07:00
Cedric Beust
2e7de257aa Better javadoc default args. 2017-05-02 14:17:39 -07:00
Cedric Beust
8fa360949b Simplify. 2017-05-02 14:07:44 -07:00
Cedric Beust
083d707345 1.0.82. 2017-05-02 11:24:38 -07:00
Cedric Beust
13f544d67c Add javadoc { args() }. 2017-05-02 11:24:21 -07:00
Cedric Beust
c0ed9a5a03 Not used. 2017-05-02 11:19:38 -07:00
Cedric Beust
dcfa18ceb8 1.0.81 2017-05-01 11:11:20 -07:00
Cedric Beust
bc4bee8461 OSGi improvements. 2017-05-01 11:11:11 -07:00
Cedric Beust
4385a81308 1.0.80. 2017-04-28 10:18:11 -07:00
Cedric Beust
60a7c88377 Restructure. 2017-04-28 10:18:11 -07:00
Cedric Beust
f674ed65d6 Don’t include stubs in the jar file.
Fixes https://github.com/cbeust/kobalt/issues/437
2017-04-28 10:18:11 -07:00
Cedric Beust
fff392d573 Log. 2017-04-28 10:18:11 -07:00
Cedric Beust
14aab6bee1 Merge pull request #436 from ethauvin/master
Fixed config.taskName
2017-04-27 19:28:40 -07:00
d0d5e75243 Fixed config.taskName. 2017-04-27 19:13:20 -07:00
Cedric Beust
5629806df2 Refactor. 2017-04-27 16:29:05 -07:00
Cedric Beust
7ea182b42e 1.0.79. 2017-04-27 16:22:33 -07:00
Cedric Beust
bfe4140143 Fix the run dependency. 2017-04-27 16:21:44 -07:00
Cedric Beust
0e6bc67c4b Fix manifest path. 2017-04-27 16:21:35 -07:00
Cedric Beust
67da9b8dc6 Better toString(). 2017-04-27 16:21:25 -07:00
Cedric Beust
96eabbe99b 1.0.78. 2017-04-27 13:32:32 -07:00
Cedric Beust
6cab82e280 Refactor. 2017-04-27 13:32:21 -07:00
Cedric Beust
9b08f57917 Fix the case where no MANIFEST exists. 2017-04-27 13:31:19 -07:00
Cedric Beust
742fff6105 Not used. 2017-04-27 11:34:24 -07:00
Cedric Beust
5829ae49bb Fix the duplicate MANIFEST.MF bug. 2017-04-27 11:34:19 -07:00
Cedric Beust
18653c4da1 Better log message. 2017-04-27 10:57:51 -07:00
Cedric Beust
b937aa6ad8 Created the generated source directory.
Fixes https://github.com/cbeust/kobalt/issues/433
2017-04-27 10:57:44 -07:00
Cedric Beust
3ebc40d58f Update Guava. 2017-04-26 14:20:22 -07:00
Cedric Beust
161e5db53c OsgiPlugin. 2017-04-26 14:19:55 -07:00
Cedric Beust
a367621ee4 1.0.77. 2017-04-25 10:59:51 -07:00
Cedric Beust
c3c3b0863a Kotlin 1.1.2. 2017-04-25 10:59:40 -07:00
Cedric Beust
5e12e028bd Be consistent with using taskContributor everywhere. 2017-04-25 10:40:16 -07:00
Cedric Beust
ba6ab5592e Allow multiple install{} tags.
Fixes https://github.com/cbeust/kobalt/issues/430.
2017-04-25 10:24:10 -07:00
Cedric Beust
5b1c9150a5 Better error message. 2017-04-24 16:04:20 -07:00
Cedric Beust
4a5a6442ec 1.0.76. 2017-04-24 15:03:11 -07:00
Cedric Beust
93f5c541f4 Support for multiple application{} directives.
Fixes https://github.com/cbeust/kobalt/issues/430.
2017-04-24 14:58:54 -07:00
Cedric Beust
65f423ffea 1.0.75. 2017-04-24 11:39:43 -07:00
Cedric Beust
523b9c055a Not used. 2017-04-24 11:37:52 -07:00
Cedric Beust
ae6d1d51e1 Refactor. 2017-04-24 11:35:09 -07:00
Cedric Beust
cccff9e7b0 Refactor. 2017-04-24 11:34:54 -07:00
Cedric Beust
bb2e09f680 Kill the Kobalt server after 10 minutes of inactivity. 2017-04-24 09:56:53 -07:00
Cedric Beust
fd80166186 Warn if tools.jar can’t be found. 2017-04-24 09:53:37 -07:00
Cedric Beust
7e86b5ae86 Delete server file on exit. 2017-04-24 09:49:12 -07:00
Cedric Beust
ec7d24a6f8 Make sure JAVA_HOME points to the JDK and not the JRE.
Should fix https://github.com/cbeust/kobalt/issues/428.
2017-04-24 09:48:23 -07:00
Cedric Beust
0f658cf010 1.0.74. 2017-04-22 21:34:15 -07:00
Cedric Beust
0f80fe6d68 Merge branch 'master' of github.com:cbeust/kobalt 2017-04-22 21:28:44 -07:00
Cedric Beust
9ec708ebf3 Bug with kapt when no Java files are present. 2017-04-22 21:28:31 -07:00
Cedric Beust
2a545b6638 Merge branch 'master' of github.com:cbeust/kobalt 2017-04-22 13:25:20 -07:00
Cedric Beust
6a08d3caa8 Fix slashes in the zip file. 2017-04-22 13:23:24 -07:00
Cedric Beust
cc481a4a7f GH-423: Overwrite files on Windows too.
Fixes https://github.com/cbeust/kobalt/issues/423
2017-04-21 23:02:59 -07:00
Cedric Beust
c768507ed5 Reformat. 2017-04-21 22:18:56 -07:00
Cedric Beust
2abeef347e Merge pull request #425 from ethauvin/newest
Made warn() work like error() with provided message
2017-04-21 22:16:17 -07:00
Cedric Beust
35769f099f Merge branch 'master' of github.com:cbeust/kobalt 2017-04-21 21:28:58 -07:00
Cedric Beust
3a41868824 1.0.73. 2017-04-21 21:25:52 -07:00
Cedric Beust
a10777ee1d Fix the duplicate compiler args bug. 2017-04-21 21:25:35 -07:00
d157be9a18 Made warn() work like error() with provided message. 2017-04-21 20:04:27 -07:00
Cedric Beust
49e69d0964 Merge branch 'master' of github.com:cbeust/kobalt 2017-04-21 12:17:34 -07:00
Cedric Beust
1342428eb0 Reformat. 2017-04-20 11:17:28 -07:00
Cedric Beust
e1c1da55c6 Fix duplication of parameters. 2017-04-20 11:17:23 -07:00
Cedric Beust
1d015a6f93 1.0.72. 2017-04-19 11:16:28 -07:00
Cedric Beust
43844cbf80 Fix class path look up in kapt3. 2017-04-19 11:16:05 -07:00
Cedric Beust
5bcb8185b8 Refactor. 2017-04-19 11:14:34 -07:00
Cedric Beust
abc9002292 1.0.71. 2017-04-19 08:29:01 -07:00
Cedric Beust
35fe4f6494 Add tools.jar on the annotation plug-in classpath. 2017-04-19 08:20:02 -07:00
Cedric Beust
1febd47368 Better JAVA_HOME detection. 2017-04-19 08:19:46 -07:00
Cedric Beust
3686c4e110 1.0.70. 2017-04-18 20:02:08 -07:00
Cedric Beust
5d03544e31 GH-417: Don’t run abstract test classes with JUnit 4.
Fixes https://github.com/cbeust/kobalt/issues/417
2017-04-18 20:01:43 -07:00
Cedric Beust
104e71335e Read the apt() dependency correctly. 2017-04-18 08:36:17 -07:00
Cedric Beust
37709b571c Inject the Jvm object. 2017-04-18 08:16:13 -07:00
Cedric Beust
dc1ebfb15d Don’t display tasks if the build file can’t be compiled. 2017-04-17 18:54:37 -07:00
Cedric Beust
fd58ed58e4 1.0.69. 2017-04-17 17:47:24 -07:00
Cedric Beust
da332b1716 Don’t use variants for apt. 2017-04-17 17:46:56 -07:00
Cedric Beust
007e616e7f 1.0.68. 2017-04-17 16:43:06 -07:00
Cedric Beust
49bdec673e Merge branch 'master' of github.com:cbeust/kobalt 2017-04-14 15:40:21 -07:00
Cedric Beust
fad6af29ee Merge branch 'master' of github.com:cbeust/kobalt 2017-04-12 17:00:07 -07:00
Cedric Beust
90df943ec3 Merge branch 'master' of github.com:cbeust/kobalt 2017-04-12 16:50:46 -07:00
Cedric Beust
197d576440 Merge branch 'master' of github.com:cbeust/kobalt 2017-04-08 11:12:06 -07:00
Cedric Beust
c9e61e49a9 Any nonexistent version will cause Kobalt to use local build directories.
Relaxes the restriction for that version to be +1.
2017-04-08 11:08:17 -07:00
86 changed files with 2796 additions and 496 deletions

2
.gitignore vendored
View file

@ -11,3 +11,5 @@ libs
out out
.DS_Store .DS_Store
lib/kotlin-* lib/kotlin-*
build
.history

View file

@ -1,6 +1,6 @@
# Kobalt # Kobalt
[<img src="https://teamcity.jetbrains.com/app/rest/builds/buildType:(id:OpenSourceProjects_Kobalt_Build)/statusIcon">](https://teamcity.jetbrains.com/project.html?projectId=OpenSourceProjects_Kobalt&tab=projectOverview) [<img src="https://teamcity.jetbrains.com/app/rest/builds/buildType:(id:OpenSourceProjects_Kobalt_Build)/statusIcon.svg">](https://teamcity.jetbrains.com/project.html?projectId=OpenSourceProjects_Kobalt&tab=projectOverview)
Kobalt is a universal build system. Kobalt is a universal build system.
@ -8,7 +8,7 @@ Kobalt is a universal build system.
To build it: To build it:
``` ```
./kobaltw assemble $ ./kobaltw assemble
``` ```
Please see [the web site](http://beust.com/kobalt/) for the full documentation. Please see [the web site](http://beust.com/kobalt/) for the full documentation.

58
build.gradle Normal file
View file

@ -0,0 +1,58 @@
allprojects {
group = 'com.beust'
version = '1.1.0'
}
subprojects {
apply plugin: 'java'
apply plugin: 'maven-publish'
ext {
bndlib = '3.5.0'
findbugs = '3.0.2'
groovy = '2.4.12'
gson = '2.8.2'
guice = '4.2.2'
inject = '1'
jaxb = '2.3.0'
jcommander = '1.72'
kotlin = '1.2.71'
maven = '3.5.2'
mavenResolver = '1.1.0'
okhttp = '3.9.1'
okio = '1.13.0'
retrofit = '2.3.0'
slf4j = '1.7.3'
spark = '2.6.0'
testng = '6.12'
junit = '4.12'
junitJupiter = '5.1.0'
junitPlatform = '1.1.0'
}
repositories {
mavenCentral()
mavenLocal()
jcenter()
maven {
url = 'https://dl.bintray.com/cbeust/maven'
}
maven {
url = 'https://repo.maven.apache.org/maven2'
}
}
sourceCompatibility = '1.7'
task sourcesJar(type: Jar) {
from sourceSets.main.allJava
archiveClassifier = 'sources'
}
task javadocJar(type: Jar) {
from javadoc
archiveClassifier = 'javadoc'
}
}

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View file

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

188
gradlew vendored Executable file
View file

@ -0,0 +1,188 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

100
gradlew.bat vendored Normal file
View file

@ -0,0 +1,100 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View file

@ -21,26 +21,27 @@ import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream import java.util.zip.ZipOutputStream
val bs = buildScript { val bs = buildScript {
repos("http://dl.bintray.com/cbeust/maven") repos("https://dl.bintray.com/cbeust/maven")
} }
object Versions { object Versions {
val okhttp = "3.2.0" val kotlin = "1.2.71"
val okio = "1.6.0" val okhttp = "3.9.1"
val retrofit = "2.1.0" val okio = "1.13.0"
val gson = "2.6.2" val retrofit = "2.3.0"
val maven = "3.3.9" val gson = "2.8.2"
val mavenResolver = "1.0.3" val guice = "4.2.2"
val maven = "3.5.2"
val mavenResolver = "1.1.0"
val slf4j = "1.7.3" val slf4j = "1.7.3"
val kotlin = "1.1.1"
val aether = "1.0.2.v20150114" val aether = "1.0.2.v20150114"
val testng = "6.11" val testng = "6.12"
val jcommander = "1.72"
// JUnit 5 // JUnit 5
val junit = "4.12" val junit = "4.12"
val junitPlatform = "1.0.0-M4" val junitPlatform = "1.1.0"
val junitJupiter = "5.0.0-M4" val junitJupiter = "5.1.0"
val junitVintageVersion = "$junit.0-M4"
} }
fun mavenResolver(vararg m: String) fun mavenResolver(vararg m: String)
@ -78,6 +79,7 @@ val wrapper = project {
bintray { bintray {
publish = true publish = true
sign = true
} }
pom = createPom(name, "Wrapper for Kobalt") pom = createPom(name, "Wrapper for Kobalt")
@ -90,41 +92,42 @@ val kobaltPluginApi = project {
version = readVersion() version = readVersion()
directory = "modules/kobalt-plugin-api" directory = "modules/kobalt-plugin-api"
description = "A build system in Kotlin" description = "A build system in Kotlin"
url = "http://beust.com/kobalt" url = "https://beust.com/kobalt"
pom = createPom(name, "A build system in Kotlin") pom = createPom(name, "A build system in Kotlin")
dependencies { dependencies {
compile( compile(
"org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlin}", "org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlin}",
"com.google.inject:guice:4.0", "com.google.inject:guice:${Versions.guice}",
"com.google.inject.extensions:guice-assistedinject:4.0", "com.google.inject.extensions:guice-assistedinject:4.1.0",
"javax.inject:javax.inject:1", "javax.inject:javax.inject:1",
"com.google.guava:guava:19.0", "com.google.guava:guava:27.0.1-jre",
"org.apache.maven:maven-model:${Versions.maven}", "org.apache.maven:maven-model:${Versions.maven}",
"io.reactivex:rxjava:1.1.5", "io.reactivex:rxjava:1.3.3",
"com.squareup.okio:okio:${Versions.okio}", "com.squareup.okio:okio:${Versions.okio}",
"com.google.code.gson:gson:${Versions.gson}", "com.google.code.gson:gson:${Versions.gson}",
"com.squareup.okhttp3:okhttp:${Versions.okhttp}", "com.squareup.okhttp3:okhttp:${Versions.okhttp}",
"com.squareup.retrofit2:retrofit:${Versions.retrofit}", "com.squareup.retrofit2:retrofit:${Versions.retrofit}",
"com.squareup.retrofit2:converter-gson:${Versions.retrofit}", "com.squareup.retrofit2:converter-gson:${Versions.retrofit}",
"com.beust:jcommander:1.48", "com.beust:jcommander:${Versions.jcommander}",
"org.eclipse.jgit:org.eclipse.jgit:4.5.0.201609210915-r", "org.eclipse.jgit:org.eclipse.jgit:4.9.0.201710071750-r",
"org.slf4j:slf4j-simple:${Versions.slf4j}", "org.slf4j:slf4j-simple:${Versions.slf4j}",
*mavenResolver("api", "spi", "util", "impl", "connector-basic", "transport-http", "transport-file"), *mavenResolver("api", "spi", "util", "impl", "connector-basic", "transport-http", "transport-file"),
"org.apache.maven:maven-aether-provider:3.3.9", "org.apache.maven:maven-aether-provider:3.3.9",
"org.testng.testng-remote:testng-remote:1.3.2", "org.testng.testng-remote:testng-remote:1.3.2",
"org.testng:testng:${Versions.testng}", "org.testng:testng:${Versions.testng}",
"commons-io:commons-io:2.5",
"org.junit.platform:junit-platform-surefire-provider:${Versions.junitPlatform}", "org.junit.platform:junit-platform-surefire-provider:${Versions.junitPlatform}",
"org.junit.platform:junit-platform-runner:${Versions.junitPlatform}", "org.junit.platform:junit-platform-runner:${Versions.junitPlatform}",
"org.junit.platform:junit-platform-engine:${Versions.junitPlatform}", "org.junit.platform:junit-platform-engine:${Versions.junitPlatform}",
"org.junit.platform:junit-platform-console:${Versions.junitPlatform}", "org.junit.platform:junit-platform-console:${Versions.junitPlatform}",
"org.junit.jupiter:junit-jupiter-engine:${Versions.junitJupiter}", "org.junit.jupiter:junit-jupiter-engine:${Versions.junitJupiter}",
"org.junit.vintage:junit-vintage-engine:${Versions.junitVintageVersion}", "org.junit.vintage:junit-vintage-engine:${Versions.junitJupiter}",
"org.apache.commons:commons-compress:1.15",
"commons-io:commons-io:2.6",
"org.apache.commons:commons-compress:1.13", // Java 9
"commons-io:commons-io:2.5" "javax.xml.bind:jaxb-api:2.3.0"
) )
exclude(*aether("impl", "spi", "util", "api")) exclude(*aether("impl", "spi", "util", "api"))
} }
@ -161,24 +164,30 @@ val kobaltApp = project(kobaltPluginApi, wrapper) {
// Used by the main app // Used by the main app
compile( compile(
"org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlin}", "org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlin}",
"com.github.spullara.mustache.java:compiler:0.9.1", "com.github.spullara.mustache.java:compiler:0.9.5",
"javax.inject:javax.inject:1", "javax.inject:javax.inject:1",
"com.google.inject:guice:4.0", "com.google.inject:guice:${Versions.guice}",
"com.google.inject.extensions:guice-assistedinject:4.0", "com.google.inject.extensions:guice-assistedinject:${Versions.guice}",
"com.beust:jcommander:1.65", "com.beust:jcommander:${Versions.jcommander}",
"org.apache.maven:maven-model:${Versions.maven}", "org.apache.maven:maven-model:${Versions.maven}",
"com.google.code.findbugs:jsr305:3.0.1", "com.google.code.findbugs:jsr305:3.0.2",
"com.google.code.gson:gson:${Versions.gson}", "com.google.code.gson:gson:${Versions.gson}",
"com.squareup.retrofit2:retrofit:${Versions.retrofit}", "com.squareup.retrofit2:retrofit:${Versions.retrofit}",
"com.squareup.retrofit2:converter-gson:${Versions.retrofit}", "com.squareup.retrofit2:converter-gson:${Versions.retrofit}",
"com.squareup.okhttp3:okhttp-ws:${Versions.okhttp}", // "com.squareup.okhttp3:okhttp-ws:3.4.2",
"biz.aQute.bnd:bndlib:2.4.0", "biz.aQute.bnd:biz.aQute.bndlib:3.5.0",
*mavenResolver("spi"), *mavenResolver("spi"),
"com.squareup.okhttp3:logging-interceptor:3.2.0", "com.squareup.okhttp3:logging-interceptor:3.9.0",
"com.sparkjava:spark-core:2.5", "com.sparkjava:spark-core:2.6.0",
"org.codehaus.groovy:groovy:2.4.8" "org.codehaus.groovy:groovy:2.4.12",
// Java 9
"javax.xml.bind:jaxb-api:2.3.0",
"com.sun.xml.bind:jaxb-impl:2.3.0",
"com.sun.xml.bind:jaxb-core:2.3.0",
"com.sun.activation:javax.activation:1.2.0"
// "org.eclipse.jetty:jetty-server:${Versions.jetty}", // "org.eclipse.jetty:jetty-server:${Versions.jetty}",
// "org.eclipse.jetty:jetty-servlet:${Versions.jetty}", // "org.eclipse.jetty:jetty-servlet:${Versions.jetty}",
@ -194,7 +203,7 @@ val kobaltApp = project(kobaltPluginApi, wrapper) {
dependenciesTest { dependenciesTest {
compile("org.jetbrains.kotlin:kotlin-test:${Versions.kotlin}", compile("org.jetbrains.kotlin:kotlin-test:${Versions.kotlin}",
"org.testng:testng:${Versions.testng}", "org.testng:testng:${Versions.testng}",
"org.assertj:assertj-core:3.4.1", "org.assertj:assertj-core:3.8.0",
*mavenResolver("util") *mavenResolver("util")
) )
} }
@ -300,13 +309,13 @@ fun taskCopyVersionForWrapper(project: Project) : TaskResult {
fun createPom(projectName: String, projectDescription: String) = Model().apply { fun createPom(projectName: String, projectDescription: String) = Model().apply {
name = projectName name = projectName
description = projectDescription description = projectDescription
url = "http://beust.com/kobalt" url = "https://beust.com/kobalt"
licenses = listOf(License().apply { licenses = listOf(License().apply {
name = "Apache-2.0" name = "Apache-2.0"
url = "http://www.apache.org/licenses/LICENSE-2.0" url = "https://www.apache.org/licenses/LICENSE-2.0"
}) })
scm = Scm().apply { scm = Scm().apply {
url = "http://github.com/cbeust/kobalt" url = "https://github.com/cbeust/kobalt"
connection = "https://github.com/cbeust/kobalt.git" connection = "https://github.com/cbeust/kobalt.git"
developerConnection = "git@github.com:cbeust/kobalt.git" developerConnection = "git@github.com:cbeust/kobalt.git"
} }

View file

@ -1 +1 @@
kobalt.version=1.0.67 kobalt.version=1.0.122

8
kobaltw-test Executable file
View file

@ -0,0 +1,8 @@
#!/usr/bin/env sh
JAR=$(ls -1 -t kobaltBuild/libs/*.jar | grep -Ev "(sources|javadoc)" | head -1)
TEMPDIR=$(mktemp -d)
cp -pf "$JAR" "$TEMPDIR"
TEMPJAR=$TEMPDIR/$(basename "$JAR")
export KOBALT_JAR=$TEMPJAR
java -jar "$TEMPJAR" "$@"
rm -rf "$TEMPDIR"

View file

@ -0,0 +1,85 @@
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.2.71'
id 'com.github.johnrengelman.shadow' version '5.0.0'
}
dependencies {
implementation "biz.aQute.bnd:biz.aQute.bndlib:$bndlib"
implementation "com.google.code.findbugs:jsr305:$findbugs"
implementation "com.sparkjava:spark-core:$spark"
implementation "com.squareup.okhttp3:logging-interceptor:$okhttp"
implementation 'commons-io:commons-io:2.6'
implementation 'io.reactivex:rxjava:1.3.3'
implementation "javax.inject:javax.inject:$inject"
implementation "javax.xml.bind:jaxb-api:$jaxb"
implementation 'org.apache.commons:commons-compress:1.15'
implementation 'org.apache.maven:maven-aether-provider:3.3.9'
implementation "org.apache.maven.resolver:maven-resolver-api:$mavenResolver"
implementation "org.apache.maven.resolver:maven-resolver-connector-basic:$mavenResolver"
implementation "org.apache.maven.resolver:maven-resolver-impl:$mavenResolver"
implementation "org.apache.maven.resolver:maven-resolver-spi:$mavenResolver"
implementation "org.apache.maven.resolver:maven-resolver-transport-file:$mavenResolver"
implementation "org.apache.maven.resolver:maven-resolver-transport-http:$mavenResolver"
implementation "org.apache.maven.resolver:maven-resolver-util:$mavenResolver"
implementation "org.codehaus.groovy:groovy:$groovy"
implementation 'org.eclipse.jgit:org.eclipse.jgit:4.9.0.201710071750-r'
implementation "org.junit.jupiter:junit-jupiter-engine:$junitJupiter"
implementation "org.junit.platform:junit-platform-console:$junitPlatform"
implementation "org.junit.platform:junit-platform-engine:$junitPlatform"
implementation "org.junit.platform:junit-platform-runner:$junitPlatform"
implementation "org.junit.platform:junit-platform-surefire-provider:$junitPlatform"
implementation "org.junit.vintage:junit-vintage-engine:$junitJupiter"
implementation "org.slf4j:slf4j-simple:$slf4j"
implementation "org.testng:testng:$testng"
implementation 'org.testng.testng-remote:testng-remote:1.3.2'
implementation "com.beust:jcommander:$jcommander"
implementation "com.google.code.gson:gson:$gson"
implementation "com.google.inject:guice:$guice"
implementation "com.google.inject.extensions:guice-assistedinject:$guice"
implementation "com.squareup.okio:okio:$okio"
implementation "com.squareup.retrofit2:converter-gson:$retrofit"
implementation "com.squareup.retrofit2:retrofit:$retrofit"
implementation "org.apache.maven:maven-model:$maven"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin"
}
shadowJar {
classifier = null
}
test {
useTestNG()
}
publishing {
publications {
shadow(MavenPublication) { publication ->
project.shadow.component(publication)
artifact sourcesJar
artifact javadocJar
pom {
name = project.name
description = 'A build system in Kotlin'
url = 'https://beust.com/kobalt'
licenses {
license {
name = 'Apache-2.0'
url = 'https://www.apache.org/licenses/LICENSE-2.0'
}
}
developers {
developer {
name = 'Cedric Beust'
email = 'cedric@beust.com'
}
}
scm {
connection = 'scm:https://github.com/cbeust/kobalt.git'
developerConnection = 'scm:git@github.com:cbeust/kobalt.git'
url = 'https://github.com/cbeust/kobalt'
}
}
}
}
}

View file

@ -0,0 +1,279 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.beust</groupId>
<artifactId>kobalt-pom</artifactId>
<version>1.1.0</version>
<relativePath>../..</relativePath>
</parent>
<artifactId>kobalt-plugin-api</artifactId>
<packaging>jar</packaging>
<version>1.1.0</version>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-aether-provider</artifactId>
<version>3.3.9</version>
<exclusions>
<exclusion>
<groupId>org.eclipse.aether</groupId>
<artifactId>impl</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.aether</groupId>
<artifactId>spi</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.aether</groupId>
<artifactId>util</artifactId>
</exclusion>
<exclusion>
<groupId>org.eclipse.aether</groupId>
<artifactId>api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-api</artifactId>
<version>${mavenresolver.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-spi</artifactId>
<version>${mavenresolver.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-util</artifactId>
<version>${mavenresolver.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-impl</artifactId>
<version>${mavenresolver.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-connector-basic</artifactId>
<version>${mavenresolver.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-transport-http</artifactId>
<version>${mavenresolver.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-transport-file</artifactId>
<version>${mavenresolver.version}</version>
</dependency>
<dependency>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>com.squareup.okio</groupId>
<artifactId>okio</artifactId>
<version>${okio.version}</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.2.2</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-assistedinject</artifactId>
<version>4.2.2</version>
</dependency>
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
<version>1.72</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-gson</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>biz.aQute.bnd</groupId>
<artifactId>biz.aQute.bndlib</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>${okhttp3.version}</version>
</dependency>
<dependency>
<groupId>com.sparkjava</groupId>
<artifactId>spark-core</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>2.4.12</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-compress</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-surefire-provider</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-engine</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-console</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junitJupiter.version}</version>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>${junitJupiter.version}</version>
</dependency>
<dependency>
<groupId>org.testng.testng-remote</groupId>
<artifactId>testng-remote</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>4.9.0.201710071750-r</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- java 9 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<goals> <goal>compile</goal> </goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<goals> <goal>test-compile</goal> </goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<executions>
<!-- Replacing default-compile as it is treated specially by maven -->
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<!-- Replacing default-testCompile as it is treated specially by maven -->
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals> <goal>compile</goal> </goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals> <goal>testCompile</goal> </goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View file

@ -61,6 +61,9 @@ class Args {
@Parameter(names = arrayOf("--noIncremental"), description = "Turn off incremental builds") @Parameter(names = arrayOf("--noIncremental"), description = "Turn off incremental builds")
var noIncremental: Boolean = false var noIncremental: Boolean = false
@Parameter(names = arrayOf("--offline"), description = "Don't try to download dependencies even if there is no cached version")
var offline: Boolean = false
@Parameter(names = arrayOf("--plugins"), description = "Comma-separated list of plug-in Maven id's") @Parameter(names = arrayOf("--plugins"), description = "Comma-separated list of plug-in Maven id's")
var pluginIds: String? = null var pluginIds: String? = null
@ -101,5 +104,8 @@ class Args {
@Parameter(names = arrayOf("--update"), description = "Update to the latest version of Kobalt") @Parameter(names = arrayOf("--update"), description = "Update to the latest version of Kobalt")
var update: Boolean = false var update: Boolean = false
@Parameter(names = arrayOf("--version"), description = "Display the current version of Kobalt")
var version: Boolean = false
} }

View file

@ -9,13 +9,13 @@ object Constants {
val BUILD_FILE_NAME = "Build.kt" val BUILD_FILE_NAME = "Build.kt"
val BUILD_FILE_DIRECTORY = "kobalt/src" val BUILD_FILE_DIRECTORY = "kobalt/src"
val BUILD_FILE_PATH = KFiles.joinDir(BUILD_FILE_DIRECTORY, BUILD_FILE_NAME) val BUILD_FILE_PATH = KFiles.joinDir(BUILD_FILE_DIRECTORY, BUILD_FILE_NAME)
val KOTLIN_COMPILER_VERSION = "1.1.1" val KOTLIN_COMPILER_VERSION = "1.2.70"
internal val DEFAULT_REPOS = listOf<HostConfig>( internal val DEFAULT_REPOS = listOf<HostConfig>(
// "https://maven-central.storage.googleapis.com/", // "https://maven-central.storage.googleapis.com/",
HostConfig("http://repo1.maven.org/maven2/", "Maven"), HostConfig("https://repo1.maven.org/maven2/", "Maven"),
HostConfig("https://jcenter.bintray.com/", "JCenter") HostConfig("https://jcenter.bintray.com/", "JCenter")
// "http://repository.jetbrains.com/all/", // <-- contains snapshots // "https://repository.jetbrains.com/all/", // <-- contains snapshots
// snapshots // snapshots
// "https://oss.sonatype.org/content/repositories/snapshots/" // "https://oss.sonatype.org/content/repositories/snapshots/"

View file

@ -3,6 +3,7 @@ package com.beust.kobalt
import com.beust.kobalt.api.KobaltContext import com.beust.kobalt.api.KobaltContext
import com.beust.kobalt.api.Project import com.beust.kobalt.api.Project
import com.beust.kobalt.archive.Archives import com.beust.kobalt.archive.Archives
import com.beust.kobalt.archive.MetaArchive
import com.beust.kobalt.archive.Zip import com.beust.kobalt.archive.Zip
import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.maven.aether.Scope import com.beust.kobalt.maven.aether.Scope
@ -141,7 +142,7 @@ class JarGenerator @Inject constructor(val dependencyManager: DependencyManager)
val allFiles = includedFiles.flatMap { file -> val allFiles = includedFiles.flatMap { file ->
file.allFromFiles(project.directory).map { file.from(it.path) } file.allFromFiles(project.directory).map { file.from(it.path) }
} }
val manifestFiles = allFiles.filter { it.path.contains("META-INF/MANIFEST.MF") } val manifestFiles = allFiles.filter { it.path.contains(MetaArchive.MANIFEST_MF) }
return if (manifestFiles.any()) manifestFiles[0] else null return if (manifestFiles.any()) manifestFiles[0] else null
} }
@ -150,7 +151,7 @@ class JarGenerator @Inject constructor(val dependencyManager: DependencyManager)
context.logger.log(project.name, 2, "Including MANIFEST.MF file $manifestFile") context.logger.log(project.name, 2, "Including MANIFEST.MF file $manifestFile")
Manifest(FileInputStream(manifestFile)) Manifest(FileInputStream(manifestFile))
} else { } else {
Manifest() null
} }
} }

View file

@ -67,7 +67,7 @@ open class Jvm constructor(
return toolsJar return toolsJar
} }
if (javaHome!!.name.equals("jre", true)) { if (javaHome!!.name.equals("jre", true)) {
javaHome = javaHome!!.parentFile _javaHome = javaHome!!.parentFile
toolsJar = File(javaHome, "lib/tools.jar") toolsJar = File(javaHome, "lib/tools.jar")
if (toolsJar.exists()) { if (toolsJar.exists()) {
return toolsJar return toolsJar
@ -78,7 +78,7 @@ open class Jvm constructor(
val version = SystemProperties.Companion.javaVersion val version = SystemProperties.Companion.javaVersion
if (javaHome!!.name.toRegex().matches("jre\\d+") if (javaHome!!.name.toRegex().matches("jre\\d+")
|| javaHome!!.name == "jre$version") { || javaHome!!.name == "jre$version") {
javaHome = File(javaHome!!.parentFile, "jdk$version") _javaHome = File(javaHome!!.parentFile, "jdk$version")
toolsJar = File(javaHome, "lib/tools.jar") toolsJar = File(javaHome, "lib/tools.jar")
if (toolsJar.exists()) { if (toolsJar.exists()) {
return toolsJar return toolsJar

View file

@ -2,8 +2,16 @@ package com.beust.kobalt
class SystemProperties { class SystemProperties {
companion object { companion object {
val javaBase = System.getProperty("java.home") ?: val javaBase : String
(System.getenv("JAVA_HOME") ?: throw IllegalArgumentException("JAVA_HOME not defined")) get() {
val jh = System.getenv("JAVA_HOME")
?: System.getProperty("java.home")
?: throw IllegalArgumentException("JAVA_HOME not defined")
val result =
if (jh.toLowerCase().endsWith("jre")) jh.substring(0, jh.length - 4)
else jh
return result
}
val javaVersion = System.getProperty("java.version") val javaVersion = System.getProperty("java.version")
val homeDir = System.getProperty("user.home") val homeDir = System.getProperty("user.home")
val tmpDir = System.getProperty("java.io.tmpdir") val tmpDir = System.getProperty("java.io.tmpdir")

View file

@ -126,61 +126,62 @@ class Variant(val initialProductFlavor: ProductFlavorConfig? = null,
var generatedSourceDirectory: File? = null var generatedSourceDirectory: File? = null
// private fun findBuildTypeBuildConfig(project: Project, variant: Variant?) : BuildConfig? { private fun findBuildTypeBuildConfig(project: Project, variant: Variant?) : BuildConfig? {
// val buildTypeName = variant?.buildType?.name val buildTypeName = variant?.buildType?.name
// return project.buildTypes[buildTypeName]?.buildConfig return project.buildTypes[buildTypeName]?.buildConfig
// } }
//
// private fun findProductFlavorBuildConfig(project: Project, variant: Variant?) : BuildConfig? { private fun findProductFlavorBuildConfig(project: Project, variant: Variant?) : BuildConfig? {
// val buildTypeName = variant?.productFlavor?.name val buildTypeName = variant?.productFlavor?.name
// return project.productFlavors[buildTypeName]?.buildConfig return project.productFlavors[buildTypeName]?.buildConfig
// } }
/** /**
* Return a list of the BuildConfigs found on the productFlavor{}, buildType{} and project{} (in that order). * Return a list of the BuildConfigs found on the productFlavor{}, buildType{} and project{} (in that order).
*/ */
// private fun findBuildConfigs(project: Project, variant: Variant?) : List<BuildConfig> { private fun findBuildConfigs(project: Project, variant: Variant?) : List<BuildConfig> {
// val result = listOf( val result = listOf(
// findBuildTypeBuildConfig(project, variant), findBuildTypeBuildConfig(project, variant),
// findProductFlavorBuildConfig(project, variant), findProductFlavorBuildConfig(project, variant),
// project.buildConfig) project.buildConfig)
// .filterNotNull() .filterNotNull()
//
// return result return result
// } }
/** /**
* Generate BuildConfig.java if requested. Also look up if any BuildConfig is defined on the current build type, * Generate BuildConfig.java if requested. Also look up if any BuildConfig is defined on the current build type,
* product flavor or main project, and use them to generateAndSave any additional field (in that order to * product flavor or main project, and use them to generateAndSave any additional field (in that order to
* respect the priorities). Return the generated file if it was generated, null otherwise. * respect the priorities). Return the generated file if it was generated, null otherwise.
*/ */
// fun maybeGenerateBuildConfig(project: Project, context: KobaltContext) : File? { fun maybeGenerateBuildConfig(project: Project, context: KobaltContext) : File? {
// val buildConfigs = findBuildConfigs(project, this) val buildConfigs = findBuildConfigs(project, this)
//
// if (buildConfigs.size > 0) { if (buildConfigs.size > 0) {
// val pkg = project.packageName ?: project.group val pkg = project.packageName ?: project.group
// ?: throw KobaltException( ?: throw KobaltException(
// "packageName needs to be defined on the project in order to generateAndSave BuildConfig") "packageName needs to be defined on the project in order to generateAndSave BuildConfig")
//
// val contributor = ActorUtils.selectAffinityActor(context.pluginInfo.buildConfigContributors, project) val contributor = ActorUtils.selectAffinityActor(project, context,
// if (contributor != null) { context.pluginInfo.buildConfigContributors)
// val code = contributor.generateBuildConfig(project, context, pkg, this, buildConfigs) if (contributor != null) {
// val result = KFiles.makeDir(KFiles.generatedSourceDir(project, this, "buildConfig")) val code = contributor.generateBuildConfig(project, context, pkg, this, buildConfigs)
// // Make sure the generatedSourceDirectory doesn't contain the project.directory since val result = KFiles.makeDir(KFiles.generatedSourceDir(project, this, "buildConfig"))
// // that directory will be added when trying to find recursively all the sources in it // Make sure the generatedSourceDirectory doesn't contain the project.directory since
// generatedSourceDirectory = result.relativeTo(File(project.directory)) // that directory will be added when trying to find recursively all the sources in it
// val outputGeneratedSourceDirectory = File(result, pkg.replace('.', File.separatorChar)) generatedSourceDirectory = result.relativeTo(File(project.directory))
// val outputDir = File(outputGeneratedSourceDirectory, "BuildConfig." + contributor.buildConfigSuffix) val outputGeneratedSourceDirectory = File(result, pkg.replace('.', File.separatorChar))
// KFiles.saveFile(outputDir, code) val outputDir = File(outputGeneratedSourceDirectory, "BuildConfig." + contributor.buildConfigSuffix)
// context.logger.log(project.name, 2, "Generated ${outputDir.path}") KFiles.saveFile(outputDir, code)
// return result context.logger.log(project.name, 2, "Generated ${outputDir.path}")
// } else { return result
// throw KobaltException("Couldn't find a contributor to generateAndSave BuildConfig") } else {
// } throw KobaltException("Couldn't find a contributor to generateAndSave BuildConfig")
// } else { }
// return null } else {
// } return null
// } }
}
override fun toString() = toTask("") override fun toString() = toTask("")

View file

@ -12,4 +12,5 @@ data class CompilerActionInfo(val directory: String?,
val outputDir: File, val outputDir: File,
val compilerArgs: List<String>, val compilerArgs: List<String>,
val friendPaths: List<String>, val friendPaths: List<String>,
val forceRecompile: Boolean) val forceRecompile: Boolean,
val compilerSeparateProcess: Boolean = false)

View file

@ -5,7 +5,7 @@ import com.beust.kobalt.Variant
/** /**
* Plug-ins that can generate a BuildConfig file. * Plug-ins that can generate a BuildConfig file.
*/ */
interface IBuildConfigContributor : ISimpleAffinity<Project> { interface IBuildConfigContributor : IProjectAffinity {
fun generateBuildConfig(project: Project, context: KobaltContext, packageName: String, variant: Variant, fun generateBuildConfig(project: Project, context: KobaltContext, packageName: String, variant: Variant,
buildConfigs: List<BuildConfig>) : String buildConfigs: List<BuildConfig>) : String

View file

@ -1,10 +1,11 @@
package com.beust.kobalt.api package com.beust.kobalt.api
import com.beust.kobalt.TaskResult import com.beust.kobalt.TaskResult
import com.beust.kobalt.api.IClasspathDependency
/** /**
* Plugins that can run a project (task "run" or "test") should implement this interface. * Plugins that can run a project (task "run" or "test") should implement this interface.
*
* Currently not used.
*/ */
interface IRunnerContributor : IContributor, IProjectAffinity { interface IRunnerContributor : IContributor, IProjectAffinity {
/** /**

View file

@ -26,6 +26,7 @@ class DynamicTask(override val plugin: IPlugin, override val name: String, overr
return TaskResult2(taskResult.success, errorMessage = taskResult.errorMessage, value = this) return TaskResult2(taskResult.success, errorMessage = taskResult.errorMessage, value = this)
} }
override fun toString() = "[DynamicTask $name dependsOn=$dependsOn reverseDependsOn=$reverseDependsOn]" override fun toString() =
"[DynamicTask ${project.name}:$name dependsOn=$dependsOn reverseDependsOn=$reverseDependsOn]"
} }

View file

@ -44,6 +44,25 @@ class TaskContributor @Inject constructor(val incrementalManagerFactory: Increme
} }
} }
fun addTask(plugin: IPlugin, project: Project, taskName: String, description: String,
group: String = AnnotationDefault.GROUP,
dependsOn: List<String> = emptyList(),
reverseDependsOn : List<String> = emptyList(),
runBefore : List<String> = emptyList(),
runAfter : List<String> = emptyList(),
alwaysRunAfter: List<String> = emptyList(),
runTask: (Project) -> TaskResult) {
dynamicTasks.add(DynamicTask(plugin, taskName, description, group, project,
dependsOn = dependsOn,
reverseDependsOn = reverseDependsOn,
runBefore = runBefore,
runAfter = runAfter,
alwaysRunAfter = alwaysRunAfter,
closure = { p: Project ->
runTask(project)
}))
}
fun addIncrementalVariantTasks(plugin: IPlugin, project: Project, context: KobaltContext, taskName: String, fun addIncrementalVariantTasks(plugin: IPlugin, project: Project, context: KobaltContext, taskName: String,
group: String = AnnotationDefault.GROUP, group: String = AnnotationDefault.GROUP,
dependsOn: List<String> = emptyList(), dependsOn: List<String> = emptyList(),

View file

@ -17,7 +17,8 @@ class Archives {
@ExportedProjectProperty(doc = "The name of the a jar file with a main() method", type = "String") @ExportedProjectProperty(doc = "The name of the a jar file with a main() method", type = "String")
const val JAR_NAME_WITH_MAIN_CLASS = "jarNameWithMainClass" const val JAR_NAME_WITH_MAIN_CLASS = "jarNameWithMainClass"
fun defaultArchiveName(project: Project) = project.name + "-" + project.version fun defaultArchiveName(project: Project) = project.name +
if (project.version.isNullOrBlank()) "" else "-${project.version}"
fun generateArchive(project: Project, fun generateArchive(project: Project,
context: KobaltContext, context: KobaltContext,

View file

@ -9,7 +9,6 @@ import java.io.Closeable
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import java.nio.file.Files
import java.util.jar.Manifest import java.util.jar.Manifest
import org.apache.commons.compress.archivers.zip.ZipFile as ApacheZipFile import org.apache.commons.compress.archivers.zip.ZipFile as ApacheZipFile
@ -18,15 +17,40 @@ import org.apache.commons.compress.archivers.zip.ZipFile as ApacheZipFile
* Uses ZipArchiveOutputStream for fast inclusion of expanded jar files. * Uses ZipArchiveOutputStream for fast inclusion of expanded jar files.
*/ */
class MetaArchive(outputFile: File, val manifest: Manifest?) : Closeable { class MetaArchive(outputFile: File, val manifest: Manifest?) : Closeable {
private val zos = ZipArchiveOutputStream(outputFile).apply { companion object {
const val MANIFEST_MF = "META-INF/MANIFEST.MF"
}
private val zos= ZipArchiveOutputStream(outputFile).apply {
encoding = "UTF-8" encoding = "UTF-8"
} }
init {
// If no manifest was passed, create an empty one so it's the first one in the archive
val m = manifest ?: Manifest()
val manifestFile = File.createTempFile("kobalt", "tmpManifest")
addEntry(ZipArchiveEntry("META-INF/"), null)
if (manifest != null) {
FileOutputStream(manifestFile).use { fos ->
m.write(fos)
}
}
val entry = zos.createArchiveEntry(manifestFile, MetaArchive.MANIFEST_MF)
addEntry(entry, FileInputStream(manifestFile))
}
fun addFile(f: File, entryFile: File, path: String?) { fun addFile(f: File, entryFile: File, path: String?) {
maybeCreateParentDirectories(f)
addFile2(f, entryFile, path)
}
private fun addFile2(f: File, entryFile: File, path: String?) {
val file = f.normalize() val file = f.normalize()
FileInputStream(file).use { inputStream -> FileInputStream(file).use { inputStream ->
val actualPath = if (path != null) path + entryFile.path else entryFile.path val actualPath = KFiles.fixSlashes(if (path != null) path + entryFile.path else entryFile.path)
ZipArchiveEntry(actualPath).let { entry -> ZipArchiveEntry(actualPath).let { entry ->
maybeCreateParentDirectories(File(actualPath))
maybeAddEntry(entry) { maybeAddEntry(entry) {
addEntry(entry, inputStream) addEntry(entry, inputStream)
} }
@ -34,6 +58,30 @@ class MetaArchive(outputFile: File, val manifest: Manifest?) : Closeable {
} }
} }
private val createdDirs = hashSetOf<String>()
/**
* For an entry a/b/c/File, an entry needs to be created for each individual directory:
* a/
* a/b/
* a/b/c
* a/b/c/File
*/
private fun maybeCreateParentDirectories(file: File) {
val toCreate = arrayListOf<String>()
var current = file.parentFile
while (current != null && current.path != ".") {
if (!createdDirs.contains(current.path)) {
toCreate.add(0, KFiles.fixSlashes(current) + "/")
createdDirs.add(current.path)
}
current = current.parentFile
}
toCreate.forEach { dir ->
addEntry(ZipArchiveEntry(dir), null)
}
}
fun addArchive(jarFile: File) { fun addArchive(jarFile: File) {
ApacheZipFile(jarFile).use { jar -> ApacheZipFile(jarFile).use { jar ->
val jarEntries = jar.entries val jarEntries = jar.entries
@ -45,40 +93,33 @@ class MetaArchive(outputFile: File, val manifest: Manifest?) : Closeable {
} }
} }
private val DEFAULT_JAR_EXCLUDES =
Glob("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA")
private val seen = hashSetOf<String>()
private fun okToAdd(name: String): Boolean = ! seen.contains(name) private fun okToAdd(name: String) : Boolean {
&& ! KFiles.isExcluded(name, DEFAULT_JAR_EXCLUDES) val result = !KFiles.isExcluded(name,
Glob("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA", MANIFEST_MF))
override fun close() { // if (name.startsWith("META-INF")) println((if (result) "ADDING" else "NOT ADDING") + " $name")
if (manifest != null) { return result
Files.createTempFile("aaa", "bbb").toFile().let { manifestFile ->
FileOutputStream(manifestFile).use { fos ->
manifest.write(fos)
}
val entry = zos.createArchiveEntry(manifestFile, "META-INF/MANIFEST.MF")
addEntry(entry, FileInputStream(manifestFile))
}
}
zos.close()
} }
private fun addEntry(entry: ArchiveEntry, inputStream: FileInputStream) { override fun close() = zos.close()
private fun addEntry(entry: ArchiveEntry, inputStream: FileInputStream?) {
zos.putArchiveEntry(entry) zos.putArchiveEntry(entry)
inputStream.use { ins -> inputStream?.use { ins ->
ins.copyTo(zos, 50 * 1024) ins.copyTo(zos, 50 * 1024)
} }
zos.closeArchiveEntry() zos.closeArchiveEntry()
} }
private val seen = hashSetOf<String>()
private fun maybeAddEntry(entry: ArchiveEntry, action:() -> Unit) { private fun maybeAddEntry(entry: ArchiveEntry, action:() -> Unit) {
if (okToAdd(entry.name)) { entry.name.let { name ->
action() if (!seen.contains(name) && okToAdd(name)) {
action()
}
seen.add(name)
} }
seen.add(entry.name)
} }
} }

View file

@ -2,7 +2,7 @@ package com.beust.kobalt.internal
class DocUrl { class DocUrl {
companion object { companion object {
private const val HOST = "http://beust.com/kobalt/" private const val HOST = "https://beust.com/kobalt/"
private fun url(path: String) = HOST + path private fun url(path: String) = HOST + path
val PUBLISH_PLUGIN_URL = url("plug-ins/index.html#publishing") val PUBLISH_PLUGIN_URL = url("plug-ins/index.html#publishing")

View file

@ -4,6 +4,7 @@ import com.beust.kobalt.*
import com.beust.kobalt.api.* import com.beust.kobalt.api.*
import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KFiles
import com.google.common.annotations.VisibleForTesting import com.google.common.annotations.VisibleForTesting
import com.google.inject.Inject
import java.io.File import java.io.File
import java.util.* import java.util.*
@ -19,6 +20,9 @@ abstract class GenericTestRunner: ITestRunnerContributor {
open var shortMessage: String? = null open var shortMessage: String? = null
open var longMessage: String? = null open var longMessage: String? = null
@Inject
private lateinit var jvm: Jvm
abstract fun args(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>, abstract fun args(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
testConfig: TestConfig) : List<String> testConfig: TestConfig) : List<String>
@ -26,7 +30,7 @@ abstract class GenericTestRunner: ITestRunnerContributor {
open val extraClasspath: List<String> = emptyList() open val extraClasspath: List<String> = emptyList()
open fun filterTestClasses(classes: List<String>) : List<String> = classes open fun filterTestClasses(project: Project, context: KobaltContext, classes: List<String>) : List<String> = classes
override fun run(project: Project, context: KobaltContext, configName: String, override fun run(project: Project, context: KobaltContext, configName: String,
classpath: List<IClasspathDependency>) : TaskResult { classpath: List<IClasspathDependency>) : TaskResult {
@ -65,7 +69,7 @@ abstract class GenericTestRunner: ITestRunnerContributor {
// } // }
context.logger.log(project.name, 2, "Found ${result.size} test classes") context.logger.log(project.name, 2, "Found ${result.size} test classes")
return filterTestClasses(result.map { it.second }) return filterTestClasses(project, context, result.map { it.second })
} }
/** /**
@ -108,15 +112,16 @@ abstract class GenericTestRunner: ITestRunnerContributor {
configName: String) : TestResult { configName: String) : TestResult {
var result = false var result = false
context.logger.log(project.name, 1, "Running tests with " + runnerName) context.logger.log(project.name, 1, "Running tests with $runnerName")
val testConfig = project.testConfigs.firstOrNull { it.name == configName } val testConfig = project.testConfigs.firstOrNull { it.name == configName }
var errorCode = -1
if (testConfig != null) { if (testConfig != null) {
val args = args(project, context, classpath, testConfig) val args = args(project, context, classpath, testConfig)
if (args.size > 0) { if (args.size > 0) {
val java = JavaInfo.create(File(SystemProperties.javaBase)).javaExecutable val java = jvm.javaExecutable
val jvmArgs = calculateAllJvmArgs(project, context, testConfig, classpath, val jvmArgs = calculateAllJvmArgs(project, context, testConfig, classpath,
Kobalt.INJECTOR.getInstance (PluginInfo::class.java)) Kobalt.INJECTOR.getInstance (PluginInfo::class.java))
val allArgs = arrayListOf<String>().apply { val allArgs = arrayListOf<String>().apply {
@ -132,12 +137,7 @@ abstract class GenericTestRunner: ITestRunnerContributor {
context.logger.log(project.name, 2, "Running tests with classpath size ${classpath.size}") context.logger.log(project.name, 2, "Running tests with classpath size ${classpath.size}")
context.logger.log(project.name, 2, "Launching " + allArgs.joinToString(" ")) context.logger.log(project.name, 2, "Launching " + allArgs.joinToString(" "))
val process = pb.start() val process = pb.start()
val errorCode = process.waitFor() errorCode = process.waitFor()
if (errorCode == 0) {
context.logger.log(project.name, 1, "All tests passed")
} else {
context.logger.log(project.name, 1, "Test failures")
}
result = result || errorCode == 0 result = result || errorCode == 0
} else { } else {
context.logger.log(project.name, 1, " No tests to run") context.logger.log(project.name, 1, " No tests to run")
@ -148,6 +148,13 @@ abstract class GenericTestRunner: ITestRunnerContributor {
} }
onFinish(project) onFinish(project)
if (errorCode == 0) {
context.logger.log(project.name, 1, "All tests passed")
} else {
context.logger.log(project.name, 1, longMessage!!)
}
return TestResult(result, shortMessage, longMessage) return TestResult(result, shortMessage, longMessage)
} }

View file

@ -35,7 +35,8 @@ class JUnit5Runner @Inject constructor(kFiles: KFiles) : GenericTestRunner() {
override fun affinity(project: Project, context: KobaltContext) : Int { override fun affinity(project: Project, context: KobaltContext) : Int {
val result = val result =
if (project.testDependencies.any { it.id.contains("jupiter") }) IAffinity.DEFAULT_POSITIVE_AFFINITY + 100 if (project.testDependencies.any { it.id.contains("junit5") || it.id.contains("jupiter") })
IAffinity.DEFAULT_POSITIVE_AFFINITY + 100
else 0 else 0
return result return result

View file

@ -4,6 +4,10 @@ import com.beust.kobalt.TestConfig
import com.beust.kobalt.api.IClasspathDependency import com.beust.kobalt.api.IClasspathDependency
import com.beust.kobalt.api.KobaltContext import com.beust.kobalt.api.KobaltContext
import com.beust.kobalt.api.Project import com.beust.kobalt.api.Project
import com.beust.kobalt.maven.DependencyManager
import com.google.inject.Inject
import java.lang.reflect.Modifier
import java.net.URLClassLoader
open class JUnitRunner() : GenericTestRunner() { open class JUnitRunner() : GenericTestRunner() {
@ -14,5 +18,15 @@ open class JUnitRunner() : GenericTestRunner() {
override fun args(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>, override fun args(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
testConfig: TestConfig) = findTestClasses(project, context, testConfig) testConfig: TestConfig) = findTestClasses(project, context, testConfig)
@Inject
lateinit var dependencyManager: DependencyManager
override fun filterTestClasses(project: Project, context: KobaltContext, classes: List<String>) : List<String> {
val deps = dependencyManager.testDependencies(project, context)
val cl = URLClassLoader(deps.map { it.jarFile.get().toURI().toURL() }.toTypedArray())
return classes.filter { !Modifier.isAbstract(cl.loadClass(it).modifiers) }
}
} }

View file

@ -28,7 +28,6 @@ class JvmCompiler @Inject constructor(val dependencyManager: DependencyManager)
.distinct() .distinct()
// Plugins that add flags to the compiler // Plugins that add flags to the compiler
val currentFlags = arrayListOf<String>().apply { addAll(info.compilerArgs) }
val contributorFlags : List<String> = if (project != null) flags else emptyList() val contributorFlags : List<String> = if (project != null) flags else emptyList()
val addedFlags = contributorFlags + ArrayList(info.compilerArgs) val addedFlags = contributorFlags + ArrayList(info.compilerArgs)

View file

@ -9,7 +9,6 @@ import com.beust.kobalt.api.annotation.ExportedProjectProperty
import com.beust.kobalt.api.annotation.IncrementalTask import com.beust.kobalt.api.annotation.IncrementalTask
import com.beust.kobalt.api.annotation.Task import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.maven.LocalRepo
import com.beust.kobalt.maven.Md5 import com.beust.kobalt.maven.Md5
import com.beust.kobalt.maven.aether.Scope import com.beust.kobalt.maven.aether.Scope
import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KFiles
@ -27,7 +26,6 @@ import javax.inject.Singleton
*/ */
@Singleton @Singleton
open class JvmCompilerPlugin @Inject constructor( open class JvmCompilerPlugin @Inject constructor(
open val localRepo: LocalRepo,
open val files: KFiles, open val files: KFiles,
open val dependencyManager: DependencyManager, open val dependencyManager: DependencyManager,
open val executors: KobaltExecutors, open val executors: KobaltExecutors,
@ -159,6 +157,10 @@ open class JvmCompilerPlugin @Inject constructor(
if (compilerContributors.isEmpty()) { if (compilerContributors.isEmpty()) {
throw KobaltException("Couldn't find any compiler for project ${project.name}") throw KobaltException("Couldn't find any compiler for project ${project.name}")
} else { } else {
// Generate BuildConfig if applicable
context.variant.maybeGenerateBuildConfig(project, context)
val allCompilers = compilerContributors.flatMap { it.compilersFor(project, context)}.sorted() val allCompilers = compilerContributors.flatMap { it.compilersFor(project, context)}.sorted()
/** /**
@ -172,7 +174,10 @@ open class JvmCompilerPlugin @Inject constructor(
if (wi.value.sourceSuffixes.contains("java")) ij = wi.index if (wi.value.sourceSuffixes.contains("java")) ij = wi.index
if (wi.value.sourceSuffixes.contains("kt")) ik = wi.index if (wi.value.sourceSuffixes.contains("kt")) ik = wi.index
} }
Collections.swap(result, ik, ij)
if (ik >= 0 && ij >= 0) {
Collections.swap(result, ik, ij)
}
return result return result
} }
@ -182,8 +187,8 @@ open class JvmCompilerPlugin @Inject constructor(
var done = false var done = false
// The directory where the classes get compiled // The directory where the classes get compiled
val buildDirectory = val buildDirectory =
if (isTest) File(project.buildDirectory, KFiles.TEST_CLASSES_DIR) if (isTest) File(KFiles.joinDir(project.buildDirectory, KFiles.TEST_CLASSES_DIR))
else File(project.classesDir(context)) else File(KFiles.joinDir(project.classesDir(context)))
allCompilersSorted.doWhile({ ! done }) { compiler -> allCompilersSorted.doWhile({ ! done }) { compiler ->
val compilerResults = compilerUtils.invokeCompiler(project, context, compiler, val compilerResults = compilerUtils.invokeCompiler(project, context, compiler,
@ -221,7 +226,7 @@ open class JvmCompilerPlugin @Inject constructor(
} }
@Task(name = "doc", description = "Generate the documentation for the project", group = GROUP_DOCUMENTATION, @Task(name = "doc", description = "Generate the documentation for the project", group = GROUP_DOCUMENTATION,
runBefore = arrayOf("assemble")) runBefore = arrayOf("assemble"), runAfter = arrayOf("clean"))
fun taskJavadoc(project: Project): TaskResult { fun taskJavadoc(project: Project): TaskResult {
val docGenerator = ActorUtils.selectAffinityActor(project, context, context.pluginInfo.docContributors) val docGenerator = ActorUtils.selectAffinityActor(project, context, context.pluginInfo.docContributors)
if (docGenerator != null) { if (docGenerator != null) {

View file

@ -78,7 +78,7 @@ class PluginInfo(val xml: KobaltPluginXml, val pluginClassLoader: ClassLoader?,
val compilerInterceptors = arrayListOf<ICompilerInterceptor>() val compilerInterceptors = arrayListOf<ICompilerInterceptor>()
val sourceDirectoriesInterceptors = arrayListOf<ISourceDirectoryInterceptor>() val sourceDirectoriesInterceptors = arrayListOf<ISourceDirectoryInterceptor>()
val buildDirectoryInterceptors = arrayListOf<IBuildDirectoryInterceptor>() val buildDirectoryInterceptors = arrayListOf<IBuildDirectoryInterceptor>()
val runnerContributors = arrayListOf<IRunnerContributor>() // val runnerContributors = arrayListOf<IRunnerContributor>()
val testRunnerContributors = arrayListOf<ITestRunnerContributor>() val testRunnerContributors = arrayListOf<ITestRunnerContributor>()
val classpathInterceptors = arrayListOf<IClasspathInterceptor>() val classpathInterceptors = arrayListOf<IClasspathInterceptor>()
val compilerContributors = arrayListOf<ICompilerContributor>() val compilerContributors = arrayListOf<ICompilerContributor>()
@ -197,7 +197,7 @@ class PluginInfo(val xml: KobaltPluginXml, val pluginClassLoader: ClassLoader?,
if (this is IPlugin) plugins.add(this) if (this is IPlugin) plugins.add(this)
if (this is IProjectContributor) projectContributors.add(this) if (this is IProjectContributor) projectContributors.add(this)
if (this is IRepoContributor) repoContributors.add(this) if (this is IRepoContributor) repoContributors.add(this)
if (this is IRunnerContributor) runnerContributors.add(this) // if (this is IRunnerContributor) runnerContributors.add(this)
if (this is ISourceDirectoryContributor) sourceDirContributors.add(this) if (this is ISourceDirectoryContributor) sourceDirContributors.add(this)
if (this is ISourceDirectoryInterceptor) sourceDirectoriesInterceptors.add(this) if (this is ISourceDirectoryInterceptor) sourceDirectoriesInterceptors.add(this)
if (this is ITaskContributor) taskContributors.add(this) if (this is ITaskContributor) taskContributors.add(this)
@ -225,7 +225,7 @@ class PluginInfo(val xml: KobaltPluginXml, val pluginClassLoader: ClassLoader?,
listOf(projectContributors, classpathContributors, templateContributors, listOf(projectContributors, classpathContributors, templateContributors,
repoContributors, compilerFlagContributors, compilerInterceptors, repoContributors, compilerFlagContributors, compilerInterceptors,
sourceDirectoriesInterceptors, buildDirectoryInterceptors, sourceDirectoriesInterceptors, buildDirectoryInterceptors,
runnerContributors, testRunnerContributors, classpathInterceptors, /* runnerContributors, */ testRunnerContributors, classpathInterceptors,
compilerContributors, docContributors, sourceDirContributors, compilerContributors, docContributors, sourceDirContributors,
testSourceDirContributors, buildConfigFieldContributors, testSourceDirContributors, buildConfigFieldContributors,
taskContributors, incrementalTaskContributors, assemblyContributors, taskContributors, incrementalTaskContributors, assemblyContributors,
@ -252,7 +252,7 @@ class PluginInfo(val xml: KobaltPluginXml, val pluginClassLoader: ClassLoader?,
compilerInterceptors.addAll(pluginInfo.compilerInterceptors) compilerInterceptors.addAll(pluginInfo.compilerInterceptors)
sourceDirectoriesInterceptors.addAll(pluginInfo.sourceDirectoriesInterceptors) sourceDirectoriesInterceptors.addAll(pluginInfo.sourceDirectoriesInterceptors)
buildDirectoryInterceptors.addAll(pluginInfo.buildDirectoryInterceptors) buildDirectoryInterceptors.addAll(pluginInfo.buildDirectoryInterceptors)
runnerContributors.addAll(pluginInfo.runnerContributors) // runnerContributors.addAll(pluginInfo.runnerContributors)
testRunnerContributors.addAll(pluginInfo.testRunnerContributors) testRunnerContributors.addAll(pluginInfo.testRunnerContributors)
classpathInterceptors.addAll(pluginInfo.classpathInterceptors) classpathInterceptors.addAll(pluginInfo.classpathInterceptors)
compilerContributors.addAll(pluginInfo.compilerContributors) compilerContributors.addAll(pluginInfo.compilerContributors)

View file

@ -16,6 +16,5 @@ class KotlinJarFiles @Inject constructor(val dependencyManager: DependencyManage
} }
val stdlib: File get() = getKotlinCompilerJar("stdlib") val stdlib: File get() = getKotlinCompilerJar("stdlib")
val runtime: File get() = getKotlinCompilerJar("runtime")
val compiler: File get() = getKotlinCompilerJar("compiler-embeddable") val compiler: File get() = getKotlinCompilerJar("compiler-embeddable")
} }

View file

@ -1,5 +1,8 @@
package com.beust.kobalt.internal package com.beust.kobalt.internal
import com.beust.kobalt.api.KobaltContext
import com.beust.kobalt.api.Project
/** /**
* KotlinTestRunner triggers if it finds a dependency on io.kotlintest but other than that, it just * KotlinTestRunner triggers if it finds a dependency on io.kotlintest but other than that, it just
* uses the regular JUnitRunner. * uses the regular JUnitRunner.
@ -12,6 +15,7 @@ class KotlinTestRunner : JUnitRunner() {
* KotlinTestRunner runs tests in the init{} initializer, so ignore all the extra * KotlinTestRunner runs tests in the init{} initializer, so ignore all the extra
* classes generated by the Kotlin compiler. * classes generated by the Kotlin compiler.
*/ */
override fun filterTestClasses(classes: List<String>) = classes.filter { ! it.contains("$") } override fun filterTestClasses(projet: Project, context: KobaltContext, classes: List<String>)
= classes.filter { !it.contains("$") }
} }

View file

@ -320,7 +320,9 @@ class TaskWorker(val tasks: List<ITask>, val dryRun: Boolean, val pluginInfo: Pl
val tr = if (dryRun) TaskResult() else it.call() val tr = if (dryRun) TaskResult() else it.call()
BaseProjectRunner.runBuildListenersForTask(it.project, context, name, start = false, success = tr.success) BaseProjectRunner.runBuildListenersForTask(it.project, context, name, start = false, success = tr.success)
success = success and tr.success success = success and tr.success
if (tr.errorMessage != null) errorMessages.add(tr.errorMessage) tr.errorMessage?.let {
errorMessages.add(it)
}
} }
return TaskResult2(success, errorMessage = errorMessages.joinToString("\n"), value = tasks[0]) return TaskResult2(success, errorMessage = errorMessages.joinToString("\n"), value = tasks[0])
} }

View file

@ -14,11 +14,14 @@ import org.testng.remote.strprotocol.MessageHelper
import org.testng.remote.strprotocol.MessageHub import org.testng.remote.strprotocol.MessageHub
import org.testng.remote.strprotocol.TestResultMessage import org.testng.remote.strprotocol.TestResultMessage
import org.w3c.dom.Attr import org.w3c.dom.Attr
import org.w3c.dom.NodeList
import org.xml.sax.InputSource import org.xml.sax.InputSource
import java.io.File import java.io.File
import java.io.FileReader import java.io.FileReader
import java.io.IOException import java.io.IOException
import javax.xml.parsers.DocumentBuilderFactory import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.xpath.XPathConstants
import javax.xml.xpath.XPathFactory
class TestNgRunner : GenericTestRunner() { class TestNgRunner : GenericTestRunner() {
@ -27,7 +30,10 @@ class TestNgRunner : GenericTestRunner() {
override val annotationPackage = "org.testng" override val annotationPackage = "org.testng"
override val runnerName = "TestNG" override val runnerName = "TestNG"
fun defaultOutput(project: Project) = KFiles.joinDir(project.buildDirectory, "test-output") private fun defaultOutputWithoutProjectDir(project: Project)
= KFiles.joinDir(project.buildDirectory, "test-output")
private fun defaultOutput(project: Project)
= KFiles.joinDir(project.directory, project.buildDirectory, "test-output")
override fun args(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>, override fun args(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>,
testConfig: TestConfig) = arrayListOf<String>().apply { testConfig: TestConfig) = arrayListOf<String>().apply {
@ -39,7 +45,9 @@ class TestNgRunner : GenericTestRunner() {
if (testConfig.testArgs.none { it == "-d" }) { if (testConfig.testArgs.none { it == "-d" }) {
add("-d") add("-d")
add(defaultOutput(project)) // Don't include the project directory here since the generic runner will cd to that directory before
// running the tests
add(defaultOutputWithoutProjectDir(project))
} }
if (testConfig.testArgs.size == 0) { if (testConfig.testArgs.size == 0) {
@ -77,6 +85,15 @@ class TestNgRunner : GenericTestRunner() {
var failed = 0 var failed = 0
var skipped = 0 var skipped = 0
var passed = 0 var passed = 0
val xp = XPathFactory.newInstance().newXPath()
val testMethods = xp.compile("/testng-results/suite/test/class/test-method[@status='FAIL']")
.evaluate(doc, XPathConstants.NODESET)
as NodeList
val failedMethods = arrayListOf<String>()
repeat(testMethods.length) {
val tm = testMethods.item(it)
failedMethods.add(tm.attributes.getNamedItem("signature").textContent)
}
repeat(root.attributes.length) { repeat(root.attributes.length) {
val attribute = root.attributes.item(it) val attribute = root.attributes.item(it)
if (attribute is Attr) when (attribute.name) { if (attribute is Attr) when (attribute.name) {
@ -90,6 +107,7 @@ class TestNgRunner : GenericTestRunner() {
shortMessage = "$passed tests" shortMessage = "$passed tests"
} else if (failed > 0) { } else if (failed > 0) {
shortMessage = "$failed failed" + (if (skipped > 0) ", $skipped skipped" else "") + " tests" shortMessage = "$failed failed" + (if (skipped > 0) ", $skipped skipped" else "") + " tests"
longMessage = "Failed tests:\n " + failedMethods.joinToString("\n ")
} }
} }
} }

View file

@ -1,16 +1,18 @@
package com.beust.kobalt.maven package com.beust.kobalt.maven
import com.beust.kobalt.OperatingSystem import com.beust.kobalt.OperatingSystem
import com.beust.kobalt.misc.LocalProperties
import com.beust.kobalt.misc.error import com.beust.kobalt.misc.error
import com.beust.kobalt.misc.kobaltLog import com.beust.kobalt.misc.kobaltLog
import com.beust.kobalt.misc.warn import com.beust.kobalt.misc.warn
import com.google.inject.Inject
import com.google.inject.Singleton import com.google.inject.Singleton
import java.io.BufferedReader import java.io.BufferedReader
import java.io.File import java.io.File
import java.io.InputStreamReader import java.io.InputStreamReader
@Singleton @Singleton
class Gpg { class Gpg @Inject constructor(val localProperties: LocalProperties) {
val COMMANDS = listOf("gpg", "gpg2") val COMMANDS = listOf("gpg", "gpg2")
fun findGpgCommand() : String? { fun findGpgCommand() : String? {
@ -42,6 +44,21 @@ class Gpg {
ascFile.delete() ascFile.delete()
val allArgs = arrayListOf<String>() val allArgs = arrayListOf<String>()
allArgs.add(gpg) allArgs.add(gpg)
fun maybeAdd(prop: String, f: (String) -> Unit) = localProperties.getNoThrows(prop)?.let {
f(it)
}
maybeAdd("gpg.password") {
allArgs.addAll(listOf("--passphrase", it, "--batch", "--yes"))
}
maybeAdd("gpg.keyId") {
allArgs.addAll(listOf("--local-user", it))
}
maybeAdd("gpg.secretKeyRingFile") {
allArgs.addAll(listOf("--secret-keyring", "\"$it\""))
}
allArgs.add("-ab") allArgs.add("-ab")
allArgs.add(file.absolutePath) allArgs.add(file.absolutePath)

View file

@ -2,6 +2,7 @@ package com.beust.kobalt.maven.aether
import com.beust.kobalt.internal.KobaltSettings import com.beust.kobalt.internal.KobaltSettings
import com.google.common.eventbus.EventBus import com.google.common.eventbus.EventBus
import com.beust.kobalt.Args
import org.eclipse.aether.DefaultRepositorySystemSession import org.eclipse.aether.DefaultRepositorySystemSession
import org.eclipse.aether.RepositorySystem import org.eclipse.aether.RepositorySystem
import org.eclipse.aether.repository.LocalRepository import org.eclipse.aether.repository.LocalRepository
@ -32,8 +33,9 @@ object Booter {
// } // }
fun newRepositorySystemSession(system: RepositorySystem, repo: File, settings: KobaltSettings, fun newRepositorySystemSession(system: RepositorySystem, repo: File, settings: KobaltSettings,
eventBus: EventBus): DefaultRepositorySystemSession { args: Args, eventBus: EventBus): DefaultRepositorySystemSession {
val session = MavenRepositorySystemUtils.newSession(settings) val session = MavenRepositorySystemUtils.newSession(settings)
session.isOffline = args.offline
val localRepo = LocalRepository(repo.absolutePath) val localRepo = LocalRepository(repo.absolutePath)
session.localRepositoryManager = system.newLocalRepositoryManager(session, localRepo) session.localRepositoryManager = system.newLocalRepositoryManager(session, localRepo)

View file

@ -52,7 +52,7 @@ class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings,
} }
fun error(s1: String, s2: String) { fun error(s1: String, s2: String) {
throw KobaltException("Found \"$s1\" but not \"$s2\" in local.properties for ${Kurl.KEY}.$host", throw KobaltException("Found \"$s1\" but not \"$s2\" in local.properties for ${Kurl.KEY}.$host",
docUrl = "http://beust.com/kobalt/documentation/index.html#maven-repos-authenticated") docUrl = "https://beust.com/kobalt/documentation/index.html#maven-repos-authenticated")
} }
if (! hostInfo.username.isNullOrBlank() && hostInfo.password.isNullOrBlank()) { if (! hostInfo.username.isNullOrBlank() && hostInfo.password.isNullOrBlank()) {
error("username", "password") error("username", "password")
@ -76,9 +76,13 @@ class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings,
val artifact = DefaultArtifact(mavenId) val artifact = DefaultArtifact(mavenId)
val request = VersionRangeRequest(artifact, createRepos(repos), null) val request = VersionRangeRequest(artifact, createRepos(repos), null)
val rr = system.resolveVersionRange(session, request) val rr = system.resolveVersionRange(session, request)
val newArtifact = DefaultArtifact(artifact.groupId, artifact.artifactId, artifact.classifier, if (rr.highestVersion != null) {
artifact.extension, rr.highestVersion.toString()) val newArtifact = DefaultArtifact(artifact.groupId, artifact.artifactId, artifact.classifier,
artifactToId(newArtifact) artifact.extension, rr.highestVersion.toString())
artifactToId(newArtifact)
} else {
throw KobaltException("Couldn't resolve $passedId")
}
} else { } else {
passedId passedId
} }
@ -137,7 +141,7 @@ class KobaltMavenResolver @Inject constructor(val settings: KobaltSettings,
fun create(id: String, optional: Boolean) = AetherDependency(DefaultArtifact(id), optional, args) fun create(id: String, optional: Boolean) = AetherDependency(DefaultArtifact(id), optional, args)
private val system = Booter.newRepositorySystem() private val system = Booter.newRepositorySystem()
private val session = Booter.newRepositorySystemSession(system, localRepo.localRepo, settings, eventBus) private val session = Booter.newRepositorySystemSession(system, localRepo.localRepo, settings, args, eventBus)
private fun createRepo(hostConfig: HostConfig) : RemoteRepository { private fun createRepo(hostConfig: HostConfig) : RemoteRepository {
val builder = RemoteRepository.Builder(hostConfig.name, "default", hostConfig.url) val builder = RemoteRepository.Builder(hostConfig.name, "default", hostConfig.url)

View file

@ -6,10 +6,11 @@ import com.google.inject.Inject
import java.io.File import java.io.File
class Git @Inject constructor() { class Git @Inject constructor() {
fun maybeTagRelease(project: Project, uploadResult: TaskResult, enabled: Boolean, annotated: Boolean, tag: String, message: String) : TaskResult { fun maybeTagRelease(project: Project, uploadResult: TaskResult, enabled: Boolean, annotated: Boolean,
push: Boolean, tag: String, message: String) : TaskResult {
val result = val result =
if (uploadResult.success && enabled) { if (uploadResult.success && enabled) {
val tagSuccess = tagRelease(project, annotated, tag, message) val tagSuccess = tagRelease(project, annotated, push, tag, message)
if (! tagSuccess) { if (! tagSuccess) {
TaskResult(false, errorMessage = "Couldn't tag the project") TaskResult(false, errorMessage = "Couldn't tag the project")
} else { } else {
@ -21,7 +22,7 @@ class Git @Inject constructor() {
return result return result
} }
private fun tagRelease(project: Project, annotated: Boolean, tag: String, message: String) : Boolean { private fun tagRelease(project: Project, annotated: Boolean, push: Boolean, tag: String, message: String) : Boolean {
val version = if (tag.isNullOrBlank()) project.version else tag val version = if (tag.isNullOrBlank()) project.version else tag
val success = try { val success = try {
log(2, "Tagging this release as \"$version\"") log(2, "Tagging this release as \"$version\"")
@ -37,7 +38,9 @@ class Git @Inject constructor() {
} else { } else {
git.tag().setName(version).setMessage(message).call() git.tag().setName(version).setMessage(message).call()
} }
git.push().setPushTags().call() if (push) {
git.push().setPushTags().call()
}
true true
} catch(ex: Exception) { } catch(ex: Exception) {
warn("Couldn't create tag ${version}: ${ex.message}", ex) warn("Couldn't create tag ${version}: ${ex.message}", ex)

View file

@ -86,12 +86,12 @@ class GithubApi2 @Inject constructor(
.execute() .execute()
val code = response.code() val code = response.code()
if (code != Http.CREATED) { if (code != Http.CREATED) {
val error = Gson().fromJson(response.errorBody().string(), RetrofitError::class.java) val error = Gson().fromJson(response.errorBody()?.string(), RetrofitError::class.java)
throw KobaltException("Couldn't upload release, ${error.message}: " + error.errors[0].code) throw KobaltException("Couldn't upload release, ${error.message}: " + error.errors[0].code)
} else { } else {
val body = response.body() val body = response.body()
uploadAsset(accessToken, body.uploadUrl!!, Http.TypedFile("application/zip", zipFile), tagName) uploadAsset(accessToken, body?.uploadUrl!!, Http.TypedFile("application/zip", zipFile), tagName)
.toBlocking() .toBlocking()
.forEach { action -> .forEach { action ->
kobaltLog(1, "\n${zipFile.name} successfully uploaded") kobaltLog(1, "\n${zipFile.name} successfully uploaded")
@ -120,8 +120,8 @@ class GithubApi2 @Inject constructor(
Duration.between(VersionCheckTimestampFile.timestamp, Instant.now())) { Duration.between(VersionCheckTimestampFile.timestamp, Instant.now())) {
kobaltLog(2, "Skipping GitHub latest release check, too soon.") kobaltLog(2, "Skipping GitHub latest release check, too soon.")
} else { } else {
val username = localProperties.getNoThrows(PROPERTY_USERNAME, DOC_URL) val username = localProperties.getNoThrows(PROPERTY_USERNAME)
val accessToken = localProperties.getNoThrows(PROPERTY_ACCESS_TOKEN, DOC_URL) val accessToken = localProperties.getNoThrows(PROPERTY_ACCESS_TOKEN)
try { try {
val req = val req =
if (username != null && accessToken != null) { if (username != null && accessToken != null) {
@ -138,8 +138,8 @@ class GithubApi2 @Inject constructor(
val releases = ex.body() val releases = ex.body()
if (releases != null) { if (releases != null) {
releases.firstOrNull()?.let { releases.firstOrNull()?.let {
try { result = try {
result = listOf(it.name, it.tagName).filterNotNull().first { !it.isBlank() } listOf(it.name, it.tagName).filterNotNull().first { !it.isBlank() }
} catch(ex: NoSuchElementException) { } catch(ex: NoSuchElementException) {
throw KobaltException("Couldn't find the latest release") throw KobaltException("Couldn't find the latest release")
} }

View file

@ -55,7 +55,6 @@ class JarUtils {
kobaltLog(2, " Writing contents of jar file $foundFile") kobaltLog(2, " Writing contents of jar file $foundFile")
metaArchive.addArchive(foundFile) metaArchive.addArchive(foundFile)
} else { } else {
val fp = foundFile.path
val toPath = File(file.to).normalize().path val toPath = File(file.to).normalize().path
val finalPath = if (toPath.isEmpty()) null else (toPath + "/") val finalPath = if (toPath.isEmpty()) null else (toPath + "/")
metaArchive.addFile(File(directory, fromFile.path), foundFile, finalPath) metaArchive.addFile(File(directory, fromFile.path), foundFile, finalPath)

View file

@ -10,7 +10,9 @@ import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.Paths import java.nio.file.Paths
import java.nio.file.StandardCopyOption import java.nio.file.StandardCopyOption
import java.util.*
import java.util.jar.JarInputStream import java.util.jar.JarInputStream
import java.util.regex.Pattern
class KFiles { class KFiles {
@ -20,6 +22,20 @@ class KFiles {
*/ */
val kobaltJar : List<String> val kobaltJar : List<String>
get() { get() {
val PATTERN = Pattern.compile("kobalt-([-.0-9]+)")
fun latestInstalledVersion() : StringVersion {
val versions = File(distributionsDir).listFiles().map { it.name }.map {
val matcher = PATTERN.matcher(it)
val result =
if (matcher.matches()) matcher.group(1)
else null
result
}.filterNotNull().map(::StringVersion)
Collections.sort(versions, reverseOrder())
return versions[0]
}
val envJar = System.getenv("KOBALT_JAR") val envJar = System.getenv("KOBALT_JAR")
if (envJar != null) { if (envJar != null) {
debug("Using kobalt jar $envJar") debug("Using kobalt jar $envJar")
@ -31,19 +47,21 @@ class KFiles {
if (jarFile.exists()) { if (jarFile.exists()) {
return listOf(jarFile.absolutePath) return listOf(jarFile.absolutePath)
} else { } else {
// In development mode, keep your kobalt.properties version one above kobalt-wrapper.properties: // In development mode, keep your kobalt.properties version to a nonexistent version
// kobalt.properties: kobalt.version=0.828 // kobalt.properties: kobalt.version=0.828
// kobalt-wrapper.properties: kobalt.version=0.827 // kobalt-wrapper.properties: kobalt.version=0.827
// When Kobalt can't find the newest jar file, it will instead use the classes produced by IDEA // When Kobalt can't find the newest jar file, it will instead use the classes produced by IDEA
// in the directories specified here: // in the directories specified here:
val leftSuffix = Kobalt.version.substring(0, Kobalt.version.lastIndexOf(".") + 1) val previousVersion = latestInstalledVersion().version
val previousVersion = leftSuffix +
(Kobalt.version.split(".").let { it[it.size - 1] }.toInt() - 1).toString()
val previousJar = joinDir(distributionsDir, "kobalt-" + previousVersion, val previousJar = joinDir(distributionsDir, "kobalt-" + previousVersion,
"kobalt/wrapper/kobalt-$previousVersion.jar") "kobalt/wrapper/kobalt-$previousVersion.jar")
latestInstalledVersion()
val result = listOf("", "modules/kobalt-plugin-api", "modules/wrapper").map { val result = listOf("", "modules/kobalt-plugin-api", "modules/wrapper").map {
File(homeDir(KFiles.joinDir("kotlin", "kobalt", it, "kobaltBuild", "classes"))) File(homeDir(KFiles.joinDir("kotlin", "kobalt", it, "kobaltBuild", "classes"))) //kobalt build dirs
.absolutePath .absolutePath
} + listOf("modules/kobalt", "modules/kobalt-plugin-api", "modules/wrapper").map {
File(homeDir(KFiles.joinDir("kotlin", "kobalt", it, "target", "classes"))) //maven build dirs
.absolutePath
} + listOf(previousJar) } + listOf(previousJar)
debug("Couldn't find ${jarFile.absolutePath}, using\n " + result.joinToString(" ")) debug("Couldn't find ${jarFile.absolutePath}, using\n " + result.joinToString(" "))
return result.filter { File(it).exists() } return result.filter { File(it).exists() }
@ -119,7 +137,7 @@ class KFiles {
fun joinFileAndMakeDir(vararg ts: String) = joinDir(joinAndMakeDir(ts.slice(0..ts.size - 2)), ts[ts.size - 1]) fun joinFileAndMakeDir(vararg ts: String) = joinDir(joinAndMakeDir(ts.slice(0..ts.size - 2)), ts[ts.size - 1])
fun fixSlashes(f: File) = f.normalize().path.replace('\\', '/') fun fixSlashes(f: File) = f.normalize().path.replace('\\', '/')
fun fixSlashes(s: String) = fixSlashes(File(s)) fun fixSlashes(s: String) = s.replace('\\', '/')
fun makeDir(dir: String, s: String? = null) = fun makeDir(dir: String, s: String? = null) =
(if (s != null) File(dir, s) else File(dir)).apply { mkdirs() } (if (s != null) File(dir, s) else File(dir)).apply { mkdirs() }
@ -227,22 +245,18 @@ class KFiles {
private fun isWindows() = System.getProperty("os.name").contains("Windows") private fun isWindows() = System.getProperty("os.name").contains("Windows")
fun copy(from: Path?, to: Path?, option: StandardCopyOption = StandardCopyOption.REPLACE_EXISTING) { fun copy(from: Path?, to: Path?, option: StandardCopyOption = StandardCopyOption.REPLACE_EXISTING) {
if (isWindows() && to!!.toFile().exists()) { try {
kobaltLog(2, "Windows detected, not overwriting $to") if (from != null && to != null) {
} else { if (!Files.exists(to) || Md5.toMd5(from.toFile()) != Md5.toMd5(to.toFile())) {
try { kobaltLog(3, "Copy from $from to $to")
if (from != null && to != null) { Files.copy(from, to, option)
if (!Files.exists(to) || Md5.toMd5(from.toFile()) != Md5.toMd5(to.toFile())) { } else {
kobaltLog(3, "Copy from $from to $to") kobaltLog(3, " Not copying, indentical files: $from $to")
Files.copy(from, to, option)
} else {
kobaltLog(3, " Not copying, indentical files: $from $to")
}
} }
} catch(ex: IOException) {
// Windows is anal about this
kobaltLog(1, "Couldn't copy $from to $to: ${ex.message}")
} }
} catch(ex: IOException) {
// Windows is anal about this
kobaltLog(1, "Couldn't copy $from to $to: ${ex.message}")
} }
} }

View file

@ -1,6 +1,9 @@
package com.beust.kobalt.misc package com.beust.kobalt.misc
import com.beust.kobalt.* import com.beust.kobalt.Args
import com.beust.kobalt.AsciiArt
import com.beust.kobalt.Constants
import com.beust.kobalt.KobaltException
import com.beust.kobalt.api.Kobalt import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.maven.aether.Exceptions import com.beust.kobalt.maven.aether.Exceptions
import java.lang.Exception import java.lang.Exception
@ -57,6 +60,14 @@ object KobaltLogger {
} else { } else {
Logger(false) Logger(false)
} }
fun setLogLevel(args: Args) {
LOG_LEVEL = when {
args.log < Constants.LOG_QUIET_LEVEL -> Constants.LOG_DEFAULT_LEVEL
args.log > Constants.LOG_MAX_LEVEL -> Constants.LOG_MAX_LEVEL
else -> args.log
}
}
} }
class Logger(val dev: Boolean) { class Logger(val dev: Boolean) {
@ -75,7 +86,8 @@ class Logger(val dev: Boolean) {
fun error(tag: String, message: CharSequence, e: Throwable? = null) { fun error(tag: String, message: CharSequence, e: Throwable? = null) {
val docUrl = if (e is KobaltException && e.docUrl != null) e.docUrl else null val docUrl = if (e is KobaltException && e.docUrl != null) e.docUrl else null
val text = if (! message.isBlank()) message val text =
if (message.isNotBlank()) message
else if (e != null && (! e.message.isNullOrBlank())) e.message else if (e != null && (! e.message.isNullOrBlank())) e.message
else { e?.toString() } else { e?.toString() }
val shortMessage = "***** E $text " + if (docUrl != null) " Documentation: $docUrl" else "" val shortMessage = "***** E $text " + if (docUrl != null) " Documentation: $docUrl" else ""
@ -88,7 +100,10 @@ class Logger(val dev: Boolean) {
} }
fun warn(tag: String, message: CharSequence, e: Throwable? = null) { fun warn(tag: String, message: CharSequence, e: Throwable? = null) {
val fullMessage = "***** WARNING " + (e?.message ?: message) val fullMessage = "***** WARNING " +
if (message.isNotBlank()) message
else if (e != null && (!e.message.isNullOrBlank())) e.message
else e?.toString()
println(AsciiArt.Companion.warnColor(getPattern("W", fullMessage, fullMessage, tag))) println(AsciiArt.Companion.warnColor(getPattern("W", fullMessage, fullMessage, tag)))
if (KobaltLogger.LOG_LEVEL > 1 && e != null) { if (KobaltLogger.LOG_LEVEL > 1 && e != null) {
Exceptions.printStackTrace(e) Exceptions.printStackTrace(e)

View file

@ -24,7 +24,7 @@ class KobaltWrapperProperties @Inject constructor() {
} }
private fun defaultUrlFor(version: String) = private fun defaultUrlFor(version: String) =
"http://beust.com/kobalt/kobalt-$version.zip" "https://beust.com/kobalt/kobalt-$version.zip"
private val file: File private val file: File
get() = File("$WRAPPER_DIR/$KOBALT_WRAPPER_PROPERTIES") get() = File("$WRAPPER_DIR/$KOBALT_WRAPPER_PROPERTIES")

View file

@ -6,6 +6,9 @@ import java.nio.file.Files
import java.nio.file.Paths import java.nio.file.Paths
import java.util.* import java.util.*
/**
* Encapsulate read access to local.properties.
*/
@Singleton @Singleton
class LocalProperties { class LocalProperties {
val localProperties: Properties by lazy { val localProperties: Properties by lazy {
@ -22,11 +25,11 @@ class LocalProperties {
result result
} }
fun getNoThrows(name: String, docUrl: String? = null) = localProperties.getProperty(name) fun getNoThrows(name: String): String? = localProperties.getProperty(name)
fun get(name: String, docUrl: String? = null) : String { fun get(name: String, docUrl: String? = null) : String {
val result = getNoThrows(name, docUrl) val result = getNoThrows(name)
?: throw KobaltException("Couldn't find $name in local.properties", docUrl = docUrl) ?: throw KobaltException("Couldn't find $name in local.properties", docUrl = docUrl)
return result as String return result
} }
} }

View file

@ -19,6 +19,7 @@ class RunCommandInfo {
*/ */
var useErrorStreamAsErrorIndicator : Boolean = true var useErrorStreamAsErrorIndicator : Boolean = true
var useInputStreamAsErrorIndicator : Boolean = false var useInputStreamAsErrorIndicator : Boolean = false
var ignoreExitValue : Boolean = false
var errorCallback: Function1<List<String>, Unit> = NewRunCommand.DEFAULT_ERROR var errorCallback: Function1<List<String>, Unit> = NewRunCommand.DEFAULT_ERROR
var successCallback: Function1<List<String>, Unit> = NewRunCommand.DEFAULT_SUCCESS var successCallback: Function1<List<String>, Unit> = NewRunCommand.DEFAULT_SUCCESS
@ -78,19 +79,31 @@ open class NewRunCommand(val info: RunCommandInfo) {
val process = pb.start() val process = pb.start()
// Run the command and collect the return code and streams // Run the command and collect the return code and streams
val returnCode = process.waitFor(30, TimeUnit.SECONDS) val processFinished = process.waitFor(120, TimeUnit.SECONDS)
val input = if (process.inputStream.available() > 0) fromStream(process.inputStream)
else listOf() if (!processFinished)
val error = if (process.errorStream.available() > 0) fromStream(process.errorStream) kobaltError("process timed out!")
else listOf()
val input =
if (process.inputStream.available() > 0) fromStream(process.inputStream)
else listOf()
val error =
if (process.errorStream.available() > 0) fromStream(process.errorStream)
else listOf()
kobaltLog(3, "info contains errors: " + (info.containsErrors != null))
// Check to see if the command succeeded // Check to see if the command succeeded
val isSuccess = val isSuccess =
if (info.containsErrors != null) ! info.containsErrors!!(error) if (info.containsErrors != null) ! info.containsErrors!!(error)
else isSuccess(returnCode, input, error) else isSuccess(if (info.ignoreExitValue) true else processFinished, input, error)
if (isSuccess) { if (isSuccess) {
info.successCallback(input) if (!info.useErrorStreamAsErrorIndicator) {
info.successCallback(error + input)
} else {
info.successCallback(input)
}
} else { } else {
info.errorCallback(error + input) info.errorCallback(error + input)
} }
@ -103,12 +116,12 @@ open class NewRunCommand(val info: RunCommandInfo) {
* have various ways to signal errors. * have various ways to signal errors.
*/ */
open protected fun isSuccess(isSuccess: Boolean, input: List<String>, error: List<String>) : Boolean { open protected fun isSuccess(isSuccess: Boolean, input: List<String>, error: List<String>) : Boolean {
var hasErrors = ! isSuccess var hasErrors: Boolean = ! isSuccess
if (info.useErrorStreamAsErrorIndicator && ! hasErrors) { if (info.useErrorStreamAsErrorIndicator && ! hasErrors) {
hasErrors = hasErrors || error.size > 0 hasErrors = hasErrors || error.isNotEmpty()
} }
if (info.useInputStreamAsErrorIndicator && ! hasErrors) { if (info.useInputStreamAsErrorIndicator && ! hasErrors) {
hasErrors = hasErrors || input.size > 0 hasErrors = hasErrors || input.isNotEmpty()
} }
return ! hasErrors return ! hasErrors

View file

@ -29,8 +29,12 @@ class StringVersion(val version: String) : Comparable<StringVersion> {
if (v1 < v2) return -1 if (v1 < v2) return -1
else if (v1 > v2) return 1 else if (v1 > v2) return 1
} catch(ex: NumberFormatException) { } catch(ex: NumberFormatException) {
warn("Couldn't parse version $version or $other") if (version == other.toString()) {
return -1 return 0
} else {
log(2, "Couldn't parse version $version or $other")
return -1
}
} }
} }
return 0 return 0

View file

@ -0,0 +1,79 @@
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.2.71'
id 'com.github.johnrengelman.shadow' version '5.0.0'
}
dependencies {
implementation project(':wrapper')
implementation project(':kobalt-plugin-api')
implementation "biz.aQute.bnd:biz.aQute.bndlib:$bndlib"
implementation 'com.github.spullara.mustache.java:compiler:0.9.5'
implementation "com.google.code.findbugs:jsr305:$findbugs"
implementation "com.sparkjava:spark-core:$spark"
implementation "com.squareup.okhttp3:logging-interceptor:$okhttp"
implementation 'com.sun.activation:javax.activation:1.2.0'
implementation "com.sun.xml.bind:jaxb-core:$jaxb"
implementation "com.sun.xml.bind:jaxb-impl:$jaxb"
implementation "javax.inject:javax.inject:$inject"
implementation "javax.xml.bind:jaxb-api:$jaxb"
implementation "org.apache.maven.resolver:maven-resolver-spi:$mavenResolver"
implementation "org.codehaus.groovy:groovy:$groovy"
implementation "com.beust:jcommander:$jcommander"
implementation "com.google.code.gson:gson:$gson"
implementation "com.google.inject:guice:$guice"
implementation "com.google.inject.extensions:guice-assistedinject:$guice"
implementation "com.squareup.retrofit2:converter-gson:$retrofit"
implementation "com.squareup.retrofit2:retrofit:$retrofit"
implementation "org.apache.maven:maven-model:$maven"
implementation "org.jetbrains.kotlin:kotlin-compiler-embeddable:$kotlin"
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin"
testImplementation 'org.assertj:assertj-core:3.8.0'
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin"
testImplementation "org.testng:testng:$testng"
}
sourceSets {
main.kotlin.srcDirs += "${rootProject.projectDir}../../src/main/kotlin"
test.kotlin.srcDirs += "${rootProject.projectDir}../../src/test/kotlin"
}
shadowJar {
classifier = null
}
test {
useTestNG()
}
publishing {
publications {
shadow(MavenPublication) { publication ->
project.shadow.component(publication)
artifact sourcesJar
artifact javadocJar
pom {
name = project.name
description = 'A build system in Kotlin'
url = 'https://beust.com/kobalt'
licenses {
license {
name = 'Apache-2.0'
url = 'https://www.apache.org/licenses/LICENSE-2.0'
}
}
developers {
developer {
name = 'Cedric Beust'
email = 'cedric@beust.com'
}
}
scm {
connection = 'scm:https://github.com/cbeust/kobalt.git'
developerConnection = 'scm:git@github.com:cbeust/kobalt.git'
url = 'https://github.com/cbeust/kobalt'
}
}
}
}
}

231
modules/kobalt/pom.xml Normal file
View file

@ -0,0 +1,231 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.beust</groupId>
<artifactId>kobalt-pom</artifactId>
<version>1.1.0</version>
<relativePath>../..</relativePath>
</parent>
<artifactId>kobalt</artifactId>
<packaging>jar</packaging>
<version>1.1.0</version>
<dependencies>
<dependency>
<groupId>com.beust</groupId>
<artifactId>kobalt-plugin-api</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>com.beust</groupId>
<artifactId>wrapper</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-compiler-embeddable</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
<version>0.9.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.2.2</version>
</dependency>
<dependency>
<groupId>com.google.inject.extensions</groupId>
<artifactId>guice-assistedinject</artifactId>
<version>4.2.2</version>
</dependency>
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
<version>1.72</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-gson</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>biz.aQute.bnd</groupId>
<artifactId>biz.aQute.bndlib</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>${okhttp3.version}</version>
</dependency>
<dependency>
<groupId>com.sparkjava</groupId>
<artifactId>spark-core</artifactId>
<version>2.6.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy</artifactId>
<version>2.4.12</version>
</dependency>
<dependency>
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-spi</artifactId>
<version>${mavenresolver.version}</version>
</dependency>
<!-- java 9 -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.sun.activation</groupId>
<artifactId>javax.activation</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.8.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>${testng.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<goals> <goal>compile</goal> </goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}../../src/main/kotlin</sourceDir>
</sourceDirs>
</configuration>
</execution>
<execution>
<id>test-compile</id>
<goals> <goal>test-compile</goal> </goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}../../src/test/kotlin</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<executions>
<!-- Replacing default-compile as it is treated specially by maven -->
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<!-- Replacing default-testCompile as it is treated specially by maven -->
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-compile</id>
<phase>compile</phase>
<goals> <goal>compile</goal> </goals>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals> <goal>testCompile</goal> </goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.beust.kobalt.MainKt</mainClass>
</transformer>
</transformers>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,38 @@
jar {
manifest {
attributes 'Main-Class': 'com.beust.kobalt.wrapper.Main'
}
}
publishing {
publications {
maven(MavenPublication) {
from(components.java)
artifact sourcesJar
artifact javadocJar
pom {
name = project.name
description = 'Wrapper for Kobalt'
url = 'https://beust.com/kobalt'
licenses {
license {
name = 'Apache-2.0'
url = 'https://www.apache.org/licenses/LICENSE-2.0'
}
}
developers {
developer {
name = 'Cedric Beust'
email = 'cedric@beust.com'
}
}
scm {
connection = 'scm:https://github.com/cbeust/kobalt.git'
developerConnection = 'scm:git@github.com:cbeust/kobalt.git'
url = 'https://github.com/cbeust/kobalt'
}
}
}
}
}

28
modules/wrapper/pom.xml Normal file
View file

@ -0,0 +1,28 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.beust</groupId>
<artifactId>kobalt-pom</artifactId>
<version>1.1.0</version>
<relativePath>../..</relativePath>
</parent>
<artifactId>wrapper</artifactId>
<packaging>jar</packaging>
<version>1.1.0</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -47,7 +47,6 @@ public class Main {
private int installAndLaunchMain(String[] argv) throws IOException, InterruptedException { private int installAndLaunchMain(String[] argv) throws IOException, InterruptedException {
String version = getVersion(); String version = getVersion();
initWrapperFile(version);
List<String> kobaltArgv = new ArrayList<>(); List<String> kobaltArgv = new ArrayList<>();
boolean noLaunch = false; boolean noLaunch = false;
@ -78,6 +77,7 @@ public class Main {
} }
int result = 0; int result = 0;
if (! exit) { if (! exit) {
initWrapperFile(version);
Path kobaltJarFile = installDistribution(); Path kobaltJarFile = installDistribution();
if (!noLaunch) { if (!noLaunch) {
result = launchMain(kobaltJarFile, kobaltArgv); result = launchMain(kobaltJarFile, kobaltArgv);
@ -118,7 +118,7 @@ public class Main {
} }
private static String downloadUrl(String version) { private static String downloadUrl(String version) {
return "http://beust.com/kobalt/kobalt-" + version + ".zip"; return "https://beust.com/kobalt/kobalt-" + version + ".zip";
} }
private void initWrapperFile(String version) throws IOException { private void initWrapperFile(String version) throws IOException {
@ -133,7 +133,7 @@ public class Main {
} }
private String getWrapperVersion() { private String getWrapperVersion() {
return wrapperProperties.getProperty(PROPERTY_VERSION); return wrapperProperties.getProperty(PROPERTY_VERSION, "N/A");
} }
private String getWrapperDownloadUrl(String version) { private String getWrapperDownloadUrl(String version) {

34
pom.xml Normal file
View file

@ -0,0 +1,34 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.beust</groupId>
<artifactId>kobalt-pom</artifactId>
<packaging>pom</packaging>
<version>1.1.0</version>
<modules>
<module>modules/kobalt-plugin-api</module>
<module>modules/wrapper</module>
<module>modules/kobalt</module>
</modules>
<repositories>
<repository>
<id>testng</id>
<url>https://dl.bintray.com/cbeust/maven</url>
</repository>
</repositories>
<properties>
<kotlin.version>1.2.71</kotlin.version>
<okio.version>1.13.0</okio.version>
<okhttp3.version>3.9.1</okhttp3.version>
<mavenresolver.version>1.1.0</mavenresolver.version>
<junit.version>1.1.0</junit.version>
<junitJupiter.version>5.1.0</junitJupiter.version>
<testng.version>6.12</testng.version>
<slf4j.version>1.7.3</slf4j.version>
</properties>
</project>

5
settings.gradle Normal file
View file

@ -0,0 +1,5 @@
rootProject.name = 'kobalt-pom'
include(':kobalt-plugin-api', ':wrapper', ':kobalt')
project(':kobalt-plugin-api').projectDir = file('modules/kobalt-plugin-api')
project(':wrapper').projectDir = file('modules/wrapper')
project(':kobalt').projectDir = file('modules/kobalt')

View file

@ -38,6 +38,14 @@ class Main @Inject constructor(
companion object { companion object {
fun mainNoExit(argv: Array<String>): Int { fun mainNoExit(argv: Array<String>): Int {
val (jc, args) = parseArgs(argv) val (jc, args) = parseArgs(argv)
if (args.usage) {
jc.usage()
return 0
}
if (args.version) {
println("Kobalt ${Kobalt.version}")
return 0
}
Kobalt.init(MainModule(args, KobaltSettings.readSettingsXml())) Kobalt.init(MainModule(args, KobaltSettings.readSettingsXml()))
val result = launchMain(Kobalt.INJECTOR.getInstance(Main::class.java), jc, args, argv) val result = launchMain(Kobalt.INJECTOR.getInstance(Main::class.java), jc, args, argv)
return result return result
@ -47,11 +55,7 @@ class Main @Inject constructor(
val args = Args() val args = Args()
val result = JCommander(args) val result = JCommander(args)
result.parse(*argv) result.parse(*argv)
KobaltLogger.LOG_LEVEL = if (args.log < Constants.LOG_QUIET_LEVEL) { KobaltLogger.setLogLevel(args)
Constants.LOG_DEFAULT_LEVEL
} else if (args.log > Constants.LOG_MAX_LEVEL) {
Constants.LOG_MAX_LEVEL
} else args.log
return Main.RunInfo(result, args) return Main.RunInfo(result, args)
} }

View file

@ -1,8 +1,9 @@
package com.beust.kobalt package com.beust.kobalt
import com.beust.jcommander.JCommander import com.beust.jcommander.JCommander
import com.beust.kobalt.api.ITask
import com.beust.kobalt.api.Kobalt import com.beust.kobalt.api.Kobalt
import com.beust.kobalt.api.PluginTask import com.beust.kobalt.api.KobaltContext
import com.beust.kobalt.api.Project import com.beust.kobalt.api.Project
import com.beust.kobalt.app.ProjectFinder import com.beust.kobalt.app.ProjectFinder
import com.beust.kobalt.app.ProjectGenerator import com.beust.kobalt.app.ProjectGenerator
@ -108,7 +109,9 @@ class Options @Inject constructor(
}), }),
Option( { args.tasks }, { Option( { args.tasks }, {
// --tasks // --tasks
displayTasks() runIfSuccessfulBuild(buildError) {
displayTasks(allProjects, Kobalt.context!!)
}
}), }),
Option( { args.checkVersions }, { Option( { args.checkVersions }, {
// --checkVersions // --checkVersions
@ -175,19 +178,29 @@ class Options @Inject constructor(
} }
} }
private fun displayTasks() { private fun displayTasks(projects: List<Project>, context: KobaltContext) {
// //
// List of tasks, --tasks // List of tasks, --tasks
// //
val tasksByPlugins = HashMultimap.create<String, PluginTask>() val tasksByPlugins = HashMultimap.create<String, ITask>()
taskManager.annotationTasks.forEach { projects.forEach { project ->
tasksByPlugins.put(it.plugin.name, it) pluginInfo.taskContributors.forEach {
val tasks = it.tasksFor(project, context)
tasks.forEach {
tasksByPlugins.put(it.plugin.name, it)
}
}
}
listOf(taskManager.annotationTasks, taskManager.dynamicTasks).forEach { tasks ->
tasks.forEach {
tasksByPlugins.put(it.plugin.name, it)
}
} }
val sb = StringBuffer("List of tasks\n") val sb = StringBuffer("List of tasks\n")
tasksByPlugins.keySet().forEach { name -> tasksByPlugins.keySet().forEach { name ->
sb.append("\n " + AsciiArt.horizontalDoubleLine + " $name " sb.append("\n " + AsciiArt.horizontalDoubleLine + " $name "
+ AsciiArt.horizontalDoubleLine + "\n") + AsciiArt.horizontalDoubleLine + "\n")
tasksByPlugins[name].distinctBy(PluginTask::name).sortedBy(PluginTask::name).forEach { task -> tasksByPlugins[name].distinctBy(ITask::name).sortedBy(ITask::name).forEach { task ->
sb.append(" ${task.name}\t\t${task.doc}\n") sb.append(" ${task.name}\t\t${task.doc}\n")
} }
} }

View file

@ -119,7 +119,7 @@ class BuildFiles @Inject constructor(val factory: BuildFileCompiler.IFactory,
parentFile.mkdirs() parentFile.mkdirs()
val imp = arrayListOf<String>().apply { val imp = arrayListOf<String>().apply {
addAll(imports) addAll(imports)
}.distinct() }.toMutableSet().toMutableList()
Collections.sort(imp) Collections.sort(imp)
writeText(imp.joinToString("\n")) writeText(imp.joinToString("\n"))
appendText(code.joinToString("\n")) appendText(code.joinToString("\n"))

View file

@ -20,6 +20,8 @@ abstract class LanguageTemplateGenerator : ITemplate {
abstract val defaultSourceDirectories : HashSet<String> abstract val defaultSourceDirectories : HashSet<String>
abstract val defaultTestDirectories : HashSet<String> abstract val defaultTestDirectories : HashSet<String>
abstract val mainDependencies : ArrayList<Pom.Dependency>
abstract val testDependencies : ArrayList<Pom.Dependency>
abstract val directive : String abstract val directive : String
abstract val fileMatch : (String) -> Boolean abstract val fileMatch : (String) -> Boolean
abstract val fileMap: List<FileInfo> abstract val fileMap: List<FileInfo>
@ -131,20 +133,19 @@ abstract class LanguageTemplateGenerator : ITemplate {
put("directory", currentDir.absolutePath) put("directory", currentDir.absolutePath)
put("sourceDirectories", defaultSourceDirectories) put("sourceDirectories", defaultSourceDirectories)
put("sourceDirectoriesTest", defaultTestDirectories) put("sourceDirectoriesTest", defaultTestDirectories)
put("mainDependencies", mainDependencies)
put("testDependencies", testDependencies)
put("imports", "import com.beust.kobalt.plugin.$templateName.*") put("imports", "import com.beust.kobalt.plugin.$templateName.*")
put("directive", "project") put("directive", "project")
} }
var mainDeps = arrayListOf<Pom.Dependency>()
var testDeps = arrayListOf<Pom.Dependency>()
map.put("mainDependencies", mainDeps)
map.put("testDependencies", testDeps)
File("pom.xml").let { File("pom.xml").let {
if (it.absoluteFile.exists()) { if (it.absoluteFile.exists()) {
importPom(it, mainDeps, testDeps, map) importPom(it, mainDependencies, testDependencies, map)
} }
} }
val fileInputStream = javaClass.classLoader val fileInputStream = javaClass.classLoader
.getResource(ITemplateContributor.DIRECTORY_NAME + "/build.mustache").openStream() .getResource(ITemplateContributor.DIRECTORY_NAME + "/build.mustache").openStream()
val sw = StringWriter() val sw = StringWriter()

View file

@ -1,6 +1,8 @@
package com.beust.kobalt.app package com.beust.kobalt.app
import com.beust.kobalt.Args import com.beust.kobalt.Args
import com.beust.kobalt.JavaInfo
import com.beust.kobalt.Jvm
import com.beust.kobalt.app.remote.KobaltServer import com.beust.kobalt.app.remote.KobaltServer
import com.beust.kobalt.internal.IncrementalManager import com.beust.kobalt.internal.IncrementalManager
import com.beust.kobalt.internal.KobaltSettings import com.beust.kobalt.internal.KobaltSettings
@ -17,6 +19,7 @@ import com.google.inject.Provider
import com.google.inject.Singleton import com.google.inject.Singleton
import com.google.inject.TypeLiteral import com.google.inject.TypeLiteral
import com.google.inject.assistedinject.FactoryModuleBuilder import com.google.inject.assistedinject.FactoryModuleBuilder
import java.io.File
import java.util.concurrent.ExecutorService import java.util.concurrent.ExecutorService
open class MainModule(val args: Args, val settings: KobaltSettings) : AbstractModule() { open class MainModule(val args: Args, val settings: KobaltSettings) : AbstractModule() {
@ -49,15 +52,14 @@ open class MainModule(val args: Args, val settings: KobaltSettings) : AbstractMo
bind(Args::class.java).toProvider(Provider<Args> { bind(Args::class.java).toProvider(Provider<Args> {
args args
}) })
EventBus().let { eventBus -> bind(EventBus::class.java).toInstance(EventBus())
bind(EventBus::class.java).toInstance(eventBus)
}
bind(PluginInfo::class.java).toProvider(Provider<PluginInfo> { bind(PluginInfo::class.java).toProvider(Provider<PluginInfo> {
PluginInfo.readKobaltPluginXml() PluginInfo.readKobaltPluginXml()
}).`in`(Singleton::class.java) }).`in`(Singleton::class.java)
bind(KobaltSettings::class.java).toProvider(Provider<KobaltSettings> { bind(KobaltSettings::class.java).toProvider(Provider<KobaltSettings> {
settings settings
}).`in`(Singleton::class.java) }).`in`(Singleton::class.java)
bind(Jvm::class.java).toInstance(JavaInfo.create(File(com.beust.kobalt.SystemProperties.javaBase)))
// bindListener(Matchers.any(), object: TypeListener { // bindListener(Matchers.any(), object: TypeListener {
// override fun <I> hear(typeLiteral: TypeLiteral<I>?, typeEncounter: TypeEncounter<I>?) { // override fun <I> hear(typeLiteral: TypeLiteral<I>?, typeEncounter: TypeEncounter<I>?) {

View file

@ -56,7 +56,7 @@ class Profiles(val context: KobaltContext) {
val variable = if (match.first) match.second else oldMatch.second val variable = if (match.first) match.second else oldMatch.second
if (oldMatch.first) { if (oldMatch.first) {
warn("Old profile syntax detected for \"$line\"," + warn("Old profile syntax detected for \"${line.trim()}\"," +
" please update to \"val $variable by profile()\"") " please update to \"val $variable by profile()\"")
} }

View file

@ -1,11 +1,14 @@
package com.beust.kobalt.app.java package com.beust.kobalt.app.java
import com.beust.kobalt.app.LanguageTemplateGenerator import com.beust.kobalt.app.LanguageTemplateGenerator
import com.beust.kobalt.maven.Pom
/** /**
* Template for the "java" generator. * Template for the "java" generator.
*/ */
class JavaTemplateGenerator : LanguageTemplateGenerator() { class JavaTemplateGenerator : LanguageTemplateGenerator() {
override val mainDependencies = arrayListOf<Pom.Dependency>()
override val testDependencies = arrayListOf<Pom.Dependency>()
override val defaultSourceDirectories = hashSetOf("src/main/java") override val defaultSourceDirectories = hashSetOf("src/main/java")
override val defaultTestDirectories = hashSetOf("src/test/java") override val defaultTestDirectories = hashSetOf("src/test/java")
override val directive = "project" override val directive = "project"

View file

@ -1,10 +1,16 @@
package com.beust.kobalt.app.kotlin package com.beust.kobalt.app.kotlin
import com.beust.kobalt.Constants
import com.beust.kobalt.app.LanguageTemplateGenerator import com.beust.kobalt.app.LanguageTemplateGenerator
import com.beust.kobalt.maven.Pom
class KotlinTemplateGenerator : LanguageTemplateGenerator() { class KotlinTemplateGenerator : LanguageTemplateGenerator() {
override val defaultSourceDirectories = hashSetOf("src/main/kotlin") override val defaultSourceDirectories = hashSetOf("src/main/kotlin")
override val defaultTestDirectories = hashSetOf("src/test/kotlin") override val defaultTestDirectories = hashSetOf("src/test/kotlin")
override val mainDependencies = arrayListOf(
Pom.Dependency("org.jetbrains.kotlin", "kotlin-stdlib", null, Constants.KOTLIN_COMPILER_VERSION)
)
override val testDependencies = arrayListOf<Pom.Dependency>()
override val directive = "project" override val directive = "project"
override val templateName = "kotlin" override val templateName = "kotlin"
override val templateDescription = "Generate a simple Kotlin project" override val templateDescription = "Generate a simple Kotlin project"

View file

@ -35,6 +35,7 @@ class GetDependencyGraphHandler : WebSocketListener {
fun <T> sendWebsocketCommand(endpoint: RemoteEndpoint, commandName: String, payload: T, fun <T> sendWebsocketCommand(endpoint: RemoteEndpoint, commandName: String, payload: T,
errorMessage: String? = null) { errorMessage: String? = null) {
SparkServer.watchDog.rearm()
val json = Gson().toJson(WebSocketCommand(commandName, payload = Gson().toJson(payload), val json = Gson().toJson(WebSocketCommand(commandName, payload = Gson().toJson(payload),
errorMessage = errorMessage)) errorMessage = errorMessage))
endpoint.sendString(json) endpoint.sendString(json)

View file

@ -12,15 +12,7 @@ import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.warn import com.beust.kobalt.misc.warn
import com.google.gson.Gson import com.google.gson.Gson
import com.google.inject.Guice import com.google.inject.Guice
import okhttp3.OkHttpClient import okhttp3.*
import okhttp3.Request
import okhttp3.Response
import okhttp3.ResponseBody
import okhttp3.ws.WebSocket
import okhttp3.ws.WebSocketCall
import okhttp3.ws.WebSocketListener
import okio.Buffer
import java.io.IOException
fun main(argv: Array<String>) { fun main(argv: Array<String>) {
Kobalt.INJECTOR = Guice.createInjector(MainModule(Args(), KobaltSettings.readSettingsXml())) Kobalt.INJECTOR = Guice.createInjector(MainModule(Args(), KobaltSettings.readSettingsXml()))
@ -39,26 +31,22 @@ class KobaltClient : Runnable {
.url("$url?projectRoot=$projectRoot&buildFile=$buildFile") .url("$url?projectRoot=$projectRoot&buildFile=$buildFile")
.build() .build()
var webSocket: WebSocket? = null var webSocket: WebSocket? = null
val ws = WebSocketCall.create(client, request).enqueue(object: WebSocketListener { val socketListener = object: WebSocketListener() {
override fun onOpen(ws: WebSocket, response: Response) { override fun onFailure(webSocket: WebSocket, ex: Throwable, response: Response?) {
webSocket = ws
}
override fun onPong(p0: Buffer?) {
println("WebSocket pong")
}
override fun onClose(p0: Int, p1: String?) {
println("WebSocket closed")
}
override fun onFailure(ex: IOException, response: Response?) {
Exceptions.printStackTrace(ex) Exceptions.printStackTrace(ex)
error("WebSocket failure: ${ex.message} response: $response") error("WebSocket failure: ${ex.message} response: $response")
} }
override fun onMessage(body: ResponseBody) { override fun onOpen(ws: WebSocket, response: Response) {
val json = body.string() webSocket = ws
}
override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
println("Closing socket")
}
override fun onMessage(webSocket: WebSocket, text: String) {
val json = text
val wsCommand = Gson().fromJson(json, WebSocketCommand::class.java) val wsCommand = Gson().fromJson(json, WebSocketCommand::class.java)
if (wsCommand.errorMessage != null) { if (wsCommand.errorMessage != null) {
warn("Received error message from server: " + wsCommand.errorMessage) warn("Received error message from server: " + wsCommand.errorMessage)
@ -87,7 +75,10 @@ class KobaltClient : Runnable {
} }
} }
} }
}) }
val ws = client.newWebSocket(request, socketListener)
ws.close(1000, "All good")
} }
} }

View file

@ -1,6 +1,5 @@
package com.beust.kobalt.app.remote package com.beust.kobalt.app.remote
import com.beust.kobalt.api.Project
import com.beust.kobalt.homeDir import com.beust.kobalt.homeDir
import com.beust.kobalt.internal.PluginInfo import com.beust.kobalt.internal.PluginInfo
import com.beust.kobalt.maven.aether.Exceptions import com.beust.kobalt.maven.aether.Exceptions
@ -74,15 +73,12 @@ class KobaltServer @Inject constructor(@Assisted val force: Boolean, @Assisted @
try { try {
if (createServerFile(port, force)) { if (createServerFile(port, force)) {
kobaltLog(1, "KobaltServer listening on port $port") kobaltLog(1, "KobaltServer listening on port $port")
// OldServer(initCallback, cleanUpCallback).run(port)
// JerseyServer(initCallback, cleanUpCallback).run(port)
SparkServer(cleanUpCallback, pluginInfo).run(port) SparkServer(cleanUpCallback, pluginInfo).run(port)
// WasabiServer(initCallback, cleanUpCallback).run(port)
} }
} catch(ex: Exception) { } catch(ex: Exception) {
Exceptions.printStackTrace(ex) Exceptions.printStackTrace(ex)
} finally { } finally {
// deleteServerFile() deleteServerFile()
} }
return port return port
} }

View file

@ -5,6 +5,7 @@ import com.beust.kobalt.app.Templates
import com.beust.kobalt.internal.PluginInfo import com.beust.kobalt.internal.PluginInfo
import com.google.common.collect.ListMultimap import com.google.common.collect.ListMultimap
import com.google.gson.Gson import com.google.gson.Gson
import org.slf4j.Logger
import spark.ResponseTransformer import spark.ResponseTransformer
import spark.Route import spark.Route
import spark.Spark import spark.Spark
@ -14,6 +15,8 @@ class SparkServer(val cleanUpCallback: () -> Unit, val pluginInfo : PluginInfo)
companion object { companion object {
lateinit var cleanUpCallback: () -> Unit lateinit var cleanUpCallback: () -> Unit
val URL_QUIT = "/quit"
lateinit var watchDog: WatchDog
} }
init { init {
@ -28,19 +31,25 @@ class SparkServer(val cleanUpCallback: () -> Unit, val pluginInfo : PluginInfo)
private fun jsonRoute(path: String, route: Route) private fun jsonRoute(path: String, route: Route)
= Spark.get(path, "application/json", route, JsonTransformer()) = Spark.get(path, "application/json", route, JsonTransformer())
val log = org.slf4j.LoggerFactory.getLogger("SparkServer") val log: Logger = org.slf4j.LoggerFactory.getLogger("SparkServer")
override fun run(port: Int) { override fun run(port: Int) {
val threadPool = Executors.newFixedThreadPool(2)
watchDog = WatchDog(port, 60 * 10 /* 10 minutes */, log)
threadPool.submit {
watchDog.run()
}
log.debug("Server running") log.debug("Server running")
Spark.port(port) Spark.port(port)
Spark.webSocket("/v1/getDependencyGraph", GetDependencyGraphHandler::class.java) Spark.webSocket("/v1/getDependencyGraph", GetDependencyGraphHandler::class.java)
Spark.get("/ping") { req, res -> Spark.get("/ping") { req, res ->
watchDog.rearm()
log.debug(" Received ping") log.debug(" Received ping")
""" { "result" : "ok" } """ """ { "result" : "ok" } """
} }
Spark.get("/quit", { req, res -> Spark.get(URL_QUIT, { req, res ->
log.debug(" Received quit") log.debug(" Received quit")
Executors.newFixedThreadPool(1).let { executor -> threadPool.let { executor ->
executor.submit { executor.submit {
Thread.sleep(1000) Thread.sleep(1000)
Spark.stop() Spark.stop()

View file

@ -0,0 +1,71 @@
package com.beust.kobalt.app.remote
import com.beust.kobalt.misc.warn
import org.slf4j.Logger
import java.net.HttpURLConnection
import java.net.URL
import java.time.Duration
import java.time.LocalDateTime
import java.time.OffsetDateTime
import java.time.format.DateTimeFormatter
/**
* Wakes up every `WAKE_UP_INTERVAL` and check if a certain period of time (`checkPeriod`) has elapsed
* without being rearmed. If that time has elapsed, send a QUIT command to the Kobalt server. If the WatchDog
* gets rearmed, the expiration period is reset.
*/
class WatchDog(val port: Int, val checkPeriodSeconds: Long, val log: Logger) {
private val WAKE_UP_INTERVAL: Duration = Duration.ofSeconds(60)
private val FORMAT: DateTimeFormatter = DateTimeFormatter.ofPattern("MM/d/y HH:mm:ss")
private var nextWakeUpMillis: Long = arm()
private var stop: Boolean = false
/**
* Rearm for another `checkPeriod`.
*/
fun rearm() {
nextWakeUpMillis = arm()
log.info("Watchdog rearmed for " + format(nextWakeUpMillis))
}
/**
* Start the watch dog.
*/
fun run() {
val wakeUpSeconds = WAKE_UP_INTERVAL.toMillis()
log.info("Server dying at " + format(nextWakeUpMillis) + ", next wake up in "
+ (wakeUpSeconds / 1000) + " seconds")
while (! stop) {
Thread.sleep(wakeUpSeconds)
val diffSeconds = (nextWakeUpMillis - System.currentTimeMillis()) / 1000
if (diffSeconds <= 0) {
log.info("Time to die")
stop = true
} else {
log.info("Dying in $diffSeconds seconds")
}
}
try {
val connection = (URL("http://localhost:$port" + SparkServer.URL_QUIT)
.openConnection() as HttpURLConnection).apply {
requestMethod = "GET"
}
val code = connection.responseCode
if (code == 200) {
log.info("Successfully stopped the server")
} else {
warn("Couldn't stop the server, response: " + code)
}
} catch(ex: Exception) {
warn("Couldn't stop the server: " + ex.message, ex)
}
}
private fun arm() = System.currentTimeMillis() + (checkPeriodSeconds * 1000)
private fun toLocalDate(millis: Long) = LocalDateTime.ofEpochSecond(millis / 1000, 0, OffsetDateTime.now().offset)
private fun format(millis: Long) = FORMAT.format(toLocalDate(millis))
}

View file

@ -1,11 +1,12 @@
package com.beust.kobalt.plugin.application package com.beust.kobalt.plugin.application
import com.beust.kobalt.* import com.beust.kobalt.Jvm
import com.beust.kobalt.KobaltException
import com.beust.kobalt.Plugins
import com.beust.kobalt.TaskResult
import com.beust.kobalt.api.* import com.beust.kobalt.api.*
import com.beust.kobalt.api.annotation.Directive import com.beust.kobalt.api.annotation.Directive
import com.beust.kobalt.api.annotation.Task
import com.beust.kobalt.archive.Archives import com.beust.kobalt.archive.Archives
import com.beust.kobalt.internal.ActorUtils
import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.maven.aether.Scope import com.beust.kobalt.maven.aether.Scope
import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KFiles
@ -19,6 +20,9 @@ import com.google.inject.Singleton
import java.io.File import java.io.File
class ApplicationConfig { class ApplicationConfig {
@Directive
var taskName: String = "run"
@Directive @Directive
var mainClass: String? = null var mainClass: String? = null
@ -29,6 +33,15 @@ class ApplicationConfig {
@Directive @Directive
fun args(vararg argv: String) = argv.forEach { args.add(it) } fun args(vararg argv: String) = argv.forEach { args.add(it) }
val args = arrayListOf<String>() val args = arrayListOf<String>()
@Directive
var ignoreErrorStream: Boolean = false
@Directive
var ignoreInputStream: Boolean = true
@Directive
var ignoreExitValue: Boolean = false
} }
@Directive @Directive
@ -40,10 +53,10 @@ fun Project.application(init: ApplicationConfig.() -> Unit): ApplicationConfig {
} }
@Singleton @Singleton
class ApplicationPlugin @Inject constructor(val configActor: ConfigActor<ApplicationConfig>, class ApplicationPlugin @Inject constructor(val configActor: ConfigsActor<ApplicationConfig>,
val executors: KobaltExecutors, val nativeManager: NativeManager, val executors: KobaltExecutors, val nativeManager: NativeManager,
val dependencyManager: DependencyManager, val taskContributor : TaskContributor) val dependencyManager: DependencyManager, val taskContributor : TaskContributor, val jvm: Jvm)
: BasePlugin(), IRunnerContributor, ITaskContributor, IConfigActor<ApplicationConfig> by configActor { : BasePlugin(), ITaskContributor, IConfigsActor<ApplicationConfig> by configActor {
companion object { companion object {
const val PLUGIN_NAME = "Application" const val PLUGIN_NAME = "Application"
@ -53,49 +66,50 @@ class ApplicationPlugin @Inject constructor(val configActor: ConfigActor<Applica
override fun apply(project: Project, context: KobaltContext) { override fun apply(project: Project, context: KobaltContext) {
super.apply(project, context) super.apply(project, context)
taskContributor.addVariantTasks(this, project, context, "run", group = "run", dependsOn = listOf("install"),
runTask = { taskRun(project) })
}
@Task(name = "run", description = "Run the main class", group = "run", dependsOn = arrayOf("install")) configurationFor(project)?.let { configs ->
fun taskRun(project: Project): TaskResult { configs.forEach { config ->
val runContributor = ActorUtils.selectAffinityActor(project, context, taskContributor.addTask(this, project, config.taskName,
context.pluginInfo.runnerContributors) description = "Run the class " + config.mainClass,
if (runContributor != null && runContributor.affinity(project, context) > 0) { group = "run",
return runContributor.run(project, context, dependsOn = listOf("assemble"),
dependencyManager.dependencies(project, context, listOf(Scope.RUNTIME))) runTask = { run(project, context, config) })
} else { }
context.logger.log(project.name, 1,
"Couldn't find a runner for project ${project.name}. Please make sure" +
" your build file contains " +
"an application{} directive with a mainClass=... in it")
return TaskResult()
} }
} }
// fun taskRun(project: Project, config: ApplicationConfig): TaskResult {
// val runContributor = ActorUtils.selectAffinityActor(project, context,
// context.pluginInfo.runnerContributors)
// if (runContributor != null && runContributor.affinity(project, context) > 0) {
// return runContributor.run(project, context,
// dependencyManager.dependencies(project, context, listOf(Scope.RUNTIME)))
// } else {
// context.logger.log(project.name, 1,
// "Couldn't find a runner for project ${project.name}. Please make sure" +
// " your build file contains " +
// "an application{} directive with a mainClass=... in it")
// return TaskResult()
// }
// }
private fun isFatJar(packages: List<PackageConfig>, jarName: String): Boolean { private fun isFatJar(packages: List<PackageConfig>, jarName: String): Boolean {
val foundJar = packages.flatMap { it.jars }.filter { jarName.endsWith(it.name) } val foundJar = packages.flatMap { it.jars }.filter { jarName.endsWith(it.name) }
return foundJar.size == 1 && foundJar[0].fatJar return foundJar.size == 1 && foundJar[0].fatJar
} }
// IRunContributor private fun run(project: Project, context: KobaltContext, config: ApplicationConfig): TaskResult {
override fun affinity(project: Project, context: KobaltContext): Int {
return if (configurationFor(project) != null) IAffinity.DEFAULT_POSITIVE_AFFINITY else 0
}
override fun run(project: Project, context: KobaltContext, classpath: List<IClasspathDependency>): TaskResult {
var result = TaskResult()
if (project.nativeDependencies.any()) { if (project.nativeDependencies.any()) {
nativeManager.installLibraries(project) nativeManager.installLibraries(project)
} }
configurationFor(project)?.let { config ->
val result =
if (config.mainClass != null) { if (config.mainClass != null) {
result = runJarFile(project, context, config) runJarFile(project, context, config)
} else { } else {
throw KobaltException("No \"mainClass\" specified in the application{} part of project ${project.name}") throw KobaltException("No \"mainClass\" specified in the application{} part of project ${project.name}")
} }
}
return result return result
} }
@ -111,7 +125,7 @@ class ApplicationPlugin @Inject constructor(val configActor: ConfigActor<Applica
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val packages = project.projectProperties.get(PackagingPlugin.PACKAGES) as List<PackageConfig> val packages = project.projectProperties.get(PackagingPlugin.PACKAGES) as List<PackageConfig>
val allDeps = arrayListOf(jarName) val allDeps = arrayListOf(jarName)
val java = JavaInfo.create(File(SystemProperties.javaBase)).javaExecutable!! val java = jvm.javaExecutable!!
if (! isFatJar(packages, jarName)) { if (! isFatJar(packages, jarName)) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
// If the jar file is not fat, we need to add the transitive closure of all dependencies // If the jar file is not fat, we need to add the transitive closure of all dependencies
@ -133,6 +147,7 @@ class ApplicationPlugin @Inject constructor(val configActor: ConfigActor<Applica
val exitCode = runCommand { val exitCode = runCommand {
command = "java" command = "java"
args = allArgs args = allArgs
useErrorStreamAsErrorIndicator = false
directory = File(project.directory) directory = File(project.directory)
successCallback = { output: List<String> -> successCallback = { output: List<String> ->
kobaltLog(1, output.joinToString("\n")) kobaltLog(1, output.joinToString("\n"))
@ -141,11 +156,25 @@ class ApplicationPlugin @Inject constructor(val configActor: ConfigActor<Applica
kobaltLog(1, "ERROR") kobaltLog(1, "ERROR")
kobaltLog(1, output.joinToString("\n")) kobaltLog(1, output.joinToString("\n"))
} }
useErrorStreamAsErrorIndicator = !config.ignoreErrorStream
useInputStreamAsErrorIndicator = !config.ignoreInputStream
ignoreExitValue = config.ignoreExitValue
} }
return TaskResult(exitCode == 0) return TaskResult(exitCode == 0)
} }
//ITaskContributor //ITaskContributor
override fun tasksFor(project: Project, context: KobaltContext): List<DynamicTask> = taskContributor.dynamicTasks override fun tasksFor(project: Project, context: KobaltContext): List<DynamicTask> {
val result = arrayListOf<DynamicTask>()
configurationFor(project)?.let { configs ->
configs.forEach { config ->
result.add(DynamicTask(this, config.taskName, "Run the class " + config.mainClass, "run", project,
dependsOn = listOf("assemble"),
closure = { run(project, context, config) }))
}
}
return result
}
} }

View file

@ -1,11 +1,11 @@
package com.beust.kobalt.plugin.apt package com.beust.kobalt.plugin.apt
import com.beust.kobalt.Constants import com.beust.kobalt.Constants
import com.beust.kobalt.Jvm
import com.beust.kobalt.TaskResult import com.beust.kobalt.TaskResult
import com.beust.kobalt.api.* import com.beust.kobalt.api.*
import com.beust.kobalt.api.annotation.AnnotationDefault import com.beust.kobalt.api.annotation.AnnotationDefault
import com.beust.kobalt.api.annotation.Directive import com.beust.kobalt.api.annotation.Directive
import com.beust.kobalt.homeDir
import com.beust.kobalt.internal.CompilerUtils import com.beust.kobalt.internal.CompilerUtils
import com.beust.kobalt.maven.DependencyManager import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.maven.aether.Filters import com.beust.kobalt.maven.aether.Filters
@ -30,7 +30,7 @@ import javax.inject.Singleton
*/ */
@Singleton @Singleton
class AptPlugin @Inject constructor(val dependencyManager: DependencyManager, val kotlinPlugin: KotlinPlugin, class AptPlugin @Inject constructor(val dependencyManager: DependencyManager, val kotlinPlugin: KotlinPlugin,
val compilerUtils: CompilerUtils) val compilerUtils: CompilerUtils, val jvm: Jvm)
: BasePlugin(), ICompilerFlagContributor, ISourceDirectoryContributor, IClasspathContributor, ITaskContributor { : BasePlugin(), ICompilerFlagContributor, ISourceDirectoryContributor, IClasspathContributor, ITaskContributor {
companion object { companion object {
@ -41,17 +41,15 @@ class AptPlugin @Inject constructor(val dependencyManager: DependencyManager, va
override val name = PLUGIN_NAME override val name = PLUGIN_NAME
var kaptConfig: KaptConfig? = null
override fun apply(project: Project, context: KobaltContext) { override fun apply(project: Project, context: KobaltContext) {
super.apply(project, context) super.apply(project, context)
kaptConfig = kaptConfigs[project.name] val kaptConfig = kaptConfigs[project.name]
// Delete the output directories // Delete the output directories
listOf(aptConfigs[project.name]?.outputDir, kaptConfig?.outputDir) listOf(aptConfigs[project.name]?.outputDir, kaptConfig?.outputDir)
.filterNotNull() .filterNotNull()
.distinct() .distinct()
.map { generatedDir(project, it) } .map { aptGeneratedDir(project, it) }
.forEach { .forEach {
it.normalize().absolutePath.let { path -> it.normalize().absolutePath.let { path ->
context.logger.log(project.name, 1, " Deleting " + path) context.logger.log(project.name, 1, " Deleting " + path)
@ -64,9 +62,10 @@ class AptPlugin @Inject constructor(val dependencyManager: DependencyManager, va
// IClasspathContributor // IClasspathContributor
override fun classpathEntriesFor(project: Project?, context: KobaltContext): Collection<IClasspathDependency> { override fun classpathEntriesFor(project: Project?, context: KobaltContext): Collection<IClasspathDependency> {
val result = arrayListOf<IClasspathDependency>() val result = arrayListOf<IClasspathDependency>()
val kaptConfig = kaptConfigs[project?.name]
if (project != null && kaptConfig != null) { if (project != null && kaptConfig != null) {
kaptConfig?.let { config -> kaptConfig.let { config ->
val c = generatedClasses(project, context, config.outputDir) val c = kaptClassesDir(project, config.outputDir)
File(c).mkdirs() File(c).mkdirs()
result.add(FileDependency(c)) result.add(FileDependency(c))
} }
@ -74,46 +73,46 @@ class AptPlugin @Inject constructor(val dependencyManager: DependencyManager, va
return result return result
} }
private fun generatedDir(project: Project, outputDir: String) : File private fun aptGeneratedDir(project: Project, outputDir: String) : File
= File(KFiles.joinDir(project.directory, KFiles.KOBALT_BUILD_DIR, outputDir)) = File(KFiles.joinDir(project.directory, KFiles.KOBALT_BUILD_DIR, outputDir))
// ISourceDirectoryContributor // ISourceDirectoryContributor
override fun sourceDirectoriesFor(project: Project, context: KobaltContext): List<File> { override fun sourceDirectoriesFor(project: Project, context: KobaltContext): List<File> {
val result = arrayListOf<File>() val result = arrayListOf<File>()
aptConfigs[project.name]?.let { config -> aptConfigs[project.name]?.let { config ->
result.add(generatedDir(project, config.outputDir)) result.add(aptGeneratedDir(project, config.outputDir))
} }
kaptConfigs[project.name]?.let { config -> kaptConfigs[project.name]?.let { config ->
result.add(generatedDir(project, config.outputDir)) result.add(File(kaptSourcesDir(project, config.outputDir)))
} }
return result return result
} }
private fun generated(project: Project, context: KobaltContext, outputDir: String) = private fun kaptGenerated(project: Project, outputDir: String) =
KFiles.joinAndMakeDir(project.directory, project.buildDirectory, outputDir, KFiles.joinAndMakeDir(project.directory, project.buildDirectory, outputDir)
context.variant.toIntermediateDir())
private fun generatedSources(project: Project, context: KobaltContext, outputDir: String) = private fun kaptSourcesDir(project: Project, outputDir: String) =
KFiles.joinDir(generated(project, context, outputDir), "sources") KFiles.joinDir(kaptGenerated(project, outputDir), "sources")
private fun generatedStubs(project: Project, context: KobaltContext, outputDir: String) = private fun kaptStubsDir(project: Project, outputDir: String) =
KFiles.joinDir(generated(project, context, outputDir), "stubs") KFiles.joinDir(kaptGenerated(project, outputDir), "stubs")
private fun generatedClasses(project: Project, context: KobaltContext, outputDir: String) = private fun kaptClassesDir(project: Project, outputDir: String) =
KFiles.joinDir(generated(project, context, outputDir), "classes") KFiles.joinDir(kaptGenerated(project, outputDir), "classes")
// ITaskContributor // ITaskContributor
override fun tasksFor(project: Project, context: KobaltContext): List<DynamicTask> { override fun tasksFor(project: Project, context: KobaltContext): List<DynamicTask> {
val kaptConfig = kaptConfigs[project.name]
val result = val result =
if (kaptConfig != null) { if (kaptConfig != null) {
listOf( listOf(
DynamicTask(this, "runKapt", "Run kapt", AnnotationDefault.GROUP, project, DynamicTask(this, "runKapt", "Run kapt", AnnotationDefault.GROUP, project,
reverseDependsOn = listOf("compile"), runAfter = listOf("clean"), reverseDependsOn = listOf("compile"), runAfter = listOf("clean"),
closure = {p: Project -> taskRunKapt(p)}), closure = {p: Project -> taskRunKapt(p)}),
DynamicTask(this, "compileKapt", "Compile the sources generated by kapt", DynamicTask(this, "compileKapt", "Compile the sources generated by kapt",
AnnotationDefault.GROUP, project, AnnotationDefault.GROUP, project,
dependsOn = listOf("runKapt"), reverseDependsOn = listOf("compile"), dependsOn = listOf("runKapt"), reverseDependsOn = listOf("compile"),
closure = {p: Project -> taskCompileKapt(p)}) closure = {p: Project -> taskCompileKapt(p)})
) )
} else { } else {
emptyList() emptyList()
@ -125,14 +124,14 @@ class AptPlugin @Inject constructor(val dependencyManager: DependencyManager, va
var success = true var success = true
kaptConfigs[project.name]?.let { config -> kaptConfigs[project.name]?.let { config ->
val sourceDirs = listOf( val sourceDirs = listOf(
generatedStubs(project, context, config.outputDir), kaptStubsDir(project, config.outputDir),
generatedSources(project, context, config.outputDir)) kaptSourcesDir(project, config.outputDir))
val sourceFiles = KFiles.findSourceFiles(project.directory, sourceDirs, listOf("kt")).toList() val sourceFiles = KFiles.findSourceFiles(project.directory, sourceDirs, listOf("kt")).toList()
val buildDirectory = File(KFiles.joinDir(project.directory, val buildDirectory = File(KFiles.joinDir(project.directory,
generatedClasses(project, context, config.outputDir))) kaptClassesDir(project, config.outputDir)))
val flags = listOf<String>() val flags = listOf<String>()
val cai = CompilerActionInfo(project.directory, allDependencies(), sourceFiles, listOf(".kt"), val cai = CompilerActionInfo(project.directory, allDependencies(project), sourceFiles, listOf(".kt"),
buildDirectory, flags, emptyList(), forceRecompile = true) buildDirectory, flags, emptyList(), forceRecompile = true, compilerSeparateProcess = true)
val cr = compilerUtils.invokeCompiler(project, context, kotlinPlugin.compiler, cai) val cr = compilerUtils.invokeCompiler(project, context, kotlinPlugin.compiler, cai)
success = cr.failedResult == null success = cr.failedResult == null
@ -146,14 +145,12 @@ class AptPlugin @Inject constructor(val dependencyManager: DependencyManager, va
fun annotationProcessorDependency() = dependencyManager.create(annotationDependencyId) fun annotationProcessorDependency() = dependencyManager.create(annotationDependencyId)
fun aptJarDependencies() : List<IClasspathDependency> { fun aptJarDependencies(project: Project) = aptDependencies[project.name].map { dependencyManager.create(it) }
val apDep = dependencyManager.create("net.thauvin.erik.:semver:0.9.6-beta")
val apDep2 = FileDependency(homeDir("t/semver-example-kotlin/lib/semver-0.9.7.jar"))
return listOf(apDep2)
}
fun allDependencies(): List<IClasspathDependency> { fun allDependencies(project: Project): List<IClasspathDependency> {
val allDeps = listOf(annotationProcessorDependency()) + aptJarDependencies() val allDeps = arrayListOf<IClasspathDependency>()
allDeps.add(annotationProcessorDependency())
allDeps.addAll(aptJarDependencies(project))
return allDeps return allDeps
} }
@ -161,30 +158,42 @@ class AptPlugin @Inject constructor(val dependencyManager: DependencyManager, va
fun taskRunKapt(project: Project) : TaskResult { fun taskRunKapt(project: Project) : TaskResult {
var success = true var success = true
val flags = arrayListOf<String>() val flags = arrayListOf<String>()
val kaptConfig = kaptConfigs[project.name]
kaptConfig?.let { config -> kaptConfig?.let { config ->
val generated = kaptGenerated(project, config.outputDir)
val generatedSources = kaptSourcesDir(project, config.outputDir).replace("//", "/")
val generated = generated(project, context, config.outputDir)
val generatedSources = generatedSources(project, context, config.outputDir).replace("//", "/")
File(generatedSources).mkdirs() File(generatedSources).mkdirs()
// //
// Tell the Kotlin compiler to use the annotation plug-in // Tell the Kotlin compiler to use the annotation plug-in
// //
val allDeps = allDependencies()
flags.add("-Xplugin") flags.add("-Xplugin")
flags.add(annotationProcessorDependency().jarFile.get().absolutePath) flags.add(annotationProcessorDependency().jarFile.get().absolutePath)
flags.add("-P")
// Also need tools.jar on the plug-in classpath
val toolsJar = jvm.toolsJar
if (toolsJar != null) {
flags.add("-Xplugin")
flags.add(toolsJar.absolutePath)
} else {
warn("Couldn't find tools.jar from the JDK")
}
aptJarDependencies(project).forEach {
flags.add("-Xplugin")
flags.add(it.jarFile.get().absolutePath)
}
// //
// Pass options to the annotation plugin // Pass options to the annotation plugin
// //
flags.add("-P")
fun kaptPluginFlag(flagValue: String) = "plugin:org.jetbrains.kotlin.kapt3:$flagValue" fun kaptPluginFlag(flagValue: String) = "plugin:org.jetbrains.kotlin.kapt3:$flagValue"
val kaptPluginFlags = arrayListOf<String>() val kaptPluginFlags = arrayListOf<String>()
val verbose = KobaltLogger.LOG_LEVEL >= 2 val verbose = KobaltLogger.LOG_LEVEL >= 2
listOf("sources=" + generatedSources, listOf("sources=" + generatedSources,
"classes=" + generatedClasses(project, context, config.outputDir), "classes=" + kaptClassesDir(project, config.outputDir),
"stubs=" + generatedStubs(project, context, config.outputDir), "stubs=" + kaptStubsDir(project, config.outputDir),
"verbose=$verbose", "verbose=$verbose",
"aptOnly=true").forEach { "aptOnly=true").forEach {
kaptPluginFlags.add(kaptPluginFlag(it)) kaptPluginFlags.add(kaptPluginFlag(it))
@ -193,17 +202,18 @@ class AptPlugin @Inject constructor(val dependencyManager: DependencyManager, va
// //
// Dependencies for the annotation plug-in and the generation // Dependencies for the annotation plug-in and the generation
// //
val allDeps = allDependencies(project)
val dependencies = dependencyManager.calculateDependencies(project, context, val dependencies = dependencyManager.calculateDependencies(project, context,
Filters.EXCLUDE_OPTIONAL_FILTER, Filters.EXCLUDE_OPTIONAL_FILTER,
listOf(Scope.COMPILE), listOf(Scope.COMPILE),
allDeps) allDeps)
dependencies.forEach { dependencies.forEach {
val jarFile = it.jarFile.get() val jarFile = it.jarFile.get().absolutePath
kaptPluginFlags.add(kaptPluginFlag("apclasspath=$jarFile")) kaptPluginFlags.add(kaptPluginFlag("apclasspath=$jarFile"))
} }
flags.add(kaptPluginFlags.joinToString(",")) flags.add(kaptPluginFlags.joinToString(","))
listOf("-language-version", "1.1", " -api-version", "1.1").forEach { listOf("-language-version", "1.1", "-api-version", "1.1").forEach {
flags.add(it) flags.add(it)
} }
@ -212,8 +222,9 @@ class AptPlugin @Inject constructor(val dependencyManager: DependencyManager, va
.toList() + generatedSources .toList() + generatedSources
val buildDirectory = File(KFiles.joinDir(project.directory, generated)) val buildDirectory = File(KFiles.joinDir(project.directory, generated))
val cai = CompilerActionInfo(project.directory, allDeps, sourceFiles, listOf(".kt"), val cai = CompilerActionInfo(project.directory, allDeps, sourceFiles, listOf(".kt"),
buildDirectory, flags, emptyList(), forceRecompile = true) buildDirectory, flags, emptyList(), forceRecompile = true, compilerSeparateProcess = true)
context.logger.log(project.name, 2, "kapt3 flags:")
context.logger.log(project.name, 2, " " + kaptPluginFlags.joinToString("\n ")) context.logger.log(project.name, 2, " " + kaptPluginFlags.joinToString("\n "))
val cr = compilerUtils.invokeCompiler(project, context, kotlinPlugin.compiler, cai) val cr = compilerUtils.invokeCompiler(project, context, kotlinPlugin.compiler, cai)
success = cr.failedResult == null success = cr.failedResult == null
@ -233,7 +244,10 @@ class AptPlugin @Inject constructor(val dependencyManager: DependencyManager, va
fun addFlags(outputDir: String) { fun addFlags(outputDir: String) {
aptDependencies[project.name]?.let { aptDependencies[project.name]?.let {
result.add("-s") result.add("-s")
result.add(generatedSources(project, context, outputDir)) aptGeneratedDir(project, outputDir).let { generatedSource ->
generatedSource.mkdirs()
result.add(generatedSource.path)
}
} }
} }

View file

@ -1,7 +1,6 @@
package com.beust.kobalt.plugin.java package com.beust.kobalt.plugin.java
import com.beust.kobalt.JavaInfo import com.beust.kobalt.Jvm
import com.beust.kobalt.SystemProperties
import com.beust.kobalt.TaskResult import com.beust.kobalt.TaskResult
import com.beust.kobalt.api.* import com.beust.kobalt.api.*
import com.beust.kobalt.internal.CompilerUtils import com.beust.kobalt.internal.CompilerUtils
@ -22,7 +21,7 @@ import javax.tools.ToolProvider
@Singleton @Singleton
class JavaCompiler @Inject constructor(val jvmCompiler: JvmCompiler, val kobaltLog: ParallelLogger, class JavaCompiler @Inject constructor(val jvmCompiler: JvmCompiler, val kobaltLog: ParallelLogger,
val compilerUtils: CompilerUtils) : ICompiler { val compilerUtils: CompilerUtils, val jvm: Jvm) : ICompiler {
fun compilerAction(executable: File) = object : ICompilerAction { fun compilerAction(executable: File) = object : ICompilerAction {
override fun compile(project: Project?, info: CompilerActionInfo): TaskResult { override fun compile(project: Project?, info: CompilerActionInfo): TaskResult {
val projectName = project?.name val projectName = project?.name
@ -84,7 +83,7 @@ class JavaCompiler @Inject constructor(val jvmCompiler: JvmCompiler, val kobaltL
val pb = ProcessBuilder(executable.absolutePath, "@" + KFiles.fixSlashes(atFile)) val pb = ProcessBuilder(executable.absolutePath, "@" + KFiles.fixSlashes(atFile))
pb.inheritIO() pb.inheritIO()
logk(1, " Java compiling " + Strings.pluralizeAll(info.sourceFiles.size, "file")) logk(1, " Java compiling " + Strings.pluralizeAll(info.sourceFiles.size, "file"))
logk(2, " Java compiling file: " + KFiles.fixSlashes(atFile)) logk(2, " Java compiling using file: " + KFiles.fixSlashes(atFile))
command = allArgs.joinToString(" ") + " " + info.sourceFiles.joinToString(" ") command = allArgs.joinToString(" ") + " " + info.sourceFiles.joinToString(" ")
val process = pb.start() val process = pb.start()
@ -119,7 +118,7 @@ class JavaCompiler @Inject constructor(val jvmCompiler: JvmCompiler, val kobaltL
-> it.compilerFlagsFor(project, context, currentFlags, suffixesBeingCompiled) } -> it.compilerFlagsFor(project, context, currentFlags, suffixesBeingCompiled) }
FlagContributor(it.flagPriority, closure) FlagContributor(it.flagPriority, closure)
} }
return run(project, context, info, JavaInfo.create(File(SystemProperties.javaBase)).javacExecutable!!, return run(project, context, info, jvm.javacExecutable!!,
compilerUtils.compilerFlags(project, context, info, adapters)) compilerUtils.compilerFlags(project, context, info, adapters))
} }
@ -130,7 +129,7 @@ class JavaCompiler @Inject constructor(val jvmCompiler: JvmCompiler, val kobaltL
-> it.docFlagsFor(project, context, currentFlags, suffixesBeingCompiled) } -> it.docFlagsFor(project, context, currentFlags, suffixesBeingCompiled) }
FlagContributor(it.flagPriority, closure) FlagContributor(it.flagPriority, closure)
} }
return run(project, context, info, JavaInfo.create(File(SystemProperties.javaBase)).javadocExecutable!!, return run(project, context, info, jvm.javadocExecutable!!,
compilerUtils.compilerFlags(project, context, info, adapters)) compilerUtils.compilerFlags(project, context, info, adapters))
} }
} }

View file

@ -44,9 +44,18 @@ class JavaPlugin @Inject constructor(val javaCompiler: JavaCompiler, override va
// IDocFlagContributor // IDocFlagContributor
override fun docFlagsFor(project: Project, context: KobaltContext, currentFlags: List<String>, override fun docFlagsFor(project: Project, context: KobaltContext, currentFlags: List<String>,
suffixesBeingCompiled: List<String>): List<String> { suffixesBeingCompiled: List<String>): List<String> {
return listOf("-d", "javadoc", "-Xdoclint:none", "-Xmaxerrs", "1", "-quiet") val config = javadocConfigurations[project.name]
return if (config == null || config.args.isEmpty()) DEFAULT_JAVADOC_ARGS
else config.args
} }
val DEFAULT_JAVADOC_ARGS = listOf("-d", "javadoc", "-Xdoclint:none", "-Xmaxerrs", "1", "-quiet")
val javadocConfigurations = hashMapOf<String, JavadocConfig>()
fun addJavadocConfiguration(project: Project, configuration: JavadocConfig)
= javadocConfigurations.put(project.name, configuration)
// ICompilerContributor // ICompilerContributor
val compiler = CompilerDescription(PLUGIN_NAME, "java", SOURCE_SUFFIXES, javaCompiler) val compiler = CompilerDescription(PLUGIN_NAME, "java", SOURCE_SUFFIXES, javaCompiler)
@ -78,3 +87,11 @@ fun Project.javaCompiler(init: JavaConfig.() -> Unit) =
config.init() config.init()
(Kobalt.findPlugin(JavaPlugin.PLUGIN_NAME) as JavaPlugin).addConfiguration(this, config) (Kobalt.findPlugin(JavaPlugin.PLUGIN_NAME) as JavaPlugin).addConfiguration(this, config)
} }
@Directive
fun Project.javadoc(init: JavadocConfig.() -> Unit) =
JavadocConfig(this).also { config ->
config.init()
(Kobalt.findPlugin(JavaPlugin.PLUGIN_NAME) as JavaPlugin).addJavadocConfiguration(this, config)
}

View file

@ -0,0 +1,603 @@
package com.beust.kobalt.plugin.java
import com.beust.kobalt.api.Project
import com.google.inject.Singleton
import java.io.BufferedReader
import java.io.File
import java.io.InputStream
import java.io.InputStreamReader
import java.util.concurrent.TimeUnit
@Singleton
class JavadocConfig(val project: Project) {
val args = arrayListOf("-Xdoclint:none", "-Xmaxerrs", "1", "-quiet")
private fun removeArg(match: String, startsWith: Boolean = false, pair: Boolean = false) {
val it = args.iterator()
while (it.hasNext()) {
val next = it.next()
var removed = false
if (startsWith) {
if (next.startsWith(match)) {
it.remove()
removed = true
}
} else if (next == match) {
it.remove()
removed = true
}
// If it's a pair, delete the next arg too.
if (pair && removed && it.hasNext()) {
it.next()
it.remove()
}
}
}
private fun addInt(option: String, value: Int): Int {
args.add("-$option")
args.add(value.toString())
return value
}
private fun addBoolean(option: String, value: Boolean): Boolean {
args.remove("-$option")
if (value) {
args.add("-$option")
}
return value
}
private fun addString(option: String, value: String): String {
if (value.isNotEmpty()) {
args.add("-$option")
args.add("\"$value\"")
}
return value
}
private fun addStrings(option: String, vararg value: String) {
value.forEach {
addString(option, it)
}
}
private fun addPair(option: String, first: String, second: String) {
if (first.isNotEmpty() && second.isNotEmpty()) {
args.add("-$option")
args.add("\"$first\"")
args.add("\"$second\"")
}
}
private fun addFile(option: String, value: String): String {
val f = File(value)
if (f.exists()) {
args.add("-$option")
args.add("\"${f.absolutePath}\"")
}
return value
}
/**
* Set arguments manually.
*/
fun args(vararg options: String) = args.addAll(options)
//
// Jvm Options
//
/**
* @see <a href="https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javac.html">-Xdoclint</a>
*/
var docLint: String = "none"
set(value) {
removeArg("-Xdoclint:", startsWith = true)
addString("Xdoclint:", value)
}
/**
* @see <a href="https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javac.html">-Xmaxerrs</a>
*/
var maxErrs: Int = 1
set(value) {
removeArg("-Xmaxerrs", startsWith = true, pair = true)
addInt("Xmaxerrs", value)
}
/**
* @see <a href="https://docs.oracle.com/javase/8/docs/technotes/tools/unix/javac.html">-Xmaxwarns</a>
*/
var maxWarns: Int = 1
set(value) {
removeArg("-Xmaxwarns", startsWith = true, pair = true)
addInt("Xmaxwarns", value)
}
//
// Javadoc Options
//
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#BEJICGGH">-overview</a>
*/
var overview: String = ""
set(value) {
addFile("overview", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDCHFEB">-public</a>
*/
var public: Boolean = false
set(value) {
addBoolean("public", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDCIFFD">-protected</a>
*/
var protected: Boolean = false
set(value) {
addBoolean("protected", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDEDJJJ">-pakage</a>
*/
var pkg: Boolean = false
set(value) {
addBoolean("package", pkg)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDJDFJG">-private</a>
*/
var private: Boolean = false
set(value) {
addBoolean("private", private)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDCGDCA">-doclet</a>
*/
var doclet: String = ""
set(value) {
addString("doclet", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDBGIED">-docletpath</a>
*/
var docletPath: String = ""
set(value) {
addString("docletpath", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDBGDFI">-source</a>
*/
var source: String = ""
set(value) {
addString("source", source)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDEHCDG">-sourcepath</a>
*/
var sourcePath: String = ""
set(value) {
addString("sourcepath", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDGAHAJ">-classpath</a>
*/
var classPath: String = ""
set(value) {
addString("classpath", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDJEDJI">-subpackages</a>
*/
var subPackages: String = ""
set(value) {
addString("subpackages", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDFBDCF">-exclude</a>
*/
var exclude: String = ""
set(value) {
addString("exclude", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDHDACA">-bootClassPath</a>
*/
var bootClassPath: String = ""
set(value) {
addString("bootclasspath", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDCJGIC">-extdirs</a>
*/
var extDirs: String = ""
set(value) {
addString("extdirs", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDGHFJJ">-verbose</a>
*/
var verbose: Boolean = false
set(value) {
addBoolean("verbose", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDGFHAA">-quiet</a>
*/
var quiet: Boolean = true
set(value) {
addBoolean("quiet", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDHHIDI">-breakiterator</a>
*/
var breakIterator: Boolean = false
set(value) {
addBoolean("breakiterator", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDEBGCE">-locale</a>
*/
var locale: String = ""
set(value) {
addString("locale", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDEIGDC">-encoding</a>
*/
var encoding: String = ""
set(value) {
addString("encoding", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDGDEEE">-Jflag</a>
*/
var jFlag: String = ""
set(value) {
addString("J-", value)
}
//
// Standard Doclet
//
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDGCJEG">-use</a>
*/
var use: Boolean = false
set(value) {
addBoolean("use", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDGCEFG">-version</a>
*/
var version: Boolean = false
set(value) {
addBoolean("version", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDCBHDB">-author</a>
*/
var author: Boolean = false
set(value) {
addBoolean("author", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDFGBHB">-splitindex</a>
*/
var splitIndex: Boolean = false
set(value) {
addBoolean("splitindex", value)
}
/**
* Set both the [windowTitle] and [docTitle]
*/
var title: String = ""
set(value) {
windowTitle = value
docTitle = value
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDBIEEI">-windowtitle</a>
*/
var windowTitle: String = ""
set(value) {
addString("windowtitle", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDJGBIE">-doctitle</a>
*/
var docTitle: String = ""
set(value) {
addString("doctitle", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDDAEGD">-header</a>
*/
var header: String = ""
set(value) {
addString("header", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDFACCA">-footer</a>
*/
var footer: String = ""
set(value) {
addString("footer", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDHHGBF">-top</a>
*/
var top: String = ""
set(value) {
addString("top", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDECAJE">-bottom</a>
*/
var bottom: String = ""
set(value) {
addString("bottom", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDFBBID">-linksource</a>
*/
var linkSource: Boolean = false
set(value) {
addBoolean("linksource", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDCDFGD">-nodeprecated</a>
*/
var noDeprecated: Boolean = false
set(value) {
addBoolean("nodeprecated", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDGFHJJ">-nodeprecatedlist</a>
*/
var noDeprecatedList: Boolean = false
set(value) {
addBoolean("nodeprecatedlist", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDFICFB">-nosince</a>
*/
var noSince: Boolean = false
set(value) {
addBoolean("nosince", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDBGJBI">-notree</a>
*/
var noTree: Boolean = false
set(value) {
addBoolean("notree", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDHHHEI">-noindex</a>
*/
var noIndex: Boolean = false
set(value) {
addBoolean("noindex", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDHHDBI">-nohelp</a>
*/
var noHelp: Boolean = false
set(value) {
addBoolean("nohelp", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDEDCCG">-nonavbar</a>
*/
var noNavBar: Boolean = false
set(value) {
addBoolean("nonavbar", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDJICID">-helpfile</a>
*/
var helpFile: String = ""
set(value) {
addFile("helpfile", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#BEJFCAIH">-stylesheet</a>
*/
var stylesheet: String = ""
set(value) {
addFile("stylesheet", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDFJAFC">-serialwarn</a>
*/
var serialWarn: Boolean = false
set(value) {
addBoolean("serialwarn", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDHDEAD">-charset</a>
*/
var charSet: String = ""
set(value) {
addString("charset", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDGIHCH">-docencoding</a>
*/
var docEncoding: String = ""
set(value) {
addString("docencoding", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDBHIGE">-keywords</a>
*/
var keywords: Boolean = false
set(value) {
addBoolean("keywords", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDJFHDG">-tagletpath</a>
*/
var tagletPath: String = ""
set(value) {
addString("tagletpath", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDCBDHI">-docfilessubdirs</a>
*/
var docFilesSubDirs: Boolean = false
set(value) {
addBoolean("docfilessubdirs", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDGHIAE">-excludedocfilessubdir</a>
*/
var excludeDocFilesSubDir: String = ""
set(value) {
addString("excludedocfilessubdir", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDFJFBE">-noqualifiers</a>
*/
var noQualifiers: String = ""
set(value) {
addString("noqualifier", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDGBABE">-notimestamp</a>
*/
var noTimestamp: Boolean = false
set(value) {
addBoolean("notimestamp", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDFCGJD">-nocomment</a>
*/
var noComment: Boolean = false
set(value) {
addBoolean("nocomment", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDIAGAG">-sourcetab</a>
*/
var sourceTab: String = ""
set(value) {
addString("sourcetab", value)
}
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDIGGII">-group</a>
*/
fun group(groupHeading: String, packagePattern: String) = addPair("group", groupHeading, packagePattern)
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDFIIJH">-linkoffline</a>
*/
fun linkOffline(extdocURL: String, packagelistLoc: String) = addPair("linkoffline", extdocURL, packagelistLoc)
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDEDJFI">-link</a>
*/
fun links(vararg links: String) = addStrings("link", *links)
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#tag">-tag</a>
*/
fun tags(vararg tags: String) = addStrings("tag", *tags)
/**
* @see <a href="http://docs.oracle.com/javase/8/docs/technotes/tools/windows/javadoc.html#CHDHEFHH">-taglets</a>
*/
fun taglets(vararg taglets: String) = addStrings("taglet", *taglets)
}
fun main(args: Array<String>) {
fun fromStream(ins: InputStream): List<String> {
val result = arrayListOf<String>()
val br = BufferedReader(InputStreamReader(ins))
var line = br.readLine()
while (line != null) {
result.add(line)
println(line)
line = br.readLine()
}
return result
}
val config = JavadocConfig(Project())
config.title = "This is a test."
config.verbose = true
config.quiet = false
config.links("http://docs.oracle.com/javase/8/docs/api/")
config.args.add(0, ".\\kobaltBuild\\docs\\javadoc")
config.args.add(0, "-d")
config.args.add(0, "javadoc")
config.args.add(".\\modules\\wrapper\\src\\main\\java\\com\\beust\\kobalt\\wrapper\\Config.java")
config.args.add(".\\modules\\wrapper\\src\\main\\java\\com\\beust\\kobalt\\wrapper\\Main.java")
println(config.args.joinToString(" "))
val pb = ProcessBuilder().command(config.args.toList())
pb.directory(File("."))
val proc = pb.start()
val err = proc.waitFor(30, TimeUnit.SECONDS)
val stdout = if (proc.inputStream.available() > 0) fromStream(proc.inputStream) else emptyList()
val stderr = if (proc.errorStream.available() > 0) fromStream(proc.errorStream) else emptyList()
}

View file

@ -8,10 +8,12 @@ import com.beust.kobalt.maven.dependency.FileDependency
import com.beust.kobalt.misc.* import com.beust.kobalt.misc.*
import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.Services import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.ICReporter import org.jetbrains.kotlin.incremental.ICReporter
import org.jetbrains.kotlin.incremental.makeIncrementally import org.jetbrains.kotlin.incremental.makeIncrementally
@ -35,7 +37,8 @@ class KotlinCompiler @Inject constructor(
val settings: KobaltSettings, val settings: KobaltSettings,
val jvmCompiler: JvmCompiler, val jvmCompiler: JvmCompiler,
val compilerUtils: CompilerUtils, val compilerUtils: CompilerUtils,
val kobaltLog: ParallelLogger) { val kobaltLog: ParallelLogger,
val jvm: Jvm) {
val compilerAction = object: ICompilerAction { val compilerAction = object: ICompilerAction {
override fun compile(project: Project?, info: CompilerActionInfo): TaskResult { override fun compile(project: Project?, info: CompilerActionInfo): TaskResult {
@ -71,35 +74,25 @@ class KotlinCompiler @Inject constructor(
File(outputDir).parentFile.mkdirs() File(outputDir).parentFile.mkdirs()
} }
val classpath = cp.joinToString(File.pathSeparator) val classpath = cp.joinToString(File.pathSeparator)
val allArgs = arrayListOf(
"-d", outputDir,
"-classpath", classpath,
*(info.compilerArgs.toTypedArray()),
*(info.sourceFiles.toTypedArray())
)
// Get rid of annoying and useless warning
if (! info.compilerArgs.contains("-no-stdlib")) {
allArgs.add("-no-stdlib")
}
// If the Kotlin compiler version in settings.xml is different from the default, we // If the Kotlin compiler version in settings.xml is different from the default, we
// need to spawn a Kotlin compiler in a separate process. Otherwise, we can just invoke // need to spawn a Kotlin compiler in a separate process. Otherwise, we can just invoke
// the K2JVMCompiler class directly // the K2JVMCompiler class directly
val actualVersion = kotlinVersion(project) val actualVersion = kotlinVersion(project)
if (settings.kobaltCompilerSeparateProcess || actualVersion != Constants.KOTLIN_COMPILER_VERSION) { return if (settings.kobaltCompilerSeparateProcess || actualVersion != Constants.KOTLIN_COMPILER_VERSION
return invokeCompilerInSeparateProcess(classpath, info, actualVersion, project) || info.compilerSeparateProcess) {
invokeCompilerInSeparateProcess(classpath, info, actualVersion, project)
} else { } else {
return invokeCompilerDirectly(project, projectName ?: "kobalt-" + Random().nextInt(), outputDir, invokeCompilerDirectly(project, projectName ?: "kobalt-" + Random().nextInt(), outputDir,
info, classpath, filesToCompile) info, classpath, filesToCompile)
} }
} }
private fun invokeCompilerInSeparateProcess(classpath: String, info: CompilerActionInfo, private fun invokeCompilerInSeparateProcess(classpath: String, info: CompilerActionInfo,
compilerVersion: String, project: Project?): TaskResult { compilerVersion: String, project: Project?): TaskResult {
val java = JavaInfo.create(File(SystemProperties.javaBase)).javaExecutable val java = jvm.javaExecutable
val compilerClasspath = compilerDep(compilerVersion).jarFile.get().path + File.pathSeparator + val compilerClasspath = compilerDep(compilerVersion).jarFile.get().path + File.pathSeparator +
compilerEmbeddableDependencies(null, compilerVersion).map { it.jarFile.get().path } compilerEmbeddableDependencies(null, compilerVersion).map { it.jarFile.get().path }
@ -109,24 +102,37 @@ class KotlinCompiler @Inject constructor(
.filterNotNull() .filterNotNull()
.joinToString(" ") .joinToString(" ")
val xFlagsArray = xFlagsString.split(" ").toTypedArray() ?: emptyArray() val infoDir = info.directory
val outputDir =
if (infoDir != null) {
KFiles.joinDir(infoDir, info.outputDir.path)
} else {
info.outputDir.path
}
val xFlagsArray = xFlagsString.split(" ").toTypedArray()
val newArgs = listOf( val newArgs = listOf(
"-classpath", compilerClasspath, "-classpath", compilerClasspath,
K2JVMCompiler::class.java.name, K2JVMCompiler::class.java.name,
*info.compilerArgs.toTypedArray(),
"-classpath", classpath, "-classpath", classpath,
"-d", info.outputDir.absolutePath, "-d", outputDir,
*xFlagsArray, *xFlagsArray,
*info.sourceFiles.toTypedArray()) *info.sourceFiles.toTypedArray())
.filter { ! it.isEmpty() } .filter { ! it.isEmpty() }
log(2, " Invoking separate kotlinc:\n " + java!!.absolutePath + " " + newArgs.joinToString()) log(2, " Invoking separate kotlinc:\n " + java!!.absolutePath + " " + newArgs.joinToString(" "))
val result = NewRunCommand(RunCommandInfo().apply { val result = NewRunCommand(RunCommandInfo().apply {
command = java.absolutePath command = java.absolutePath
args = newArgs args = newArgs
directory = File(".") directory = File(".")
// The Kotlin compiler issues warnings on stderr :-( // // The Kotlin compiler issues warnings on stderr :-(
containsErrors = { errors: List<String> -> errors.any { it.contains("rror")} } useErrorStreamAsErrorIndicator = false
// containsErrors = {
// errors: List<String> -> errors.any { it.contains("rror")}
// }
}).invoke() }).invoke()
return TaskResult(result == 0, errorMessage = "Error while compiling") return TaskResult(result == 0, errorMessage = "Error while compiling")
} }
@ -139,18 +145,17 @@ class KotlinCompiler @Inject constructor(
// Collect the compiler args from kotlinCompiler{} and from settings.xml and parse them // Collect the compiler args from kotlinCompiler{} and from settings.xml and parse them
val args2 = val args2 =
info.compilerArgs + info.compilerArgs +
(kotlinConfig(project)?.args ?: arrayListOf<String>()) + (settings.kobaltCompilerFlags?.split(" ") ?: listOf())
(settings.kobaltCompilerFlags?.split(" ") ?: listOf<String>())
val args = K2JVMCompilerArguments() val args = K2JVMCompilerArguments()
val compiler = K2JVMCompiler() val compiler = K2JVMCompiler()
compiler.parseArguments(args2.toTypedArray(), args) parseCommandLineArguments(args2, args)
// Override important arguments with our values // Override important arguments with our values
args.apply { args.apply {
moduleName = projectName moduleName = projectName
destination = outputDir destination = outputDir
classpath = classpathString classpath = classpathString
freeArgs = sourceFiles freeArgs = sourceFiles.toMutableList()
friendPaths = friends friendPaths = friends
} }
@ -174,12 +179,12 @@ class KotlinCompiler @Inject constructor(
"single-module" -> args.singleModule = true "single-module" -> args.singleModule = true
"load-builtins-from-dependencies" -> args.loadBuiltInsFromDependencies = true "load-builtins-from-dependencies" -> args.loadBuiltInsFromDependencies = true
"coroutines=enable" -> args.coroutinesEnable = true "coroutines=enable" -> args.coroutinesState = LanguageFeature.State.ENABLED.name
"coroutines=warn" -> args.coroutinesWarn = true "coroutines=warn" -> args.coroutinesState = LanguageFeature.State.ENABLED_WITH_WARNING.name
"coroutines=error" -> args.coroutinesError = true "coroutines=error" -> args.coroutinesState = LanguageFeature.State.ENABLED_WITH_ERROR.name
"no-inline" -> args.noInline = true "no-inline" -> args.noInline = true
"multi-platform" -> args.multiPlatform = true "multi-platform" -> args.multiPlatform = true
"no-check-impl" -> args.noCheckImpl = true // "no-check-impl" -> args.noCheckImpl = true
else -> warn("Unknown Kotlin compiler flag found in config.xml: $it") else -> warn("Unknown Kotlin compiler flag found in config.xml: $it")
} }
} }
@ -209,7 +214,7 @@ class KotlinCompiler @Inject constructor(
+ " " + sourceFiles.joinToString(" ")) + " " + sourceFiles.joinToString(" "))
logk(2, " Additional kotlinc arguments: " logk(2, " Additional kotlinc arguments: "
+ " -moduleName " + args.moduleName + " -moduleName " + args.moduleName
+ " -friendPaths " + args.friendPaths.joinToString(";")) + " -friendPaths " + args.friendPaths?.joinToString(";"))
val collector = object : MessageCollector { val collector = object : MessageCollector {
override fun clear() { override fun clear() {
throw UnsupportedOperationException("not implemented") throw UnsupportedOperationException("not implemented")
@ -220,7 +225,7 @@ class KotlinCompiler @Inject constructor(
} }
fun dump(location: CompilerMessageLocation?, s: String) = fun dump(location: CompilerMessageLocation?, s: String) =
if (location != null && location.lineContent != null) { if (location?.lineContent != null) {
with(location) { with(location) {
"$lineContent\n$path:$line:$column $s" "$lineContent\n$path:$line:$column $s"
} }
@ -228,11 +233,13 @@ class KotlinCompiler @Inject constructor(
s s
} }
override fun report(severity: CompilerMessageSeverity, override fun report(severity: CompilerMessageSeverity, message: String,
message: String, location: CompilerMessageLocation) { location: CompilerMessageLocation?) {
if (severity.isError) { if (severity.isError) {
"Couldn't compile file: ${dump(location, message)}".let { fullMessage -> "Couldn't compile file: ${dump(location, message)}".let { fullMessage ->
throw KobaltException(fullMessage) error(fullMessage)
val ex = KobaltException(fullMessage)
throw ex
} }
} else if (severity == CompilerMessageSeverity.WARNING && KobaltLogger.LOG_LEVEL >= 2) { } else if (severity == CompilerMessageSeverity.WARNING && KobaltLogger.LOG_LEVEL >= 2) {
warn(dump(location, message)) warn(dump(location, message))
@ -246,24 +253,22 @@ class KotlinCompiler @Inject constructor(
// // TODO: experimental should be removed as soon as it becomes standard // // TODO: experimental should be removed as soon as it becomes standard
// System.setProperty("kotlin.incremental.compilation.experimental", "true") // System.setProperty("kotlin.incremental.compilation.experimental", "true")
val result = return if (cliArgs.noIncrementalKotlin || Kobalt.context?.internalContext?.noIncrementalKotlin ?: false) {
if (cliArgs.noIncrementalKotlin || Kobalt.context?.internalContext?.noIncrementalKotlin ?: false) { log(2, " Kotlin incremental compilation is disabled")
log(2, " Kotlin incremental compilation is disabled") val duration = benchmarkMillis {
val duration = benchmarkMillis { compiler.exec(collector, Services.Builder().build(), args)
compiler.exec(collector, Services.Builder().build(), args) }
} log(1, " Regular compilation time: ${duration.first} ms")
log(1, " Regular compilation time: ${duration.first} ms") TaskResult(duration.second == ExitCode.OK)
TaskResult(duration.second == ExitCode.OK) } else {
} else { log(1, " Kotlin incremental compilation is enabled")
log(1, " Kotlin incremental compilation is enabled") //val start = System.currentTimeMillis()
val start = System.currentTimeMillis() val duration = benchmarkMillis {
val duration = benchmarkMillis { compileIncrementally(filesToCompile, sourceFiles, outputDir, info, args, collector)
compileIncrementally(filesToCompile, sourceFiles, outputDir, info, args, collector) }
} log(1, " Incremental compilation time: ${duration.first} ms")
log(1, " Incremental compilation time: ${duration.first} ms") TaskResult()
TaskResult() }
}
return result
} }
private fun compileIncrementally(filesToCompile: Int, sourceFiles: List<String>, outputDir: String?, private fun compileIncrementally(filesToCompile: Int, sourceFiles: List<String>, outputDir: String?,
@ -377,8 +382,7 @@ class KotlinCompiler @Inject constructor(
= dependencyManager.create("org.jetbrains" + ".kotlin:kotlin-compiler-embeddable:$version") = dependencyManager.create("org.jetbrains" + ".kotlin:kotlin-compiler-embeddable:$version")
fun compilerEmbeddableDependencies(project: Project?, version: String): List<IClasspathDependency> { fun compilerEmbeddableDependencies(project: Project?, version: String): List<IClasspathDependency> {
val deps = dependencyManager.transitiveClosure(listOf(compilerDep(version)), requiredBy = project?.name ?: "") return dependencyManager.transitiveClosure(listOf(compilerDep(version)), requiredBy = project?.name ?: "")
return deps
} }
/** /**
@ -387,7 +391,8 @@ class KotlinCompiler @Inject constructor(
* JvmCompilerPlugin#createCompilerActionInfo instead * JvmCompilerPlugin#createCompilerActionInfo instead
*/ */
fun compile(project: Project?, context: KobaltContext?, compileDependencies: List<IClasspathDependency>, fun compile(project: Project?, context: KobaltContext?, compileDependencies: List<IClasspathDependency>,
otherClasspath: List<String>, sourceFiles: List<String>, outputDir: File, args: List<String>) : TaskResult { otherClasspath: List<String>, sourceFiles: List<String>, outputDir: File, args: List<String>,
compilerSeparateProcess: Boolean) : TaskResult {
val executor = executors.newExecutor("KotlinCompiler", 10) val executor = executors.newExecutor("KotlinCompiler", 10)
@ -410,13 +415,15 @@ class KotlinCompiler @Inject constructor(
if (project != null) { if (project != null) {
listOf(KFiles.joinDir(project.directory, project.buildDirectory, KFiles.CLASSES_DIR)) listOf(KFiles.joinDir(project.directory, project.buildDirectory, KFiles.CLASSES_DIR))
} else { } else {
emptyList<String>() emptyList()
} }
val info = CompilerActionInfo(project?.directory, dependencies, sourceFiles, listOf("kt"), outputDir, args, val info = CompilerActionInfo(project?.directory, dependencies, sourceFiles, listOf("kt"), outputDir, args,
friendPaths, context?.internalContext?.forceRecompile ?: false) friendPaths, context?.internalContext?.forceRecompile ?: false, compilerSeparateProcess)
return jvmCompiler.doCompile(project, context, compilerAction, info, val compilerFlags =
if (context != null) compilerUtils.sourceCompilerFlags(project, context, info) else emptyList()) if (context != null) compilerUtils.sourceCompilerFlags(project, context, info)
else emptyList()
return jvmCompiler.doCompile(project, context, compilerAction, info, compilerFlags)
} }
} }
@ -427,6 +434,7 @@ class KConfiguration @Inject constructor(val compiler: KotlinCompiler){
var output: File by Delegates.notNull() var output: File by Delegates.notNull()
val args = arrayListOf<String>() val args = arrayListOf<String>()
var noIncrementalKotlin = false var noIncrementalKotlin = false
var compilerSeparateProcess = false
fun sourceFiles(s: String) = source.add(s) fun sourceFiles(s: String) = source.add(s)
@ -441,7 +449,8 @@ class KConfiguration @Inject constructor(val compiler: KotlinCompiler){
fun compile(project: Project? = null, context: KobaltContext? = null) : TaskResult { fun compile(project: Project? = null, context: KobaltContext? = null) : TaskResult {
val saved = context?.internalContext?.noIncrementalKotlin ?: false val saved = context?.internalContext?.noIncrementalKotlin ?: false
if (context != null) context.internalContext.noIncrementalKotlin = noIncrementalKotlin if (context != null) context.internalContext.noIncrementalKotlin = noIncrementalKotlin
val result = compiler.compile(project, context, dependencies, classpath, source, output, args) val result = compiler.compile(project, context, dependencies, classpath, source, output, args,
compilerSeparateProcess)
if (context != null) context.internalContext.noIncrementalKotlin = saved if (context != null) context.internalContext.noIncrementalKotlin = saved
return result return result
} }

View file

@ -83,6 +83,7 @@ class KotlinPlugin @Inject constructor(val executors: KobaltExecutors, val depen
sourceFiles(info.sourceFiles) sourceFiles(info.sourceFiles)
compilerArgs(info.compilerArgs) compilerArgs(info.compilerArgs)
output = info.outputDir output = info.outputDir
compilerSeparateProcess = info.compilerSeparateProcess
}.compile(project, context) }.compile(project, context)
} }
@ -98,9 +99,10 @@ class KotlinPlugin @Inject constructor(val executors: KobaltExecutors, val depen
// IClasspathContributor // IClasspathContributor
override fun classpathEntriesFor(project: Project?, context: KobaltContext): List<IClasspathDependency> = override fun classpathEntriesFor(project: Project?, context: KobaltContext): List<IClasspathDependency> =
if (project == null || accept(project)) { if (project == null ||
context.pluginInfo.plugins.any { it is KotlinPlugin && it.settings.kobaltCompilerVersion == null }) {
// All Kotlin projects automatically get the Kotlin runtime added to their class path // All Kotlin projects automatically get the Kotlin runtime added to their class path
listOf(kotlinJarFiles.stdlib, kotlinJarFiles.runtime) listOf(kotlinJarFiles.stdlib)
.map { FileDependency(it.absolutePath) } .map { FileDependency(it.absolutePath) }
} else { } else {
emptyList() emptyList()

View file

@ -0,0 +1,118 @@
package com.beust.kobalt.plugin.osgi
import aQute.bnd.osgi.Analyzer
import com.beust.kobalt.TaskResult
import com.beust.kobalt.api.*
import com.beust.kobalt.api.annotation.Directive
import com.beust.kobalt.archive.Archives
import com.beust.kobalt.archive.MetaArchive
import com.beust.kobalt.maven.DependencyManager
import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.plugin.packaging.PackagingPlugin
import com.google.common.reflect.ClassPath
import com.google.inject.Inject
import com.google.inject.Singleton
import java.io.ByteArrayOutputStream
import java.io.File
import java.net.URLClassLoader
import java.nio.file.*
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.jar.JarFile
/**
* Generate OSGi attributes in the MANIFEST.MF if an osgi{} directive was found in the project.
*/
@Singleton
class OsgiPlugin @Inject constructor(val configActor: ConfigActor<OsgiConfig>, val taskContributor: TaskContributor,
val dependencyManager: DependencyManager)
: BasePlugin(), ITaskContributor by taskContributor, IConfigActor<OsgiConfig> by configActor {
companion object {
const val PLUGIN_NAME = "Osgi"
}
override val name: String = PLUGIN_NAME
override fun apply(project: Project, context: KobaltContext) {
super.apply(project, context)
configurationFor(project)?.let { config ->
taskContributor.addTask(this, project, "generateOsgiManifest",
description = "Generate the OSGi information in the manifest",
group = "build",
alwaysRunAfter = listOf(PackagingPlugin.TASK_ASSEMBLE),
runTask = { generateManifest(project, context) })
}
}
private fun generateManifest(project: Project, context: KobaltContext): TaskResult {
val jarName = project.projectProperties.get(Archives.JAR_NAME) as String
val jarFile = File(KFiles.libsDir(project), jarName)
val cp = ClassPath.from(URLClassLoader(arrayOf(jarFile.toURI().toURL()), null))
val packages = cp.allClasses.map { it.packageName }.distinct()
val exportPackageLine = packages.map {
it + ";version=\"" + project.version + "\""
}.joinToString(",")
val toFile = Files.createTempFile(null, ".jar")
val analyzer = Analyzer().apply {
jar = aQute.bnd.osgi.Jar(jarName)
val dependencies = project.compileDependencies + project.compileRuntimeDependencies
dependencyManager.calculateDependencies(project, context, passedDependencies = dependencies).forEach {
addClasspath(it.jarFile.get())
}
setProperty("Build-Date", LocalDate.now().format(DateTimeFormatter.ofPattern("y-MM-dd")))
setProperty(Analyzer.BUNDLE_VERSION, project.version)
setProperty(Analyzer.BUNDLE_NAME, project.group + "." + project.artifactId)
setProperty(Analyzer.BUNDLE_DESCRIPTION, project.description)
setProperty(Analyzer.IMPORT_PACKAGE, "*")
setProperty(Analyzer.EXPORT_PACKAGE, exportPackageLine)
project.pom?.let { pom ->
if (pom.licenses.any()) {
setProperty(Analyzer.BUNDLE_LICENSE, pom.licenses[0].url)
}
}
}
analyzer.calcManifest().let { manifest ->
val lines2 = ByteArrayOutputStream().use { baos ->
manifest.write(baos)
String(baos.toByteArray())
}
context.logger.log(project.name, 2, " Generated manifest:\n$lines2")
//
// Update or create META-INF/MANIFEST.MF
//
KFiles.copy(Paths.get(jarFile.toURI()), Paths.get(toFile.toUri()))
val fileSystem = FileSystems.newFileSystem(toFile, null)
fileSystem.use { fs ->
JarFile(jarFile).use { jf ->
val mf = jf.getEntry(MetaArchive.MANIFEST_MF)
if (mf == null) {
Files.createDirectories(fs.getPath("META-INF/"))
}
val jarManifest = fs.getPath(MetaArchive.MANIFEST_MF)
Files.write(jarManifest, listOf(lines2),
if (mf != null) StandardOpenOption.APPEND else StandardOpenOption.CREATE)
}
}
Files.copy(Paths.get(toFile.toUri()), Paths.get(jarFile.toURI()), StandardCopyOption.REPLACE_EXISTING)
return TaskResult()
}
}
}
class OsgiConfig
@Directive
fun Project.osgi(init: OsgiConfig.() -> Unit) {
OsgiConfig().let {
it.init()
(Kobalt.findPlugin(OsgiPlugin.PLUGIN_NAME) as OsgiPlugin).addConfiguration(this, it)
}
}

View file

@ -26,9 +26,9 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
val executors: KobaltExecutors, val jarGenerator: JarGenerator, val warGenerator: WarGenerator, val executors: KobaltExecutors, val jarGenerator: JarGenerator, val warGenerator: WarGenerator,
val zipGenerator: ZipGenerator, val taskContributor: TaskContributor, val zipGenerator: ZipGenerator, val taskContributor: TaskContributor,
val kobaltLog: ParallelLogger, val kobaltLog: ParallelLogger,
val pomFactory: PomGenerator.IFactory, val configActor: ConfigActor<InstallConfig>) val pomFactory: PomGenerator.IFactory, val configActor: ConfigsActor<InstallConfig>)
: BasePlugin(), ITaskContributor, IIncrementalAssemblyContributor, : BasePlugin(), ITaskContributor by taskContributor, IIncrementalAssemblyContributor,
IConfigActor<InstallConfig> by configActor { IConfigsActor<InstallConfig> by configActor {
companion object { companion object {
const val PLUGIN_NAME = "Packaging" const val PLUGIN_NAME = "Packaging"
@ -41,7 +41,6 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
const val PACKAGES = "packages" const val PACKAGES = "packages"
const val TASK_ASSEMBLE: String = "assemble" const val TASK_ASSEMBLE: String = "assemble"
const val TASK_INSTALL: String = "install"
} }
override val name = PLUGIN_NAME override val name = PLUGIN_NAME
@ -56,9 +55,20 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
taskContributor.addVariantTasks(this, project, context, "assemble", group = "build", taskContributor.addVariantTasks(this, project, context, "assemble", group = "build",
dependsOn = listOf("compile"), dependsOn = listOf("compile"),
runTask = { doTaskAssemble(project) }) runTask = { doTaskAssemble(project) })
taskContributor.addVariantTasks(this, project, context, "install",
dependsOn = listOf("assemble"), configurationFor(project)?.let { configs ->
runTask = { taskInstall(project) }) configs.forEach { config ->
taskContributor.addTask(this, project, config.taskName,
description = "Install to \"" + config.target + "\"",
group = "build",
dependsOn = listOf(PackagingPlugin.TASK_ASSEMBLE),
runTask = { taskInstall(project, context, config) })
taskContributor.addVariantTasks(this, project, context, config.taskName,
dependsOn = listOf("assemble"),
runTask = { taskInstall(project, context, config) })
}
}
} }
override fun assemble(project: Project, context: KobaltContext) : IncrementalTaskInfo { override fun assemble(project: Project, context: KobaltContext) : IncrementalTaskInfo {
@ -95,7 +105,7 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
val outputFile = jarGenerator.fullArchiveName(project, context, it.name) val outputFile = jarGenerator.fullArchiveName(project, context, it.name)
outputFiles.add(outputFile) outputFiles.add(outputFile)
allIncludedFiles.addAll(files) allIncludedFiles.addAll(files)
zipToFiles[it.name] = files zipToFiles[outputFile.name] = files
} }
} }
} }
@ -138,9 +148,7 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
Pair(packageConfig.zips, zipGenerator) Pair(packageConfig.zips, zipGenerator)
) )
pairs.forEach { pair -> pairs.forEach { (zips, generator) ->
val zips = pair.first
val generator = pair.second
zips.forEach { zips.forEach {
generator.generateArchive(packageConfig.project, context, it, generator.generateArchive(packageConfig.project, context, it,
findFiles(generator, it)) findFiles(generator, it))
@ -186,31 +194,7 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
packages.add(p) packages.add(p)
} }
// @Task(name = "generateOsgiManifest", alwaysRunAfter = arrayOf(TASK_ASSEMBLE)) private fun taskInstall(project: Project, context: KobaltContext, config: InstallConfig) : TaskResult {
// fun generateManifest(project: Project): TaskResult {
// val analyzer = Analyzer().apply {
// jar = aQute.bnd.osgi.Jar(project.projectProperties.get(Archives.JAR_NAME) as String)
// val dependencies = project.compileDependencies + project.compileRuntimeDependencies
// dependencyManager.calculateDependencies(project, context, passedDependencies = dependencies).forEach {
// addClasspath(it.jarFile.get())
// }
// setProperty(Analyzer.BUNDLE_VERSION, project.version)
// setProperty(Analyzer.BUNDLE_NAME, project.group)
// setProperty(Analyzer.BUNDLE_DESCRIPTION, project.description)
// setProperty(Analyzer.IMPORT_PACKAGE, "*")
// setProperty(Analyzer.EXPORT_PACKAGE, "*;-noimport:=false;version=" + project.version)
// }
//
// val manifest = analyzer.calcManifest()
// manifest.write(System.out)
// return TaskResult()
// }
@Task(name = PackagingPlugin.TASK_INSTALL, description = "Install the artifacts",
dependsOn = arrayOf(PackagingPlugin.TASK_ASSEMBLE))
fun taskInstall(project: Project) : TaskResult {
val config = configurationFor(project) ?: InstallConfig()
val buildDir = project.projectProperties.getString(LIBS_DIR) val buildDir = project.projectProperties.getString(LIBS_DIR)
val buildDirFile = File(buildDir) val buildDirFile = File(buildDir)
if (buildDirFile.exists()) { if (buildDirFile.exists()) {
@ -241,9 +225,6 @@ class PackagingPlugin @Inject constructor(val dependencyManager : DependencyMana
return TaskResult() return TaskResult()
} }
//ITaskContributor
override fun tasksFor(project: Project, context: KobaltContext): List<DynamicTask> = taskContributor.dynamicTasks
} }
@Directive @Directive
@ -254,7 +235,7 @@ fun Project.install(init: InstallConfig.() -> Unit) {
} }
} }
class InstallConfig(var target : String = "libs") : IncludeFromTo() class InstallConfig(var target : String = "libs", var taskName : String = "install") : IncludeFromTo()
@Directive @Directive
fun Project.assemble(init: PackageConfig.(p: Project) -> Unit): PackageConfig = let { fun Project.assemble(init: PackageConfig.(p: Project) -> Unit): PackageConfig = let {

View file

@ -15,6 +15,7 @@ import com.google.gson.Gson
import com.google.gson.JsonArray import com.google.gson.JsonArray
import com.google.gson.JsonObject import com.google.gson.JsonObject
import com.google.gson.TypeAdapter import com.google.gson.TypeAdapter
import com.google.gson.annotations.SerializedName
import com.google.gson.reflect.TypeToken import com.google.gson.reflect.TypeToken
import com.google.inject.assistedinject.Assisted import com.google.inject.assistedinject.Assisted
import okhttp3.* import okhttp3.*
@ -62,7 +63,7 @@ class BintrayApi @Inject constructor(val http: Http,
@Path("publish") publish: Int, @Path("publish") publish: Int,
@Body file: File): Call<BintrayResponse> @Body file: File): Call<BintrayResponse>
class UpdateVersion(val desc: String?, val vcsTag: String?) class UpdateVersion(val desc: String?, @SerializedName("vcs_tag") val vcsTag: String?)
@PATCH("/packages/{owner}/maven/{repo}/versions/{version}") @PATCH("/packages/{owner}/maven/{repo}/versions/{version}")
fun updateVersion(@Path("owner") owner: String, fun updateVersion(@Path("owner") owner: String,
@ -79,12 +80,12 @@ class BintrayApi @Inject constructor(val http: Http,
// level = HttpLoggingInterceptor.Level.BASIC // level = HttpLoggingInterceptor.Level.BASIC
// }) // })
builder.interceptors().add(Interceptor { chain -> builder.interceptors().add(Interceptor { chain ->
val original = chain.request(); val original = chain.request()
chain.proceed(original.newBuilder() chain.proceed(original.newBuilder()
.header("Authorization", Credentials.basic(username, password)) .header("Authorization", Credentials.basic(username, password))
.method(original.method(), original.body()) .method(original.method(), original.body())
.build()); .build())
}) })
val okHttpClient = builder.build() val okHttpClient = builder.build()
@ -96,25 +97,29 @@ class BintrayApi @Inject constructor(val http: Http,
.create(Api::class.java) .create(Api::class.java)
} }
fun validatePackage(project: Project) { fun validatePackage(project: Project, config: BintrayConfig) {
val execute = service.getPackage(org ?: username!!, project.name).execute() val pkgName = config.name ?: project.name
val execute = service.getPackage(org ?: username!!, pkgName).execute()
if (execute.errorBody()?.string()?.contains("'${project.name}' was not found") ?: false) { if (execute.errorBody()?.string()?.contains("'$pkgName' was not found") == true) {
warn("Package does not exist on bintray. Creating now.") warn("Package does not exist on bintray. Creating now.")
val result = service.createPackage(org ?: username!!, buildPackageInfo(project)) val result = service.createPackage(org ?: username!!, buildPackageInfo(project, config))
.execute() .execute()
if (result.errorBody() != null) { if (result.errorBody() != null) {
throw KobaltException("Error while creating package:\n" + result.errorBody().string()) throw KobaltException("Error while creating package:\n" + result.errorBody()!!.string())
} }
} }
} }
private fun buildPackageInfo(project: Project): JsonObject { private fun buildPackageInfo(project: Project, config: BintrayConfig): JsonObject {
val jsonObject = JsonObject() val jsonObject = JsonObject().apply {
jsonObject.addNonNull("name", project.name) addNonNull("name", config.name ?: project.name)
jsonObject.addNonNull("desc", project.description) addNonNull("desc",
jsonObject.addNonNull("vcs_url", project.pom?.scm?.url) if (project.description.isNotBlank()) project.description else project.pom?.description)
jsonObject.addNonNull("website_url", project.url) addNonNull("vcs_url", project.pom?.scm?.url)
addNonNull("website_url", project.url ?: project.pom?.url)
addNonNull("issue_tracker_url", config.issueTrackerUrl)
}
val licenses = JsonArray() val licenses = JsonArray()
project.pom?.licenses?.forEach { project.pom?.licenses?.forEach {
licenses.add(it.name) licenses.add(it.name)
@ -124,7 +129,7 @@ class BintrayApi @Inject constructor(val http: Http,
} }
fun uploadMaven(project: Project, files: List<File>, config: BintrayConfig): TaskResult { fun uploadMaven(project: Project, files: List<File>, config: BintrayConfig): TaskResult {
validatePackage(project) validatePackage(project, config)
return upload(project, files, config, generateMd5 = true) return upload(project, files, config, generateMd5 = true)
} }
@ -158,13 +163,13 @@ class BintrayApi @Inject constructor(val http: Http,
fun dots(total: Int, list: List<Boolean>, file: File? = null): String { fun dots(total: Int, list: List<Boolean>, file: File? = null): String {
val spaces: String = Array(total - list.size, { " " }).joinToString("") val spaces: String = Array(total - list.size, { " " }).joinToString("")
return "|" + list.map { if (it) "." else "X" }.joinToString("") + spaces + return "|" + list.joinToString("") { if (it) "." else "X" } + spaces +
(if (file != null) "| [ $file ]" else "|") (if (file != null) "| [ $file ]" else "|")
} }
val results = arrayListOf<Boolean>() val results = arrayListOf<Boolean>()
val owner = org ?: username!! val owner = org ?: username!!
val repo = project.name val repo = config.name ?: project.name
val group = project.group!!.replace('.', '/') val group = project.group!!.replace('.', '/')
val artifact = project.artifactId!! val artifact = project.artifactId!!
val version = project.version!! val version = project.version!!
@ -203,7 +208,7 @@ class BintrayApi @Inject constructor(val http: Http,
return TaskResult() return TaskResult()
} else { } else {
error(" Errors while uploading:\n" + errorMessages.map { " $it" }.joinToString("\n")) error(" Errors while uploading:\n" + errorMessages.joinToString("\n") { " $it" })
return TaskResult(false, errorMessage = errorMessages.joinToString("\n")) return TaskResult(false, errorMessage = errorMessages.joinToString("\n"))
} }
} else { } else {
@ -216,7 +221,7 @@ class BintrayApi @Inject constructor(val http: Http,
fun JsonObject.addNonNull(name: String, value: String?) { fun JsonObject.addNonNull(name: String, value: String?) {
if (value != null) { if (value != null) {
addProperty(name, value); addProperty(name, value)
} }
} }
@ -231,20 +236,16 @@ class ConverterFactory : Converter.Factory() {
override fun requestBodyConverter(type: Type, parameterAnnotations: Array<out Annotation>, override fun requestBodyConverter(type: Type, parameterAnnotations: Array<out Annotation>,
methodAnnotations: Array<out Annotation>, methodAnnotations: Array<out Annotation>,
retrofit: Retrofit?): Converter<*, RequestBody>? { retrofit: Retrofit?): Converter<*, RequestBody>? {
val result = return if (type.typeName == File::class.java.name) FileBodyConverter()
if (type.typeName == File::class.java.name) FileBodyConverter() else GsonBodyConverter()
else GsonBodyConverter()
return result
} }
} }
class GsonResponseBodyConverter(private val gson: Gson, private val adapter: TypeAdapter<out Any>) : Converter<ResponseBody, Any> { class GsonResponseBodyConverter(private val gson: Gson, private val adapter: TypeAdapter<out Any>) : Converter<ResponseBody, Any> {
override fun convert(value: ResponseBody): Any { override fun convert(value: ResponseBody): Any {
val jsonReader = gson.newJsonReader(value.charStream()) val jsonReader = gson.newJsonReader(value.charStream())
try { value.use {
return adapter.read(jsonReader) return adapter.read(jsonReader)
} finally {
value.close()
} }
} }
} }

View file

@ -47,7 +47,7 @@ class PublishPlugin @Inject constructor(val files: KFiles, val factory: PomGener
private fun autoGitTag(project: Project, uploadResult: TaskResult, config: AutoGitTagConfig?) : TaskResult { private fun autoGitTag(project: Project, uploadResult: TaskResult, config: AutoGitTagConfig?) : TaskResult {
if (config != null) { if (config != null) {
with(config) { with(config) {
return git.maybeTagRelease(project, uploadResult, enabled, annotated, tag, message) return git.maybeTagRelease(project, uploadResult, enabled, annotated, push, tag, message)
} }
} else { } else {
return TaskResult() return TaskResult()
@ -117,7 +117,7 @@ class PublishPlugin @Inject constructor(val files: KFiles, val factory: PomGener
val docUrl = DocUrl.PUBLISH_PLUGIN_URL val docUrl = DocUrl.PUBLISH_PLUGIN_URL
val user = localProperties.get(PROPERTY_BINTRAY_USER, docUrl) val user = localProperties.get(PROPERTY_BINTRAY_USER, docUrl)
val password = localProperties.get(PROPERTY_BINTRAY_PASSWORD, docUrl) val password = localProperties.get(PROPERTY_BINTRAY_PASSWORD, docUrl)
val org = localProperties.getNoThrows(PROPERTY_BINTRAY_ORG, docUrl) val org = localProperties.getNoThrows(PROPERTY_BINTRAY_ORG)
val jcenter = bintrayFactory.create(user, password, org) val jcenter = bintrayFactory.create(user, password, org)
var success = false var success = false
@ -222,6 +222,9 @@ data class AutoGitTagConfig(val project: Project) {
@Directive @Directive
var annotated: Boolean = false var annotated: Boolean = false
@Directive
var push: Boolean = true
@Directive @Directive
var tag : String = project.version!! var tag : String = project.version!!
@ -268,9 +271,18 @@ data class BintrayConfig(val project: Project) {
files.add(Pair(filePath, url)) files.add(Pair(filePath, url))
} }
/**
* The package name on Bintray which is not always the project name.
*/
@Directive
var name: String? = null
@Directive @Directive
var description: String? = null var description: String? = null
@Directive
var issueTrackerUrl: String? = null
@Directive @Directive
var vcsTag: String? = null var vcsTag: String? = null
} }

View file

@ -15,6 +15,7 @@
<class-name>com.beust.kobalt.plugin.groovy.GroovyPlugin</class-name> <class-name>com.beust.kobalt.plugin.groovy.GroovyPlugin</class-name>
<class-name>com.beust.kobalt.internal.JvmCompilerPlugin</class-name> <class-name>com.beust.kobalt.internal.JvmCompilerPlugin</class-name>
<class-name>com.beust.kobalt.internal.BuildListeners</class-name> <class-name>com.beust.kobalt.internal.BuildListeners</class-name>
<class-name>com.beust.kobalt.plugin.osgi.OsgiPlugin</class-name>
<!-- These classes manage -init for Java and Kotlin --> <!-- These classes manage -init for Java and Kotlin -->
<class-name>com.beust.kobalt.app.Templates</class-name> <class-name>com.beust.kobalt.app.Templates</class-name>

View file

@ -1 +1 @@
kobalt.version=1.0.67 kobalt.version=1.0.122

View file

@ -1,12 +1,12 @@
<component name="libraryTable"> <component name="libraryTable">
<library name="KotlinJavaRuntime"> <library name="KotlinJavaRuntime">
<CLASSES> <CLASSES>
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-runtime.jar!/" /> <root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-stdlib.jar!/" />
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" /> <root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" />
</CLASSES> </CLASSES>
<JAVADOC /> <JAVADOC />
<SOURCES> <SOURCES>
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-runtime-sources.jar!/" /> <root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-stdlib-sources.jar!/" />
</SOURCES> </SOURCES>
</library> </library>
</component> </component>

View file

@ -9,6 +9,7 @@ import com.beust.kobalt.internal.KobaltPluginXml
import com.beust.kobalt.internal.PluginInfo import com.beust.kobalt.internal.PluginInfo
import com.beust.kobalt.internal.build.SingleFileBuildSources import com.beust.kobalt.internal.build.SingleFileBuildSources
import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.KobaltLogger
import com.beust.kobalt.misc.log import com.beust.kobalt.misc.log
import org.testng.annotations.BeforeClass import org.testng.annotations.BeforeClass
import org.testng.annotations.Guice import org.testng.annotations.Guice
@ -121,6 +122,9 @@ open class BaseTest(val compilerFactory: BuildFileCompiler.IFactory? = null) {
val main = Kobalt.INJECTOR.getInstance(Main::class.java) val main = Kobalt.INJECTOR.getInstance(Main::class.java)
val args = Args() val args = Args()
val jc = JCommander(args).apply { parse(*commandLine) } val jc = JCommander(args).apply { parse(*commandLine) }
KobaltLogger.setLogLevel(args)
args.buildFile = KFiles.fixSlashes(project.file.absolutePath) + "/kobalt/src/Build.kt" args.buildFile = KFiles.fixSlashes(project.file.absolutePath) + "/kobalt/src/Build.kt"
val result = Main.launchMain(main, jc, args, arrayOf("assemble")) val result = Main.launchMain(main, jc, args, arrayOf("assemble"))
return LaunchProjectResult(project, result) return LaunchProjectResult(project, result)

View file

@ -3,6 +3,7 @@ package com.beust.kobalt
import com.beust.kobalt.misc.KFiles import com.beust.kobalt.misc.KFiles
import com.beust.kobalt.misc.kobaltLog import com.beust.kobalt.misc.kobaltLog
import com.beust.kobalt.misc.warn import com.beust.kobalt.misc.warn
import org.assertj.core.api.Assertions.assertThat
import org.testng.annotations.Test import org.testng.annotations.Test
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
@ -38,6 +39,7 @@ class VerifyKobaltZipTest : KobaltTest() {
val stream = JarInputStream(FileInputStream(zipFilePath)) val stream = JarInputStream(FileInputStream(zipFilePath))
var entry = stream.nextEntry var entry = stream.nextEntry
while (entry != null) { while (entry != null) {
assertThat(entry.name).doesNotContain("\\")
if (! entry.name.startsWith(root)) { if (! entry.name.startsWith(root)) {
throw AssertionError("Entries in the zip file should be under the directory $root") throw AssertionError("Entries in the zip file should be under the directory $root")
} }
@ -65,7 +67,7 @@ class VerifyKobaltZipTest : KobaltTest() {
} else if (entry.name.endsWith("kobalt-wrapper.jar")) { } else if (entry.name.endsWith("kobalt-wrapper.jar")) {
val ins = zipFile.getInputStream(entry) val ins = zipFile.getInputStream(entry)
foundWrapperJar = true foundWrapperJar = true
assertExistence(ins, listOf("kobalt.properties")) assertExistence(ins, listOf("kobalt.properties", "com/beust/kobalt/wrapper/Main.class"))
} }
entry = stream.nextEntry entry = stream.nextEntry
} }

View file

@ -0,0 +1,58 @@
package com.beust.kobalt.internal
import com.beust.kobalt.BaseTest
import com.beust.kobalt.BuildFile
import com.beust.kobalt.ProjectFile
import com.beust.kobalt.ProjectInfo
import com.beust.kobalt.misc.KFiles
import org.assertj.core.api.Assertions.assertThat
import org.testng.annotations.Test
import java.io.File
class KotlinCompilerVersionTest : BaseTest() {
@Test
fun shouldCompileWithExternalKotlin() {
val projectInfo = ProjectInfo(
BuildFile(
listOf("com.beust.kobalt.plugin.packaging.*", "com.beust.kobalt.plugin.kotlin.kotlinCompiler"),
"""
kotlinCompiler {
version = "1.2.60"
}
assemble{ jar{} }
"""
),
listOf(
ProjectFile("src/main/kotlin/A.kt", "val a = Bob()"),
ProjectFile("src/main/kotlin/Bob.java", "class Bob { }")
)
)
val result = launchProject(projectInfo, arrayOf("assemble", "--log", "2"))
val project = result.projectDescription
val jarFile = File(KFiles.joinDir(project.file.absolutePath, "kobaltBuild/libs", project.name + "-"
+ project.version + ".jar"))
assertThat(jarFile).exists()
}
@Test
fun shouldFailWhenKotlinVersionDoesNotExist() {
val projectInfo = ProjectInfo(
BuildFile(
listOf("com.beust.kobalt.plugin.packaging.*", "com.beust.kobalt.plugin.kotlin.kotlinCompiler"),
"""
kotlinCompiler { version = "1.1.20" }
assemble{ jar{} }
"""
),
listOf(ProjectFile("src/main/kotlin/A.kt", "val a = \"foo\""))
)
val result = launchProject(projectInfo, arrayOf("assemble", "--log", "2"))
assertThat(result.result).isEqualTo(1)
}
}

View file

@ -1,5 +1,6 @@
package com.beust.kobalt.misc package com.beust.kobalt.misc
import com.beust.kobalt.Args
import com.beust.kobalt.BaseTest import com.beust.kobalt.BaseTest
import com.beust.kobalt.internal.KobaltSettings import com.beust.kobalt.internal.KobaltSettings
import com.beust.kobalt.internal.KobaltSettingsXml import com.beust.kobalt.internal.KobaltSettingsXml
@ -95,7 +96,7 @@ class MavenResolverTest : BaseTest() {
private fun resolve(id: String): List<ArtifactResult> { private fun resolve(id: String): List<ArtifactResult> {
val system = Booter.newRepositorySystem() val system = Booter.newRepositorySystem()
val session = Booter.newRepositorySystemSession(system, val session = Booter.newRepositorySystemSession(system,
localRepo.localRepo, KobaltSettings(KobaltSettingsXml()), EventBus()) localRepo.localRepo, KobaltSettings(KobaltSettingsXml()), Args(), EventBus())
val artifact = DefaultArtifact(id) val artifact = DefaultArtifact(id)
val collectRequest = CollectRequest().apply { val collectRequest = CollectRequest().apply {