realityforge-buildr 1.5.9 → 1.5.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8aead139867720099e785867e129cdbd0ac5d7755c9aecaa82cad4ba79e8b703
4
- data.tar.gz: e5b61d9c94ec8ca7cda8ca3583cf99223b9e47226a2a8c7e8bf4620521ee7eb4
3
+ metadata.gz: 63d48d00ff2c45664c2dee85712e4c8014d1015519e3cf24fca25428c5cb2232
4
+ data.tar.gz: 0de204d07f99d6bb57b4e7d1ca68c44e22aeecac0e84ed4c4eb35ab4f454412d
5
5
  SHA512:
6
- metadata.gz: d6f7cbf839087fd897e8cea08b42697a1cf5109eba3a77223c70db7e9a124f83e98c2627d411f5b8effad5e691cf2dfffedfc01ae2bf886e5d6d781eb688a49e
7
- data.tar.gz: c23a3d5b5c4f8bc1996395405d83d059244cd9ed71b97a9fbc653eb05a42b7884e186c936017f561c5fd8b065b3bcb0ed0e7795f67410d6f3d048d0e482c934e
6
+ metadata.gz: 117f3e4c4d92fd43da908c0a32b468c9eca92d6ca6a79817f8a27d70241da999d8999b6ed9d9af721f71cf8be81c467db02f8331530c16b1ed03ffb1316c27f4
7
+ data.tar.gz: 0a9f1a1a159a23bf386027068d7285510ea223838f5bda0e5482d2e596dbccdeb585250be197916ba4eb473174cc104771470b61a28738079e5eeccd238221c3
@@ -148,6 +148,9 @@ module Buildr
148
148
  options[:html_output_directory] = project._(:reports, :jacoco, 'docs')
149
149
 
150
150
  unless execution_files.empty?
151
+ FileUtils.mkdir_p File.dirname(options[:xml_output_file])
152
+ FileUtils.mkdir_p File.dirname(options[:csv_output_file])
153
+ FileUtils.mkdir_p options[:html_output_directory]
151
154
  Buildr::JaCoCo.jacoco_report(execution_files, class_paths, source_paths, options)
152
155
  end
153
156
  end
@@ -0,0 +1,42 @@
1
+ #
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ #
14
+
15
+ module Buildr
16
+ # Provides the shade method.
17
+ module Shade
18
+ class << self
19
+ def shade(input_jar, output_jar, relocations = {})
20
+
21
+ shaded_jar = (input_jar.to_s + '-shaded')
22
+ a = Buildr.artifact('org.realityforge.shade:shade-cli:jar:1.0.0')
23
+ a.invoke
24
+
25
+ args = []
26
+ args << Java::Commands.path_to_bin('java')
27
+ args << '-jar'
28
+ args << a.to_s
29
+ args << '--input'
30
+ args << input_jar.to_s
31
+ args << '--output'
32
+ args << shaded_jar.to_s
33
+ relocations.each_pair do |k, v|
34
+ args << "-r#{k}=#{v}"
35
+ end
36
+
37
+ sh args.join(' ')
38
+ FileUtils.mv shaded_jar, output_jar.to_s
39
+ end
40
+ end
41
+ end
42
+ end
@@ -25,7 +25,7 @@ module Buildr
25
25
  include Extension
26
26
 
27
27
  before_define do |project|
28
- project.layout[:target, :generated] = "generated"
28
+ project.layout[:target, :generated] = 'generated'
29
29
  project.clean { rm_rf project._(:target, :generated) }
30
30
  end
31
31
  end
data/buildr.gemspec CHANGED
@@ -35,12 +35,12 @@ for those one-off tasks, with a language that's a joy to use.
35
35
  TEXT
36
36
 
37
37
  spec.files = Dir['{addon,bin,lib,rakelib,spec}/**/*', '*.{gemspec}'] +
38
- %w(LICENSE NOTICE CHANGELOG.md README.md Rakefile)
38
+ %w(LICENSE NOTICE README.md Rakefile)
39
39
  spec.require_paths = 'lib', 'addon'
40
40
  spec.bindir = 'bin'
41
41
  spec.executable = 'buildr'
42
42
 
43
- spec.extra_rdoc_files = 'README.md', 'CHANGELOG.md', 'LICENSE', 'NOTICE'
43
+ spec.extra_rdoc_files = 'README.md', 'LICENSE', 'NOTICE'
44
44
  spec.rdoc_options = '--title', 'Buildr', '--main', 'README.md',
45
45
  '--webcvs', 'https://github.com/realityforge/buildr'
46
46
  spec.post_install_message = 'To get started run buildr --help'
data/lib/buildr.rb CHANGED
@@ -50,6 +50,7 @@ require 'buildr/core/test'
50
50
  require 'buildr/java/commands'
