build.gradle 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. /*
  2. * Licensed to Elasticsearch under one or more contributor
  3. * license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright
  5. * ownership. Elasticsearch licenses this file to you under
  6. * the Apache License, Version 2.0 (the "License"); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. import org.apache.tools.ant.taskdefs.condition.Os
  20. import org.elasticsearch.gradle.BuildPlugin
  21. import org.elasticsearch.gradle.EmptyDirTask
  22. import org.elasticsearch.gradle.LoggedExec
  23. import org.elasticsearch.gradle.MavenFilteringHack
  24. import org.elasticsearch.gradle.VersionProperties
  25. import org.elasticsearch.gradle.plugin.PluginBuildPlugin
  26. import java.nio.file.Files
  27. import java.nio.file.Path
  28. // need this so Zip/Tar tasks get basic defaults...
  29. apply plugin: 'base'
  30. // CopySpec does not make it easy to create an empty directory so we
  31. // create the directory that we want, and then point CopySpec to its
  32. // parent to copy to the root of the distribution
  33. ext.logsDir = new File(buildDir, 'logs-hack/logs')
  34. task createLogsDir(type: EmptyDirTask) {
  35. dir "${logsDir}"
  36. dirMode 0755
  37. }
  38. ext.pluginsDir= new File(buildDir, 'plugins-hack/plugins')
  39. task createPluginsDir(type: EmptyDirTask) {
  40. dir "${pluginsDir}"
  41. dirMode 0755
  42. }
  43. CopySpec archiveFiles(CopySpec modulesFiles, String distributionType, String platform, boolean oss, boolean jdk) {
  44. return copySpec {
  45. into("elasticsearch-${version}") {
  46. into('lib') {
  47. with libFiles(oss)
  48. }
  49. into('config') {
  50. dirMode 0750
  51. fileMode 0660
  52. with configFiles(distributionType, oss, jdk)
  53. }
  54. into('bin') {
  55. with binFiles(distributionType, oss, jdk)
  56. }
  57. if (jdk) {
  58. into('jdk') {
  59. with jdkFiles(platform)
  60. }
  61. }
  62. into('') {
  63. from {
  64. dirMode 0755
  65. logsDir.getParent()
  66. }
  67. }
  68. into('') {
  69. from {
  70. dirMode 0755
  71. pluginsDir.getParent()
  72. }
  73. }
  74. from(rootProject.projectDir) {
  75. include 'README.textile'
  76. }
  77. from(rootProject.file('licenses')) {
  78. include oss ? 'APACHE-LICENSE-2.0.txt' : 'ELASTIC-LICENSE.txt'
  79. rename { 'LICENSE.txt' }
  80. }
  81. with noticeFile(oss, jdk)
  82. into('modules') {
  83. with modulesFiles
  84. }
  85. }
  86. }
  87. }
  88. // common config across all zip/tar
  89. tasks.withType(AbstractArchiveTask) {
  90. dependsOn createLogsDir, createPluginsDir
  91. String subdir = it.name.substring('build'.size()).replaceAll(/[A-Z]/) { '-' + it.toLowerCase() }.substring(1)
  92. destinationDir = file("${subdir}/build/distributions")
  93. baseName = "elasticsearch${subdir.contains('oss') ? '-oss' : ''}"
  94. }
  95. Closure commonZipConfig = {
  96. dirMode 0755
  97. fileMode 0644
  98. }
  99. task buildIntegTestZip(type: Zip) {
  100. configure(commonZipConfig)
  101. with archiveFiles(transportModulesFiles, 'zip', null, true, false)
  102. }
  103. task buildWindowsZip(type: Zip) {
  104. configure(commonZipConfig)
  105. archiveClassifier = 'windows-x86_64'
  106. with archiveFiles(modulesFiles(false), 'zip', 'windows', false, true)
  107. }
  108. task buildOssWindowsZip(type: Zip) {
  109. configure(commonZipConfig)
  110. archiveClassifier = 'windows-x86_64'
  111. with archiveFiles(modulesFiles(true), 'zip', 'windows', true, true)
  112. }
  113. task buildNoJdkWindowsZip(type: Zip) {
  114. configure(commonZipConfig)
  115. archiveClassifier = 'no-jdk-windows-x86_64'
  116. with archiveFiles(modulesFiles(false), 'zip', 'windows', false, false)
  117. }
  118. task buildOssNoJdkWindowsZip(type: Zip) {
  119. configure(commonZipConfig)
  120. archiveClassifier = 'no-jdk-windows-x86_64'
  121. with archiveFiles(modulesFiles(true), 'zip', 'windows', true, false)
  122. }
  123. Closure commonTarConfig = {
  124. extension = 'tar.gz'
  125. compression = Compression.GZIP
  126. dirMode 0755
  127. fileMode 0644
  128. }
  129. task buildDarwinTar(type: Tar) {
  130. configure(commonTarConfig)
  131. archiveClassifier = 'darwin-x86_64'
  132. with archiveFiles(modulesFiles(false), 'tar', 'darwin', false, true)
  133. }
  134. task buildOssDarwinTar(type: Tar) {
  135. configure(commonTarConfig)
  136. archiveClassifier = 'darwin-x86_64'
  137. with archiveFiles(modulesFiles(true), 'tar', 'darwin', true, true)
  138. }
  139. task buildNoJdkDarwinTar(type: Tar) {
  140. configure(commonTarConfig)
  141. archiveClassifier = 'no-jdk-darwin-x86_64'
  142. with archiveFiles(modulesFiles(false), 'tar', 'darwin', false, false)
  143. }
  144. task buildOssNoJdkDarwinTar(type: Tar) {
  145. configure(commonTarConfig)
  146. archiveClassifier = 'no-jdk-darwin-x86_64'
  147. with archiveFiles(modulesFiles(true), 'tar', 'darwin', true, false)
  148. }
  149. task buildLinuxTar(type: Tar) {
  150. configure(commonTarConfig)
  151. archiveClassifier = 'linux-x86_64'
  152. with archiveFiles(modulesFiles(false), 'tar', 'linux', false, true)
  153. }
  154. task buildOssLinuxTar(type: Tar) {
  155. configure(commonTarConfig)
  156. archiveClassifier = 'linux-x86_64'
  157. with archiveFiles(modulesFiles(true), 'tar', 'linux', true, true)
  158. }
  159. task buildNoJdkLinuxTar(type: Tar) {
  160. configure(commonTarConfig)
  161. archiveClassifier = 'no-jdk-linux-x86_64'
  162. with archiveFiles(modulesFiles(false), 'tar', 'linux', false, false)
  163. }
  164. task buildOssNoJdkLinuxTar(type: Tar) {
  165. configure(commonTarConfig)
  166. archiveClassifier = 'no-jdk-linux-x86_64'
  167. with archiveFiles(modulesFiles(true), 'tar', 'linux', true, false)
  168. }
  169. Closure tarExists = { it -> new File('/bin/tar').exists() || new File('/usr/bin/tar').exists() || new File('/usr/local/bin/tar').exists() }
  170. Closure unzipExists = { it -> new File('/bin/unzip').exists() || new File('/usr/bin/unzip').exists() || new File('/usr/local/bin/unzip').exists() }
  171. // This configures the default artifact for the distribution specific
  172. // subprojects. We have subprojects for two reasons:
  173. // 1. Gradle project substitutions can only bind to the default
  174. // configuration of a project
  175. // 2. The integ-test-zip and zip distributions have the exact same
  176. // filename, so they must be placed in different directories.
  177. subprojects {
  178. apply plugin: 'distribution'
  179. String buildTask = "build${it.name.replaceAll(/-[a-z]/) { it.substring(1).toUpperCase() }.capitalize()}"
  180. ext.buildDist = parent.tasks.getByName(buildTask)
  181. artifacts {
  182. 'default' buildDist
  183. }
  184. // sanity checks if archives can be extracted
  185. File archiveExtractionDir
  186. if (project.name.contains('tar')) {
  187. archiveExtractionDir = new File(buildDir, 'tar-extracted')
  188. } else {
  189. assert project.name.contains('zip')
  190. archiveExtractionDir = new File(buildDir, 'zip-extracted')
  191. }
  192. task checkExtraction(type: LoggedExec) {
  193. dependsOn buildDist
  194. doFirst {
  195. project.delete(archiveExtractionDir)
  196. archiveExtractionDir.mkdirs()
  197. }
  198. }
  199. check.dependsOn checkExtraction
  200. if (project.name.contains('tar')) {
  201. checkExtraction {
  202. onlyIf tarExists
  203. commandLine 'tar', '-xvzf', "${-> buildDist.outputs.files.singleFile}", '-C', archiveExtractionDir
  204. }
  205. } else {
  206. assert project.name.contains('zip')
  207. checkExtraction {
  208. onlyIf unzipExists
  209. commandLine 'unzip', "${-> buildDist.outputs.files.singleFile}", '-d', archiveExtractionDir
  210. }
  211. }
  212. Closure toolExists
  213. if (project.name.contains('tar')) {
  214. toolExists = tarExists
  215. } else {
  216. assert project.name.contains('zip')
  217. toolExists = unzipExists
  218. }
  219. task checkLicense {
  220. dependsOn buildDist, checkExtraction
  221. onlyIf toolExists
  222. doLast {
  223. String licenseFilename = null
  224. if (project.name.contains('oss-') || project.name == 'integ-test-zip') {
  225. licenseFilename = "APACHE-LICENSE-2.0.txt"
  226. } else {
  227. licenseFilename = "ELASTIC-LICENSE.txt"
  228. }
  229. final List<String> licenseLines = Files.readAllLines(rootDir.toPath().resolve("licenses/" + licenseFilename))
  230. final Path licensePath = archiveExtractionDir.toPath().resolve("elasticsearch-${VersionProperties.elasticsearch}/LICENSE.txt")
  231. assertLinesInFile(licensePath, licenseLines)
  232. }
  233. }
  234. check.dependsOn checkLicense
  235. task checkNotice {
  236. dependsOn buildDist, checkExtraction
  237. onlyIf toolExists
  238. doLast {
  239. final List<String> noticeLines = Arrays.asList("Elasticsearch", "Copyright 2009-2018 Elasticsearch")
  240. final Path noticePath = archiveExtractionDir.toPath().resolve("elasticsearch-${VersionProperties.elasticsearch}/NOTICE.txt")
  241. assertLinesInFile(noticePath, noticeLines)
  242. }
  243. }
  244. check.dependsOn checkNotice
  245. if (project.name == 'zip' || project.name == 'tar') {
  246. project.ext.licenseName = 'Elastic License'
  247. project.ext.licenseUrl = ext.elasticLicenseUrl
  248. task checkMlCppNotice {
  249. dependsOn buildDist, checkExtraction
  250. onlyIf toolExists
  251. doLast {
  252. // this is just a small sample from the C++ notices, the idea being that if we've added these lines we've probably added all the required lines
  253. final List<String> expectedLines = Arrays.asList("Apache log4cxx", "Boost Software License - Version 1.0 - August 17th, 2003")
  254. final Path noticePath = archiveExtractionDir.toPath().resolve("elasticsearch-${VersionProperties.elasticsearch}/modules/x-pack-ml/NOTICE.txt")
  255. final List<String> actualLines = Files.readAllLines(noticePath)
  256. for (final String expectedLine : expectedLines) {
  257. if (actualLines.contains(expectedLine) == false) {
  258. throw new GradleException("expected [${noticePath}] to contain [${expectedLine}] but it did not")
  259. }
  260. }
  261. }
  262. }
  263. check.dependsOn checkMlCppNotice
  264. }
  265. }
  266. /*****************************************************************************
  267. * Rest test config *
  268. *****************************************************************************/
  269. configure(subprojects.findAll { it.name == 'integ-test-zip' }) {
  270. apply plugin: 'elasticsearch.standalone-rest-test'
  271. apply plugin: 'elasticsearch.rest-test'
  272. integTest {
  273. includePackaged = true
  274. }
  275. integTestCluster {
  276. dependsOn assemble
  277. distribution = project.name
  278. }
  279. integTestRunner {
  280. if (Os.isFamily(Os.FAMILY_WINDOWS) && System.getProperty('tests.timeoutSuite') == null) {
  281. // override the suite timeout to 30 mins for windows, because it has the most inefficient filesystem known to man
  282. systemProperty 'tests.timeoutSuite', '1800000!'
  283. }
  284. }
  285. processTestResources {
  286. inputs.properties(project(':distribution').restTestExpansions)
  287. MavenFilteringHack.filter(it, project(':distribution').restTestExpansions)
  288. }
  289. }
  290. /*****************************************************************************
  291. * Maven config *
  292. *****************************************************************************/
  293. configure(subprojects.findAll { it.name.contains('zip') }) {
  294. // only zip distributions go to maven
  295. BuildPlugin.configurePomGeneration(project)
  296. apply plugin: 'nebula.info-scm'
  297. apply plugin: 'nebula.maven-base-publish'
  298. apply plugin: 'nebula.maven-scm'
  299. // note: the group must be correct before applying the nexus plugin, or
  300. // it will capture the wrong value...
  301. String subgroup = project.name == 'integ-test-zip' ? 'integ-test-zip' : 'zip'
  302. project.group = "org.elasticsearch.distribution.${subgroup}"
  303. // make the pom file name use elasticsearch instead of the project name
  304. archivesBaseName = "elasticsearch${it.name.contains('oss') ? '-oss' : ''}"
  305. publishing {
  306. publications {
  307. nebula {
  308. artifactId archivesBaseName
  309. artifact buildDist
  310. }
  311. /*
  312. * HUGE HACK: the underlying maven publication library refuses to
  313. * deploy any attached artifacts when the packaging type is set to
  314. * 'pom'. But Sonatype's OSS repositories require source files for
  315. * artifacts that are of type 'zip'. We already publish the source
  316. * and javadoc for Elasticsearch under the various other subprojects.
  317. * So here we create another publication using the same name that
  318. * has the "real" pom, and rely on the fact that gradle will execute
  319. * the publish tasks in alphabetical order. This lets us publish the
  320. * zip file and even though the pom says the type is 'pom' instead of
  321. * 'zip'. We cannot setup a dependency between the tasks because the
  322. * publishing tasks are created *extremely* late in the configuration
  323. * phase, so that we cannot get ahold of the actual task. Furthermore,
  324. * this entire hack only exists so we can make publishing to maven
  325. * local work, since we publish to maven central externally.
  326. */
  327. nebulaRealPom(MavenPublication) {
  328. artifactId archivesBaseName
  329. pom.packaging = 'pom'
  330. pom.withXml { XmlProvider xml ->
  331. Node root = xml.asNode()
  332. root.appendNode('name', 'Elasticsearch')
  333. root.appendNode('description', 'A Distributed RESTful Search Engine')
  334. root.appendNode('url', PluginBuildPlugin.urlFromOrigin(project.scminfo.origin))
  335. Node scmNode = root.appendNode('scm')
  336. scmNode.appendNode('url', project.scminfo.origin)
  337. }
  338. }
  339. }
  340. }
  341. }