# encoding: UTF-8 # Copyright 2012 Twitter, Inc # http://www.apache.org/licenses/LICENSE-2.0 require 'nokogiri' require 'rexml/document' require 'fileutils' module TwitterCldr module Resources module Requirements class PomManager class Dep attr_reader :pom, :group_id, :artifact_id, :version def initialize(pom, group_id, artifact_id, version) @pom = pom @group_id = group_id @artifact_id = artifact_id @version = version end def path @path ||= begin sub_path = File.join(*group_id.split('.'), artifact_id, version) pom.classpath.find do |cp| cp.include?(sub_path) end end end end BLANK_POM = <<~END.freeze 4.0.0 com.mycompany.app my-app 1.0-SNAPSHOT 1.9 1.9 END DEPENDENCY_TEMPLATE = <<~END.freeze %{group_id} %{artifact_id} %{version} END attr_reader :pom_file, :path def initialize(pom_file) @pom_file = pom_file @path = File.dirname(pom_file) end def add_dependency(group_id, artifact_id, version) existing_dep = (contents / 'dependencies' / 'dependency').find do |dep| (dep / 'groupId').text == group_id && (dep / 'artifactId').text == artifact_id end existing_dep.remove if existing_dep dep = DEPENDENCY_TEMPLATE % { group_id: group_id, artifact_id: artifact_id, version: version } (contents / 'dependencies').first.add_child( Nokogiri::XML(dep) / 'dependency' ) end def install save mvn('install') end def get(group_id, artifact_id) dep = (contents / 'dependencies' / 'dependency').find do |dep| (dep / 'groupId').text == group_id && (dep / 'artifactId').text == artifact_id end Dep.new(self, group_id, artifact_id, (dep / 'version').text) end def classpath @classpath ||= mvn('dependency:build-classpath') .split("\n") .map(&:strip) .reject { |line| line =~ /\[[^\]]+\]/ } .first .split(':') end def require_jar(group_id, artifact_id) require get(group_id, artifact_id).path end private def contents @contents ||= if File.exist?(pom_file) Nokogiri::XML(File.read(pom_file)) do |config| config.options = Nokogiri::XML::ParseOptions::NOBLANKS end else Nokogiri::XML(BLANK_POM) do |config| config.options = Nokogiri::XML::ParseOptions::NOBLANKS end end end def save FileUtils.mkdir_p(File.dirname(pom_file)) File.open(pom_file, 'w+') do |f| formatter.write(REXML::Document.new(contents.to_xml), f) end end def formatter @formatter ||= begin REXML::Formatters::Pretty.new(2).tap do |fmt| fmt.compact = true end end end def mvn(cmd) Dir.chdir(path) { `mvn #{cmd}` } end end end end end