51
51
  require 'buildr/core/transports'
52
52
  require 'buildr/java/pom'
53
+ require 'buildr/java/publish'
53
54
  require 'buildr/core/doc'
54
55
  require 'buildr/packaging/version_requirement'
55
56
  require 'buildr/packaging/artifact_namespace'
@@ -65,6 +66,7 @@ require 'buildr/java/packaging'
65
66
  require 'buildr/java/commands'
66
67
  require 'buildr/java/doc'
67
68
  require 'buildr/java/custom_pom'
69
+ require 'buildr/java/annotation_processor'
68
70
  require 'buildr/ide/idea'
69
71
 
70
72
  # Methods defined in Buildr are both instance methods (e.g. when included in Project)
@@ -273,7 +273,7 @@ module URI
273
273
  headers['Cache-Control'] = 'no-cache'
274
274
  headers['User-Agent'] = "Buildr-#{Buildr::VERSION}"
275
275
  request = Net::HTTP::Get.new(request_uri.empty? ? '/' : request_uri, headers)
276
- request.basic_auth URI.decode(self.user), URI.decode(self.password) if self.user
276
+ request.basic_auth CGI.unescape(self.user), CGI.unescape(self.password) if self.user
277
277
  http.verify_mode = ::OpenSSL::SSL.const_get(ENV['SSL_VERIFY_MODE']) if ENV['SSL_VERIFY_MODE']
278
278
  http.ca_path = ENV['SSL_CA_CERTS'] if ENV['SSL_CA_CERTS']
279
279
  http.request request do |response|
@@ -330,7 +330,7 @@ module URI
330
330
  end
331
331
  headers = { 'Content-MD5'=>Digest::MD5.hexdigest(content.string), 'Content-Type'=>'application/octet-stream', 'User-Agent'=>"Buildr-#{Buildr::VERSION}" }
332
332
  request = Net::HTTP::Put.new(request_uri.empty? ? '/' : request_uri, headers)
333
- request.basic_auth URI.decode(self.user), URI.decode(self.password) if self.user
333
+ request.basic_auth CGI.unescape(self.user), CGI.unescape(self.password) if self.user
334
334
  response = nil
335
335
  with_progress_bar options[:progress], path.split('/').last, content.size do |progress|
336
336
  request.content_length = content.size
@@ -56,6 +56,12 @@ module Buildr #:nodoc:
56
56
  self.components << create_component(name, attrs, &xml)
57
57
  end
58
58
 
59
+ def add_component_in_lambda(name, attrs = {}, &xml)
60
+ self.components << lambda do
61
+ create_component(name, attrs, &xml)
62
+ end
63
+ end
64
+
59
65
  def add_component_from_file(filename)
60
66
  self.components << lambda do
61
67
  raise "Unable to locate file #{filename} adding component to idea file" unless File.exist?(filename)
@@ -719,6 +725,16 @@ module Buildr #:nodoc:
719
725
  @jdk_version ||= buildr_project.compile.options.source || '1.7'
720
726
  end
721
727
 
728
+ def nonnull_assertions?
729
+ @nonnull_assertions.nil? ? true : !!@nonnull_assertions
730
+ end
731
+
732
+ attr_writer :nonnull_assertions
733
+
734
+ def wildcard_resource_patterns
735
+ @wildcard_resource_patterns ||= %w(!?*.java !?*.form !?*.class !?*.groovy !?*.scala !?*.flex !?*.kt !?*.clj !?*.aj)
736
+ end
737
+
722
738
  def add_artifact(name, type, build_on_make = false)
723
739
  add_to_composite_component(self.artifacts) do |xml|
724
740
  xml.artifact(:name => name, :type => type, 'build-on-make' => build_on_make) do |xml|
@@ -793,7 +809,7 @@ module Buildr #:nodoc:
793
809
  }.merge(options)
794
810
 
795
811
  if params[:url]
796
- if /jdbc\:jtds\:sqlserver\:\/\/[^:\\]+(\:\d+)?\/([^;]*)(\;.*)?/ =~ params[:url]
812
+ if /jdbc:jtds:sqlserver:\/\/[^:\\]+(:\d+)?\/([^;]*)(;.*)?/ =~ params[:url]
797
813
  database_name = $2
798
814
  params[:schema_pattern] = "#{database_name}.*"
799
815
  params[:default_schemas] = "#{database_name}.*"
@@ -803,6 +819,47 @@ module Buildr #:nodoc:
803
819
  add_data_source(name, params)
804
820
  end
805
821
 
