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,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'jar_dependencies'
|
|
4
|
+
require 'jars/gemspec_artifacts'
|
|
5
|
+
|
|
6
|
+
module Jars
|
|
7
|
+
class MavenExec
|
|
8
|
+
def find_spec(allow_no_file)
|
|
9
|
+
specs = Dir['*.gemspec']
|
|
10
|
+
case specs.size
|
|
11
|
+
when 0
|
|
12
|
+
raise 'no gemspec found' unless allow_no_file
|
|
13
|
+
when 1
|
|
14
|
+
specs.first
|
|
15
|
+
else
|
|
16
|
+
raise 'more than one gemspec found; please specify a specfile' unless allow_no_file
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
private :find_spec
|
|
20
|
+
|
|
21
|
+
attr_reader :basedir, :spec, :specfile
|
|
22
|
+
|
|
23
|
+
def initialize(spec = nil)
|
|
24
|
+
setup(spec)
|
|
25
|
+
rescue StandardError, LoadError => e
|
|
26
|
+
Jars.warn "unable to load gemspec (#{e.message}); skipping jar dependency discovery"
|
|
27
|
+
Jars.debug(e)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def setup(spec = nil, allow_no_file: false)
|
|
31
|
+
spec ||= find_spec(allow_no_file)
|
|
32
|
+
|
|
33
|
+
case spec
|
|
34
|
+
when String
|
|
35
|
+
@specfile = File.expand_path(spec)
|
|
36
|
+
@basedir = File.dirname(@specfile)
|
|
37
|
+
Dir.chdir(@basedir) do
|
|
38
|
+
spec = eval(File.read(@specfile), TOPLEVEL_BINDING, @specfile) # rubocop:disable Security/Eval
|
|
39
|
+
end
|
|
40
|
+
when Gem::Specification
|
|
41
|
+
if File.exist?(spec.loaded_from)
|
|
42
|
+
@basedir = spec.gem_dir
|
|
43
|
+
@specfile = spec.loaded_from
|
|
44
|
+
else
|
|
45
|
+
# this happens with bundle and local gems
|
|
46
|
+
# there spec_file is "not installed" but is inside the gem_dir directory
|
|
47
|
+
Dir.chdir(spec.gem_dir) do
|
|
48
|
+
setup(nil, allow_no_file: true)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
when nil
|
|
52
|
+
# ignore
|
|
53
|
+
else
|
|
54
|
+
Jars.debug "unsupported spec argument #{spec.class}; expected String or Gem::Specification"
|
|
55
|
+
end
|
|
56
|
+
@spec = spec
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def resolve_dependencies_list(file)
|
|
60
|
+
require 'jars/mima'
|
|
61
|
+
|
|
62
|
+
artifacts = GemspecArtifacts.new(@spec)
|
|
63
|
+
is_local_file = File.expand_path(File.dirname(@specfile)) == File.expand_path(Dir.pwd)
|
|
64
|
+
|
|
65
|
+
resolved = Jars::Mima.resolve_artifacts(artifacts.artifacts, all_dependencies: is_local_file)
|
|
66
|
+
|
|
67
|
+
# Write output in Maven dependency:list format for Installer::Dependency compatibility
|
|
68
|
+
allowed_types = %w[jar pom].freeze
|
|
69
|
+
File.open(file, 'w') do |f|
|
|
70
|
+
f.puts
|
|
71
|
+
f.puts 'The following files have been resolved:'
|
|
72
|
+
resolved.each do |dep|
|
|
73
|
+
next unless allowed_types.include?(dep.type)
|
|
74
|
+
|
|
75
|
+
line = +" #{dep.group_id}:#{dep.artifact_id}:#{dep.type}:"
|
|
76
|
+
line << "#{dep.classifier}:" if dep.classifier
|
|
77
|
+
line << "#{dep.version}:#{dep.scope}:#{dep.file}"
|
|
78
|
+
f.puts line
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jars
|
|
4
|
+
class MavenSettings
|
|
5
|
+
class << self
|
|
6
|
+
def local_settings
|
|
7
|
+
@_jars_maven_local_settings_ = nil unless instance_variable_defined?(:@_jars_maven_local_settings_)
|
|
8
|
+
if @_jars_maven_local_settings_.nil?
|
|
9
|
+
settings = Jars.absolute('settings.xml')
|
|
10
|
+
@_jars_maven_local_settings_ =
|
|
11
|
+
if settings && File.exist?(settings)
|
|
12
|
+
settings
|
|
13
|
+
else
|
|
14
|
+
false
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
@_jars_maven_local_settings_ || nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def user_settings
|
|
21
|
+
@_jars_maven_user_settings_ = nil unless instance_variable_defined?(:@_jars_maven_user_settings_)
|
|
22
|
+
if @_jars_maven_user_settings_.nil?
|
|
23
|
+
if (settings = Jars.absolute(Jars.to_prop(MAVEN_SETTINGS)))
|
|
24
|
+
unless File.exist?(settings)
|
|
25
|
+
Jars.warn { "configured ENV['#{MAVEN_SETTINGS}'] = '#{settings}' not found" }
|
|
26
|
+
settings = false
|
|
27
|
+
end
|
|
28
|
+
else # use maven default (user) settings
|
|
29
|
+
settings = File.join(Jars.user_home, '.m2', 'settings.xml')
|
|
30
|
+
settings = false unless File.exist?(settings)
|
|
31
|
+
end
|
|
32
|
+
@_jars_maven_user_settings_ = settings
|
|
33
|
+
end
|
|
34
|
+
@_jars_maven_user_settings_ || nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def settings
|
|
38
|
+
@_jars_maven_settings_ = nil unless instance_variable_defined?(:@_jars_maven_settings_)
|
|
39
|
+
local_settings || user_settings if @_jars_maven_settings_.nil?
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def global_settings
|
|
43
|
+
@_jars_maven_global_settings_ = nil unless instance_variable_defined?(:@_jars_maven_global_settings_)
|
|
44
|
+
if @_jars_maven_global_settings_.nil?
|
|
45
|
+
if (mvn_home = ENV['M2_HOME'] || ENV['MAVEN_HOME'])
|
|
46
|
+
settings = File.join(mvn_home, 'conf/settings.xml')
|
|
47
|
+
settings = false unless File.exist?(settings)
|
|
48
|
+
else
|
|
49
|
+
settings = false
|
|
50
|
+
end
|
|
51
|
+
@_jars_maven_global_settings_ = settings
|
|
52
|
+
end
|
|
53
|
+
@_jars_maven_global_settings_ || nil
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def reset
|
|
57
|
+
instance_variables.each { |var| instance_variable_set(var, nil) }
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Jars
|
|
4
|
+
module Mima
|
|
5
|
+
MIMA_VERSION = '2.4.42'
|
|
6
|
+
SLF4J_VERSION = '2.0.17'
|
|
7
|
+
|
|
8
|
+
MAVEN_CENTRAL = 'https://repo.maven.apache.org/maven2'
|
|
9
|
+
MIMA_DIR = 'lib/jars/mima'
|
|
10
|
+
|
|
11
|
+
# GAV and SHA-1 checksum (as published on Maven Central) for each jar
|
|
12
|
+
jars = %w[
|
|
13
|
+
org.slf4j:slf4j-api:2.0.17
|
|
14
|
+
d9e58ac9c7779ba3bf8142aff6c830617a7fe60f
|
|
15
|
+
|
|
16
|
+
org.slf4j:slf4j-simple:2.0.17
|
|
17
|
+
9872a3fd794ffe7b18d17747926a64d61526ca96
|
|
18
|
+
|
|
19
|
+
org.slf4j:jcl-over-slf4j:2.0.17
|
|
20
|
+
76ea503eb688f06556a9ba69995d7eab63e34531
|
|
21
|
+
|
|
22
|
+
eu.maveniverse.maven.mima:context:2.4.42
|
|
23
|
+
72aa4d9ccef7a329f473e43752ec863c5194c72c
|
|
24
|
+
|
|
25
|
+
eu.maveniverse.maven.mima.runtime:standalone-static-uber:2.4.42
|
|
26
|
+
43666099e6eb31610f9d3b146811479dd3e4aef1
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
JARS = jars.each_slice(2).to_h do |gav, sha1|
|
|
30
|
+
group, artifact, version = gav.split(':')
|
|
31
|
+
group = group.tr('.', '/')
|
|
32
|
+
jar_file = "#{artifact}-#{version}.jar"
|
|
33
|
+
[
|
|
34
|
+
jar_file,
|
|
35
|
+
{
|
|
36
|
+
url: "#{MAVEN_CENTRAL}/#{group}/#{artifact}/#{version}/#{jar_file}",
|
|
37
|
+
sha1: sha1
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
data/lib/jars/mima.rb
ADDED
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'jars/mima/version'
|
|
4
|
+
require 'jars/gemspec_artifacts'
|
|
5
|
+
|
|
6
|
+
module Jars
|
|
7
|
+
# Resolver backed by the Mima Java library (MIni MAven).
|
|
8
|
+
# Replaces the previous ruby-maven based resolution pipeline.
|
|
9
|
+
#
|
|
10
|
+
# Mima wraps the Maven Resolver (Aether) API as a standalone library (no Maven process is spawned).
|
|
11
|
+
module Mima
|
|
12
|
+
class << self
|
|
13
|
+
@@jars_loaded = nil # rubocop:disable Style/ClassVars
|
|
14
|
+
|
|
15
|
+
# Loads the bundled Mima jars onto the classpath.
|
|
16
|
+
# Safe to call multiple times; only loads once.
|
|
17
|
+
def ensure_jars_loaded
|
|
18
|
+
return if @@jars_loaded
|
|
19
|
+
|
|
20
|
+
configure_logging if Jars.debug?
|
|
21
|
+
|
|
22
|
+
mima_dir = File.expand_path('mima', File.dirname(__FILE__))
|
|
23
|
+
|
|
24
|
+
load File.join(mima_dir, "slf4j-api-#{SLF4J_VERSION}.jar")
|
|
25
|
+
load File.join(mima_dir, "slf4j-simple-#{SLF4J_VERSION}.jar")
|
|
26
|
+
load File.join(mima_dir, "jcl-over-slf4j-#{SLF4J_VERSION}.jar")
|
|
27
|
+
load File.join(mima_dir, "context-#{MIMA_VERSION}.jar")
|
|
28
|
+
load File.join(mima_dir, "standalone-static-uber-#{MIMA_VERSION}.jar")
|
|
29
|
+
|
|
30
|
+
@@jars_loaded = true # rubocop:disable Style/ClassVars
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Builds a +ContextOverrides+ from jar-dependencies configuration
|
|
34
|
+
# (local repo, user/global settings.xml).
|
|
35
|
+
#
|
|
36
|
+
# @return [Java::eu.maveniverse.maven.mima.context.ContextOverrides]
|
|
37
|
+
def context_overrides
|
|
38
|
+
ensure_jars_loaded
|
|
39
|
+
|
|
40
|
+
builder = Java::eu.maveniverse.maven.mima.context.ContextOverrides.create
|
|
41
|
+
builder.withUserSettings(true)
|
|
42
|
+
|
|
43
|
+
# Local repository override
|
|
44
|
+
local_repo = ::Jars.local_maven_repo
|
|
45
|
+
builder.withLocalRepositoryOverride(java.nio.file.Paths.get(local_repo)) if local_repo
|
|
46
|
+
|
|
47
|
+
# User settings.xml override
|
|
48
|
+
settings = ::Jars::MavenSettings.settings
|
|
49
|
+
builder.withUserSettingsXmlOverride(java.nio.file.Paths.get(settings)) if settings
|
|
50
|
+
|
|
51
|
+
# Global settings.xml override
|
|
52
|
+
global = ::Jars::MavenSettings.global_settings
|
|
53
|
+
builder.withGlobalSettingsXmlOverride(java.nio.file.Paths.get(global)) if global
|
|
54
|
+
|
|
55
|
+
builder.repositoryListener(aether_repository_listener)
|
|
56
|
+
builder.transferListener(aether_transfer_listener)
|
|
57
|
+
builder.build
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Creates a Mima Context. Caller is responsible for closing it.
|
|
61
|
+
#
|
|
62
|
+
# @param overrides [Java::eu.maveniverse.maven.mima.context.ContextOverrides, nil]
|
|
63
|
+
# optional overrides; when +nil+, {#context_overrides} is used
|
|
64
|
+
# @return [Java::eu.maveniverse.maven.mima.context.Context]
|
|
65
|
+
def create_context(overrides = nil)
|
|
66
|
+
ensure_jars_loaded
|
|
67
|
+
|
|
68
|
+
overrides ||= context_overrides
|
|
69
|
+
runtime = Java::eu.maveniverse.maven.mima.context.Runtimes::INSTANCE.getRuntime
|
|
70
|
+
runtime.create(overrides)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Resolves transitive dependencies for the given artifacts.
|
|
74
|
+
# Creates (and closes) its own Mima context.
|
|
75
|
+
#
|
|
76
|
+
# @param artifacts [Array<Jars::GemspecArtifacts::Artifact>] jar dependency declarations
|
|
77
|
+
# @param all_dependencies [Boolean] when +true+, include provided/test scoped artifacts
|
|
78
|
+
# @return [Array<ResolvedDependency>] resolved artifacts with local file paths
|
|
79
|
+
def resolve_artifacts(artifacts, all_dependencies: false)
|
|
80
|
+
context = create_context
|
|
81
|
+
begin
|
|
82
|
+
resolve_with_context(context, artifacts, all_dependencies: all_dependencies)
|
|
83
|
+
ensure
|
|
84
|
+
context.close
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Resolves transitive dependencies using an existing Mima context.
|
|
89
|
+
#
|
|
90
|
+
# @param context [Java::eu.maveniverse.maven.mima.context.Context] an open Mima context
|
|
91
|
+
# @param artifacts [Array<Jars::GemspecArtifacts::Artifact>] jar dependency declarations
|
|
92
|
+
# @param all_dependencies [Boolean] when +true+, include provided/test scoped artifacts
|
|
93
|
+
# @return [Array<ResolvedDependency>] resolved artifacts with local file paths
|
|
94
|
+
def resolve_with_context(context, artifacts, all_dependencies: false)
|
|
95
|
+
deps = artifacts_to_dependencies(artifacts, all_dependencies: all_dependencies)
|
|
96
|
+
return [] if deps.empty?
|
|
97
|
+
|
|
98
|
+
collect_request = org.eclipse.aether.collection.CollectRequest.new
|
|
99
|
+
deps.each { |d| collect_request.addDependency(d) }
|
|
100
|
+
collect_request.setRepositories(context.remoteRepositories)
|
|
101
|
+
|
|
102
|
+
dependency_request = org.eclipse.aether.resolution.DependencyRequest.new
|
|
103
|
+
dependency_request.setCollectRequest(collect_request)
|
|
104
|
+
|
|
105
|
+
result = context.repositorySystem.resolveDependencies(
|
|
106
|
+
context.repositorySystemSession, dependency_request
|
|
107
|
+
)
|
|
108
|
+
collect_resolved(result.getRoot)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
private
|
|
112
|
+
|
|
113
|
+
def configure_logging
|
|
114
|
+
return unless Object.const_defined?(:ENV_JAVA)
|
|
115
|
+
|
|
116
|
+
set_default_java_property('org.slf4j.simpleLogger.defaultLogLevel', 'info')
|
|
117
|
+
set_default_java_property('org.slf4j.simpleLogger.showThreadName', 'false')
|
|
118
|
+
set_default_java_property('org.slf4j.simpleLogger.log.org.apache.maven', 'debug')
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def set_default_java_property(key, value)
|
|
122
|
+
ENV_JAVA[key] = value unless ENV_JAVA[key]
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def aether_repository_listener
|
|
126
|
+
org.eclipse.aether.RepositoryListener.impl do |method, event|
|
|
127
|
+
case method
|
|
128
|
+
when :artifactDescriptorInvalid
|
|
129
|
+
Jars.debug { "[mima] invalid artifact descriptor #{artifact_label(event.getArtifact)}" }
|
|
130
|
+
when :artifactDescriptorMissing
|
|
131
|
+
Jars.debug { "[mima] missing artifact descriptor #{artifact_label(event.getArtifact)}" }
|
|
132
|
+
when :metadataInvalid
|
|
133
|
+
Jars.debug { "[mima] invalid metadata #{metadata_label(event.getMetadata)}" }
|
|
134
|
+
when :artifactResolving
|
|
135
|
+
progress_dot
|
|
136
|
+
Jars.debug { "[mima] resolving artifact #{artifact_label(event.getArtifact)}" }
|
|
137
|
+
when :artifactResolved
|
|
138
|
+
Jars.debug { resolved_message('artifact', event) }
|
|
139
|
+
when :metadataResolving
|
|
140
|
+
progress_dot
|
|
141
|
+
Jars.debug { "[mima] resolving metadata #{metadata_label(event.getMetadata)}" }
|
|
142
|
+
when :metadataResolved
|
|
143
|
+
Jars.debug { resolved_message('metadata', event) }
|
|
144
|
+
when :artifactDownloading
|
|
145
|
+
progress_dot
|
|
146
|
+
Jars.debug { download_message('artifact', event) }
|
|
147
|
+
when :artifactDownloaded
|
|
148
|
+
Jars.debug { downloaded_message('artifact', event) }
|
|
149
|
+
when :metadataDownloading
|
|
150
|
+
progress_dot
|
|
151
|
+
Jars.debug { download_message('metadata', event) }
|
|
152
|
+
when :metadataDownloaded
|
|
153
|
+
Jars.debug { downloaded_message('metadata', event) }
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def aether_transfer_listener
|
|
159
|
+
org.eclipse.aether.transfer.TransferListener.impl do |method, event|
|
|
160
|
+
case method
|
|
161
|
+
when :transferInitiated
|
|
162
|
+
Jars.debug { transfer_message('initiated', event) }
|
|
163
|
+
when :transferStarted
|
|
164
|
+
Jars.debug { transfer_message('started', event) }
|
|
165
|
+
when :transferCorrupted
|
|
166
|
+
Jars.debug { transfer_message('corrupted', event) }
|
|
167
|
+
when :transferSucceeded
|
|
168
|
+
Jars.debug { transfer_message('succeeded', event, bytes: true) }
|
|
169
|
+
when :transferFailed
|
|
170
|
+
Jars.debug { transfer_message('failed', event) }
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Emits a single progress dot (no newline) unless in debug mode
|
|
176
|
+
def progress_dot
|
|
177
|
+
Jars.info('.', newline: false) unless Jars.debug?
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def resolved_message(kind, event)
|
|
181
|
+
message = +"[mima] resolved #{kind} #{repository_item_label(event)}"
|
|
182
|
+
message << " -> #{event.getFile.getAbsolutePath}" if event.getFile
|
|
183
|
+
message << " (#{event.getException.message})" if event.getException
|
|
184
|
+
message
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def download_message(kind, event)
|
|
188
|
+
message = +"[mima] downloading #{kind} #{repository_item_label(event)}"
|
|
189
|
+
repository = event.getRepository
|
|
190
|
+
message << " from #{repository}" if repository
|
|
191
|
+
message
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def downloaded_message(kind, event)
|
|
195
|
+
message = +"[mima] downloaded #{kind} #{repository_item_label(event)}"
|
|
196
|
+
message << " -> #{event.getFile.getAbsolutePath}" if event.getFile
|
|
197
|
+
message << " (#{event.getException.message})" if event.getException
|
|
198
|
+
message
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def repository_item_label(event)
|
|
202
|
+
artifact = event.getArtifact
|
|
203
|
+
return artifact_label(artifact) if artifact
|
|
204
|
+
|
|
205
|
+
metadata_label(event.getMetadata)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def artifact_label(artifact)
|
|
209
|
+
artifact&.to_s || 'unknown'
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def metadata_label(metadata)
|
|
213
|
+
metadata&.to_s || 'unknown'
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def transfer_message(action, event, bytes: false)
|
|
217
|
+
resource = event.getResource
|
|
218
|
+
location = "#{resource.getRepositoryUrl}#{resource.getResourceName}"
|
|
219
|
+
message = +"[mima] transfer #{action} #{event.getRequestType.to_s.downcase} #{location}"
|
|
220
|
+
message << " (#{format_bytes(event.getTransferredBytes)})" if bytes
|
|
221
|
+
message << " (#{event.getException})" if event.getException
|
|
222
|
+
message
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def format_bytes(bytes)
|
|
226
|
+
return "#{bytes} B" if bytes < 1024
|
|
227
|
+
|
|
228
|
+
"#{(bytes / 1024.0).round(1)} KB"
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# Converts {GemspecArtifacts::Artifact} objects to Aether +Dependency+ list,
|
|
232
|
+
# filtering by scope unless +all_dependencies+ is set.
|
|
233
|
+
#
|
|
234
|
+
# @param artifacts [Array<Jars::GemspecArtifacts::Artifact>]
|
|
235
|
+
# @param all_dependencies [Boolean]
|
|
236
|
+
# @return [Array<org.eclipse.aether.graph.Dependency>]
|
|
237
|
+
def artifacts_to_dependencies(artifacts, all_dependencies: false)
|
|
238
|
+
filtered_artifacts = artifacts.select do |artifact|
|
|
239
|
+
all_dependencies || (artifact.scope != 'provided' && artifact.scope != 'test')
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
filtered_artifacts.map do |artifact|
|
|
243
|
+
aether_artifact = build_aether_artifact(artifact)
|
|
244
|
+
scope = artifact.scope || 'compile'
|
|
245
|
+
dep = org.eclipse.aether.graph.Dependency.new(aether_artifact, scope)
|
|
246
|
+
|
|
247
|
+
if artifact.exclusions && !artifact.exclusions.empty?
|
|
248
|
+
exclusions = artifact.exclusions.map do |ex|
|
|
249
|
+
org.eclipse.aether.graph.Exclusion.new(ex.group_id, ex.artifact_id, '*', '*')
|
|
250
|
+
end
|
|
251
|
+
dep = dep.setExclusions(exclusions)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
dep
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
# Converts a single {GemspecArtifacts::Artifact} to an Aether +DefaultArtifact+.
|
|
259
|
+
#
|
|
260
|
+
# @param artifact [Jars::GemspecArtifacts::Artifact]
|
|
261
|
+
# @return [org.eclipse.aether.artifact.DefaultArtifact]
|
|
262
|
+
def build_aether_artifact(artifact)
|
|
263
|
+
version = Jars::MavenVersion.resolve(artifact.version) || artifact.version
|
|
264
|
+
if artifact.classifier
|
|
265
|
+
org.eclipse.aether.artifact.DefaultArtifact.new(
|
|
266
|
+
artifact.group_id, artifact.artifact_id, artifact.classifier,
|
|
267
|
+
artifact.type || 'jar', version
|
|
268
|
+
)
|
|
269
|
+
else
|
|
270
|
+
org.eclipse.aether.artifact.DefaultArtifact.new(
|
|
271
|
+
artifact.group_id, artifact.artifact_id,
|
|
272
|
+
artifact.type || 'jar', version
|
|
273
|
+
)
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
# Walks the resolved dependency tree and collects {ResolvedDependency} objects.
|
|
278
|
+
#
|
|
279
|
+
# @param node [org.eclipse.aether.graph.DependencyNode] root of the resolved tree
|
|
280
|
+
# @param result [Array<ResolvedDependency>] accumulator
|
|
281
|
+
# @return [Array<ResolvedDependency>]
|
|
282
|
+
def collect_resolved(node, result = [])
|
|
283
|
+
node.getChildren.each do |child|
|
|
284
|
+
dep = child.getDependency
|
|
285
|
+
next unless dep
|
|
286
|
+
|
|
287
|
+
artifact = dep.getArtifact
|
|
288
|
+
next unless artifact.getFile # skip unresolved
|
|
289
|
+
|
|
290
|
+
result << ResolvedDependency.new(
|
|
291
|
+
artifact.getGroupId,
|
|
292
|
+
artifact.getArtifactId,
|
|
293
|
+
artifact.getVersion,
|
|
294
|
+
artifact.getClassifier.to_s.empty? ? nil : artifact.getClassifier,
|
|
295
|
+
artifact.getExtension,
|
|
296
|
+
dep.getScope,
|
|
297
|
+
artifact.getFile.getAbsolutePath
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
collect_resolved(child, result)
|
|
301
|
+
end
|
|
302
|
+
result
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Structured result from dependency resolution.
|
|
307
|
+
#
|
|
308
|
+
# @!attribute [r] group_id
|
|
309
|
+
# @return [String] Maven group ID
|
|
310
|
+
# @!attribute [r] artifact_id
|
|
311
|
+
# @return [String] Maven artifact ID
|
|
312
|
+
# @!attribute [r] version
|
|
313
|
+
# @return [String] resolved version
|
|
314
|
+
# @!attribute [r] classifier
|
|
315
|
+
# @return [String, nil] Maven classifier (e.g. +"sources"+, +"no_aop"+)
|
|
316
|
+
# @!attribute [r] type
|
|
317
|
+
# @return [String] artifact type/extension (e.g. +"jar"+, +"pom"+)
|
|
318
|
+
# @!attribute [r] scope
|
|
319
|
+
# @return [String] Maven scope (+"compile"+, +"runtime"+, +"test"+, +"provided"+, +"system"+)
|
|
320
|
+
# @!attribute [r] file
|
|
321
|
+
# @return [String] absolute path to the resolved artifact in the local repository
|
|
322
|
+
ResolvedDependency = Struct.new(:group_id, :artifact_id, :version, :classifier, :type, :scope, :file) do
|
|
323
|
+
# @return [Boolean] true if scope is neither +test+ nor +provided+
|
|
324
|
+
def runtime?
|
|
325
|
+
scope != 'test' && scope != 'provided'
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# @return [Boolean] true if scope is +system+
|
|
329
|
+
def system?
|
|
330
|
+
scope == 'system'
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
# Maven repository layout path relative to repo root.
|
|
334
|
+
#
|
|
335
|
+
# @return [String] e.g. +"org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar"+
|
|
336
|
+
def path
|
|
337
|
+
parts = group_id.split('.')
|
|
338
|
+
parts << artifact_id
|
|
339
|
+
parts << version
|
|
340
|
+
filename = +"#{artifact_id}-#{version}"
|
|
341
|
+
filename << "-#{classifier}" if classifier
|
|
342
|
+
filename << ".#{type || 'jar'}"
|
|
343
|
+
parts << filename
|
|
344
|
+
File.join(parts)
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
# Formats a line suitable for the +Jars.lock+ file.
|
|
348
|
+
#
|
|
349
|
+
# @return [String] e.g. +"org.slf4j:slf4j-api:1.7.36:compile:"+
|
|
350
|
+
def to_lock_entry
|
|
351
|
+
entry = +"#{group_id}:#{artifact_id}:"
|
|
352
|
+
entry << "#{classifier}:" if classifier
|
|
353
|
+
entry << "#{version}:#{scope}:"
|
|
354
|
+
entry
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
# Colon-separated GAV string suitable for +require_jar+ calls.
|
|
358
|
+
#
|
|
359
|
+
# @return [String] e.g. +"org.slf4j:slf4j-api:1.7.36"+
|
|
360
|
+
def gav
|
|
361
|
+
parts = [group_id, artifact_id]
|
|
362
|
+
parts << classifier if classifier
|
|
363
|
+
parts << version
|
|
364
|
+
parts.join(':')
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
# Relative jar path for vendoring / +require_jar+.
|
|
368
|
+
#
|
|
369
|
+
# @return [String] e.g. +"org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar"+
|
|
370
|
+
def jar_path
|
|
371
|
+
parts = group_id.split('.')
|
|
372
|
+
parts << artifact_id
|
|
373
|
+
parts << version
|
|
374
|
+
filename = +"#{artifact_id}-#{version}"
|
|
375
|
+
filename << "-#{classifier}" if classifier
|
|
376
|
+
filename << '.jar'
|
|
377
|
+
parts << filename
|
|
378
|
+
File.join(parts)
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2014 Christian Meier
|
|
5
|
+
#
|
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
7
|
+
# this software and associated documentation files (the "Software"), to deal in
|
|
8
|
+
# the Software without restriction, including without limitation the rights to
|
|
9
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
10
|
+
# the Software, and to permit persons to whom the Software is furnished to do so,
|
|
11
|
+
# subject to the following conditions:
|
|
12
|
+
#
|
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
# copies or substantial portions of the Software.
|
|
15
|
+
#
|
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
18
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
19
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
20
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
21
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
#
|
|
23
|
+
|
|
24
|
+
if defined?(JRUBY_VERSION) && Gem.post_install_hooks.empty?
|
|
25
|
+
Gem.post_install do |gem_installer|
|
|
26
|
+
if ENV['JARS_SKIP'] != 'true' && ENV_JAVA['jars.skip'] != 'true'
|
|
27
|
+
require 'jars/installer'
|
|
28
|
+
jars = Jars::Installer.new(gem_installer.spec)
|
|
29
|
+
jars.vendor_jars
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
data/lib/jars/setup.rb
ADDED
data/lib/jars/version.rb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Copyright (C) 2014 Christian Meier
|
|
5
|
+
#
|
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
7
|
+
# this software and associated documentation files (the "Software"), to deal in
|
|
8
|
+
# the Software without restriction, including without limitation the rights to
|
|
9
|
+
# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
10
|
+
# the Software, and to permit persons to whom the Software is furnished to do so,
|
|
11
|
+
# subject to the following conditions:
|
|
12
|
+
#
|
|
13
|
+
# The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
# copies or substantial portions of the Software.
|
|
15
|
+
#
|
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
18
|
+
# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
19
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
20
|
+
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
21
|
+
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
#
|
|
23
|
+
require 'jars/post_install_hook'
|