dtk-client 0.5.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +15 -0
  2. data/Gemfile +5 -0
  3. data/Gemfile_dev +12 -0
  4. data/README.md +78 -0
  5. data/bin/dtk +54 -0
  6. data/bin/dtk-shell +15 -0
  7. data/dtk-client.gemspec +49 -0
  8. data/lib/auxiliary.rb +13 -0
  9. data/lib/bundler_monkey_patch.rb +9 -0
  10. data/lib/client.rb +48 -0
  11. data/lib/command_helper.rb +16 -0
  12. data/lib/command_helpers/git_repo.rb +391 -0
  13. data/lib/command_helpers/jenkins_client/config_xml.rb +271 -0
  14. data/lib/command_helpers/jenkins_client.rb +91 -0
  15. data/lib/command_helpers/service_importer.rb +99 -0
  16. data/lib/command_helpers/service_link.rb +18 -0
  17. data/lib/command_helpers/ssh_processing.rb +43 -0
  18. data/lib/commands/common/thor/assembly_workspace.rb +1089 -0
  19. data/lib/commands/common/thor/clone.rb +39 -0
  20. data/lib/commands/common/thor/common.rb +34 -0
  21. data/lib/commands/common/thor/edit.rb +168 -0
  22. data/lib/commands/common/thor/list_diffs.rb +84 -0
  23. data/lib/commands/common/thor/pull_clone_changes.rb +11 -0
  24. data/lib/commands/common/thor/pull_from_remote.rb +99 -0
  25. data/lib/commands/common/thor/purge_clone.rb +26 -0
  26. data/lib/commands/common/thor/push_clone_changes.rb +45 -0
  27. data/lib/commands/common/thor/push_to_remote.rb +45 -0
  28. data/lib/commands/common/thor/reparse.rb +36 -0
  29. data/lib/commands/common/thor/set_required_params.rb +29 -0
  30. data/lib/commands/common/thor/task_status.rb +81 -0
  31. data/lib/commands/thor/account.rb +213 -0
  32. data/lib/commands/thor/assembly.rb +329 -0
  33. data/lib/commands/thor/attribute.rb +62 -0
  34. data/lib/commands/thor/component.rb +52 -0
  35. data/lib/commands/thor/component_module.rb +829 -0
  36. data/lib/commands/thor/component_template.rb +153 -0
  37. data/lib/commands/thor/dependency.rb +18 -0
  38. data/lib/commands/thor/developer.rb +105 -0
  39. data/lib/commands/thor/dtk.rb +117 -0
  40. data/lib/commands/thor/library.rb +107 -0
  41. data/lib/commands/thor/node.rb +411 -0
  42. data/lib/commands/thor/node_group.rb +211 -0
  43. data/lib/commands/thor/node_template.rb +88 -0
  44. data/lib/commands/thor/project.rb +17 -0
  45. data/lib/commands/thor/provider.rb +155 -0
  46. data/lib/commands/thor/repo.rb +35 -0
  47. data/lib/commands/thor/service.rb +656 -0
  48. data/lib/commands/thor/service_module.rb +806 -0
  49. data/lib/commands/thor/state_change.rb +10 -0
  50. data/lib/commands/thor/target.rb +94 -0
  51. data/lib/commands/thor/task.rb +100 -0
  52. data/lib/commands/thor/utils.rb +4 -0
  53. data/lib/commands/thor/workspace.rb +437 -0
  54. data/lib/commands.rb +40 -0
  55. data/lib/config/cacert.pem +3785 -0
  56. data/lib/config/client.conf.header +18 -0
  57. data/lib/config/configuration.rb +82 -0
  58. data/lib/config/default.conf +14 -0
  59. data/lib/config/disk_cacher.rb +60 -0
  60. data/lib/configurator.rb +92 -0
  61. data/lib/context_router.rb +23 -0
  62. data/lib/core.rb +460 -0
  63. data/lib/domain/git_adapter.rb +221 -0
  64. data/lib/domain/response.rb +234 -0
  65. data/lib/dtk-client/version.rb +3 -0
  66. data/lib/dtk_constants.rb +23 -0
  67. data/lib/dtk_logger.rb +96 -0
  68. data/lib/error.rb +74 -0
  69. data/lib/git-logs/git.log +0 -0
  70. data/lib/parser/adapters/option_parser.rb +53 -0
  71. data/lib/parser/adapters/thor/common_option_defs.rb +12 -0
  72. data/lib/parser/adapters/thor.rb +509 -0
  73. data/lib/require_first.rb +87 -0
  74. data/lib/search_hash.rb +27 -0
  75. data/lib/shell/context.rb +975 -0
  76. data/lib/shell/context_aux.rb +29 -0
  77. data/lib/shell/domain.rb +447 -0
  78. data/lib/shell/header_shell.rb +27 -0
  79. data/lib/shell/help_monkey_patch.rb +221 -0
  80. data/lib/shell/interactive_wizard.rb +233 -0
  81. data/lib/shell/parse_monkey_patch.rb +22 -0
  82. data/lib/shell/status_monitor.rb +105 -0
  83. data/lib/shell.rb +219 -0
  84. data/lib/util/console.rb +143 -0
  85. data/lib/util/dtk_puppet.rb +46 -0
  86. data/lib/util/os_util.rb +265 -0
  87. data/lib/view_processor/augmented_simple_list.rb +27 -0
  88. data/lib/view_processor/hash_pretty_print.rb +106 -0
  89. data/lib/view_processor/simple_list.rb +139 -0
  90. data/lib/view_processor/table_print.rb +277 -0
  91. data/lib/view_processor.rb +112 -0
  92. data/puppet/manifests/init.pp +72 -0
  93. data/puppet/manifests/params.pp +16 -0
  94. data/puppet/r8meta.puppet.yml +18 -0
  95. data/puppet/templates/bash_profile.erb +2 -0
  96. data/puppet/templates/client.conf.erb +1 -0
  97. data/puppet/templates/dtkclient.erb +2 -0
  98. data/spec/assembly_spec.rb +50 -0
  99. data/spec/assembly_template_spec.rb +51 -0
  100. data/spec/component_template_spec.rb +40 -0
  101. data/spec/dependency_spec.rb +6 -0
  102. data/spec/dtk_shell_spec.rb +13 -0
  103. data/spec/dtk_spec.rb +33 -0
  104. data/spec/lib/spec_helper.rb +10 -0
  105. data/spec/lib/spec_thor.rb +105 -0
  106. data/spec/module_spec.rb +35 -0
  107. data/spec/node_spec.rb +43 -0
  108. data/spec/node_template_spec.rb +25 -0
  109. data/spec/project_spec.rb +6 -0
  110. data/spec/repo_spec.rb +7 -0
  111. data/spec/response_spec.rb +52 -0
  112. data/spec/service_spec.rb +41 -0
  113. data/spec/state_change_spec.rb +7 -0
  114. data/spec/table_print_spec.rb +48 -0
  115. data/spec/target_spec.rb +57 -0
  116. data/spec/task_spec.rb +28 -0
  117. data/views/assembly/augmented_simple_list.rb +12 -0
  118. data/views/assembly_template/augmented_simple_list.rb +12 -0
  119. data/views/list_task/augmented_simple_list.rb +12 -0
  120. metadata +351 -0