822
+ def add_javac_settings(javac_args)
823
+ add_component('JavacSettings') do |xml|
824
+ xml.option(:name => 'ADDITIONAL_OPTIONS_STRING', :value => javac_args)
825
+ end
826
+ end
827
+
828
+ def add_code_insight_settings(options = {})
829
+ excluded_names = options[:excluded_names] || default_code_sight_excludes
830
+ excluded_names += (options[:extra_excluded_names] || [])
831
+ add_component('JavaProjectCodeInsightSettings') do |xml|
832
+ xml.tag!('excluded-names') do
833
+ excluded_names.each do |excluded_name|
834
+ xml << "<name>#{excluded_name}</name>"
835
+ end
836
+ end
837
+ end
838
+ end
839
+
840
+ def add_nullable_manager
841
+ add_component('NullableNotNullManager') do |component|
842
+ component.option :name => 'myDefaultNullable', :value => 'javax.annotation.Nullable'
843
+ component.option :name => 'myDefaultNotNull', :value => 'javax.annotation.Nonnull'
844
+ component.option :name => 'myNullables' do |option|
845
+ option.value do |value|
846
+ value.list :size => '2' do |list|
847
+ list.item :index => '0', :class => 'java.lang.String', :itemvalue => 'org.jetbrains.annotations.Nullable'
848
+ list.item :index => '1', :class => 'java.lang.String', :itemvalue => 'javax.annotation.Nullable'
849
+ end
850
+ end
851
+ end
852
+ component.option :name => 'myNotNulls' do |option|
853
+ option.value do |value|
854
+ value.list :size => '2' do |list|
855
+ list.item :index => '0', :class => 'java.lang.String', :itemvalue => 'org.jetbrains.annotations.NotNull'
856
+ list.item :index => '1', :class => 'java.lang.String', :itemvalue => 'javax.annotation.Nonnull'
857
+ end
858
+ end
859
+ end
860
+ end
861
+ end
862
+
806
863
  def add_less_compiler_component(project, options = {})
807
864
  source_dir = options[:source_dir] || project._(:source, :main, :webapp, :less).to_s
808
865
  source_pattern = options[:pattern] || '*.less'
@@ -1376,6 +1433,7 @@ module Buildr #:nodoc:
1376
1433
  lambda { modules_component },
1377
1434
  vcs_component,
1378
1435
  artifacts_component,
1436
+ compiler_configuration_component,
1379
1437
  lambda { data_sources_component },
1380
1438
  configurations_component,
1381
1439
  lambda { framework_detection_exclusion_component }
@@ -1477,6 +1535,60 @@ module Buildr #:nodoc:
1477
1535
  create_composite_component('ArtifactManager', {}, self.artifacts)
1478
1536
  end
1479
1537
 
1538
+ def compiler_configuration_component
1539
+ lambda do
1540
+ create_component('CompilerConfiguration') do |component|
1541
+ component.addNotNullAssertions :enabled => 'false' unless nonnull_assertions?
1542
+ component.wildcardResourcePatterns do |xml|
1543
+ wildcard_resource_patterns.each do |pattern|
1544
+ xml.entry :name => pattern.to_s
1545
+ end
1546
+ end
1547
+ component.annotationProcessing do |xml|
1548
+ xml.profile(:default => true, :name => 'Default', :enabled => true) do
1549
+ xml.sourceOutputDir :name => 'generated/processors/main/java'
1550
+ xml.sourceTestOutputDir :name => 'generated/processors/test/java'
1551
+ xml.outputRelativeToContentRoot :value => true
1552
+ xml.processorPath :useClasspath => true
1553
+ end
1554
+ disabled = []
1555
+ Buildr.projects.each do |prj|
1556
+ next unless prj.iml?
1557
+ main_processor = !!prj.compile.options[:processor] || prj.compile.options[:processor].nil?
1558
+ test_processor = !!prj.test.compile.options[:processor] || prj.test.compile.options[:processor].nil?
1559
+ if main_processor || test_processor
1560
+ xml.profile(:name => "#{prj.name}", :enabled => true) do
1561
+ xml.sourceOutputDir :name => 'generated/processors/main/java' if main_processor
1562
+ xml.sourceTestOutputDir :name => 'generated/processors/test/java' if test_processor
1563
+ xml.outputRelativeToContentRoot :value => true
1564
+ xml.module :name => prj.iml.name
1565
+ processor_path = (prj.compile.options[:processor_path] || []) + (prj.test.compile.options[:processor_path] || [])
1566
+ if processor_path.empty?
1567
+ xml.processorPath :useClasspath => true
1568
+ else
1569
+ xml.processorPath :useClasspath => false do
1570
+ Buildr.artifacts(processor_path).each do |path|
1571
+ xml.entry :name => resolve_path(path.to_s)
1572
+ end
1573
+ end
1574
+ end
1575
+ end
1576
+ else
1577
+ disabled << prj
1578
+ end
1579
+ end
1580
+ unless disabled.empty?
1581
+ xml.profile(:name => 'Disabled') do
1582
+ disabled.each do |p|
1583
+ xml.module :name => p.iml.name
1584
+ end
1585
+ end
1586
+ end
1587
+ end
1588
+ end
1589
+ end
1590
+ end
1591
+
1480
1592
  def configurations_component
