butler-mainframe 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2be056e6d5c2cd0b24cdd1ba7c27a92f2e11d295
4
- data.tar.gz: 0265a490b0c3891b40e0c336c05e4d73563d9150
3
+ metadata.gz: 622cd36fbabc8ca579e69b36ef0d3ce535995854
4
+ data.tar.gz: bb98f4819d07e639c8cb88e092cc3a3a443fa648
5
5
  SHA512:
6
- metadata.gz: 71d70a1deaf10b776b6e4b49a5eb57d608c5931b245f72010876f32d9946e05ac9aa1cee342c87df895719a63b79dd6ae2ebac3ab6b715269f173b454f6185f7
7
- data.tar.gz: 721c158317b5282ca9e51df2988e1b081992420427176092a0a3001581ca2930792ae7392003ec6284a51a62f0e6b6247c07f97cdd872aa745a7d54092b5ee77
6
+ metadata.gz: 98f255d73ae417b65735be57cea9571d8d9f181ff794e4459a07e494ee8d1866af234d681a1f3af8301233d2b66ca166985677bbd94c14f23f33ae7c5a6565b7
7
+ data.tar.gz: 0f7ae6b50f6f8d5bdd0f0ede9fae786f3927f88ef707531f4c8fa871a8f3ddd0885331d98176b9a1fcdb6d4a82c9eeb0a30ac3ecfe6719b394505b6124e6c391
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ 0.2.0 [☰](https://github.com/marcomd/butler-mainframe/compare/v0.1.0...v0.2.0) October 20th, 2015
2
+ ------------------------------
3
+ * Added support for the free and open source x3270 terminal emulator, use :x3270 as host gateway in butler configuration
4
+ * Added x3270 sections to documentation
5
+ * Passport sub class now remove spaces from command input
6
+ * Added :erase_field_first param to write method in the host base class in addition to :clean_first_chars to clear a given number of chars
7
+
1
8
  0.1.0 [☰](https://github.com/marcomd/butler-mainframe/compare/v0.0.6...v0.1.0) October 14th, 2015
2
9
  ------------------------------
3
10
  * Added IBM personal communication support (tested on 6.0.16), use :pcomm as host gateway in butler configuration
data/README.md CHANGED
@@ -18,17 +18,15 @@ Instal the gem from rubygems
18
18
  gem install butler-mainframe
19
19
 
20
20
  Then you have to install your favorite emulator.
21
- At the moment is supported only [Passport web to host by rocket software](http://www.rocketsoftware.com/products/rocket-passport-web-to-host)
22
21
 
23
- ## Emulator
24
-
25
- At the moment are managed two emulators both are commercial which must be purchased and installed on the machine.
26
- Both have x days free trial.
27
22
 
28
- * [Passport web to host by Rocket Software](http://www.rocketsoftware.com/resource/rocket-passport-web-host-overview)
29
- * [Personal communication by IBM](http://www-03.ibm.com/software/products/en/pcomm)
23
+ ## Emulator
30
24
 
25
+ At the moment are managed the below emulators. First two are commercial which must be purchased and installed on the machine (both have x days free trial). The last is free and open source.
31
26
 
27
+ * [Passport web to host by Rocket Software](http://www.rocketsoftware.com/resource/rocket-passport-web-host-overview)
28
+ * [Personal communication by IBM](http://www-03.ibm.com/software/products/en/pcomm)
29
+ * [x3270 maintained by Paul Mates](http://x3270.bgp.nu/)
32
30
 
33
31
 
34
32
  ## Configuration
@@ -43,29 +41,37 @@ In the config folder there are two files:
43
41
  config.rb can be used for the configuration of the gem and the emulator
44
42
 
45
43
  ```ruby
46
- # Example to configura Personal communication
44
+ # Example to configure Passport web to host
47
45
 
48
46
  ButlerMainframe.configure do |config|
49
- config.host_gateway = :pcomm
50
- config.browser_path = "'C:/Program Files (x86)/IBM/Personal Communications/pcsws.exe'"
51
- config.session_path = "'C:/Users/Marco/AppData/Roaming/IBM/Personal Communications/host3270.ws'"
52
- config.session_tag = 'A'
47
+ config.host_gateway = :passport
48
+ config.browser_path = 'c:/Program Files (x86)/Internet Explorer/iexplore.exe'
49
+ config.session_path = 'https://localhost/zephyr/Ecomes.zwh?sessionprofile=3270dsp/Sessions/host3270'
50
+ config.session_tag = 1
53
51
  config.timeout = 3000
54
52
  end
55
53
  ```
56
54
 
57
55
  ```ruby
58
- # Example to configura Passport web to host
56
+ # Example to configure Personal communication
59
57
 
60
58
  ButlerMainframe.configure do |config|
61
- config.host_gateway = :passport
62
- config.browser_path = 'c:/Program Files (x86)/Internet Explorer/iexplore.exe'
63
- config.session_path = 'https://localhost/zephyr/Ecomes.zwh?sessionprofile=3270dsp/Sessions/host3270'
64
- config.session_tag = 1
59
+ config.host_gateway = :pcomm
60
+ config.session_path = '"C:/Program Files (x86)/IBM/Personal Communications/pcsws.exe" "C:/Users/Marco/AppData/Roaming/IBM/Personal Communications/host3270.ws"'
61
+ config.session_tag = 'A'
65
62
  config.timeout = 3000
66
63
  end
67
64
  ```
68
65
 
66
+ ```ruby
67
+ # Example to configure X3270
68
+ ButlerMainframe.configure do |config|
69
+ config.host_gateway = :x3270
70
+ config.session_path = '"C:/Program Files (x86)/wc3270/ws3270.exe" 127.0.0.1 -model 2 --'
71
+ config.timeout = 5 # In seconds
72
+ end
73
+ ```
74
+
69
75
  ### Use configuration
70
76
 
71
77
  settings.yml for the variables necessary to use the emulator like user, password, cics selection and everything else. It has one section for every environment in rails style.
@@ -89,7 +95,7 @@ In this example, I dont start the session and immediately create a new instance:
89
95
  Session not found, starting new...
90
96
  Starting session with process id 8560, wait please...
91
97
  ** Connection established with host3270 **
92
- => #<ButlerMainframe::Host:0x29f3358 @debug=true, @wait=0.01, @wait_debug=2, @session=1, @close_session=:evaluate, @pid=8560, @action=#<WIN32OLE:0x29ebe10>, @session_started_by_me=true>
98
+ => #<ButlerMainframe::Host:0x29f3358 @debug=true, @wait=0.01, @wait_debug=2, @session=1, @close_session=:evaluate, @pid=8560, @action=#<WIN32OLE:0x29ebe10>>
93
99
 
94
100
  now session is ready to use:
95
101
 
@@ -128,8 +134,7 @@ host.write 'ruby on rails', :y => 6, :x => 15, hook: 'SYSTEM='
128
134
 
129
135
  The aim is to speed up browsing through static screens.
130
136
  The butler detects the current screen and It moves towards the target.
131
- For example, if the current screen is the login_session and you want to go to the next, to do that Butler log in
132
- In this case it identifies the first map the session login to the mainframe and it does the login to go to the next screen.
137
+ For example, if the current screen is the login_session and you want to go to the next, Butler log in for you.
133
138
 
134
139
  ```ruby
135
140
  # Go to the login session screen
@@ -153,7 +158,6 @@ My advice is to use navigate method for generic navigation and use a specific mo
153
158
 
154
159
  ## With Rails
155
160
 
156
- __In development...__
157
161
  This module can be use on rails project.
158
162
  Add in your gemfile
159
163
 
@@ -195,10 +199,14 @@ end
195
199
  ```
196
200
 
197
201
  Create a polimorphic model:
198
- rails generate screen hook_id:integer 'hook_type:string{30}' 'screen_type:integer{1}' video:text 'message:string{160}' 'cursor_x:integer{1}' 'cursor_y:integer{1}'
202
+
203
+ rails generate screen hook_id:integer 'hook_type:string{30}' 'screen_type:integer{1}' video:text 'message:string{160}' 'cursor_x:integer{1}' 'cursor_y:integer{1}'
199
204
 
200
205
  In the model to be related to screen we insert:
206
+
207
+ ```ruby
201
208
  has_many :screens, :as => :hook, :dependent => :destroy
209
+ ```
202
210
 
203
211
 
204
212
  ## Test with rake
@@ -325,11 +333,24 @@ session.autECLOIA.ole_methods (screen):
325
333
  # CancelWaits # RegisterCommEvent # UnregisterCommEvent # RegisterOIAEvent
326
334
  # UnregisterOIAEvent # GetTypeInfoCount # GetTypeInfo # GetIDsOfNames
327
335
 
336
+ ### x3270
337
+
338
+ Documentation can be found [here](http://x3270.bgp.nu/documentation-manpages.html)
339
+ __At the moment it doesn't support check on protect area__
340
+ __x3270 module works only on ruby 1.9+__
341
+
342
+ ```ruby
343
+ require 'open3'
344
+ stdin, stdout, thread = Open3.popen2e('"C:/Program Files (x86)/wc3270/ws3270.exe" YOUR_HOST_IP -model 2 --')
345
+ ```
346
+
347
+ Read the methods list documentation: [windows](http://x3270.bgp.nu/Windows/wc3270-script.html) or [unix](http://x3270.bgp.nu/Unix/x3270-script.html)
328
348
 
329
349
  ## ToDo
330
350
 
331
351
  * Improve unit test
332
352
  * Improve static navigation
353
+ * Add meta class to choose your host method name and multi language support as well
333
354
 
334
355
  ## License
335
356
 
@@ -25,7 +25,9 @@ env = Rails.env if defined?(Rails)
25
25
  env ||= $ARGV[0] if $ARGV
26
26
  env ||= "development"
27
27
  debug = env == "development" ? true : false
28
- require "mainframe/#{ButlerMainframe.configuration.host_gateway.to_s.downcase}"
28
+
29
+ # require the emulator sub class specified in the config.rb
30
+ require "mainframe/emulators/#{ButlerMainframe.configuration.host_gateway.to_s.downcase}"
29
31
 
30
32
 
31
33
  ButlerMainframe::Settings.load!(File.join(ButlerMainframe.root,'lib','config','settings.yml'), :env => env)
data/lib/config/config.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  ButlerMainframe.configure do |config|
2
- config.host_gateway = 'passport'
3
- config.browser_path = 'c:/Program Files (x86)/Internet Explorer/iexplore.exe'
4
- config.session_url = 'https://ergmilict10/zephyr/Ecomes.zwh?sessionprofile=3270dsp/Sessions/host3270'
5
- config.session_tag = 1
6
- config.timeout = 3000
2
+ config.host_gateway = :x3270
3
+ config.session_path = '"C:/Program Files (x86)/wc3270/ws3270.exe" YOUR_HOST_IP -model 2 --'
4
+ config.timeout = 5 # In seconds
7
5
  end
8
6
 
@@ -0,0 +1,6 @@
1
+ ButlerMainframe.configure do |config|
2
+ config.host_gateway = :x3270
3
+ config.session_path = '"C:/Program Files (x86)/wc3270/ws3270.exe" YOUR_HOST_IP -model 2 --'
4
+ config.timeout = 5 # In seconds
5
+ end
6
+
@@ -48,7 +48,7 @@ module ButlerMainframe
48
48
  #Execute keyboard command like PF1 or PA2 or ENTER ...
49
49
  def sub_exec_command cmd, options={}
50
50
  # Cast cmd to_s cause it could be passed as label
51
- @screen.SendKeys "<#{cmd}>"
51
+ @screen.SendKeys "<#{cmd.gsub /\s/, ''}>"
52
52
  @screen.WaitHostQuiet
53
53
  end
54
54
 
File without changes
@@ -0,0 +1,135 @@
1
+ require 'open3'
2
+ require 'mainframe/host_base'
3
+
4
+ # This class use X3270, an interesting project open source
5
+ # http://x3270.bgp.nu/Windows/wc3270-script.html
6
+ # http://x3270.bgp.nu/Windows/ws3270-man.html
7
+ module ButlerMainframe
8
+ class Host < HostBase
9
+
10
+ private
11
+
12
+ def sub_create_object options={}
13
+ str_obj = "#{options[:session_path]}"
14
+ puts "#{Time.now.strftime "%H:%M:%S"} Creating object #{str_obj}..." if @debug == :full
15
+ @action = {}
16
+ @action[:in], @action[:out], @action[:thr] = Open3.popen2e(str_obj)
17
+ @pid = @action[:thr].pid
18
+ end
19
+
20
+ # Check is session is started
21
+ def sub_object_created?
22
+ res = @action[:in] && @action[:out] && @action[:thr]
23
+ puts "#{Time.now.strftime "%H:%M:%S"} Terminal successfully detected" if @debug == :full && res
24
+ res
25
+ end
26
+
27
+ # Check is session is operative
28
+ def sub_object_ready?
29
+ res = !x_cmd("Query(ConnectionState)").strip.empty?
30
+ puts "#{Time.now.strftime "%H:%M:%S"} Session ready" if @debug == :full && res
31
+ res
32
+ end
33
+
34
+ def sub_name
35
+ "X3270 #{x_cmd "Query(Host)"}".strip
36
+ end
37
+
38
+ def sub_fullname
39
+ "#{sub_name} #{x_cmd "Query(LuName)"}".strip
40
+ end
41
+
42
+ #Ends the connection and closes the session
43
+ def sub_close_session
44
+ @action[:in].close
45
+ @action[:out].close
46
+ end
47
+
48
+ #Execute keyboard command like PF1 or PA2 or ENTER ...
49
+ def sub_exec_command cmd, options={}
50
+ cmd = cmd.split.map(&:capitalize).join
51
+ if m=/^(Pf|Pa)(\d+)$/.match(cmd)
52
+ cmd = "#{m[1]}(#{m[2]})"
53
+ end
54
+ x_cmd cmd
55
+
56
+ command_skip_wait = %w(^erase ^delete)
57
+ x_cmd "Wait(#{@timeout}, Output)" unless /(#{command_skip_wait.join('|')})/i === cmd
58
+ end
59
+
60
+ #It reads one line part of the screen
61
+ def sub_scan_row y, x, len
62
+ x_cmd "Ascii(#{y-1},#{x-1},#{len})"
63
+ end
64
+
65
+ #It reads a rectangle on the screen
66
+ def sub_scan_area y1, x1, y2, x2
67
+ x_cmd "Ascii(#{y1-1},#{x1-1},#{y2-y1+1},#{x2-x1+1})"
68
+ end
69
+
70
+ # Get cursor coordinates
71
+ def sub_get_cursor_axes
72
+ res = x_cmd "Query(Cursor)"
73
+ res.split.map{|c| c.to_i + 1}
74
+ end
75
+
76
+ # Move cursor to given coordinates
77
+ def sub_set_cursor_axes y, x, options={}
78
+ options = {
79
+ :wait => true
80
+ }.merge(options)
81
+ x_cmd "MoveCursor(#{y-1},#{x-1})"
82
+ if options[:wait]
83
+ x_cmd "Wait(#{@timeout},InputField)"
84
+ raise "Positioning the cursor at the coordinates (#{y}, #{x}) failed!" unless sub_get_cursor_axes == [y, x]
85
+ end
86
+ end
87
+
88
+ # Write text on the screen at given coordinates
89
+ # :check_protect => true add sensitivity to protected areas
90
+ def sub_write_text text, y, x, options={}
91
+ options = {
92
+ :check_protect => true
93
+ }.merge(options)
94
+ sub_set_cursor_axes y, x
95
+ x_cmd "String(#{text})"
96
+ # TODO
97
+ # if options[:check_protect]
98
+ # end
99
+ end
100
+
101
+ # Wait text at given coordinates and wait the session is available again
102
+ def sub_wait_for_string text, y, x
103
+ x_cmd "Wait(#{@timeout},InputField)"
104
+ total_time = 0.0
105
+ sleep_time = 0.5
106
+ while sub_scan_row(y, x, text.size) != text do
107
+ sleep sleep_time
108
+ total_time = total_time + sleep_time
109
+ # @timeout should be in milliseconds but everything is possible
110
+ break if total_time >= @timeout
111
+ end
112
+ raise "sub_wait_for_string: string #{text} not found at (#{y}, #{x})" unless sub_scan_row(y, x, text.size) == text
113
+ true
114
+ end
115
+
116
+ def x_cmd cmd
117
+ puts "x_cmd in: #{cmd}" if @debug
118
+ @action[:in].print "#{cmd}\n"
119
+ @action[:in].flush
120
+
121
+ str_res_ok = 'ok'
122
+ ar_res = [str_res_ok, 'error']
123
+
124
+ line, str_out = '', ''
125
+ while line = @action[:out].gets.chomp do
126
+ puts "x_cmd out: '#{line}'" if @debug
127
+ break if ar_res.include? line
128
+ str_out << "#{line[6..-1]}" if /^data:\s/ === line
129
+ end
130
+ line == str_res_ok ? str_out : raise(str_out)
131
+ end
132
+
133
+ end
134
+ end
135
+
@@ -31,7 +31,7 @@ module ButlerMainframe
31
31
  @session_tag = options[:session_tag]
32
32
  @close_session = options[:close_session]
33
33
  @timeout = options[:timeout]
34
- @pid = nil
34
+ @pid = nil
35
35
 
36
36
  create_object options
37
37
  end
@@ -45,9 +45,9 @@ module ButlerMainframe
45
45
  puts "Session closed" if @debug
46
46
  wait_session 0.1
47
47
  when :evaluate
48
- if @session_started_by_me
48
+ if @pid
49
49
  sub_close_session
50
- puts "Session closed cause started by this process" if @debug
50
+ puts "Session closed because started by this process with id #{@pid}" if @debug
51
51
  wait_session 0.1
52
52
  else
53
53
  puts "Session not closed because it was already existing" if @debug
@@ -95,7 +95,7 @@ module ButlerMainframe
95
95
  :check => true,
96
96
  :raise_error_on_check => true,
97
97
  :sensible_data => nil,
98
- :clean_first_chars => nil
98
+ :clean_first_chars => nil # clean x chars before writing a value
99
99
  }.merge(options)
100
100
 
101
101
  y = options[:y]
@@ -104,18 +104,19 @@ module ButlerMainframe
104
104
  raise "Missing coordinates! y(row)=#{y} x(column)=#{x} " unless x && y
105
105
  raise "Sorry, cannot write null values" unless text
106
106
 
107
- bol_written = nil
107
+ bol_written = false
108
108
  if options[:hook]
109
109
  (y-hooked_rows..y+hooked_rows).each do |row_number|
110
110
  if /#{options[:hook]}/ === scan_row(row_number, 1, MAX_TERMINAL_COLUMNS)
111
111
  puts "Change y from #{y} to #{row_number} cause hook to:#{options[:hook]}" if row_number != y && @debug
112
- bol_written = write_clean_text_on_map text, row_number, x, options
112
+ bol_written = write_text_on_map text, row_number, x, options
113
113
  break
114
114
  end
115
115
  end
116
+ else
117
+ #If no control is required or was not found the label reference
118
+ bol_written = write_text_on_map(text, y, x, options) unless bol_written
116
119
  end
117
- #If no control is required or was not found the label reference
118
- bol_written = write_clean_text_on_map(text, y, x, options) unless bol_written
119
120
  bol_written
120
121
  end
121
122
 
@@ -144,8 +145,10 @@ module ButlerMainframe
144
145
 
145
146
  sub_create_object options
146
147
 
147
- # if the terminal is not found then we start it
148
- unless sub_object_created?
148
+ if sub_object_created?
149
+ puts "Using the terminal with process id #{@pid}" if @pid && @debug
150
+ else
151
+ # if the terminal is not found then we start it
149
152
  puts "Session #{@session_tag} not found, starting new..." if @debug
150
153
 
151
154
  executable, args = if options[:browser_path] && !options[:browser_path].empty?
@@ -172,7 +175,6 @@ module ButlerMainframe
172
175
  sub_create_object
173
176
  sub_object_created? ? break : sleep(seconds_between_attempts)
174
177
  end
175
- @session_started_by_me = true
176
178
  end
177
179
 
178
180
  raise "Session #{@session_tag} not started. Check the session #{options[:browser_path]} #{options[:session_path]}" unless sub_object_created?
@@ -210,47 +212,49 @@ module ButlerMainframe
210
212
  str
211
213
  end
212
214
 
213
- # It has an additional option to clean the line before writing a value
214
- def write_clean_text_on_map text, y, x, options={}
215
- if options[:clean_first_chars] && options[:clean_first_chars].to_i > 0
216
- puts "Clean #{options[:clean_first_chars]} char#{options[:clean_first_chars] == 1 ? '' : 's'} y:#{y} x:#{x}" if @debug
217
- bol_cleaned = write_text_on_map(" " * options[:clean_first_chars], y, x, options)
218
- unless bol_cleaned
219
- puts "EHI! Impossible to clean the area specified" if @debug
220
- return false
221
- end
222
- end
223
- puts "Clean: #{options[:sensible_data] ? ('*' * text.size) : text} y:#{y} x:#{x}" if @debug
224
- write_text_on_map(text, y, x, options)
225
- end
226
-
227
215
  # Write a text on the screen
228
216
  # It also contains the logic to control the successful writing
229
217
  def write_text_on_map text, y, x, options={}
230
218
  options = {
231
219
  :check => true,
232
220
  :raise_error_on_check => true,
233
- :sensible_data => nil
221
+ :sensible_data => nil,
222
+ :clean_first_chars => nil,
223
+ :erase_field_first => nil
234
224
  }.merge(options)
235
- raise "Impossible to write beyond row #{MAX_TERMINAL_ROWS}" if y > MAX_TERMINAL_ROWS
225
+ raise "Impossible to write beyond row #{MAX_TERMINAL_ROWS}" if y > MAX_TERMINAL_ROWS
236
226
  raise "Impossible to write beyond column #{MAX_TERMINAL_COLUMNS}" if x > MAX_TERMINAL_COLUMNS
237
- raise "Impossible to write a null value" unless text
227
+ raise "Impossible to write a null value" unless text
228
+
229
+ if options[:clean_first_chars] && options[:clean_first_chars].to_i > 0
230
+ puts "write_text_on_map: Clean #{options[:clean_first_chars]} char#{options[:clean_first_chars] == 1 ? '' : 's'} y:#{y} x:#{x}" if @debug
231
+ bol_cleaned = write_text_on_map(" " * options[:clean_first_chars], y, x, options)
232
+ unless bol_cleaned
233
+ puts "write_text_on_map: EHI! Impossible to clean the area specified" if @debug
234
+ return false
235
+ end
236
+ end
237
+
238
+ if options[:erase_field_first]
239
+ set_cursor_axes y, x
240
+ do_erase
241
+ end
242
+
238
243
  sub_write_text text, y, x, :check_protect => options[:check]
239
- # It returns the function's result
240
- if options[:check]
244
+ res = true
245
+ # If check is required it verify text is on the screen at given coordinates
246
+ # Sensible data option disable the check because it could be on hidden fields
247
+ if options[:check] && !options[:sensible_data]
241
248
  # It expects the string is present on the session at the specified coordinates
242
- if sub_wait_for_string text, y, x
243
- return true
244
- else
249
+ unless sub_wait_for_string text, y, x
245
250
  if options[:raise_error_on_check]
246
- raise "Impossible to write #{options[:sensible_data] ? ('*' * text.size) : text} at row #{y} column #{x}"
251
+ raise "write_text_on_map: Impossible to write #{options[:sensible_data] ? ('*' * text.size) : text} at row #{y} column #{x}"
247
252
  else
248
- return false
253
+ res = false
249
254
  end
250
255
  end
251
- else
252
- return true
253
256
  end
257
+ res
254
258
  end
255
259
 
256
260
  # If is called a not existing method there is the chance that an optional module may not have been added
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: butler-mainframe
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marco Mastrodonato
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-14 00:00:00.000000000 Z
11
+ date: 2015-10-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This gem provides a virtual butler which can perform your custom tasks
14
14
  on a 3270 emulator. You just have to choose your emulator (atm only one choice)
@@ -27,6 +27,7 @@ files:
27
27
  - lib/config/config.rb
28
28
  - lib/config/config_EXAMPLE_passport.rb
29
29
  - lib/config/config_EXAMPLE_pcomm.rb
30
+ - lib/config/config_EXAMPLE_x3270.rb
30
31
  - lib/config/settings.yml
31
32
  - lib/config/settings_EXAMPLE.yml
32
33
  - lib/core/configuration.rb
@@ -37,9 +38,10 @@ files:
37
38
  - lib/generators/butler_mainframe.rb
38
39
  - lib/mainframe/customization/active_record.rb
39
40
  - lib/mainframe/customization/generic_functions.rb
41
+ - lib/mainframe/emulators/passport.rb
42
+ - lib/mainframe/emulators/pcomm.rb
43
+ - lib/mainframe/emulators/x3270.rb
40
44
  - lib/mainframe/host_base.rb
41
- - lib/mainframe/passport.rb
42
- - lib/mainframe/pcomm.rb
43
45
  - lib/vendor/deep_symbolize.rb
44
46
  - rakefile
45
47
  - test/test.rake
@@ -62,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
62
64
  - !ruby/object:Gem::Version
63
65
  version: '0'
64
66
  requirements:
65
- - Be awake and rested
67
+ - A bit of awesomeness
66
68
  rubyforge_project:
67
69
  rubygems_version: 2.2.5
68
70
  signing_key: