jar-dependencies 0.6.0.pre3-java
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/Mavenfile +48 -0
- data/Rakefile +66 -0
- data/Readme.md +225 -0
- data/exe/lock_jars +54 -0
- data/jar-dependencies.gemspec +41 -0
- data/lib/jar-dependencies.rb +24 -0
- data/lib/jar_dependencies.rb +408 -0
- data/lib/jar_install_post_install_hook.rb +23 -0
- data/lib/jars/classpath.rb +92 -0
- data/lib/jars/gemspec_artifacts.rb +211 -0
- data/lib/jars/installer.rb +226 -0
- data/lib/jars/lock.rb +77 -0
- data/lib/jars/lock_down.rb +132 -0
- data/lib/jars/maven_exec.rb +83 -0
- data/lib/jars/maven_settings.rb +61 -0
- data/lib/jars/mima/context-2.4.42.jar +0 -0
- data/lib/jars/mima/jcl-over-slf4j-2.0.17.jar +0 -0
- data/lib/jars/mima/slf4j-api-2.0.17.jar +0 -0
- data/lib/jars/mima/slf4j-simple-2.0.17.jar +0 -0
- data/lib/jars/mima/standalone-static-uber-2.4.42.jar +0 -0
- data/lib/jars/mima/version.rb +42 -0
- data/lib/jars/mima.rb +382 -0
- data/lib/jars/post_install_hook.rb +32 -0
- data/lib/jars/setup.rb +9 -0
- data/lib/jars/version.rb +5 -0
- data/lib/rubygems_plugin.rb +23 -0
- metadata +77 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jars
|
|
4
|
+
module MavenVersion
|
|
5
|
+
class << self
|
|
6
|
+
def resolve(*args)
|
|
7
|
+
return nil if args.empty? || (args.size == 1 && args[0].nil?)
|
|
8
|
+
|
|
9
|
+
low, high = convert(args[0])
|
|
10
|
+
low, high = convert(args[1], low, high) if /[=~><]/.match?(args[1])
|
|
11
|
+
(low == high) ? low : "#{low || '[0'},#{high || ')'}"
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def convert(arg, low = nil, high = nil)
|
|
17
|
+
if arg.include?('~>')
|
|
18
|
+
val = arg.sub(/~>\s*/, '')
|
|
19
|
+
last = val.include?('.') ? val.sub(/\.[0-9]*[a-z]+.*$/, '').sub(/\.[^.]+$/, '.99999') : '99999'
|
|
20
|
+
["[#{snapshot_version(val)}", "#{snapshot_version(last)}]"]
|
|
21
|
+
elsif arg.include?('>=')
|
|
22
|
+
val = arg.sub(/>=\s*/, '')
|
|
23
|
+
["[#{snapshot_version(val)}", high]
|
|
24
|
+
elsif arg.include?('<=')
|
|
25
|
+
val = arg.sub(/<=\s*/, '')
|
|
26
|
+
[low, "#{snapshot_version(val)}]"]
|
|
27
|
+
# treat '!' the same way as '>' since maven cannot describe such range
|
|
28
|
+
elsif /[!>]/.match?(arg)
|
|
29
|
+
val = arg.sub(/[!>]\s*/, '')
|
|
30
|
+
["(#{snapshot_version(val)}", high]
|
|
31
|
+
elsif arg.include?('<')
|
|
32
|
+
val = arg.sub(/<\s*/, '')
|
|
33
|
+
[low, "#{snapshot_version(val)})"]
|
|
34
|
+
elsif arg.include?('=')
|
|
35
|
+
val = arg.sub(/=\s*/, '')
|
|
36
|
+
# for prereleased version pick the maven version (no version range)
|
|
37
|
+
if /[a-z]|[A-Z]/.match?(val)
|
|
38
|
+
[val, val]
|
|
39
|
+
else
|
|
40
|
+
["[#{val}", "#{val}.0.0.0.0.1)"]
|
|
41
|
+
end
|
|
42
|
+
else
|
|
43
|
+
# no conversion here, i.e. assume maven version
|
|
44
|
+
[arg, arg]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def snapshot_version(val)
|
|
49
|
+
if val.match(/[a-z]|[A-Z]/) && !val.match(/-SNAPSHOT|[${}]/)
|
|
50
|
+
"#{val}-SNAPSHOT"
|
|
51
|
+
else
|
|
52
|
+
val
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
class GemspecArtifacts
|
|
59
|
+
class Exclusion
|
|
60
|
+
attr_reader :group_id, :artifact_id
|
|
61
|
+
|
|
62
|
+
def initialize(line)
|
|
63
|
+
@group_id, @artifact_id = line.gsub(/['"]/, '').strip.split(':')
|
|
64
|
+
@artifact_id.strip!
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def to_s
|
|
68
|
+
"#{@group_id}:#{@artifact_id}"
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
class Exclusions < Array
|
|
73
|
+
def to_s
|
|
74
|
+
"[#{join(', ')}]"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def initialize(line)
|
|
78
|
+
super()
|
|
79
|
+
line.gsub(/'"|^\s*\[|\]\s*$/, '').split(/,\s*/).each do |exclusion|
|
|
80
|
+
self << Exclusion.new(exclusion)
|
|
81
|
+
end
|
|
82
|
+
freeze
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
class Artifact
|
|
87
|
+
attr_reader :type, :group_id, :artifact_id, :classifier, :version, :scope, :exclusions
|
|
88
|
+
|
|
89
|
+
ALLOWED_TYPES = %w[jar pom].freeze
|
|
90
|
+
|
|
91
|
+
def initialize(type, group_id, artifact_id, classifier, version, exclusions, **options)
|
|
92
|
+
@type = type
|
|
93
|
+
@group_id = group_id
|
|
94
|
+
@artifact_id = artifact_id
|
|
95
|
+
@classifier = classifier
|
|
96
|
+
@version = version
|
|
97
|
+
@exclusions = exclusions
|
|
98
|
+
options.each do |k, v|
|
|
99
|
+
instance_variable_set(:"@#{k}", v)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def self.parse(line)
|
|
104
|
+
line = line.strip
|
|
105
|
+
index = line.index(/\s/)
|
|
106
|
+
return nil if index.nil?
|
|
107
|
+
|
|
108
|
+
type = line[0..index].strip
|
|
109
|
+
return nil unless ALLOWED_TYPES.member?(type)
|
|
110
|
+
|
|
111
|
+
line = line[index..]
|
|
112
|
+
line.gsub!(/['"]/, '')
|
|
113
|
+
line.strip!
|
|
114
|
+
|
|
115
|
+
options = {}
|
|
116
|
+
line.sub!(/,\s*:exclusions\s*(:|=>)\s*(\[[^\]]+\])/) do
|
|
117
|
+
options[:exclusions] = Exclusions.new(Regexp.last_match(2).strip)
|
|
118
|
+
''
|
|
119
|
+
end
|
|
120
|
+
line.sub!(/,\s*:([a-z]+)\s*(:|=>)\s*(:?[a-zA-Z0-9_]+)/) do
|
|
121
|
+
options[Regexp.last_match(1).to_sym] = Regexp.last_match(3).sub(/^:/, '')
|
|
122
|
+
''
|
|
123
|
+
end
|
|
124
|
+
exclusions = nil
|
|
125
|
+
line.sub!(/[,:]\s*\[(.+:.+,?\s*)+\]$/) do |a|
|
|
126
|
+
exclusions = Exclusions.new(a[1..].strip)
|
|
127
|
+
''
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
line.strip!
|
|
131
|
+
line.gsub!(/,\s*/, ':')
|
|
132
|
+
|
|
133
|
+
if /[\[()\]]/.match?(line)
|
|
134
|
+
index = line.index(/[\[(].+$/)
|
|
135
|
+
version = line[index..].sub(':', ', ')
|
|
136
|
+
line = line[0..(index - 1)].strip.sub(/:$/, '')
|
|
137
|
+
else
|
|
138
|
+
index = line.index(/:[^:]+$/)
|
|
139
|
+
version = line[(index + 1)..]
|
|
140
|
+
line = line[0..(index - 1)].strip
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
case line.count(':')
|
|
144
|
+
when 2
|
|
145
|
+
group_id, artifact_id, classifier = line.split(':')
|
|
146
|
+
when 1
|
|
147
|
+
group_id, artifact_id = line.split(':')
|
|
148
|
+
classifier = nil
|
|
149
|
+
else
|
|
150
|
+
warn line
|
|
151
|
+
return nil
|
|
152
|
+
end
|
|
153
|
+
new(type, group_id, artifact_id, classifier, version, exclusions, **options)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def to_s
|
|
157
|
+
args = [@group_id, @artifact_id]
|
|
158
|
+
args << @classifier if @classifier
|
|
159
|
+
args << @version
|
|
160
|
+
args << @exclusions.to_s if @exclusions
|
|
161
|
+
"#{@type} #{group_id}:#{args[1..].join(', ')}"
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def to_gacv
|
|
165
|
+
args = [@group_id, @artifact_id]
|
|
166
|
+
args << @classifier if @classifier
|
|
167
|
+
args << @version
|
|
168
|
+
args.join(':')
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def to_coord(classifier: true)
|
|
172
|
+
args = [@group_id, @artifact_id]
|
|
173
|
+
args << @classifier if classifier && @classifier
|
|
174
|
+
args << @type
|
|
175
|
+
args << MavenVersion.resolve(@version)
|
|
176
|
+
args.join(':')
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def key
|
|
180
|
+
args = [@group_id, @artifact_id]
|
|
181
|
+
args << @classifier if @classifier
|
|
182
|
+
args.join(':')
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
attr_reader :artifacts
|
|
187
|
+
|
|
188
|
+
def initialize(spec)
|
|
189
|
+
@artifacts = []
|
|
190
|
+
spec.requirements.each do |req|
|
|
191
|
+
req.split("\n").each do |line|
|
|
192
|
+
artifact = Artifact.parse(line)
|
|
193
|
+
@artifacts << artifact if artifact
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
@artifacts.freeze
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def [](index)
|
|
200
|
+
@artifacts[index]
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def each(&block)
|
|
204
|
+
@artifacts.each(&block)
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def size
|
|
208
|
+
@artifacts.size
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'jar_dependencies'
|
|
4
|
+
require 'jars/maven_exec'
|
|
5
|
+
|
|
6
|
+
module Jars
|
|
7
|
+
class Installer
|
|
8
|
+
class Dependency
|
|
9
|
+
EMPTY = ""
|
|
10
|
+
# the trailing ":<file>" of a dependency line; the file may itself contain
|
|
11
|
+
# a ':' on Windows (C:\...), hence the optional drive-letter prefix
|
|
12
|
+
TRAILING_FILE = /:(?<file>(?:[A-Z]:\\)?[^:]+)\z/.freeze
|
|
13
|
+
|
|
14
|
+
# A dependency:list line has the form
|
|
15
|
+
# groupId:artifactId:type[:classifier]:version:scope:/path/to/file
|
|
16
|
+
def self.parse(line)
|
|
17
|
+
return unless /:jar:|:pom:/.match?(line)
|
|
18
|
+
|
|
19
|
+
line = line.dup
|
|
20
|
+
# remove ANSI escape sequences and module section (https://issues.apache.org/jira/browse/MDEP-974)
|
|
21
|
+
line.gsub!(/\e\[\d*m/, EMPTY)
|
|
22
|
+
line.gsub!(/ -- module.*/, EMPTY)
|
|
23
|
+
line.strip!
|
|
24
|
+
|
|
25
|
+
# Peel off the trailing file path first: since it may contain a ':' it
|
|
26
|
+
# cannot take part in the split below. What is left (pre_match) is
|
|
27
|
+
# colon-clean, so every field is addressed by position -- never by
|
|
28
|
+
# matching a keyword, which breaks when an artifact id is itself a scope
|
|
29
|
+
# or type keyword (e.g. "com.dylibso.chicory:runtime:jar:1.7.5").
|
|
30
|
+
tail = line.match(TRAILING_FILE)
|
|
31
|
+
file = tail[:file]
|
|
32
|
+
|
|
33
|
+
# classifier is the only optional field, so there are exactly 5 or 6
|
|
34
|
+
components = tail.pre_match.split(':')
|
|
35
|
+
if components.size == 6
|
|
36
|
+
group_id, artifact_id, type, classifier, version, scope_name = components
|
|
37
|
+
else
|
|
38
|
+
group_id, artifact_id, type, version, scope_name = components
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
coord = [group_id, artifact_id, type, classifier, version].compact.join(':')
|
|
42
|
+
gav = [group_id, artifact_id, classifier, version].compact.join(':')
|
|
43
|
+
path = File.join(*group_id.split('.'), artifact_id, version, file[%r{[^\\/]+\z}])
|
|
44
|
+
|
|
45
|
+
scope =
|
|
46
|
+
case scope_name
|
|
47
|
+
when 'provided'
|
|
48
|
+
:provided
|
|
49
|
+
when 'test'
|
|
50
|
+
:test
|
|
51
|
+
else
|
|
52
|
+
:runtime
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
new(type.to_sym, scope, coord, gav, file, path, scope_name == 'system')
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
attr_reader :path, :file, :gav, :scope, :type, :coord
|
|
59
|
+
|
|
60
|
+
def initialize(type, scope, coord, gav, file, path, system)
|
|
61
|
+
@type = type
|
|
62
|
+
@scope = scope
|
|
63
|
+
@coord = coord
|
|
64
|
+
@gav = gav
|
|
65
|
+
@file = file
|
|
66
|
+
@path = path
|
|
67
|
+
@system = system
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def system?
|
|
71
|
+
@system
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def self.install_jars(write_require_file: false)
|
|
76
|
+
new.install_jars(write_require_file: write_require_file)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def self.load_from_maven(file)
|
|
80
|
+
result = []
|
|
81
|
+
File.read(file).each_line do |line|
|
|
82
|
+
dep = Dependency.parse(line)
|
|
83
|
+
result << dep if dep && dep.scope == :runtime
|
|
84
|
+
end
|
|
85
|
+
result
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def self.vendor_file(dir, dep)
|
|
89
|
+
return unless !dep.system? && dep.type == :jar && dep.scope == :runtime
|
|
90
|
+
|
|
91
|
+
vendored = File.join(dir, dep.path)
|
|
92
|
+
FileUtils.mkdir_p(File.dirname(vendored))
|
|
93
|
+
FileUtils.cp(dep.file, vendored)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def self.print_require_jar(file, dep, fallback: false)
|
|
97
|
+
return if dep.type != :jar || dep.scope != :runtime
|
|
98
|
+
|
|
99
|
+
if dep.system?
|
|
100
|
+
file&.puts("require '#{dep.file}'")
|
|
101
|
+
elsif dep.scope == :runtime
|
|
102
|
+
if fallback
|
|
103
|
+
file&.puts(" require '#{dep.path}'")
|
|
104
|
+
else
|
|
105
|
+
file&.puts(" require_jar '#{dep.gav.gsub(':', "', '")}'")
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
COMMENT = '# this is a generated file, to avoid over-writing it just delete this comment'
|
|
111
|
+
|
|
112
|
+
def self.write_require_jars(deps, require_filename)
|
|
113
|
+
return if !require_filename || (
|
|
114
|
+
File.exist?(require_filename) && !File.read(require_filename).index(COMMENT)
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
FileUtils.mkdir_p(File.dirname(require_filename))
|
|
118
|
+
File.open(require_filename, 'w') do |f|
|
|
119
|
+
f.puts COMMENT
|
|
120
|
+
f.puts 'begin'
|
|
121
|
+
f.puts " require 'jar_dependencies'"
|
|
122
|
+
f.puts 'rescue LoadError'
|
|
123
|
+
deps.each do |dep|
|
|
124
|
+
# do not use require_jar method
|
|
125
|
+
print_require_jar(f, dep, fallback: true)
|
|
126
|
+
end
|
|
127
|
+
f.puts 'end'
|
|
128
|
+
f.puts
|
|
129
|
+
f.puts 'if defined? Jars'
|
|
130
|
+
deps.each do |dep|
|
|
131
|
+
print_require_jar(f, dep)
|
|
132
|
+
end
|
|
133
|
+
f.puts 'end'
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def self.vendor_jars(deps, dir)
|
|
138
|
+
deps.each do |dep|
|
|
139
|
+
vendor_file(dir, dep)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def initialize(spec = nil)
|
|
144
|
+
@mvn = MavenExec.new(spec)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def spec
|
|
148
|
+
@mvn.spec
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def vendor_jars(vendor_dir = nil, write_require_file: true)
|
|
152
|
+
return unless jars?
|
|
153
|
+
|
|
154
|
+
if Jars.to_prop(Jars::VENDOR) == 'false'
|
|
155
|
+
vendor_dir = nil
|
|
156
|
+
else
|
|
157
|
+
vendor_dir ||= spec.require_path
|
|
158
|
+
end
|
|
159
|
+
do_install(vendor_dir, write_require_file)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def self.vendor_jars!(vendor_dir = nil)
|
|
163
|
+
new.vendor_jars!(vendor_dir)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def vendor_jars!(vendor_dir = nil, write_require_file: true)
|
|
167
|
+
vendor_dir ||= spec.require_path
|
|
168
|
+
do_install(vendor_dir, write_require_file)
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def install_jars(write_require_file: true)
|
|
172
|
+
return unless jars?
|
|
173
|
+
|
|
174
|
+
do_install(nil, write_require_file)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def ruby_maven_install_options=(options)
|
|
178
|
+
# no-op: kept for backward compatibility with post_install_hook
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def jars?
|
|
182
|
+
spec = self.spec
|
|
183
|
+
return if spec.nil? # rubocop:disable Style/ReturnNilInPredicateMethodDefinition
|
|
184
|
+
return false unless spec.requirements&.any?
|
|
185
|
+
return false unless spec.runtime_dependencies.find { |s| s.name == 'jar-dependencies' }
|
|
186
|
+
|
|
187
|
+
return true if spec.platform.to_s == 'java'
|
|
188
|
+
|
|
189
|
+
Jars.warn "jar-dependencies found on non-java platform gem; skipping jar installation"
|
|
190
|
+
nil # rubocop:disable Style/ReturnNilInPredicateMethodDefinition
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
private
|
|
194
|
+
|
|
195
|
+
def do_install(vendor_dir, write_require_file)
|
|
196
|
+
require_paths = spec.require_paths
|
|
197
|
+
if vendor_dir && !require_paths.include?(vendor_dir)
|
|
198
|
+
raise "vendor dir #{vendor_dir} not in require_paths of gemspec #{require_paths}"
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
target_dir = File.join(@mvn.basedir, vendor_dir || spec.require_path)
|
|
202
|
+
jars_file = File.join(target_dir, "#{spec.name}_jars.rb")
|
|
203
|
+
|
|
204
|
+
# write out new jars_file if write_require_file is true or check timestamps:
|
|
205
|
+
# do not generate file if specfile is older than the generated file
|
|
206
|
+
if !write_require_file && File.exist?(jars_file) && File.mtime(@mvn.specfile) < File.mtime(jars_file)
|
|
207
|
+
jars_file = nil # leave jars_file as is
|
|
208
|
+
end
|
|
209
|
+
deps = install_dependencies
|
|
210
|
+
self.class.write_require_jars(deps, jars_file)
|
|
211
|
+
self.class.vendor_jars(deps, target_dir) if vendor_dir
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def install_dependencies
|
|
215
|
+
deps = File.join(@mvn.basedir, 'deps.lst')
|
|
216
|
+
|
|
217
|
+
Jars.info("jar dependencies for #{spec.spec_name} ", newline: false)
|
|
218
|
+
@mvn.resolve_dependencies_list(deps)
|
|
219
|
+
Jars.info("") # newline after progress dots
|
|
220
|
+
|
|
221
|
+
self.class.load_from_maven(deps)
|
|
222
|
+
ensure
|
|
223
|
+
FileUtils.rm_f(deps) if deps
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
data/lib/jars/lock.rb
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'jars/maven_exec'
|
|
4
|
+
|
|
5
|
+
module Jars
|
|
6
|
+
class JarDetails < Array
|
|
7
|
+
def scope
|
|
8
|
+
self[-2].to_sym
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def file
|
|
12
|
+
file = self[-1].strip
|
|
13
|
+
file.empty? ? path : file
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def group_id
|
|
17
|
+
self[0]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def artifact_id
|
|
21
|
+
self[1]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def version
|
|
25
|
+
self[-3]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def classifier
|
|
29
|
+
return nil if size == 5
|
|
30
|
+
|
|
31
|
+
self[2]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def gacv
|
|
35
|
+
classifier ? self[0..3] : self[0..2]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def path
|
|
39
|
+
if scope == :system
|
|
40
|
+
# replace maven like system properties embedded into the string
|
|
41
|
+
self[-1].gsub(/\$\{[a-zA-Z.]+\}/) do |a|
|
|
42
|
+
ENV_JAVA[a[2..-2]] || a
|
|
43
|
+
end
|
|
44
|
+
else
|
|
45
|
+
File.join(Jars.home, group_id.gsub(/[.]/, '/'), artifact_id, version, "#{gacv[1..].join('-')}.jar")
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class Lock
|
|
51
|
+
def initialize(file)
|
|
52
|
+
@file = file
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def process(scope)
|
|
56
|
+
scope ||= :runtime
|
|
57
|
+
File.read(@file).each_line do |line|
|
|
58
|
+
next unless /:.+:/.match?(line)
|
|
59
|
+
|
|
60
|
+
jar = JarDetails.new(line.strip.sub(':jar:', ':').sub(/:$/, ': ').split(':'))
|
|
61
|
+
case scope
|
|
62
|
+
when :all, :test
|
|
63
|
+
yield jar
|
|
64
|
+
when :compile
|
|
65
|
+
# jar.scope is maven scope
|
|
66
|
+
yield jar if jar.scope != :test
|
|
67
|
+
when :provided
|
|
68
|
+
# jar.scope is maven scope
|
|
69
|
+
yield jar if jar.scope == :provided
|
|
70
|
+
when :runtime
|
|
71
|
+
# jar.scope is maven scope
|
|
72
|
+
yield jar if (jar.scope != :test) && (jar.scope != :provided)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'jar_dependencies'
|
|
4
|
+
require 'jars/version'
|
|
5
|
+
require 'jars/gemspec_artifacts'
|
|
6
|
+
|
|
7
|
+
module Jars
|
|
8
|
+
class LockDown
|
|
9
|
+
def basedir
|
|
10
|
+
File.expand_path('.')
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def collect_artifacts
|
|
14
|
+
artifacts = []
|
|
15
|
+
done = []
|
|
16
|
+
|
|
17
|
+
attach_jar_coordinates_from_bundler_dependencies(artifacts, done)
|
|
18
|
+
|
|
19
|
+
# Also collect from local gemspec if present
|
|
20
|
+
specs = Dir['*.gemspec']
|
|
21
|
+
if specs.size == 1
|
|
22
|
+
spec = eval(File.read(specs.first), TOPLEVEL_BINDING, specs.first) # rubocop:disable Security/Eval
|
|
23
|
+
ga = GemspecArtifacts.new(spec)
|
|
24
|
+
ga.artifacts.each do |a|
|
|
25
|
+
unless done.include?(a.key)
|
|
26
|
+
artifacts << a
|
|
27
|
+
done << a.key
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
artifacts
|
|
33
|
+
end
|
|
34
|
+
private :collect_artifacts
|
|
35
|
+
|
|
36
|
+
def attach_jar_coordinates_from_bundler_dependencies(artifacts, done)
|
|
37
|
+
load_path = $LOAD_PATH.dup
|
|
38
|
+
require 'bundler'
|
|
39
|
+
# TODO: make this group a commandline option
|
|
40
|
+
Bundler.setup('default')
|
|
41
|
+
cwd = File.expand_path('.')
|
|
42
|
+
Gem.loaded_specs.each_value do |spec|
|
|
43
|
+
all = cwd == spec.full_gem_path # if gemspec is local then include all dependencies
|
|
44
|
+
ga = GemspecArtifacts.new(spec)
|
|
45
|
+
ga.artifacts.each do |a|
|
|
46
|
+
next if done.include?(a.key)
|
|
47
|
+
next unless all || (a.scope != 'provided' && a.scope != 'test')
|
|
48
|
+
|
|
49
|
+
artifacts << a
|
|
50
|
+
done << a.key
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
rescue LoadError => e
|
|
54
|
+
Jars.warn "bundler unavailable (#{e.message}); skipping dependency discovery" if Jars.verbose?
|
|
55
|
+
rescue Bundler::GemfileNotFound
|
|
56
|
+
# bundler is available, but there is no Gemfile to inspect
|
|
57
|
+
rescue Bundler::GemNotFound
|
|
58
|
+
Jars.warn "cannot set up bundler with #{Bundler.default_lockfile}"
|
|
59
|
+
raise
|
|
60
|
+
ensure
|
|
61
|
+
$LOAD_PATH.replace(load_path)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def lock_down(vendor_dir = nil, force: false, update: false, tree: nil) # rubocop:disable Lint/UnusedMethodArgument
|
|
65
|
+
lock_file = File.expand_path(Jars.lock)
|
|
66
|
+
|
|
67
|
+
if !force && File.exist?(lock_file)
|
|
68
|
+
puts 'Jars.lock already exists, use --force to overwrite'
|
|
69
|
+
return
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
artifacts = collect_artifacts
|
|
73
|
+
|
|
74
|
+
if artifacts.empty?
|
|
75
|
+
puts 'no jar dependencies found'
|
|
76
|
+
return
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
puts
|
|
80
|
+
puts '-- jar root dependencies --'
|
|
81
|
+
puts
|
|
82
|
+
artifacts.each do |a|
|
|
83
|
+
puts " #{a.to_gacv}:#{a.scope || 'compile'}"
|
|
84
|
+
puts " exclusions: #{a.exclusions}" if a.exclusions && !a.exclusions.empty?
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context = Jars::Mima.create_context
|
|
88
|
+
begin
|
|
89
|
+
resolved = Jars::Mima.resolve_with_context(context, artifacts, all_dependencies: true)
|
|
90
|
+
ensure
|
|
91
|
+
context.close
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Write Jars.lock
|
|
95
|
+
File.open(lock_file, 'w') do |f|
|
|
96
|
+
resolved.each do |dep|
|
|
97
|
+
next unless dep.type == 'jar'
|
|
98
|
+
|
|
99
|
+
f.puts dep.to_lock_entry
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Optionally vendor jars
|
|
104
|
+
if vendor_dir
|
|
105
|
+
require 'fileutils'
|
|
106
|
+
vendor_path = File.expand_path(vendor_dir)
|
|
107
|
+
resolved.each do |dep|
|
|
108
|
+
next unless dep.type == 'jar' && dep.runtime? && !dep.system?
|
|
109
|
+
|
|
110
|
+
target = File.join(vendor_path, dep.jar_path)
|
|
111
|
+
FileUtils.mkdir_p(File.dirname(target))
|
|
112
|
+
FileUtils.cp(dep.file, target)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
if tree
|
|
117
|
+
puts
|
|
118
|
+
puts '-- jar dependency tree --'
|
|
119
|
+
puts
|
|
120
|
+
resolved.each do |dep|
|
|
121
|
+
prefix = dep.classifier ? "#{dep.classifier}:" : ''
|
|
122
|
+
puts " #{dep.group_id}:#{dep.artifact_id}:#{prefix}#{dep.version}:#{dep.scope}"
|
|
123
|
+
end
|
|
124
|
+
puts
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
puts
|
|
128
|
+
puts File.read(lock_file)
|
|
129
|
+
puts
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|