1481
1593
  create_composite_component('ProjectRunConfigurationManager', {}, self.configurations)
1482
1594
  end
@@ -1487,6 +1599,21 @@ module Buildr #:nodoc:
1487
1599
 
1488
1600
  private
1489
1601
 
1602
+ def default_code_sight_excludes
1603
+ %w(
1604
+ com.sun.istack.internal.NotNull
1605
+ com.sun.istack.internal.Nullable
1606
+ org.jetbrains.annotations.Nullable
1607
+ org.jetbrains.annotations.NotNull
1608
+ org.testng.AssertJUnit
1609
+ org.testng.internal.Nullable
1610
+ org.mockito.internal.matchers.NotNull
1611
+ edu.umd.cs.findbugs.annotations.Nonnull
1612
+ edu.umd.cs.findbugs.annotations.Nullable
1613
+ edu.umd.cs.findbugs.annotations.SuppressWarnings
1614
+ )
1615
+ end
1616
+
1490
1617
  def to_artifact_name(project, options)
1491
1618
  options[:name] || project.iml.id
1492
1619
  end
@@ -0,0 +1,61 @@
1
+ # This file is licensed to you under the Apache License, Version 2.0 (the
2
+ # "License"); you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10
+ # License for the specific language governing permissions and limitations under
11
+ # the License.
12
+
13
+ module Buildr
14
+ module ProcessorPath
15
+ module ProjectExtension
16
+ include Extension
17
+
18
+ before_define do |project|
19
+ if project.iml?
20
+ project.iml.instance_variable_set('@main_generated_source_directories', [])
21
+ project.iml.instance_variable_set('@test_generated_source_directories', [])
22
+ end
23
+ end
24
+
25
+ after_define do |project|
26
+ if !!project.compile.options[:processor] || (project.compile.options[:processor].nil? && !(project.compile.options[:processor_path] || []).empty?)
27
+ path = project._(:target, :generated, 'processors/main/java')
28
+ f = project.file(path) do |t|
29
+ mkdir_p t.to_s
30
+ end
31
+ project.compile.enhance([f])
32
+ project.compile.options[:other] = [] unless project.compile.options[:other]
33
+ project.compile.options[:other] += ['-s', path]
34
+ project.iml.main_generated_source_directories << path if project.iml?
35
+
36
+ project.clean do
37
+ rm_rf path
38
+ end
39
+ end
40
+ if !!project.test.compile.options[:processor] || (project.test.compile.options[:processor].nil? && !(project.test.compile.options[:processor_path] || []).empty?)
41
+ path = project._(:target, :generated, 'processors/test/java')
42
+ f = project.file(path) do |t|
43
+ mkdir_p t.to_s
44
+ end
45
+ project.test.compile.enhance([f])
46
+ project.test.compile.options[:other] = [] unless project.test.compile.options[:other]
47
+ project.test.compile.options[:other] += ['-s', path]
48
+ project.iml.test_generated_source_directories << path if project.iml?
49
+
50
+ project.clean do
51
+ rm_rf path
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ class Buildr::Project
60
+ include Buildr::ProcessorPath::ProjectExtension
61
+ end
@@ -63,14 +63,14 @@ module Java
63
63
  cmd_args << "cd '#{options[:dir]}' && "
64
64
  end
65
65
  cmd_args << path_to_bin('java')
66
- cp = classpath_from(options)
66
+ cp = classpath_from(options[:classpath])
67
67
 
68
68
  unless cp.empty?
69
69
  if options[:pathing_jar] == true
70
70
  paths = cp.map do |c|
71
71
  File.directory?(c) && !c.end_with?('/') ? "#{c}/" : c.to_s
72
72
  end
73
- manifest = Buildr::Packaging::Java::Manifest.new([{'Class-Path' => paths.map{|p| URI.encode(p)}.join(" ")}])
73
+ manifest = Buildr::Packaging::Java::Manifest.new([{'Class-Path' => paths.map{|p| CGI.escape(p)}.join(" ")}])
74
74
  tjar = Tempfile.new(%w[javacmd .jar])
75
75
  Zip::OutputStream.open(tjar.path) do |zos|
76
76
  zos.put_next_entry('META-INF/MANIFEST.MF')
@@ -112,14 +112,16 @@ module Java
112
112
  #
113
113
  # The last argument may be a Hash with additional options:
114
114
  # * :output -- Target directory for all compiled class files.
115
- # * :classpath -- One or more file names, tasks or artifact specifications.
116
- # These are all expanded into artifacts, and all tasks are invoked.
115
+ # * :classpath -- One or more file names, tasks or artifact specifications. These are all expanded into artifacts, and all tasks are invoked.
117
116
  # * :sourcepath -- Additional source paths to use.
