dtk-network-client 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/Gemfile +2 -0
  4. data/LICENSE +201 -0
  5. data/README.md +2 -0
  6. data/dtk-network-client.gemspec +24 -0
  7. data/lib/client/args.rb +19 -0
  8. data/lib/client/client_args.rb +23 -0
  9. data/lib/client/command/add_to_group.rb +20 -0
  10. data/lib/client/command/chmod.rb +21 -0
  11. data/lib/client/command/create_namespace.rb +19 -0
  12. data/lib/client/command/delete.rb +25 -0
  13. data/lib/client/command/delete_namespace.rb +19 -0
  14. data/lib/client/command/info.rb +32 -0
  15. data/lib/client/command/install/installer.rb +9 -0
  16. data/lib/client/command/install.rb +190 -0
  17. data/lib/client/command/list.rb +13 -0
  18. data/lib/client/command/list_namespaces.rb +10 -0
  19. data/lib/client/command/publish.rb +120 -0
  20. data/lib/client/command/pull.rb +53 -0
  21. data/lib/client/command/push.rb +63 -0
  22. data/lib/client/command/remove_from_group.rb +20 -0
  23. data/lib/client/command/unpublish.rb +27 -0
  24. data/lib/client/command/update.rb +18 -0
  25. data/lib/client/command.rb +31 -0
  26. data/lib/client/config.rb +54 -0
  27. data/lib/client/conn.rb +132 -0
  28. data/lib/client/dependency_tree/activated.rb +35 -0
  29. data/lib/client/dependency_tree/cache.rb +28 -0
  30. data/lib/client/dependency_tree/candidates.rb +19 -0
  31. data/lib/client/dependency_tree/resolver.rb +16 -0
  32. data/lib/client/dependency_tree.rb +272 -0
  33. data/lib/client/error.rb +22 -0
  34. data/lib/client/file_helper.rb +8 -0
  35. data/lib/client/git_adapter/git_gem.rb +246 -0
  36. data/lib/client/git_client.rb +136 -0
  37. data/lib/client/git_repo.rb +221 -0
  38. data/lib/client/module_dir.rb +38 -0
  39. data/lib/client/module_ref/dependency/local.rb +47 -0
  40. data/lib/client/module_ref/dependency/remote.rb +18 -0
  41. data/lib/client/module_ref/dependency.rb +21 -0
  42. data/lib/client/module_ref/version/source.rb +18 -0
  43. data/lib/client/module_ref/version.rb +87 -0
  44. data/lib/client/module_ref.rb +21 -0
  45. data/lib/client/response/response_types.rb +42 -0
  46. data/lib/client/response.rb +27 -0
  47. data/lib/client/rest_wrapper.rb +43 -0
  48. data/lib/client/s3_helper.rb +23 -0
  49. data/lib/client/session.rb +54 -0
  50. data/lib/client/storage/adapters/s3.rb +25 -0
  51. data/lib/client/storage.rb +29 -0
  52. data/lib/client/util/os_util.rb +77 -0
  53. data/lib/client/util/permissions_util.rb +12 -0
  54. data/lib/client/util/tar.rb +104 -0
  55. data/lib/client/util.rb +7 -0
  56. data/lib/client/version.rb +8 -0
  57. data/lib/dtk_network_client.rb +27 -0
  58. metadata +183 -0
