lib/lock_jar/runtime/lock.rb
require 'delegate'
module LockJar
#
class Runtime
#
class Lock < SimpleDelegator
attr_accessor :jarfile, :lockfile, :opts
def initialize(runtime)
super(runtime)
@lockfile = LockJar::Domain::Lockfile.new
end
def lock(jarfile_or_dsl, opts = {}, &blk)
@opts = { download: true }.merge(opts)
create_dsl!(jarfile_or_dsl, &blk)
apply_repositories!
apply_maps!
apply_excludes!
apply_merged!
artifacts = jarfile.artifacts.values.flatten
apply_artifacts!(artifacts) unless artifacts.empty?
lockfile.write(@opts[:lockfile] || 'Jarfile.lock')
lockfile
end
private
def create_dsl!(jarfile_or_dsl, &blk)
if jarfile_or_dsl
@jarfile = if jarfile_or_dsl.is_a? LockJar::Domain::Dsl
jarfile_or_dsl
else
LockJar::Domain::JarfileDsl.create(jarfile_or_dsl)
end
end
return @jarfile if blk.nil?
if @jarfile
@jarfile = LockJar::Domain::DslMerger.new(
jarfile, LockJar::Domain::Dsl.create(&blk)).merge
else
@jarfile = LockJar::Domain::Dsl.create(&blk)
end
end
# rubocop:disable Metrics/AbcSize
def apply_artifacts!(artifacts)
# Build the dependencies_graph hash in the resolver
resolver(opts).resolve(
artifacts.select(&:resolvable?).map(&:to_dep), opts[:download] == true
)
jarfile.artifacts.each do |group_name, group_artifacts|
group = { 'locals' => [], 'dependencies' => [], 'artifacts' => [] }
group_artifacts.each do |artifact|
artifact_data = {}
add_artifact!(group, artifact_data, artifact)
next unless artifact_data['transitive']
# flatten the graph of nested hashes
group['dependencies'] += dependency_merge(artifact_data['transitive'])
# xxX: set required_by ?
group['artifacts'] << { artifact.to_urn => artifact_data }
end
lockfile.excludes.each do |exclude|
group['dependencies'].delete_if { |dep| dep =~ /#{exclude}/ }
end if lockfile.excludes
group['dependencies'] = group['dependencies'].sort.uniq
group.delete 'locals' if group['locals'].empty?
lockfile.groups[group_name] = group
end
end
# rubocop:enable Metrics/AbcSize
def apply_excludes!
lockfile.excludes = jarfile.excludes if jarfile.excludes.size > 0
end
def apply_maps!
lockfile.maps = jarfile.maps if jarfile.maps.size > 0
end
def apply_merged!
lockfile.merged = jarfile.merged unless jarfile.merged.empty?
end
def apply_repositories!
lockfile.local_repository = opts[:local_repo] ||= jarfile.local_repository
if jarfile.clear_repositories
resolver(opts).clear_remote_repositories
else
repos = resolver(opts).remote_repositories
lockfile.remote_repositories += repos.to_a if repos
end
# Add remote repos to the resolver and the lockfile
jarfile.remote_repositories.each do |repo|
resolver(opts).add_remote_repository(repo)
lockfile.remote_repositories << repo
end
end
def add_artifact!(group, artifact_data, artifact)
if artifact.is_a? LockJar::Domain::Jar
group['dependencies'] << artifact.notation
g = resolver(opts).dependencies_graph[artifact.notation]
artifact_data['transitive'] = g.to_hash if g
elsif artifact.is_a? LockJar::Domain::Pom
artifact_data['scopes'] = artifact.scopes
# iterate each dependency in Pom to map transitive dependencies
transitive = {}
artifact.notations.each do |notation|
transitive[notation] = resolver(opts).dependencies_graph[notation]
end
artifact_data['transitive'] = transitive
elsif artifact.is_a? LockJar::Domain::Local
group['locals'] << artifact.path
else
fail("Unsupported artifact: #{artifact.inspect}")
end
end
def dependency_merge(graph)
deps = graph.keys
graph.values.flat_map { |next_step| deps += dependency_merge(next_step) }
end
end
end
end