117
+ # * :processor_path -- Annotation processor path. These are all expanded into artifacts, and all tasks are invoked.
118
118
  # * :javac_args -- Any additional arguments to pass (e.g. -extdirs, -encoding)
119
119
  # * :name -- Shows this name, otherwise shows the working directory.
120
120
  def javac(*args, &block)
121
121
  options = Hash === args.last ? args.pop : {}
122
- rake_check_options options, :classpath, :sourcepath, :output, :javac_args, :name
122
+ rake_check_options options, :classpath, :sourcepath, :output, :javac_args, :name, :processor, :processor_path
123
+
124
+ processor = !!options[:processor]
123
125
 
124
126
  files = args.flatten.each { |f| f.invoke if f.respond_to?(:invoke) }.map(&:to_s).
125
127
  collect { |arg| File.directory?(arg) ? FileList["#{File.expand_path(arg)}/**/*.java"] : File.expand_path(arg) }.flatten
@@ -127,9 +129,15 @@ module Java
127
129
 
128
130
  cmd_args = []
129
131
  cmd_args << path_to_bin('javac')
130
- cp = classpath_from(options)
132
+ cp = classpath_from(options[:classpath])
131
133
  cmd_args << '-classpath' << cp.join(File::PATH_SEPARATOR) unless cp.empty?
132
134
  cmd_args << '-sourcepath' << [options[:sourcepath]].flatten.join(File::PATH_SEPARATOR) if options[:sourcepath]
135
+ if processor
136
+ processor_path = classpath_from(options[:processor_path])
137
+ cmd_args << '-processorpath' << processor_path.join(File::PATH_SEPARATOR) unless processor_path.empty?
138
+ else
139
+ cmd_args << '-proc:none'
140
+ end
133
141
  cmd_args << '-d' << File.expand_path(options[:output].to_s) if options[:output]
134
142
  cmd_args += options[:javac_args].flatten if options[:javac_args]
135
143
  Tempfile.open('javac') do |tmp|
@@ -221,9 +229,8 @@ module Java
221
229
  #
222
230
  # Extracts the classpath from the options, expands it by calling artifacts, invokes
223
231
  # each of the artifacts and returns an array of paths.
224
- def classpath_from(options)
225
- Buildr.artifacts(options[:classpath] || []).map(&:to_s).
226
- map { |t| task(t).invoke; File.expand_path(t) }
232
+ def classpath_from(classpath)
233
+ Buildr.artifacts(classpath || []).flatten.map(&:to_s).map { |t| task(t).invoke; File.expand_path(t) }
227
234
  end
228
235
  end
229
236
  end
@@ -33,9 +33,9 @@ module Buildr #:nodoc:
33
33
  # (e.g. ['-implicit:none', '-encoding', 'iso-8859-1'])
34
34
  class Javac < Base
35
35
 
36
- OPTIONS = [:warnings, :debug, :deprecation, :source, :target, :lint, :other]
36
+ OPTIONS = [:warnings, :debug, :deprecation, :source, :target, :lint, :other, :processor_path, :processor]
37
37
 
38
- specify :language=>:java, :target=>'classes', :target_ext=>'class', :packaging=>:jar
38
+ specify :language => :java, :target => 'classes', :target_ext => 'class', :packaging => :jar
39
39
 
40
40
  def initialize(project, options) #:nodoc:
41
41
  super
@@ -43,15 +43,20 @@ module Buildr #:nodoc:
43
43
  options[:warnings] ||= false
44
44
  options[:deprecation] ||= false
45
45
  options[:lint] ||= false
46
+ options[:processor] ||= nil
47
+ options[:processor_path] ||= []
46
48
  end
47
49
 
48
50
  def compile(sources, target, dependencies) #:nodoc:
49
51
  check_options options, OPTIONS
52
+ processor = !!options[:processor] || options[:processor].nil?
50
53
  Java::Commands.javac(files_from_sources(sources),
51
54
  :classpath => dependencies,
52
55
  :sourcepath => sources.select { |source| File.directory?(source) },
53
56
  :output => target,
54
- :javac_args => self.javac_args)
57
+ :processor => processor,
58
+ :processor_path => (processor ? options[:processor_path] : []),
59
+ :javac_args => javac_args)
55
60
  end
56
61
 
57
62
  # Filter out source files that are known to not produce any corresponding .class output file. If we leave
