Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 11 additions & 15 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
name: Ruby
name: jar-dependencies

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
on: [push, pull_request]

jobs:
test:

runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
ruby-version: [jruby-9.3, jruby-9.4, jruby-10.0]
ruby-version: [jruby-9.4, jruby-10.0, jruby-head]

steps:
- uses: actions/checkout@v5
- name: Set up Ruby
- uses: actions/checkout@v6
- name: Set up JRuby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true
- name: Install dependencies
run: bundle install
- name: Run test
run: jruby -Ilib -rbundler/setup -S rake specs
- name: Download Mima jars
run: bundle exec rake download_jars
- name: Run tests
run: bundle exec rake specs
- name: Run RuboCop
if: matrix.ruby-version == 'jruby-10.0' # Only run RuboCop on modern JRuby; target older jrubies via .rubocop.yml
run: jruby -Ilib -rbundler/setup -S rubocop lib specs
run: bundle exec rubocop lib
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ build.log
pom*
specs/repository/*
example/dependencies.list
lib/jars/mima/*.jar
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

source 'https://rubygems.org'
source 'https://gem.coop'

gemspec

Expand Down
45 changes: 45 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ task default: [:specs]

require 'bundler/gem_tasks'
require 'rubocop/rake_task'
require 'rake/clean'

RuboCop::RakeTask.new

Expand All @@ -15,3 +16,47 @@ task :specs do
require File.basename(f.sub(/.rb$/, ''))
end
end

require_relative 'lib/jars/mima/version'

MIMA_VERSION = Jars::Mima::MIMA_VERSION
SLF4J_VERSION = Jars::Mima::SLF4J_VERSION
MAVEN_CENTRAL = 'https://repo.maven.apache.org/maven2'
MIMA_DIR = 'lib/jars/mima'

MIMA_JARS = {
"slf4j-api-#{SLF4J_VERSION}.jar" =>
"#{MAVEN_CENTRAL}/org/slf4j/slf4j-api/#{SLF4J_VERSION}/slf4j-api-#{SLF4J_VERSION}.jar",
"slf4j-simple-#{SLF4J_VERSION}.jar" =>
"#{MAVEN_CENTRAL}/org/slf4j/slf4j-simple/#{SLF4J_VERSION}/slf4j-simple-#{SLF4J_VERSION}.jar",
"jcl-over-slf4j-#{SLF4J_VERSION}.jar" =>
"#{MAVEN_CENTRAL}/org/slf4j/jcl-over-slf4j/#{SLF4J_VERSION}/jcl-over-slf4j-#{SLF4J_VERSION}.jar",
"context-#{MIMA_VERSION}.jar" =>
"#{MAVEN_CENTRAL}/eu/maveniverse/maven/mima/context/#{MIMA_VERSION}/context-#{MIMA_VERSION}.jar",
"standalone-static-uber-#{MIMA_VERSION}.jar" =>
"#{MAVEN_CENTRAL}/eu/maveniverse/maven/mima/runtime/standalone-static-uber/#{MIMA_VERSION}/standalone-static-uber-#{MIMA_VERSION}.jar"
}

MIMA_JARS.each_key { |jar| CLEAN.include(File.join(MIMA_DIR, jar)) }

desc 'download Mima (and dependent SLF4J) jars'
task :download_jars do
require 'fileutils'
require 'open-uri'

FileUtils.mkdir_p(MIMA_DIR)

MIMA_JARS.each do |filename, url|
target = File.join(MIMA_DIR, filename)
if File.exist?(target)
puts " exists: #{target}"
next
end

puts " downloading #{filename}..."
URI.open(url) do |remote| # rubocop:disable Security/Open
File.open(target, 'wb') { |f| f.write(remote.read) }
end
puts " saved: #{target}"
end
end
14 changes: 1 addition & 13 deletions jar-dependencies.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Gem::Specification.new do |s|
s.homepage = 'https://github.com/jruby/jar-dependencies'

s.bindir = 'exe'
s.executables = [lock_jars = 'lock_jars']
s.executables = ['lock_jars']

s.license = 'MIT'

Expand All @@ -30,18 +30,6 @@ Gem::Specification.new do |s|
s.required_ruby_version = '>= 2.6'

s.add_development_dependency 'minitest', '~> 5.10'
s.add_development_dependency 'ruby-maven', ruby_maven_version = '~> 3.9'

s.post_install_message = <<~TEXT

if you want to use the executable #{lock_jars} then install ruby-maven gem before using #{lock_jars}

$ gem install ruby-maven -v '#{ruby_maven_version}'

or add it as a development dependency to your Gemfile

gem 'ruby-maven', '#{ruby_maven_version}'

TEXT
s.metadata['rubygems_mfa_required'] = 'true'
end
10 changes: 3 additions & 7 deletions lib/jar_dependencies.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ module Jars
UNKNOWN = 'unknown'
end

autoload :MavenSettings, 'jars/maven_settings'
autoload :Classpath, 'jars/classpath'
autoload :MavenSettings, 'jars/maven_settings'
autoload :Mima, 'jars/mima'

@jars_lock = false
@jars = {}
Expand Down Expand Up @@ -144,12 +145,7 @@ def lock
def jars_lock_from_class_loader
return unless defined?(JRUBY_VERSION)

if JRuby::Util.respond_to?(:class_loader_resources)
JRuby::Util.class_loader_resources('Jars.lock')
else
require 'jruby'
JRuby.runtime.jruby_class_loader.get_resources('Jars.lock').collect(&:to_s)
end
JRuby::Util.class_loader_resources('Jars.lock')
end

def lock_path(basedir = nil)
Expand Down
28 changes: 0 additions & 28 deletions lib/jars/attach_jars_pom.rb

This file was deleted.

11 changes: 0 additions & 11 deletions lib/jars/gemspec_pom.rb

This file was deleted.

2 changes: 1 addition & 1 deletion lib/jars/installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ def install_jars(write_require_file: true)
end

def ruby_maven_install_options=(options)
@mvn.ruby_maven_install_options = options
# no-op: kept for backward compatibility with post_install_hook
end

def jars?
Expand Down
133 changes: 88 additions & 45 deletions lib/jars/lock_down.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
require 'fileutils'
require 'jar_dependencies'
require 'jars/version'
require 'jars/maven_factory'
require 'jars/gemspec_artifacts'

module Jars
Expand All @@ -15,38 +14,49 @@ def initialize(debug, verbose)
@verbose = verbose
end

def maven_new
factory = MavenFactory.new({}, @debug, @verbose)
pom = File.expand_path('lock_down_pom.rb', __dir__)
m = factory.maven_new(pom)
m['jruby.plugins.version'] = Jars::JRUBY_PLUGINS_VERSION
m['dependency.plugin.version'] = Jars::DEPENDENCY_PLUGIN_VERSION
m['jars.basedir'] = File.expand_path(basedir)
jarfile = File.expand_path(Jars.jarfile)
m['jars.jarfile'] = jarfile if File.exist?(jarfile)
attach_jar_coordinates_from_bundler_dependencies(m)
m
def basedir
File.expand_path('.')
end
private :maven_new

def maven
@maven ||= maven_new
end
def collect_artifacts
artifacts = []
done = []

def basedir
File.expand_path('.')
attach_jar_coordinates_from_bundler_dependencies(artifacts, done)

# Also collect from local gemspec if present
specs = Dir['*.gemspec']
if specs.size == 1
spec = eval(File.read(specs.first), TOPLEVEL_BINDING, specs.first) # rubocop:disable Security/Eval
ga = GemspecArtifacts.new(spec)
ga.artifacts.each do |a|
unless done.include?(a.key)
artifacts << a
done << a.key
end
end
end

artifacts
end
private :collect_artifacts

def attach_jar_coordinates_from_bundler_dependencies(maven)
def attach_jar_coordinates_from_bundler_dependencies(artifacts, done)
load_path = $LOAD_PATH.dup
require 'bundler'
# TODO: make this group a commandline option
Bundler.setup('default')
maven.property('jars.bundler', true)
cwd = File.expand_path('.')
Gem.loaded_specs.each_value do |spec|
# if gemspec is local then include all dependencies
maven.attach_jars(spec, all_dependencies: cwd == spec.full_gem_path)
all = cwd == spec.full_gem_path # if gemspec is local then include all dependencies
ga = GemspecArtifacts.new(spec)
ga.artifacts.each do |a|
next if done.include?(a.key)
next unless all || (a.scope != 'provided' && a.scope != 'test')

artifacts << a
done << a.key
end
end
rescue LoadError => e
if Jars.verbose?
Expand All @@ -62,40 +72,73 @@ def attach_jar_coordinates_from_bundler_dependencies(maven)
$LOAD_PATH.replace(load_path)
end

def lock_down(vendor_dir = nil, force: false, update: false, tree: nil)
out = File.expand_path('.jars.output')
tree_provided = tree
tree ||= File.expand_path('.jars.tree')
maven.property('jars.outputFile', out)
maven.property('maven.repo.local', Jars.local_maven_repo)
maven.property('jars.home', File.expand_path(vendor_dir)) if vendor_dir
maven.property('jars.lock', File.expand_path(Jars.lock))
maven.property('jars.force', force)
maven.property('jars.update', update) if update
# tell not to use Jars.lock as part of POM when running mvn
maven.property('jars.skip.lock', true)

args = ['gem:jars-lock']
args += ['dependency:tree', '-P -gemfile.lock', "-DoutputFile=#{tree}"] if tree_provided
def lock_down(vendor_dir = nil, force: false, update: false, tree: nil) # rubocop:disable Lint/UnusedMethodArgument
require 'jars/mima'

lock_file = File.expand_path(Jars.lock)

if !force && File.exist?(lock_file)
puts 'Jars.lock already exists, use --force to overwrite'
return
end

artifacts = collect_artifacts

if artifacts.empty?
puts 'no jar dependencies found'
return
end

puts
puts '-- jar root dependencies --'
puts
status = maven.exec(*args)
exit 1 unless status
if File.exist?(tree)
artifacts.each do |a|
puts " #{a.to_gacv}:#{a.scope || 'compile'}"
puts " exclusions: #{a.exclusions}" if a.exclusions && !a.exclusions.empty?
end

context = Jars::Mima.create_context
begin
resolved = Jars::Mima.resolve_with_context(context, artifacts, all_dependencies: true)
ensure
context.close
end

# Write Jars.lock
File.open(lock_file, 'w') do |f|
resolved.each do |dep|
next unless dep.type == 'jar'

f.puts dep.to_lock_entry
end
end

# Optionally vendor jars
if vendor_dir
vendor_path = File.expand_path(vendor_dir)
resolved.each do |dep|
next unless dep.type == 'jar' && dep.runtime? && !dep.system?

target = File.join(vendor_path, dep.jar_path)
FileUtils.mkdir_p(File.dirname(target))
FileUtils.cp(dep.file, target)
end
end

if tree
puts
puts '-- jar dependency tree --'
puts
puts File.read(tree)
resolved.each do |dep|
prefix = dep.classifier ? "#{dep.classifier}:" : ''
puts " #{dep.group_id}:#{dep.artifact_id}:#{prefix}#{dep.version}:#{dep.scope}"
end
puts
end

puts
puts File.read(out).gsub("#{File.dirname(out)}/", '')
puts File.read(lock_file)
puts
ensure
FileUtils.rm_f out
FileUtils.rm_f tree
end
end
end
Loading