@@ -0,0 +1,120 @@
1
+ module DTK::Network::Client
2
+ class Command
3
+ class Publish < self
4
+ def initialize(module_ref, dependency_tree, options = {})
5
+ @module_ref = module_ref
6
+ @dependency_tree = dependency_tree
7
+ @module_directory = module_ref.repo_dir
8
+ @options = options
9
+ @parsed_module = options[:parsed_module]
10
+ @development_mode = options[:development_mode]
11
+ end
12
+
13
+ def self.run(module_info, opts = {})
14
+ module_ref = ModuleRef.new(module_info)
15
+ dependency_tree = DependencyTree.get_or_create(module_ref, opts.merge(save_to_file: true, development_mode: opts[:development_mode]))
16
+ new(module_ref, dependency_tree, opts).publish
17
+ end
18
+
19
+ def publish
20
+ module_info = rest_post('modules', { name: @module_ref.name, namespace: @module_ref.namespace, return_if_exists: true })
21
+ dependencies = []
22
+
23
+ if @parsed_module
24
+ (@parsed_module.val(:DependentModules) || []).map do |parsed_mr|
25
+ dependencies << { 'namespace' => parsed_mr.req(:Namespace), 'module' => parsed_mr.req(:ModuleName), 'version' => parsed_mr.val(:ModuleVersion) }
26
+ end
27
+ end
28
+
29
+ if @development_mode
30
+ puts "Base module.yaml dependencies:\n#{dependencies}"
31
+ end
32
+
33
+ if @module_ref.version.is_semantic_version?
34
+ publish_semantic_version(module_info, dependencies)
35
+ else
36
+ publish_named_version(module_info, dependencies)
37
+ end
38
+ end
39
+
40
+ def publish_semantic_version(module_info, dependencies)
41
+ module_id = module_info['id']
42
+ module_ref_version = @module_ref.version
43
+ branch = rest_post("modules/#{module_id}/branch", { version: module_ref_version.str_version, dependencies: dependencies.to_json })
44
+ # repo_url = ret_codecommit_url(module_info)
45
+
46
+ # git_init_and_publish_to_remote(branch['name'], repo_url)
47
+
48
+ published_response = rest_post("modules/#{module_id}/publish", { version: module_ref_version.str_version })
49
+ bucket, object_name = S3Helper.ret_s3_bucket_info(published_response)
50
+ # gz_body = ModuleDir.create_and_ret_tar_gz(@module_directory, exclude_git: true)
51
+
52
+ resource_name = object_name.gsub('/','__')
53
+ published_creds = published_response['publish_credentails']
54
+ `tar -cpzf /tmp/#{resource_name} -C #{@module_directory} .`
55
+
56
+ require 'aws-sdk-s3'
57
+ s3_args = Args.new({
58
+ region: 'us-east-1',
59
+ access_key_id: published_creds['access_key_id'],
60
+ secret_access_key: published_creds['secret_access_key'],
61
+ session_token: published_creds['session_token']
62
+ })
63
+ s3 = Aws::S3::Resource.new(s3_args)
64
+ # storage = Storage.new(:s3, s3_args)
65
+
66
+ obj = s3.bucket(bucket).object(object_name)
67
+ obj.upload_file("/tmp/#{resource_name}")
68
+ FileUtils.remove_entry("/tmp/#{resource_name}")
69
+ # upload_args = Args.new({
70
+ # body: gz_body,
71
+ # bucket: bucket,
72
+ # key: object_name
73
+ # })
74
+ # storage.upload(upload_args)
75
+
76
+ rest_post("modules/update_status", { branch_id: branch['id'], status: 'published' })
77
+ end
78
+
79
+ def publish_named_version(module_info, dependencies)
80
+ module_id = module_info['id']
81
+ branch = rest_post("modules/#{module_id}/branch", { version: @module_ref.version.str_version, dependencies: dependencies.to_json })
82
+ repo_url = ret_codecommit_url(module_info)
83
+
84
+ git_init_and_publish_to_remote(branch['name'], repo_url)
85
+
86
+ rest_post("modules/update_status", { branch_id: branch['id'], status: 'published' })
87
+ end
88
+
89
+ def git_init_and_publish_to_remote(branch, repo_url)
90
+ git_args = Args.new({
91
+ repo_dir: @module_directory,
92
+ branch: branch,
93
+ remote_url: repo_url
94
+ })
95
+ GitRepo.add_remote_and_publish(git_args)
96
+ end
97
+
98
+ def ret_codecommit_url(module_info)
99
+ require 'open-uri'
100
+
101
+ if clone_url_http = module_info['meta']['aws']['codecommit']['repository_metadata']['clone_url_http']
102
+ codecommit_data = Session.get_codecommit_data
103
+ service_user_name = codecommit_data['service_specific_credential']['service_user_name']
104
+ service_password = codecommit_data['service_specific_credential']['service_password']
105
+ encoded_password = URI.encode_www_form_component(service_password)
106
+
107
+ url = nil
108
+ if match = clone_url_http.match(/^(https:\/\/)(.*)$/)
109
+ url = "#{match[1]}#{service_user_name}:#{encoded_password}@#{match[2]}"
110
+ end
111
+
112
+ url
113
+ else
114
+ raise "Unable to find codecommit https url"
115
+ end
116
+ end
117
+
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,53 @@
1
+ module DTK::Network::Client
2
+ class Command
3
+ class Pull < self
4
+ def initialize(module_ref, dependency_tree, options = {})
5
+ @module_ref = module_ref
6
+ @dependency_tree = dependency_tree
7
+ @module_directory = module_ref.repo_dir
8
+ @options = options
9
+ @parsed_module = options[:parsed_module]
10
+ end
11
+
12
+ def self.run(module_info, opts = {})
13
+ module_ref = ModuleRef.new(module_info)
14
+ dependency_tree = DependencyTree.get_or_create(module_ref, opts.merge(save_to_file: true))
15
+ new(module_ref, dependency_tree, opts).pull
16
+ end
17
+
18
+ def pull
19
+ module_info = rest_get('modules/module_info', { name: @module_ref.name, namespace: @module_ref.namespace, version: @module_ref.version.str_version })
20
+ remote_url = construct_remote_url(module_info)
21
+ git_args = Args.new({
22
+ repo_dir: @module_directory,
23
+ branch: @module_ref.version.str_version,
24
+ remote_url: remote_url
25
+ })
26
+ GitRepo.pull_from_remote(git_args)
27
+ end
28
+
29
+ # TODO: move construct_remote_url to helper or mixin and use for all commands when needed
30
+ def construct_remote_url(module_info)
31
+ require 'open-uri'
32
+
33
+ # if clone_url_http = module_info.dig('meta', 'aws', 'codecommit', 'repository_metadata', 'clone_url_http')
34
+ if clone_url_http = module_info['meta']['aws']['codecommit']['repository_metadata']['clone_url_http']
35
+ codecommit_data = Session.get_codecommit_data
36
+ # service_user_name = codecommit_data.dig('service_specific_credential', 'service_user_name')
37
+ # service_password = codecommit_data.dig('service_specific_credential', 'service_password')
38
+ service_user_name = codecommit_data['service_specific_credential']['service_user_name']
39
+ service_password = codecommit_data['service_specific_credential']['service_password']
40
+ encoded_password = URI.encode_www_form_component(service_password)
41
+ url = nil
42
+ if match = clone_url_http.match(/^(https:\/\/)(.*)$/)
43
+ url = "#{match[1]}#{service_user_name}:#{encoded_password}@#{match[2]}"
44
+ end
45
+ url
46
+ else
47
+ raise "Unable to find codecommit https url"
48
+ end
49
+ end
50
+
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,63 @@
1
+ module DTK::Network::Client
2
+ class Command
3
+ class Push < self
4
+ def initialize(module_ref, dependency_tree, options = {})
5
+ @module_ref = module_ref
6
+ @dependency_tree = dependency_tree
7
+ @module_directory = module_ref.repo_dir
8
+ @options = options
9
+ @parsed_module = options[:parsed_module]
10
+ end
11
+
12
+ def self.run(module_info, opts = {})
13
+ module_ref = ModuleRef.new(module_info)
14
+ dependency_tree = DependencyTree.get_or_create(module_ref, opts.merge(save_to_file: true))
15
+ new(module_ref, dependency_tree, opts).push
16
+ end
17
+
18
+ def push
19
+ module_info = rest_get('modules/module_info', { name: @module_ref.name, namespace: @module_ref.namespace, version: @module_ref.version.str_version, module_action: 'push' })
20
+ remote_url = construct_remote_url(module_info)
21
+ git_args = Args.new({
22
+ repo_dir: @module_directory,
23
+ branch: @module_ref.version.str_version,
24
+ remote_url: remote_url
25
+ })
26
+ GitRepo.push_to_remote(git_args)
27
+
28
+ dependencies = []
29
+ if @parsed_module
30
+ (@parsed_module.val(:DependentModules) || []).map do |parsed_mr|
31
+ dependencies << { 'namespace' => parsed_mr.req(:Namespace), 'module' => parsed_mr.req(:ModuleName), 'version' => parsed_mr.val(:ModuleVersion) }
32
+ end
33
+ end
34
+
35
+ rest_post("modules/#{module_info['id']}/dependencies", { version: @module_ref.version.str_version, dependencies: dependencies.to_json })
36
+ nil
37
+ end
38
+
39
+ # TODO: move construct_remote_url to helper or mixin and use for all commands when needed
40
+ def construct_remote_url(module_info)
41
+ require 'open-uri'
42
+
43
+ # if clone_url_http = module_info.dig('meta', 'aws', 'codecommit', 'repository_metadata', 'clone_url_http')
44
+ if clone_url_http = module_info['meta']['aws']['codecommit']['repository_metadata']['clone_url_http']
45
+ codecommit_data = Session.get_codecommit_data
46
+ # service_user_name = codecommit_data.dig('service_specific_credential', 'service_user_name')
47
+ service_user_name = codecommit_data['service_specific_credential']['service_user_name']
48
+ # service_password = codecommit_data.dig('service_specific_credential', 'service_password')
49
+ service_password = codecommit_data['service_specific_credential']['service_password']
50
+ encoded_password = URI.encode_www_form_component(service_password)
51
+ url = nil
52
+ if match = clone_url_http.match(/^(https:\/\/)(.*)$/)
53
+ url = "#{match[1]}#{service_user_name}:#{encoded_password}@#{match[2]}"
54
+ end
55
+ url
56
+ else
57
+ raise "Unable to find codecommit https url"
58
+ end
59
+ end
60
+
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,20 @@
1
+ module DTK::Network::Client
2
+ class Command
3
+ class RemoveFromGroup < self
4
+ def initialize(group, user, options = {})
5
+ @group = group
6
+ @user = user
7
+ end
8
+
9
+ def self.run(group, user, opts = {})
10
+ new(group, user, opts).revoke_access
11
+ end
12
+
13
+ def revoke_access
14
+ rest_post("groups/#{@group}/remove_member", { name: @group, username: @user })
15
+ nil
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ module DTK::Network::Client
2
+ class Command
3
+ class Unpublish < self
4
+ def initialize(module_ref, options = {})
5
+ @module_ref = module_ref
6
+ @options = options
7
+ end
8
+
9
+ def self.run(module_info, opts = {})
10
+ module_ref = ModuleRef.new(module_info)
11
+ new(module_ref, opts).unpublish
12
+ end
13
+
14
+ def unpublish
15
+ version = @module_ref.version
16
+ params = {
17
+ name: @module_ref.name,
18
+ namespace: @module_ref.namespace,
19
+ version: version.str_version
20
+ }
21
+ rest_post("modules/unpublish", params)
22
+
23
+ nil
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ module DTK::Network::Client
2
+ class Command
3
+ class Update < self
4
+ def initialize(module_ref, dependency_tree, options = {})
5
+ @module_ref = module_ref
6
+ @dependency_tree = dependency_tree
7
+ @module_directory = module_ref.repo_dir
8
+ @options = options
9
+ @parsed_module = options[:parsed_module]
10
+ end
11
+
12
+ def self.run(module_info, opts = {})
13
+ module_ref = ModuleRef.new(module_info)
14
+ DependencyTree.get_or_create(module_ref, opts.merge(save_to_file: true, update_lock_file: true))
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,31 @@
1
+ module DTK::Network
2
+ module Client
3
+ class Command
4
+ require_relative('command/install')
5
+ require_relative('command/publish')
6
+ require_relative('command/list')
7
+ require_relative('command/info')
8
+ require_relative('command/push')
9
+ require_relative('command/pull')
10
+ require_relative('command/add_to_group')
11
+ require_relative('command/remove_from_group')
12
+ require_relative('command/delete')
13
+ require_relative('command/create_namespace')
14
+ require_relative('command/unpublish')
15
+ require_relative('command/update')
16
+ require_relative('command/chmod')
17
+ require_relative('command/delete_namespace')
18
+ require_relative('command/list_namespaces')
19
+
20
+ include RestWrapper
21
+ extend RestWrapper
22
+ include DTK::Network::Client::Util::Tar
23
+ extend DTK::Client::PermissionsUtil
24
+ include DTK::Client::PermissionsUtil
25
+
26
+ def self.wrap_command(args = Args.new, &block)
27
+ block.call(Args.convert(args))
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,54 @@
1
+ require 'fileutils'
2
+
3
+ module DTK::Network::Client
4
+ class Config
5
+ extend DTK::Network::Client::Util::OsUtil
6
+
7
+ DTK_NETWORK_FILE = '.dtk_network'
8
+ DTK_NETWORK_CONFIG = File.join(dtk_local_folder, DTK_NETWORK_FILE)
9
+
10
+ def self.get_credentials
11
+ raise "Dtk network config file (#{DTK_NETWORK_CONFIG}) does not exist" unless File.exists?(DTK_NETWORK_CONFIG)
12
+ ret = parse_key_value_file(DTK_NETWORK_CONFIG)
13
+ [:email, :password].each{ |k| raise "cannot find #{k}" unless ret[k] }
14
+ {
15
+ email: ret[:email],
16
+ password: ret[:password]
17
+ }
18
+ end
19
+
20
+ def self.get_endpoint
21
+ raise "Dtk network config file (#{DTK_NETWORK_CONFIG}) does not exist" unless File.exists?(DTK_NETWORK_CONFIG)
22
+ ret = parse_key_value_file(DTK_NETWORK_CONFIG)
23
+ [:endpoint, :port].each{ |k| raise "cannot find #{k}" unless ret[k] }
24
+ "#{ret[:endpoint]}:#{ret[:port]}"
25
+ end
26
+
27
+ def self.module_download_location
28
+ if File.exists?(DTK_NETWORK_CONFIG)
29
+ ret = parse_key_value_file(DTK_NETWORK_CONFIG) || {}
30
+ ret[:download_location]
31
+ end
32
+ end
33
+
34
+ def self.parse_key_value_file(file)
35
+ raise "Config file (#{file}) does not exists" unless File.exists?(file)
36
+
37
+ ret = Hash.new
38
+ File.open(file).each do |line|
39
+ # strip blank spaces, tabs etc off the end of all lines
40
+ line.gsub!(/\s*$/, "")
41
+ unless line =~ /^#|^$/
42
+ if (line =~ /(.+?)\s*=\s*(.+)/)
43
+ key = $1
44
+ val = $2
45
+ ret[key.to_sym] = val
46
+ end
47
+ end
48
+ end
49
+
50
+ ret
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,132 @@
1
+ module DTK::Network
2
+ module Client
3
+ class Conn
4
+ def initialize
5
+ @cookies = {}
6
+ @connection_error = nil
7
+ @codecommit = nil
8
+ login
9
+ end
10
+
11
+ attr_reader :cookies, :connection_error, :codecommit
12
+
13
+ def get(route, query_string_hash = {})
14
+ check_and_wrap_response { json_parse_if_needed(get_raw(rest_url(route), query_string_hash)) }
15
+ end
16
+
17
+ def post(route, post_body = {})
18
+ check_and_wrap_response { json_parse_if_needed(post_raw(rest_url(route), post_body)) }
19
+ end
20
+
21
+ def delete(route, delete_body = {})
22
+ check_and_wrap_response { json_parse_if_needed(delete_raw(rest_url(route), delete_body)) }
23
+ end
24
+
25
+ def connection_error?
26
+ !connection_error.nil?
27
+ end
28
+
29
+ private
30
+
31
+ def error_code?
32
+ connection_error['errors'].first['code'] rescue nil
33
+ end
34
+
35
+ REST_VERSION = 'v1'
36
+ REST_PREFIX = "api/#{REST_VERSION}"
37
+
38
+ def rest_url(route = nil)
39
+ "#{rest_url_base}/#{REST_PREFIX}/#{route}"
40
+ end
41
+
42
+ def rest_url_base
43
+ @@rest_url_base ||= Config.get_endpoint
44
+ end
45
+
46
+ def check_and_wrap_response(&rest_method_func)
47
+ if @connection_error
48
+ if conn_error = connection_error['errors'].first
49
+ raise Error, conn_error
50
+ else
51
+ raise Error, "Unable to connect to dtk network, please check your credentials and try again!"
52
+ end
53
+ end
54
+
55
+ response = rest_method_func.call
56
+
57
+ # response
58
+
59
+ # if Response::ErrorHandler.check_for_session_expiried(response)
60
+ # # re-logging user and repeating request
61
+ # OsUtil.print_warning("Session expired: re-establishing session & re-trying request ...")
62
+ # @cookies = Session.re_initialize
63
+ # response = rest_method_func.call
64
+ # end
65
+
66
+
67
+ # response_obj = Response.new(response)
68
+
69
+ # queue messages from server to be displayed later
70
+ #TODO: DTK-2554: put in processing of messages Shell::MessageQueue.process_response(response_obj)
71
+ # response_obj
72
+ end
73
+
74
+ def login
75
+ response = post_raw rest_url('auth/sign_in'), get_credentials
76
+ if response.kind_of?(::DTK::Common::Response) and !response.ok?
77
+ @connection_error = response
78
+ else
79
+ @cookies = response.cookies
80
+ set_codecommit_info(response)
81
+ end
82
+ end
83
+
84
+ def logout
85
+ response = get_raw rest_url('auth/sign_out')
86
+ # TODO: see if response can be nil
87
+ raise Error, "Failed to logout, and terminate session!" unless response
88
+ @cookies = nil
89
+ end
90
+
91
+ def get_credentials
92
+ @parsed_credentials ||= Config.get_credentials
93
+ end
94
+
95
+ def default_rest_opts
96
+ @default_rest_opts ||= get_default_rest_opts
97
+ end
98
+
99
+ def get_default_rest_opts
100
+ {
101
+ :timeout => 200,
102
+ :open_timeout => 10,
103
+ :verify_ssl => OpenSSL::SSL::VERIFY_PEER
104
+ }
105
+ end
106
+
107
+ def get_raw(url, query_string_hash = {})
108
+ Response::RestClientWrapper.get_raw(url, query_string_hash, default_rest_opts.merge(:cookies => @cookies))
109
+ end
110
+
111
+ def post_raw(url, post_body, params = {})
112
+ Response::RestClientWrapper.post_raw(url, post_body, default_rest_opts.merge(:cookies => @cookies).merge(params))
113
+ end
114
+
115
+ def delete_raw(url, delete_body, params = {})
116
+ Response::RestClientWrapper.delete_raw(url, delete_body, default_rest_opts.merge(:cookies => @cookies).merge(params))
117
+ end
118
+
119
+ def json_parse_if_needed(item)
120
+ Response::RestClientWrapper.json_parse_if_needed(item)
121
+ end
122
+
123
+ def set_codecommit_info(response)
124
+ json_response = json_parse_if_needed(response)
125
+ # if codecommit_data = json_response.dig('data', 'meta', 'aws', 'codecommit')
126
+ if codecommit_data = json_response['data']['meta']['aws']['codecommit']
127
+ @codecommit = codecommit_data
128
+ end
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,35 @@
1
+ module DTK::Network
2
+ module Client
3
+ class DependencyTree
4
+ class Activated < Hash
5
+ def module_activated?(dependency)
6
+ if existing_dep = self["#{dependency.full_name}"]
7
+ if required_version = dependency.version
8
+ required_version.satisfied_by?(existing_dep[:version] || existing_dep['version'])
9
+ end
10
+ end
11
+ end
12
+
13
+ def add!(dependency_mod)
14
+ self.merge!("#{dependency_mod.full_name}" => generate_content(dependency_mod))
15
+ end
16
+
17
+ def existing_name?(name)
18
+ self[name]
19
+ end
20
+
21
+ def delete!(dependency_mod)
22
+ self.delete(dependency_mod.full_name)
23
+ end
24
+
25
+ def generate_content(dependency_mod)
26
+ if dependency_mod.respond_to?(:source)
27
+ { 'version' => dependency_mod.version.str_version, 'source' => dependency_mod.source }
28
+ else
29
+ { 'version' => dependency_mod.version.str_version }
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ module DTK::Network::Client
2
+ class DependencyTree
3
+ class Cache < ::Hash
4
+ def initialize
5
+ super()
6
+ end
7
+
8
+ def add!(module_ref, dependencies)
9
+ self[index(module_ref)] ||= {:module_ref => module_ref, :dependencies => dependencies }
10
+ end
11
+
12
+ def lookup_dependencies?(module_ref)
13
+ (self[index(module_ref)] || {})[:dependencies]
14
+ end
15
+
16
+ def all_modules_refs
17
+ values.map { |hash| hash[:module_ref] }
18
+ end
19
+
20
+ private
21
+
22
+ def index(module_ref)
23
+ "#{module_ref.module_name}--#{module_ref.namespace}--#{module_ref.version.str_version}"
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,19 @@
1
+ module DTK::Network
2
+ module Client
3
+ class DependencyTree
4
+ class Candidates < Hash
5
+ def add!(dependency_mod, versions)
6
+ self.merge!(dependency_mod.full_name => { 'dependency_obj' => dependency_mod, 'versions' => versions })
7
+ end
8
+
9
+ # def existing_name?(name)
10
+ # self[name]
11
+ # end
12
+
13
+ # def delete!(dependency_mod)
14
+ # self.delete(dependency_mod.full_name)
15
+ # end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ module DTK::Network
2
+ module Client
3
+ class DependencyTree
4
+ class Resolver
5
+ def initialize(activated, dependencies)
6
+ @children = activated[:children]
7
+ @dependencies = dependencies
8
+ end
9
+
10
+ def resolve
11
+
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end