@@ -0,0 +1,262 @@
1
+ #
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ #
14
+
15
+ require 'net/http'
16
+ require 'net/https'
17
+ require 'json'
18
+
19
+ module Buildr
20
+ class MavenCentral
21
+ class << self
22
+ def define_publish_tasks(options = {})
23
+ candidate_branches = options[:branches] || %w(master)
24
+ desc 'Publish release on maven central'
25
+ task 'mcrt:publish' do
26
+ project = options[:project] || Buildr.projects[0].root_project
27
+ profile_name = options[:profile_name] || (raise ':profile_name not specified when defining tasks')
28
+ username = options[:username] || (raise ':username name not specified when defining tasks')
29
+ password = options[:password] || ENV['MAVEN_CENTRAL_PASSWORD'] || (raise "Unable to locate environment variable with name 'MAVEN_CENTRAL_PASSWORD'")
30
+ MavenCentral.buildr_release(project, profile_name, username, password)
31
+ end
32
+
33
+ desc 'Publish release to maven central iff current HEAD is a tag'
34
+ task 'mcrt:publish_if_tagged' do
35
+ tag = MavenCentral.get_head_tag_if_any
36
+ if tag.nil?
37
+ puts 'Current HEAD is not a tag. Skipping publish step.'
38
+ else
39
+ puts "Current HEAD is a tag: #{tag}"
40
+ if MavenCentral.is_tag_on_candidate_branches?(tag, candidate_branches)
41
+ task('mcrt:publish').invoke
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ def get_head_tag_if_any
48
+ version = `git describe --exact-match --tags 2>&1`
49
+ if 0 == $?.exitstatus && version =~ /^v[0-9]/ && (ENV['TRAVIS_BUILD_ID'].nil? || ENV['TRAVIS_TAG'].to_s != '')
50
+ version.strip
51
+ else
52
+ nil
53
+ end
54
+ end
55
+
56
+ def is_tag_on_branch?(tag, branch)
57
+ output = `git tag --merged #{branch} 2>&1`
58
+ tags = output.split
59
+ tags.include?(tag)
60
+ end
61
+
62
+ def is_tag_on_candidate_branches?(tag, branches)
63
+ sh 'git fetch origin'
64
+ branches.each do |branch|
65
+ if is_tag_on_branch?(tag, branch)
66
+ puts "Tag #{tag} is on branch: #{branch}"
67
+ return true
68
+ elsif is_tag_on_branch?(tag, "origin/#{branch}")
69
+ puts "Tag #{tag} is on branch: origin/#{branch}"
70
+ return true
71
+ else
72
+ puts "Tag #{tag} is not on branches: #{branch} or origin/#{branch}"
73
+ end
74
+ end
75
+ false
76
+ end
77
+
78
+ def buildr_release(project, profile_name, username, password)
79
+ release_to_url = Buildr.repositories.release_to[:url]
80
+ release_to_username = Buildr.repositories.release_to[:username]
81
+ release_to_password = Buildr.repositories.release_to[:password]
82
+
83
+ begin
84
+ Buildr.repositories.release_to[:url] = 'https://oss.sonatype.org/service/local/staging/deploy/maven2'
85
+ Buildr.repositories.release_to[:username] = username
86
+ Buildr.repositories.release_to[:password] = password
87
+
88
+ project.task(':package').invoke
89
+
90
+ r = MavenCentral.new
91
+ r.username = username
92
+ r.password = password
93
+ r.user_agent = "Buildr-#{Buildr::VERSION}"
94
+ while r.get_staging_repositories(profile_name, false).size != 0
95
+ puts 'Another project currently staging. Waiting for other repository to complete. Please visit the website https://oss.sonatype.org/index.html#stagingRepositories to view the other staging attempts.'
96
+ sleep 1
97
+ end
98
+ puts "Beginning upload to staging repository #{profile_name}"
99
+
100
+ project.task(':upload').invoke
101
+
102
+ r.release_sole_auto_staging(profile_name)
103
+ ensure
104
+ Buildr.repositories.release_to[:url] = release_to_url
105
+ Buildr.repositories.release_to[:username] = release_to_username
106
+ Buildr.repositories.release_to[:password] = release_to_password
107
+ end
108
+ end
109
+ end
110
+
111
+ attr_writer :username
112
+
113
+ def username
114
+ @username || (raise 'Username not yet specified')
115
+ end
116
+
117
+ attr_writer :password
118
+
119
+ def password
120
+ @password || (raise 'Password not yet specified')
121
+ end
122
+
123
+ attr_writer :user_agent
124
+
125
+ def user_agent
126
+ @user_agent || "Ruby-#{RUBY_VERSION}"
127
+ end
128
+
129
+ def get_staging_repositories(profile_name, ignore_transitioning_repositories = true)
130
+ result = get_request('https://oss.sonatype.org/service/local/staging/profile_repositories')
131
+ result = JSON.parse(result)
132
+ result['data'].select do |repo|
133
+ repo['profileName'] == profile_name &&
134
+ repo['userId'] == self.username &&
135
+ repo['userAgent'] == self.user_agent &&
136
+ (!ignore_transitioning_repositories || !repo['transitioning']) &&
137
+ get_my_ip_addresses.any? { |a| a == repo['ipAddress'] }
138
+ end
139
+ end
140
+
141
+ def get_my_ip_addresses
142
+ addresses = Socket.ip_address_list.collect { |a| a.ip_address.to_s }
143
+ commands = [
144
+ "dig +short myip.opendns.com @resolver1.opendns.com",
145
+ "curl ifconfig.me",
146
+ "curl icanhazip.com",
147
+ "curl ipecho.net/plain",
148
+ "curl ifconfig.co",
149
+ "dig TXT +short o-o.myaddr.l.google.com @ns1.google.com | awk -F'\"' '{ print $2 }'"
150
+ ]
151
+ commands.each do |cmd|
152
+ begin
153
+ addresses << `#{cmd}`.strip
154
+ rescue Exception
155
+ # ignored
156
+ end
157
+ end
158
+ urls = %w[http://www.myexternalip.com/raw https://diagnostic.opendns.com/myip]
159
+ urls.each do |url|
160
+ begin
161
+ addresses << Net::HTTP.get(URI(url)).strip
162
+ rescue Exception
163
+ # ignored
164
+ end
165
+ end
166
+ begin
167
+ addresses << JSON.parse(Net::HTTP.get(URI('https://api.ipify.org?format=json')))['ip']
168
+ rescue Exception
169
+ # ignored
170
+ end
171
+ addresses.sort.uniq
172
+ end
173
+
174
+ def close_repository(repository_id, description)
175
+ post_request('https://oss.sonatype.org/service/local/staging/bulk/close',
176
+ JSON.pretty_generate('data' => { 'description' => description, 'stagedRepositoryIds' => [repository_id] }))
177
+ end
178
+
179
+ def promote_repository(repository_id, description)
180
+ post_request('https://oss.sonatype.org/service/local/staging/bulk/promote',
181
+ JSON.pretty_generate('data' => { 'autoDropAfterRelease' => true,
182
+ 'description' => description,
183
+ 'stagedRepositoryIds' => [repository_id] }))
184
+ end
185
+
186
+ def drop_repository(repository_id, description)
187
+ post_request('https://oss.sonatype.org/service/local/staging/bulk/drop',
188
+ JSON.pretty_generate('data' => { 'description' => description, 'stagedRepositoryIds' => [repository_id] }))
189
+ end
190
+
191
+ def release_sole_auto_staging(profile_name)
192
+ candidates = get_staging_repositories(profile_name)
193
+ if candidates.empty?
194
+ raise 'Release process unable to find any staging repositories.'
195
+ elsif 1 != candidates.size
196
+ raise 'Release process found multiple staging repositories that could be the release just uploaded. Please visit the website https://oss.sonatype.org/index.html#stagingRepositories and manually complete the release.'
197
+ else
198
+ candidate = candidates[0]
199
+ puts "Requesting close of staging repository #{profile_name}:#{candidate['repositoryId']}"
200
+ begin
201
+ close_repository(candidate['repositoryId'], "Closing repository for #{profile_name}")
202
+ rescue Exception => e
203
+ puts "#{e.class.name}: #{e.message}"
204
+ puts e.backtrace.join("\n")
205
+ raise 'Failed to close repository. It is likely that the release does not conform to Maven Central release requirements. Please visit the website https://oss.sonatype.org/index.html#stagingRepositories and manually complete the release.'
206
+ end
207
+ while get_staging_repositories(profile_name).size == 0
208
+ puts 'Waiting for repository to close...'
209
+ sleep 1
210
+ end
211
+ puts "Requesting promotion of staging repository #{profile_name}:#{candidate['repositoryId']}"
212
+ begin
213
+ promote_repository(candidate['repositoryId'], "Promoting repository for #{profile_name}")
214
+ rescue Exception => e
215
+ puts "#{e.class.name}: #{e.message}"
216
+ puts e.backtrace.join("\n")
217
+ raise 'Failed to promote repository. Please visit the website https://oss.sonatype.org/index.html#stagingRepositories and manually complete the release.'
218
+ end
219
+ repositories = get_staging_repositories(profile_name, false)
220
+ while repositories.size == 1
221
+ puts 'Waiting for repository to be promoted...'
222
+ sleep 1
223
+ if repositories[0]['notifications'] != 0
224
+ raise 'Failed to promote repository. Please visit the website https://oss.sonatype.org/index.html#stagingRepositories and manually complete the release.'
225
+ end
226
+ repositories = get_staging_repositories(profile_name, false)
227
+ end
228
+ end
229
+ end
230
+
231
+ private
232
+
233
+ def create_http(uri)
234
+ http = Net::HTTP.new(uri.host, uri.port)
235
+ http.use_ssl = true
236
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
237
+ http
238
+ end
239
+
240
+ def setup_standard_request(request)
241
+ request['Accept'] = 'application/json,application/vnd.siesta-error-v1+json,application/vnd.siesta-validation-errors-v1+json'
242
+ request.basic_auth(self.username, self.password)
243
+ request.add_field('User-Agent', self.user_agent)
244
+ end
245
+
246
+ def get_request(url)
247
+ uri = URI.parse(url)
248
+ request = Net::HTTP::Get.new(uri.request_uri)
249
+ setup_standard_request(request)
250
+ create_http(uri).request(request).body
251
+ end
252
+
253
+ def post_request(url, content)
254
+ uri = URI.parse(url)
255
+ request = Net::HTTP::Post.new(uri.request_uri)
256
+ setup_standard_request(request)
257
+ request.add_field('Content-Type', 'application/json')
258
+ request.body = content
259
+ create_http(uri).request(request).body
260
+ end
261
+ end
262
+ end
@@ -246,9 +246,8 @@ module Buildr #:nodoc:
246
246
  # Username/password may be part of URI, or separate entities.
247
247
  uri = URI.parse(upload_to[:url].clone)
248
248
  uri.path = uri.path + '/' unless uri.path[-1] == '/'
249
- to_escape = "!\"\#$%&'()*+,-./:;<=>?@{}|~`'"
250
- uri.user = URI.encode(upload_to[:username], to_escape) if upload_to[:username]
251
- uri.password = URI.encode(upload_to[:password], to_escape) if upload_to[:password]
249
+ uri.user = CGI.escape(upload_to[:username]) if upload_to[:username]
250
+ uri.password = CGI.escape(upload_to[:password]) if upload_to[:password]
252
251
 
253
252
  path = group.gsub('.', '/') + "/#{id}/#{version}/#{upload_name}"
254
253
 
@@ -14,5 +14,5 @@
14
14
  # the License.
15
15
 
16
16
  module Buildr #:nodoc:
17
- VERSION = '1.5.9'.freeze
17
+ VERSION = '1.5.14'.freeze
18
18
  end
data/rakelib/release.rake CHANGED
@@ -79,7 +79,7 @@ task 'perform_release' do
79
79
 
80
80
  stage('PostReleaseUpdateVersion', 'Update the version to the non-dev version') do
81
81
  filename = 'lib/buildr/version.rb'
82
- parts = ENV['PRODUCT_VERSION'].split
82
+ parts = ENV['PRODUCT_VERSION'].split('.')
83
83
  next_version = "#{parts[0]}.#{parts[1]}.#{parts[2].to_i + 1}"
84
84
  content = IO.read(filename).sub(/VERSION = '(.*)'\.freeze/, "VERSION = '#{next_version}.dev'.freeze")
85
85
  IO.write(filename, content)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: realityforge-buildr
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.9
4
+ version: 1.5.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Apache Buildr
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-08 00:00:00.000000000 Z
11
+ date: 2021-03-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -175,11 +175,9 @@ executables:
175
175
  extensions: []
176
176
  extra_rdoc_files:
177
177
  - README.md
178
- - CHANGELOG.md
179
178
  - LICENSE
180
179
  - NOTICE
181
180
  files:
182
- - CHANGELOG.md
183
181
  - LICENSE
184
182
  - NOTICE
185
183
  - README.md
@@ -191,6 +189,7 @@ files:
191
189
  - addon/buildr/gwt.rb
192
190
  - addon/buildr/jacoco.rb
193
191
  - addon/buildr/pmd.rb
192
+ - addon/buildr/shade.rb
194
193
  - addon/buildr/single_intermediate_layout.rb
195
194
  - addon/buildr/spotbugs.rb
196
195
  - addon/buildr/top_level_generate_dir.rb
@@ -214,12 +213,14 @@ files:
214
213
  - lib/buildr/core/transports.rb
215
214
  - lib/buildr/core/util.rb
216
215
  - lib/buildr/ide/idea.rb
216
+ - lib/buildr/java/annotation_processor.rb
217
217
  - lib/buildr/java/commands.rb
218
218
  - lib/buildr/java/compiler.rb
219
219
  - lib/buildr/java/custom_pom.rb
220
220
  - lib/buildr/java/doc.rb
221
221
  - lib/buildr/java/packaging.rb
222
222
  - lib/buildr/java/pom.rb
223
+ - lib/buildr/java/publish.rb
223
224
  - lib/buildr/java/test_result.rb
224
225
  - lib/buildr/java/tests.rb
225
226
  - lib/buildr/packaging/archive.rb
data/CHANGELOG.md DELETED
@@ -1,5 +0,0 @@
1
- # Change Log
2
-
3
- ### Unreleased
4
-
5
- * First release after extraction from Apache Buildr.