data/lib/shell.rb ADDED
@@ -0,0 +1,219 @@
1
+ require File.expand_path('client', File.dirname(__FILE__))
2
+ require File.expand_path('parser/adapters/thor', File.dirname(__FILE__))
3
+ require File.expand_path('commands/thor/dtk', File.dirname(__FILE__))
4
+ require File.expand_path('error', File.dirname(__FILE__))
5
+
6
+ # load all from shell directory since those are required
7
+ Dir[File.expand_path('shell/*.rb', File.dirname(__FILE__))].each { |file| require file }
8
+
9
+ require 'shellwords'
10
+ require 'readline'
11
+ require 'colorize'
12
+ require 'thor'
13
+
14
+ # ideas from http://bogojoker.com/readline/#trap_sigint_and_restore_the_state_of_the_terminal
15
+
16
+ # GLOBAL IDENTIFIER
17
+ $shell_mode = true
18
+
19
+ ALIAS_COMMANDS = {
20
+ 'ls' => 'list',
21
+ 'cd' => 'cc',
22
+ 'rm' => 'delete'
23
+ }
24
+
25
+ # METHODS
26
+
27
+ # support for alias commands (ls for list, cd for cc etc.)
28
+ def preprocess_commands(original_command)
29
+ command = ALIAS_COMMANDS[original_command]
30
+ # return command if alias for specific command exist in predefined ALIAS_COMMANDS
31
+ # else return entered command because there is no alias for it
32
+ return (command.nil? ? original_command : command)
33
+ end
34
+ # RUNTIME PART - STARTS HERE
35
+
36
+ def run_shell_command()
37
+ # init shell client
38
+ init_shell_context()
39
+
40
+ # prompt init
41
+ prompt = DTK::Shell::Context::DTK_ROOT_PROMPT
42
+
43
+ # trap CTRL-C and remove current text without leaving the dtk-shell
44
+ trap("INT"){
45
+ puts "\n"
46
+ raise Interrupt
47
+ }
48
+
49
+ # runtime part
50
+ begin
51
+ while line = Readline.readline(prompt, true)
52
+ prompt = execute_shell_command(line, prompt) unless line.strip.empty?
53
+ end
54
+ rescue DTK::Shell::ExitSignal => e
55
+ # do nothing
56
+ rescue ArgumentError => e
57
+ puts e.backtrace if ::DTK::Configuration.get(:development_mode)
58
+ retry
59
+ rescue Interrupt => e
60
+ #system('stty', stty_save) # Restore
61
+ retry
62
+ rescue Exception => e
63
+ DtkLogger.instance.error_pp("[CLI INTERNAL ERROR] #{e.message}", e.backtrace)
64
+ ensure
65
+ puts "\n" unless e.is_a? DTK::Shell::ExitSignal
66
+ # logout
67
+ DTK::Client::Session.logout()
68
+ # save users history
69
+ DTK::Shell::Context.save_session_history(Readline::HISTORY.to_a)
70
+ exit!
71
+ end
72
+ end
73
+
74
+ def init_shell_context()
75
+ begin
76
+ @context = DTK::Shell::Context.new
77
+ @shell_header = DTK::Shell::HeaderShell.new
78
+ # loads root context
79
+ @context.load_context()
80
+
81
+ @t1 = nil
82
+ Readline.completion_append_character=''
83
+ DTK::Shell::Context.load_session_history().each do |c|
84
+ Readline::HISTORY.push(c)
85
+ end
86
+
87
+ rescue DTK::Client::DtkError => e
88
+ DtkLogger.instance.error(e.message, true)
89
+ puts "Exiting ..."
90
+ raise DTK::Shell::ExitSignal
91
+ end
92
+ end
93
+
94
+ def execute_shell_command(line, prompt)
95
+ begin
96
+ # remove single/double quotes from string because shellwords module is not able to parse it
97
+ line.gsub!(/['"]/, '')
98
+
99
+ # some special cases
100
+ raise DTK::Shell::ExitSignal if line == 'exit'
101
+ return prompt if line.empty?
102
+ if line == 'clear'
103
+ DTK::Client::OsUtil::clear_screen
104
+ return prompt
105
+ end
106
+ # when using help on root this is needed
107
+ line = 'dtk help' if (line == 'help' && @context.root?)
108
+
109
+ args = Shellwords.split(line)
110
+ cmd = args.shift
111
+
112
+ # support command alias (ls for list etc.)
113
+ cmd = preprocess_commands(cmd)
114
+
115
+ # DEV only reload shell
116
+ if ::DTK::Configuration.get(:development_mode)
117
+ if ('restart' == cmd)
118
+ puts "DEV Reloading shell ..."
119
+ ::DTK::Client::OsUtil.dev_reload_shell()
120
+ return prompt
121
+ end
122
+ end
123
+
124
+
125
+ if ('cc' == cmd)
126
+ # in case there is no params we just reload command
127
+ args << "/" if args.empty?
128
+ prompt = @context.change_context(args, cmd)
129
+ elsif ('popc' == cmd)
130
+ @context.dirs.shift()
131
+ args << (@context.dirs.first.nil? ? '/' : @context.dirs.first)
132
+ prompt = @context.change_context(args, cmd)
133
+ elsif ('pushc' == cmd)
134
+ if args.empty?
135
+ args << (@context.dirs[1].nil? ? '/' : @context.dirs[1])
136
+ @context.dirs.unshift(args.first)
137
+ @context.dirs.uniq!
138
+ prompt = @context.change_context(args, cmd)
139
+ else
140
+ prompt = @context.change_context(args)
141
+ # using regex to remove dtk: and > from path returned by change_context
142
+ # e.g transform dtk:/assembly/node> to /assembly/node
143
+ full_path = prompt.match(/[dtk:](\/.*)[>]/)[1]
144
+ @context.dirs.unshift(full_path)
145
+ end
146
+ elsif ('dirs' == cmd)
147
+ puts @context.dirs.inspect
148
+ else
149
+
150
+ # get all next-context-candidates (e.g. for assembly get all assembly_names)
151
+ context_candidates = @context.get_ac_candidates_for_context(@context.active_context.last_context(), @context.active_context())
152
+
153
+ # this part of the code is used for calling of nested commands from base context (dtk:/>assembly/assembly_id converge)
154
+ # base_command is used to check if first command from n-level is valid e.g.
155
+ # (dtk:/>assembly/assembly_id converge - chech if 'assembly' exists in context_candidates)
156
+ # revert_context is used to return to context which command is called from after command is executed
157
+ base_command = cmd.split('/').first
158
+ revert_context = false
159
+
160
+ if context_candidates.include?(base_command)
161
+ @context.change_context([cmd])
162
+ cmd = args.shift
163
+ revert_context = true
164
+ end
165
+
166
+ if cmd.nil?
167
+ prompt = @context.change_context(["-"]) if revert_context
168
+ raise DTK::Client::DtkValidationError, "You have to provide command after context name. Usage: CONTEXT-TYPE/CONTEXT-NAME COMMAND [ARG1] .. [ARG2]."
169
+ end
170
+
171
+ # send monkey patch class information about context
172
+ Thor.set_context(@context)
173
+
174
+ # we get command and hash params, will return Validation error if command is not valid
175
+ entity_name, method_name, context_params, thor_options, invalid_options = @context.get_command_parameters(cmd,args)
176
+
177
+ # check if command is executed from parent context (e.g assembly_name list-nodes)
178
+ if context_candidates.include?(method_name)
179
+ context_params.add_context_to_params(method_name, entity_name, method_name)
180
+ method_name = context_params.method_arguments.shift if context_params.method_arguments.size > 0
181
+ else
182
+ unless @context.method_valid?(method_name)
183
+ prompt = @context.change_context(["-"]) if revert_context
184
+ raise DTK::Client::DtkValidationError, "Method '#{method_name}' is not valid in current context."
185
+ end
186
+ end
187
+
188
+ # raise validation error if option is not valid
189
+ raise DTK::Client::DtkValidationError.new("Option '#{invalid_options.first||method_name}' is not valid for current command!", true) unless invalid_options.empty?
190
+
191
+ # execute command via Thor
192
+ top_level_execute(entity_name, method_name, context_params, thor_options, true)
193
+
194
+ # when 'delete' or 'delete-and-destroy' command is executed reload cached tasks with latest commands
195
+ unless (args.nil? || args.empty?)
196
+ @context.reload_cached_tasks(entity_name) if (method_name.include?('delete') || method_name.include?('import'))
197
+ end
198
+
199
+ # check execution status, prints status to sttout
200
+ DTK::Shell::StatusMonitor.check_status()
201
+
202
+ # after nested command called from base context is executed successfully, return to context which command is executed from
203
+ # this is the same as 'cd -' command is executed
204
+ prompt = @context.change_context(["-"]) if revert_context
205
+ end
206
+ rescue DTK::Client::DSLParsing => e
207
+ DTK::Client::OsUtil.print(e.message, :red)
208
+ rescue DTK::Client::DtkValidationError => e
209
+ DTK::Client::OsUtil.print(e.message, :yellow)
210
+ rescue DTK::Shell::Error => e
211
+ DtkLogger.instance.error(e.message, true)
212
+ end
213
+
214
+ return prompt
215
+ end
216
+
217
+
218
+
219
+
@@ -0,0 +1,143 @@
1
+ require 'readline'
2
+ require 'shellwords'
3
+
4
+ dtk_require("os_util")
5
+ dtk_require_common_commands('../common/thor/push_clone_changes')
6
+ dtk_require_common_commands('../common/thor/reparse')
7
+ dtk_require_from_base("command_helper")
8
+
9
+ module DTK::Client
10
+ module Console
11
+ class << self
12
+ include PushCloneChangesMixin
13
+ include ReparseMixin
14
+ include CommandBase
15
+ include CommandHelperMixin
16
+
17
+ # Display confirmation prompt and repeat message until expected answer is given
18
+ def confirmation_prompt(message, add_options=true)
19
+ # used to disable skip with ctrl+c
20
+ trap("INT", "SIG_IGN")
21
+ message += " (yes|no)" if add_options
22
+
23
+ while line = Readline.readline("#{message}: ", true)
24
+ if (line.eql?("yes") || line.eql?("y"))
25
+ trap("INT",false)
26
+ return true
27
+ elsif (line.eql?("no") || line.eql?("n"))
28
+ trap("INT",false)
29
+ return false
30
+ end
31
+ end
32
+ end
33
+
34
+ # Loading output used to display waiting status
35
+ def wait_animation(message, time_seconds)
36
+ print message
37
+ print " [ ]"
38
+ STDOUT.flush
39
+ time_seconds.downto(1) do
40
+ 1.upto(4) do |i|
41
+ next_output = "\b\b\b\b\b\b\b"
42
+ case
43
+ when i % 4 == 0
44
+ next_output += "[ = ]"
45
+ when i % 3 == 0
46
+ next_output += "[ = ]"
47
+ when i % 2 == 0
48
+ next_output += "[ = ]"
49
+ else
50
+ next_output += "[ = ]"
51
+ end
52
+
53
+ print next_output
54
+ STDOUT.flush
55
+ sleep(0.25)
56
+ end
57
+ end
58
+ # remove loading animation
59
+ print "\b\b\b\b\b\b\bRefreshing..."
60
+ STDOUT.flush
61
+ puts
62
+ end
63
+
64
+
65
+ ##
66
+ # Method that will execute until interupted as unix like shell. As input takes
67
+ # path to desire directory from where unix shell can execute normaly.
68
+ #
69
+ def unix_shell(path,module_id,module_type,version=nil)
70
+
71
+ dtk_shell_ac_proc = Readline.completion_proc
72
+ dtk_shell_ac_append_char = Readline.completion_append_character
73
+
74
+ if OsUtil.is_windows?
75
+ puts "[NOTICE] Shell interaction is currenly not supported on Windows."
76
+ return
77
+ end
78
+
79
+ begin
80
+ # we need to change path like this since system call 'cd' is not supported
81
+ initial_dir = Dir.pwd
82
+ Dir.chdir(path)
83
+ puts "[NOTICE] You are switching to unix-shell, to path #{path}"
84
+
85
+ prompt = DTK::Client::OsUtil.colorize("$dtk:unix-shell ", :yellow)
86
+ Readline.completion_append_character = ""
87
+ Readline.completion_proc = Proc.new do |str|
88
+ Dir[str+'*'].grep(/^#{Regexp.escape(str)}/)
89
+ end
90
+ while line = Readline.readline("#{prompt}#{Dir.getwd()}>", true)
91
+ begin
92
+ line = line.chomp()
93
+ break if line.eql?('exit')
94
+ # since we are not able to support cd command due to ruby specific restrictions
95
+ # we will be using chdir to this.
96
+ if (line.match(/^cd /))
97
+ # remove cd part of command
98
+ line = line.gsub(/^cd /,'')
99
+ # Get path
100
+ path = line.match(/^\//) ? line : "#{Dir.getwd()}/#{line}"
101
+ # If filepat* with '*' at the end, match first directory and go in it, else try to change original input
102
+ if path.match(/\*$/)
103
+ dirs = Dir[path].select{|file| File.directory?(file)}
104
+ unless dirs.empty?
105
+ Dir.chdir(dirs.first)
106
+ next
107
+ end
108
+ end
109
+ # Change directory
110
+ Dir.chdir(path)
111
+ elsif line.match(/^dtk-push-changes/)
112
+ args = Shellwords.split(line)
113
+ commit_msg = nil
114
+
115
+ unless args.size==1
116
+ raise DTK::Client::DtkValidationError, "To push changes to server use 'dtk-push-changes [-m COMMIT-MSG]'" unless (args[1]=="-m" && args.size==3)
117
+ commit_msg = args.last
118
+ end
119
+
120
+ reparse_aux(path)
121
+ push_clone_changes_aux(module_type, module_id, version, commit_msg)
122
+ else
123
+ system(line)
124
+ end
125
+ rescue Exception => e
126
+ DtkLogger.instance.error_pp(e.message, e.backtrace)
127
+ end
128
+ end
129
+ rescue Interrupt
130
+ puts ""
131
+ # do nothing else
132
+ ensure
133
+ Dir.chdir(initial_dir)
134
+ end
135
+
136
+ Readline.completion_append_character = dtk_shell_ac_append_char unless dtk_shell_ac_append_char.nil?
137
+ Readline.completion_proc = dtk_shell_ac_proc unless dtk_shell_ac_proc.nil?
138
+ puts "[NOTICE] You are leaving unix-shell."
139
+ end
140
+
141
+ end
142
+ end
143
+ end
@@ -0,0 +1,46 @@
1
+ module DTK
2
+ module Client
3
+ #
4
+ # Class is used as puppet wrapper, at the moment it will use console comamnds, later
5
+ # to be replaced with direct usage of puppet code, or re-implentation of their direct calls
6
+ #
7
+ class DtkPuppet
8
+
9
+ MODULE_PATH = OsUtil.module_clone_location()
10
+
11
+ # installs puppet module from puppet forge via puppet module
12
+ # method will print out progress or errrors
13
+ #
14
+ # Returns: Name of directory where module is saved
15
+ def self.install_module(module_name)
16
+ output = nil
17
+
18
+ OsUtil.suspend_output do
19
+ output = `puppet module install #{module_name} --modulepath #{MODULE_PATH} --force --render-as json`
20
+ end
21
+
22
+ # extract json from output, regex will match json in string
23
+ matched = output.match(/\{.+\}/)
24
+
25
+ raise DTK::Client::DtkError, "Puppet module '#{module_name}' not found." unless matched
26
+
27
+ # parse matched json
28
+ result = JSON.parse(matched[0])
29
+
30
+ if result['result'] == 'failure'
31
+ # we remove puppet specific messages
32
+ filtered = result['error']['multiline'].gsub(/^.*puppet module.*$\n?/,'')
33
+ # we strip and join multiline message
34
+ filtered = filtered.split(/\n/).map(&:strip).join(', ')
35
+ raise DTK::Client::DtkError, filtered
36
+ end
37
+
38
+ # puppet uses last part of the module name, as dir for location
39
+ dir_name = module_name.split('-').last
40
+ puts "Successfully installed '#{module_name}' from puppet forge, location: '#{MODULE_PATH}/#{dir_name}'"
41
+ return dir_name
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,265 @@
1
+ dtk_require_from_base('domain/response')
2
+ dtk_require_from_base('auxiliary')
3
+ require 'highline'
4
+
5
+ module DTK
6
+ module Client
7
+ module OsUtil
8
+
9
+ extend Auxiliary
10
+
11
+ class << self
12
+ def is_mac?
13
+ RUBY_PLATFORM.downcase.include?('darwin')
14
+ end
15
+
16
+ def is_windows?
17
+ RUBY_PLATFORM =~ /mswin|mingw|cygwin/
18
+ end
19
+
20
+ def is_linux?
21
+ RUBY_PLATFORM.downcase.include?('linux')
22
+ end
23
+
24
+ def get_temp_location
25
+ is_windows? ? genv(:temp) : '/tmp'
26
+ end
27
+
28
+ def get_log_location
29
+ return "#{dtk_local_folder}"
30
+ end
31
+
32
+ def clear_screen
33
+ command = is_windows? ? "cls" : "clear"
34
+ system(command)
35
+ end
36
+
37
+ def dtk_home_dir
38
+ return "#{home_dir}"
39
+ end
40
+
41
+ # This will return class object from DTK::Client namespace
42
+ def get_dtk_class(command_name)
43
+ begin
44
+ Object.const_get('DTK').const_get('Client').const_get(cap_form(command_name))
45
+ rescue Exception => e
46
+ return nil
47
+ end
48
+ end
49
+
50
+ # for Windows app folder is already under OS username
51
+ def dtk_user_app_folder
52
+ if is_windows?
53
+ dtk_app_folder()
54
+ else
55
+ "#{dtk_app_folder}#{::DTK::Common::Aux.running_process_user()}/"
56
+ end
57
+ end
58
+
59
+ def dtk_app_folder
60
+ return (is_windows? ? "#{genv(:homedrive)}#{genv(:homepath)}/dtk/" : "#{/etc/}dtk/")
61
+ end
62
+
63
+ def dtk_local_folder
64
+ return (is_windows? ? "#{genv(:homedrive)}#{genv(:homepath)}/dtk/" : "#{home_dir}/dtk/")
65
+ end
66
+
67
+ def home_dir
68
+ return (is_windows? ? "#{genv(:homedrive)}#{genv(:homepath)}" : "#{genv(:home)}")
69
+ end
70
+
71
+ def genv(name)
72
+ return ENV[name.to_s.upcase].gsub(/\\/,'/')
73
+ end
74
+
75
+ def edit(file)
76
+ editor = ENV['EDITOR']
77
+ if is_windows?
78
+ raise Client::DtkError, "Environment variable EDITOR needs to be set; exit dtk-shell, set variable and log back into dtk-shell." unless editor
79
+ else
80
+ editor = 'vim' unless editor
81
+ end
82
+
83
+ system("#{editor} #{file}")
84
+ end
85
+
86
+ def module_location(module_type,module_name,version=nil,opts={})
87
+ #compact used because module_name can be nil
88
+ module_location_parts(module_type,module_name,version,opts).compact.join('/')
89
+ end
90
+
91
+ #if module location is /a/b/d/mod it returns ['/a/b/d','mod']
92
+ def module_location_parts(module_type,module_name,version=nil,opts={})
93
+ base_path = clone_base_path(opts[:assembly_module] ? :assembly_module : module_type)
94
+ if assembly_module = opts[:assembly_module]
95
+ assembly_name = opts[:assembly_module][:assembly_name]
96
+ base_all_types = "#{base_path}/#{assembly_name}"
97
+ if module_type == :all
98
+ [base_all_types,nil]
99
+ else
100
+ type = clone_base_path(module_type).split('/').last
101
+ ["#{base_all_types}/#{type}", module_name]
102
+ end
103
+ else
104
+ [base_path, "#{module_name}#{version && "-#{version}"}"]
105
+ end
106
+ end
107
+
108
+ def module_version_locations(module_type,module_name,version=nil,opts={})
109
+ base_path = module_location_parts(module_type,module_name,version,opts).first
110
+ module_versions = Dir.entries(base_path).select{|a| a.match(/^#{module_name}-\d.\d.\d$/)}
111
+ module_versions.map{|version|"#{base_path}/#{version}"}
112
+ end
113
+
114
+ def module_clone_location()
115
+ clone_base_path(:component_module)
116
+ end
117
+
118
+ def service_clone_location()
119
+ clone_base_path(:service_module)
120
+ end
121
+
122
+ def assembly_module_base_location()
123
+ clone_base_path(:assembly_module)
124
+ end
125
+
126
+ def clone_base_path(module_type)
127
+
128
+ path =
129
+ case module_type
130
+ when :service_module then Config[:service_location]
131
+ when :component_module then Config[:module_location]
132
+ when :assembly_module then Config[:assembly_module_base_location]
133
+ else raise Client::DtkError, "Unexpected module_type (#{module_type})"
134
+ end
135
+
136
+
137
+ final_path = path && path.start_with?('/') ? path : "#{dtk_local_folder}#{path}"
138
+ # remove last slash if set in configuration by mistake
139
+ final_path.gsub(/\/$/,'')
140
+ end
141
+ private :clone_base_path
142
+ #
143
+ #
144
+ #
145
+ def local_component_module_list()
146
+ component_module_dir = module_clone_location()
147
+ Dir.entries(component_module_dir).select {|entry| File.directory? File.join(component_module_dir,entry) and !(entry =='.' || entry == '..') }
148
+ end
149
+
150
+ # Public method will convert given string, to string with colorize output
151
+ #
152
+ # message - String to be colorized
153
+ # color - Symbol describing color to be used
154
+ #
155
+ # Returns String with colorize output
156
+ def colorize(message, color)
157
+ # at the moment we do not support colors in windows
158
+ ((is_windows? || message.nil?) ? message : message.colorize(color))
159
+ end
160
+
161
+ # Public method will print to STDOUT with given color
162
+ #
163
+ # message - String to be colorize and printed
164
+ # color - Symbol describing the color to be used on STDOUT
165
+ #
166
+ # Void
167
+ def print(message, color)
168
+ puts colorize(message, color)
169
+ end
170
+
171
+ # Public block, method will suspend STDOUT, STDERR in body of it
172
+ #
173
+ # Example
174
+ # suspend_output do
175
+ # # some calls
176
+ # end
177
+ def suspend_output
178
+ if is_windows?
179
+ retval = yield
180
+ else
181
+ begin
182
+ orig_stderr = $stderr.clone
183
+ orig_stdout = $stdout.clone
184
+ $stderr.reopen File.new('/dev/null', 'w')
185
+ $stdout.reopen File.new('/dev/null', 'w')
186
+ retval = yield
187
+ rescue Exception => e
188
+ $stdout.reopen orig_stdout
189
+ $stderr.reopen orig_stderr
190
+ raise e
191
+ ensure
192
+ $stdout.reopen orig_stdout
193
+ $stderr.reopen orig_stderr
194
+ end
195
+ end
196
+ retval
197
+ end
198
+
199
+ def which(cmd)
200
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
201
+ ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
202
+ exts.each { |ext|
203
+ exe = File.join(path, "#{cmd}#{ext}")
204
+ return exe if File.executable? exe
205
+ }
206
+ end
207
+ return nil
208
+ end
209
+
210
+ def dev_reload_shell()
211
+ suspend_output do
212
+ load File.expand_path('../../lib/util/os_util.rb', File.dirname(__FILE__))
213
+ load File.expand_path('../../lib/shell/help_monkey_patch.rb', File.dirname(__FILE__))
214
+ load File.expand_path('../../lib/shell/domain.rb', File.dirname(__FILE__))
215
+ path = File.expand_path('../../lib/commands/thor/*.rb', File.dirname(__FILE__))
216
+ Dir[path].each do |thor_class_file|
217
+ load thor_class_file
218
+ end
219
+ end
220
+ end
221
+
222
+ def put_warning(prefix, text, color)
223
+ width = HighLine::SystemExtensions.terminal_size[0] - (prefix.length + 1)
224
+ text_split = wrap(text, width)
225
+ Kernel.print colorize(prefix, color), " "
226
+ text_split.lines.each_with_index do |line, index|
227
+ line = " "*(prefix.length + 1) + line unless index == 0
228
+ puts line
229
+ end
230
+ end
231
+
232
+ def wrap(text, wrap_at)
233
+ wrapped = [ ]
234
+ text.each_line do |line|
235
+ # take into account color escape sequences when wrapping
236
+ wrap_at = wrap_at + (line.length - actual_length(line))
237
+ while line =~ /([^\n]{#{wrap_at + 1},})/
238
+ search = $1.dup
239
+ replace = $1.dup
240
+ if index = replace.rindex(" ", wrap_at)
241
+ replace[index, 1] = "\n"
242
+ replace.sub!(/\n[ \t]+/, "\n")
243
+ line.sub!(search, replace)
244
+ else
245
+ line[$~.begin(1) + wrap_at, 0] = "\n"
246
+ end
247
+ end
248
+ wrapped << line
249
+ end
250
+ return wrapped.join
251
+ end
252
+
253
+ def actual_length( string_with_escapes )
254
+ string_with_escapes.to_s.gsub(/\e\[\d{1,2}m/, "").length
255
+ end
256
+
257
+ private
258
+
259
+ def seperator
260
+ return (is_windows? ? "\\" : "/")
261
+ end
262
+ end
263
+ end
264
+ end
265
+ end
@@ -0,0 +1,27 @@
1
+ #TODO: test for assembly list/display; want to make assembly specfic stuff datadriven
2
+ dtk_require 'simple_list'
3
+ module DTK
4
+ module Client
5
+ class ViewProcAugmentedSimpleList < ViewProcSimpleList
6
+ private
7
+ def initialize(type,command_class,data_type_index=nil)
8
+ super
9
+ @meta = get_meta(type,command_class)
10
+ end
11
+ def failback_meta(ordered_cols)
12
+ nil
13
+ end
14
+ def simple_value_render(ordered_hash,ident_info)
15
+ augmented_def?(ordered_hash,ident_info) || super
16
+ end
17
+ def augmented_def?(ordered_hash,ident_info)
18
+ return nil unless @meta
19
+ if aug_def = @meta["#{ordered_hash.object_type}_def".to_sym]
20
+ ident_str = ident_str(ident_info[:ident]||0)
21
+ vals = aug_def[:keys].map{|k|ordered_hash[k.to_s]}
22
+ "#{ident_str}#{aug_def[:fn].call(*vals)}\n"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end