class DTK::Network::Client::DependencyTree
Constants
- LOCK_FILE
- ValidFormats
Public Class Methods
compute(module_ref, opts = {})
click to toggle source
# File lib/client/dependency_tree.rb, line 49 def self.compute(module_ref, opts = {}) new(module_ref, opts).compute end
compute_and_save_to_file(module_ref, opts = {})
click to toggle source
# File lib/client/dependency_tree.rb, line 43 def self.compute_and_save_to_file(module_ref, opts = {}) activated = compute(module_ref, opts) ModuleDir.create_file_with_content("#{module_ref.repo_dir}/#{LOCK_FILE}", YAML.dump(activated.to_h)) activated end
get_or_create(module_ref, opts = {})
click to toggle source
# File lib/client/dependency_tree.rb, line 25 def self.get_or_create(module_ref, opts = {}) content = nil module_ref = convert_to_module_ref(module_ref) unless module_ref.is_a?(ModuleRef) update_lock_file = opts[:update_lock_file] yaml_content = FileHelper.get_content?("#{module_ref.repo_dir}/#{LOCK_FILE}") if yaml_content && !update_lock_file content = YAML.load(yaml_content) raise_error_if_dependencies_changed!(content, opts[:parsed_module]) elsif opts[:save_to_file] || update_lock_file content = compute_and_save_to_file(module_ref, opts) else content = compute(module_ref, opts) end ret_required_format(content, opts[:format]) end
new(module_ref, opts = {})
click to toggle source
# File lib/client/dependency_tree.rb, line 15 def initialize(module_ref, opts = {}) @module_ref = module_ref @module_directory = opts[:module_directory] || module_ref.repo_dir @parsed_module = opts[:parsed_module] @cache = Cache.new @activated = Activated.new @candidates = Candidates.new @development_mode = opts[:development_mode] end
Private Class Methods
convert_to_module_ref(module_ref)
click to toggle source
# File lib/client/dependency_tree.rb, line 204 def self.convert_to_module_ref(module_ref) ModuleRef.new(module_ref) end
convert_to_modules_lock_format(dependencies = {})
click to toggle source
# File lib/client/dependency_tree.rb, line 229 def self.convert_to_modules_lock_format(dependencies = {}) modules_hash = {} (dependencies || {}).each do |dependency| version = dependency[:version] source = nil if version.is_a?(Hash) source = version['source'] || version[:source] if matching_source = source && source.match(/(file:)(.*)/) source = matching_source[2] end version = version['version'] || version[:version] end namespace_name = "#{dependency[:namespace]}/#{dependency[:module_name]}" content_hash = {'version' => version} content_hash['source'] = source if source modules_hash.merge!(namespace_name => content_hash) end modules_hash end
create_module_hash(full_name, version_hash)
click to toggle source
# File lib/client/dependency_tree.rb, line 175 def self.create_module_hash(full_name, version_hash) namespace, name = full_name.split('/') version = version_hash[:version] || version_hash['version'] ret = { namespace: namespace, name: name, version: version } if source = version_hash[:source] || version_hash['source'] ret.merge!(source: source) end if modules = version_hash[:modules] || version_hash['modules'] ret.merge!(modules: modules) end ret end
create_module_ref(full_name, version_hash)
click to toggle source
# File lib/client/dependency_tree.rb, line 165 def self.create_module_ref(full_name, version_hash) namespace, name = full_name.split('/') version = version_hash[:version] || version_hash['version'] ModuleRef.new({ namespace: namespace, name: name, version: version }) end
filter_out_dependencies_of_dependencies(lock_content, module_yaml_dependencies)
click to toggle source
# File lib/client/dependency_tree.rb, line 253 def self.filter_out_dependencies_of_dependencies(lock_content, module_yaml_dependencies) top_level_dependencies = {} nested_dependencies = {} lock_content.each do |lock_name, lock_value| nested_dependencies.merge!(lock_value['modules'] || lock_value[:modules] || {}) top_level_dependencies.merge!(lock_name => {'version' => lock_value['version'], 'source' => lock_value['source']}) end nested_dependencies.each do |nd_name, version| source = nil if version.is_a?(Hash) source = version['source'] || version[:source] version = version['version'] || version[:version] end if top_level_dependency = top_level_dependencies[nd_name] module_ref_version = ModuleRef::Version.new(version) matches_version = module_ref_version.satisfied_by?(top_level_dependency['version']) matches_source = (source == top_level_dependency['source']) if yaml_dep = module_yaml_dependencies[nd_name] matches_version_new = module_ref_version.satisfied_by?(yaml_dep['version']) || module_ref_version.full_version == yaml_dep['version'] matches_source_new = (source == yaml_dep['source']) next if (matches_version_new && matches_source_new) end top_level_dependencies.delete(nd_name) if (matches_version && matches_source) end end top_level_dependencies end
raise_error_if_dependencies_changed!(lock_content, parsed_module)
click to toggle source
# File lib/client/dependency_tree.rb, line 208 def self.raise_error_if_dependencies_changed!(lock_content, parsed_module) return unless parsed_module message = "Module dependencies have been changed, please use '-u' option to update '#{LOCK_FILE}' file accordingly." dependencies = convert_to_modules_lock_format(parsed_module.val(:DependentModules)) lock_deps = filter_out_dependencies_of_dependencies(lock_content, dependencies) raise Error.new(message) if dependencies.size != lock_deps.size dependencies.each do |name, value| if matching = lock_deps[name] module_ref_version = ModuleRef::Version.new(value['version']) matches_version = module_ref_version.satisfied_by?(matching['version']) matches_source = (value['source'] == matching['source']) raise Error.new(message) unless (matches_version && matches_source) else raise Error.new(message) end end end
ret_as_hash(dep_modules)
click to toggle source
# File lib/client/dependency_tree.rb, line 171 def self.ret_as_hash(dep_modules) dep_modules.map { |k,v| create_module_hash(k, v) } end
ret_as_module_refs(dep_modules)
click to toggle source
# File lib/client/dependency_tree.rb, line 161 def self.ret_as_module_refs(dep_modules) dep_modules.map { |k,v| create_module_ref(k, v) } end
ret_required_format(content, format)
click to toggle source
# File lib/client/dependency_tree.rb, line 191 def self.ret_required_format(content, format) format ||= :module_ref case format.to_sym when :module_ref ret_as_module_refs(content) when :hash ret_as_hash(content) else raise Error.new("Unsupported format '#{format}'. Valid formats are '#{ValidFormats.join(', ')}'") end end
Public Instance Methods
compute()
click to toggle source
# File lib/client/dependency_tree.rb, line 53 def compute dependencies = (ret_dependencies || []).map do |pm_ref| ModuleRef::Dependency.create_local_or_remote(pm_ref) end activate_dependencies(dependencies) @activated sort_activated_dependencies(@activated) end
Private Instance Methods
activate_dependencies(dependencies, opts = {})
click to toggle source
# File lib/client/dependency_tree.rb, line 66 def activate_dependencies(dependencies, opts = {}) dependencies.each do |dependency| next if @activated.module_activated?(dependency) puts "Calculating dependencies for module: #{dependency.full_name}(#{dependency.version.str_version})" if @development_mode check_for_conflicts(dependency) # dtkn_versions_w_deps_hash = dtkn_versions_with_dependencies(dependency) dtkn_versions_w_deps_hash = dependency.dtkn_versions_with_dependencies dtkn_versions_w_deps = dtkn_versions_w_deps_hash.map { |v| v['version'] } version_obj = dependency.version versions_in_range = version_obj.versions_in_range(dtkn_versions_w_deps) raise "No version matching requirement '#{version_obj.full_version}' for dependent module '#{dependency.full_name}'" if versions_in_range.empty? versions_in_range.sort! latest_version = versions_in_range.last if dependency.is_a?(ModuleRef::Dependency::Local) latest_version_dep = dependency else latest_version_dep = ModuleRef::Dependency::Remote.new({ name: dependency.name, namespace: dependency.namespace, version: latest_version }) end @activated.add!(latest_version_dep) @candidates.add!(dependency, versions_in_range) dtkn_deps_of_deps = dtkn_versions_w_deps_hash.find {|dep| dep['version'].eql?(latest_version) } add_nested_modules(dependency, dtkn_deps_of_deps) dtkn_deps_of_deps_objs = (dtkn_deps_of_deps['dependencies'] || {}).map do |dtkn_dep| ModuleRef::Dependency.create_local_or_remote({ name: dtkn_dep['module'], namespace: dtkn_dep['namespace'], version: dtkn_dep['version'] }) end activate_dependencies(dtkn_deps_of_deps_objs, opts) end end
add_nested_modules(dependency, dtkn_deps_of_deps)
click to toggle source
# File lib/client/dependency_tree.rb, line 128 def add_nested_modules(dependency, dtkn_deps_of_deps) if activated_module = @activated[dependency.full_name] nested_deps = {} (dtkn_deps_of_deps['dependencies'] || []).each{ |dtkn_dep| nested_deps.merge!("#{dtkn_dep['namespace']}/#{dtkn_dep['module']}" => simplify_version(dtkn_dep['version'])) } unless nested_deps.empty? activated_module.key?('modules') ? activated_module['modules'].merge!(nested_deps) : activated_module.merge!('modules' => nested_deps) end end end
check_for_conflicts(dependency)
click to toggle source
# File lib/client/dependency_tree.rb, line 122 def check_for_conflicts(dependency) if activated_mod = @activated.existing_name?(dependency.full_name) raise Error::DependencyError, "There is already activated version '#{activated_mod[:version] || activated_mod['version']}' for module '#{dependency.full_name}' and it does not match required version '#{dependency.version.full_version}'" end end
dtkn_versions_with_dependencies(module_ref)
click to toggle source
# File lib/client/dependency_tree.rb, line 117 def dtkn_versions_with_dependencies(module_ref) response = rest_get("modules/get_versions_with_dependencies", { name: module_ref.name, namespace: module_ref.namespace }) response['versions'] end
ret_dependencies()
click to toggle source
# File lib/client/dependency_tree.rb, line 106 def ret_dependencies if @parsed_module (@parsed_module.val(:DependentModules) || []).map do |parsed_mr| { 'namespace' => parsed_mr.req(:Namespace), 'module' => parsed_mr.req(:ModuleName), 'version' => parsed_mr.val(:ModuleVersion) } end else response = rest_get("modules/#{@module_ref.name}/dependencies", { name: @module_ref.name, namespace: @module_ref.namespace, version: @module_ref.version.str_version }) response['dependencies'] end end
simplify_version(version)
click to toggle source
# File lib/client/dependency_tree.rb, line 139 def simplify_version(version) if version.is_a?(Hash) # transform custom dtk hash into ruby hash to avoid strange output in yaml file version.to_h else version end end
sort_activated_dependencies(activated_deps)
click to toggle source
# File lib/client/dependency_tree.rb, line 148 def sort_activated_dependencies(activated_deps) ret_hash = {} activated_deps.each do |k, activated_dep| ret_hash.merge!({ k => activated_dep }) if modules = (activated_dep[:modules] || activated_dep['modules']) modules.each { |name, _content| ret_hash = {name => activated_deps[name]}.merge(ret_hash) } end end ret_hash end