consular-iterm 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in consular-iterm.gemspec
4
+ gemspec
@@ -0,0 +1,81 @@
1
+ # Consular - iTerm Core
2
+
3
+ Automate your iTerm Terminal with Consular
4
+
5
+
6
+ # Setup && Installation
7
+
8
+ If you haven't already, install Consular:
9
+
10
+ gem install consular
11
+
12
+ then install consular-iterm:
13
+
14
+ gem install consular-iterm
15
+
16
+
17
+ next, run `init`:
18
+
19
+ consular init
20
+
21
+ This will generate a global directory and also a `.consularc` in your home
22
+ directory. On the top of your `.consularc`, just require this core like
23
+ so:
24
+
25
+ ```ruby
26
+ # You can require your additional core gems here.
27
+ require 'consular/osx'
28
+
29
+ # You can set specific Consular configurations
30
+ # here.
31
+ Consular.configure do |c|
32
+ end
33
+ ```
34
+
35
+
36
+ ## Additional Features
37
+
38
+ With `consular-iterm`, you can also genrate `panes` likes so:
39
+
40
+ ```ruby
41
+ pane do
42
+ run "top"
43
+ pane "ps"
44
+ end
45
+
46
+ window do
47
+ pane "gitx"
48
+ end
49
+ ```
50
+
51
+ Splitting tabs into panes works as follows:
52
+
53
+ tab do
54
+ pane "gitx" # first pane
55
+ pane do # second pane level => horizontal split
56
+ run "irb"
57
+ end
58
+ pane 'ls' # first pane level => vertical split
59
+ end
60
+
61
+ should result into something like this:
62
+
63
+ # ###########################
64
+ # # # #
65
+ # # # #
66
+ # # 'gitx' # #
67
+ # # # #
68
+ # # # #
69
+ # ############## 'ls' #
70
+ # # # #
71
+ # # # #
72
+ # # 'irb' # #
73
+ # # # #
74
+ # # # #
75
+ # ###########################
76
+
77
+ It is not possible to split the second level panes (the horizontal ones).
78
+ Nevertheless you should be able to split tabs into any kind of pane pattern you wish
79
+ with this syntax.
80
+
81
+ Now you can use iTerm Terminal to run your Consular scripts!
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:spec) do |test|
5
+ test.libs << 'lib' << 'spec'
6
+ test.pattern = 'spec/**/*_spec.rb'
7
+ test.verbose = true
8
+ end
9
+
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "consular-iterm"
6
+ s.version = "1.0.0"
7
+ s.authors = ["Arthur Chiu"]
8
+ s.email = ["mr.arthur.chiu@gmail.com"]
9
+ s.homepage = "http://www.github.com/achiu/consular-iterm"
10
+ s.summary = %q{Automate your ITerm with Consular}
11
+ s.description = %q{Terminal Automation for ITerm via Consular}
12
+
13
+ s.rubyforge_project = "consular-iterm"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_dependency 'consular'
21
+
22
+ s.add_development_dependency 'minitest'
23
+
24
+ # specify any dependencies here; for example:
25
+ # s.add_development_dependency "rspec"
26
+ # s.add_runtime_dependency "rest-client"
27
+ end
@@ -0,0 +1,333 @@
1
+ require 'consular'
2
+ require 'appscript'
3
+ require File.expand_path('../iterm_dsl', __FILE__)
4
+
5
+ module Consular
6
+
7
+ # Consular Core to interact with iTerm2 for Mac OS X
8
+ #
9
+ class ITerm < Core
10
+ include Appscript
11
+
12
+ Consular.add_core self
13
+
14
+ class << self
15
+
16
+ # Checks to see if the current system is darwin and
17
+ # if $TERM_PROGRAM is iTerm.app
18
+ #
19
+ # @api public
20
+ def valid_system?
21
+ (RUBY_PLATFORM.downcase =~ /darwin/) && ENV['TERM_PROGRAM'] == 'iTerm.app'
22
+ end
23
+
24
+ # Returns the name of Core. Used in CLI core selection.
25
+ #
26
+ # @api public
27
+ def to_s
28
+ "Consular::ITerm Mac OSX iTerm2"
29
+ end
30
+
31
+ end
32
+
33
+ # Initializes a reference to the iTerm.app via appscript
34
+ #
35
+ # @param [String] path
36
+ # Path to Termfile
37
+ #
38
+ # @api public
39
+ def initialize(path)
40
+ super
41
+ @terminal = app('iTerm')
42
+ end
43
+
44
+ # Method called by runner to Execute Termfile setup.
45
+ #
46
+ # @api public
47
+ def setup!
48
+ @termfile[:setup].each { |cmd| execute_command(cmd) }
49
+ end
50
+
51
+ # Method called by runner to execute Termfile.
52
+ #
53
+ # @api public
54
+ def process!
55
+ windows = @termfile[:windows]
56
+ default = windows.delete('default')
57
+ execute_window(default, :default => true) unless default[:tabs].empty?
58
+ windows.each_pair { |_, cont| execute_window(cont) }
59
+ end
60
+
61
+ # Prepends the :before commands to the current context's
62
+ # commands if it exists.
63
+ #
64
+ # @param [Array<String>] commands
65
+ # The current tab commands
66
+ # @param [Array<String>] befores
67
+ # The current window's :befores
68
+ #
69
+ # @return [Array<String>]
70
+ # The current context commands with the :before commands prepended
71
+ #
72
+ # @api public
73
+ def prepend_befores(commands, befores = nil)
74
+ unless befores.nil? || befores.empty?
75
+ commands.insert(0, befores).flatten!
76
+ else
77
+ commands
78
+ end
79
+ end
80
+
81
+ # Prepend a title setting command prior to the other commands.
82
+ #
83
+ # @param [String] title
84
+ # The title to set for the context of the commands.
85
+ # @param [Array<String>] commands
86
+ # The context of commands to preprend to.
87
+ #
88
+ # @api public
89
+ def set_title(title, commands)
90
+ cmd = "PS1=\"$PS1\\[\\e]2;#{title}\\a\\]\""
91
+ title ? commands.insert(0, cmd) : commands
92
+ end
93
+
94
+ # Executes the commands for each designated window.
95
+ # .run_windows will iterate through each of the tabs in
96
+ # sorted order to execute the tabs in the order they were set.
97
+ # The logic follows this:
98
+ #
99
+ # If the content is for the 'default' window,
100
+ # then use the current active window and generate the commands.
101
+ #
102
+ # If the content is for a new window,
103
+ # then generate a new window and activate the windows.
104
+ #
105
+ # Otherwise, open a new tab and execute the commands.
106
+ #
107
+ # @param [Hash] content
108
+ # The hash contents of the window from the Termfile.
109
+ # @param [Hash] options
110
+ # Addional options to pass. You can use:
111
+ # :default - Whether this is being run as the default window.
112
+ #
113
+ # @example
114
+ # @core.execute_window contents, :default => true
115
+ # @core.execute_window contents, :default => true
116
+ #
117
+ # @api public
118
+ def execute_window(content, options = {})
119
+ window_options = content[:options]
120
+ _contents = content[:tabs]
121
+ _first_run = true
122
+
123
+ _contents.keys.sort.each do |key|
124
+ _content = _contents[key]
125
+ _options = content[:options]
126
+ _name = options[:name]
127
+
128
+ _tab =
129
+ if _first_run && !options[:default]
130
+ open_window options.merge(window_options)
131
+ else
132
+ key == 'default' ? active_tab : open_tab(_options) && active_tab
133
+ end
134
+
135
+ _first_run = false
136
+ commands = prepend_befores _content[:commands], content[:before]
137
+ commands = set_title _name, commands
138
+
139
+ if content.key? :panes
140
+ commands.each { |cmd| execute_command cmd, :in => _tab }
141
+ execute_panes content
142
+ content.delete :panes
143
+ else
144
+ commands.each { |cmd| execute_command cmd, :in => _tab }
145
+ end
146
+ end
147
+ end
148
+
149
+ # Execute the tab and associated panes with the designated content
150
+ #
151
+ # @param [Hash] content
152
+ # The Context containing panes.
153
+ #
154
+ # @api public
155
+ def execute_panes(content)
156
+ panes = content[:panes]
157
+ commands = content[:tabs][:commands]
158
+ top_level_pane_split panes, commands
159
+ end
160
+
161
+ # Execute commands in the context of a top level pane
162
+ #
163
+ # @param [Hash] panes
164
+ # Pane contexts.
165
+ # @param [Array] commands
166
+ # Current context tab commands.
167
+ #
168
+ # @api public
169
+ def top_level_pane_split(panes, commands)
170
+ first_pane = true
171
+
172
+ panes.keys.sort.each do |pane_key|
173
+ pane_content = panes[pane_key]
174
+ pane_commands = pane_content[:commands]
175
+
176
+ vertical_split if first_pane
177
+ execute_pane_commands(pane_commands,commands)
178
+
179
+ if pane_content.key?(:panes)
180
+ select_pane('Left') if first_pane
181
+ execute_subpanes pane_content[:panes], commands
182
+ pane_content.delete :panes
183
+ end
184
+
185
+ first_pane = false if first_pane
186
+ end
187
+
188
+ end
189
+
190
+ # Execute commands in the context of sub panes
191
+ #
192
+ # @param [Array] subpanes
193
+ # Sub panes for the top level pane
194
+ # @param [Array] tabcommands
195
+ # Tab commands
196
+ #
197
+ # @api public
198
+ def execute_subpanes(subpanes, tab_commands)
199
+ subpanes.keys.sort.each do |subpane_key|
200
+ subpane_commands = subpanes[subpane_key][:commands]
201
+ horizontal_split
202
+ execute_pane_commands(subpane_commands, tab_commands)
203
+ select_pane 'Right'
204
+ end
205
+ end
206
+
207
+ # Execute the commands within a pane
208
+ #
209
+ # @param [Array] pane_commands
210
+ # Commands for the designated pane.
211
+ # @param [Array] tab_commands
212
+ # Commands for the designated tabs.
213
+ #
214
+ # @api public
215
+ def execute_pane_commands(pane_commands, tab_commands)
216
+ pane_commands = (tab_commands || []) + (pane_commands || [])
217
+ pane_commands.each { |cmd| execute_command cmd }
218
+ end
219
+
220
+ # Split the active tab with vertical panes
221
+ #
222
+ # @api public
223
+ def vertical_split
224
+ call_ui_action "Shell", nil, "Split Vertically with Current Profile"
225
+ end
226
+
227
+ # Split the active tab with horizontal panes
228
+ #
229
+ # @api public
230
+ def horizontal_split
231
+ call_ui_action "Shell", nil, "Split Horizontally with Current Profile"
232
+ end
233
+
234
+ # to select panes; iTerm's Appscript select method does not work
235
+ # as expected, we have to select via menu instead
236
+ #
237
+ # @param [String] direction
238
+ # Direction to split the pane. The valid directions are:
239
+ # 'Above', 'Below', 'Left', 'Right'
240
+ #
241
+ # @api public
242
+ def select_pane(direction)
243
+ valid_directions = %w[Above Below Left Right]
244
+ if valid_directions.include?(direction)
245
+ call_ui_action("Window", "Select Split Pane", "Select Pane #{direction}")
246
+ else
247
+ puts "Error: #{direction} is not a valid direction to select a pane; Only Above/Below/Left/Right are valid directions"
248
+ end
249
+ end
250
+
251
+
252
+ # Opens a new tab and focuses on it.
253
+ #
254
+ # @param [Hash] options
255
+ # Additional options to further customize the tab.
256
+ #
257
+ # @api public
258
+ def open_tab(options = nil)
259
+ active_window.launch_ :session => 'New session'
260
+ end
261
+
262
+ # Opens a new window and focuses
263
+ # on the new tab.
264
+ #
265
+ # @param [Hash] options
266
+ # Additional options to further customize the window.
267
+ #
268
+ # @api public
269
+ def open_window(options = nil)
270
+ window = @terminal.make :new => :terminal
271
+ window.launch_ :session => 'New session'
272
+ end
273
+
274
+ # Execute the given command in the context of the active window.
275
+ #
276
+ # @param [String] cmd
277
+ # The command to execute.
278
+ # @param [Hash] options
279
+ # Additional options to pass into appscript for the context.
280
+ #
281
+ # @example
282
+ # @osx.execute_command 'ps aux', :in => @tab_object
283
+ #
284
+ # @api public
285
+ def execute_command(cmd, options = {})
286
+ context = options[:in] || active_tab
287
+ context.write :text => cmd
288
+ end
289
+
290
+ # Returns the active tab e.g the active terminal session.
291
+ #
292
+ # @api public
293
+ def active_tab
294
+ active_window.current_session
295
+ end
296
+
297
+ # Returns the active window/tab e.g the active terminal window.
298
+ #
299
+ # @api public
300
+ def active_window
301
+ @terminal.current_terminal
302
+ end
303
+
304
+ # Returns a reference to the iTerm menu bar.
305
+ #
306
+ # @api public
307
+ def iterm_menu
308
+ _process = app("System Events").processes["iTerm"]
309
+ _process.menu_bars.first
310
+ end
311
+
312
+ # Execute the menu action via UI.
313
+ #
314
+ # @param [String] menu
315
+ # Top level menu name
316
+ # @param [String] submenu
317
+ # Sub level menu name
318
+ # @param [String] action
319
+ # Action name/description.
320
+ #
321
+ # @example
322
+ # @core.call_ui_action 'Edit', 'Find', 'Find Next'
323
+ # @core.call_ui_action 'Shell', nil, 'Split Vertically With Same Profile'
324
+ #
325
+ # @api public
326
+ def call_ui_action(menu, submenu, action)
327
+ menu = iterm_menu.menu_bar_items[menu].menus[menu]
328
+ menu = menu.menu_items[submenu].menus[submenu] if submenu
329
+ menu.menu_items[action].click
330
+ end
331
+
332
+ end
333
+ end
@@ -0,0 +1,40 @@
1
+ module Consular
2
+ module ITermDSL
3
+
4
+ # Generates a pane in the terminal. These can be nested to
5
+ # create horizontal panes. Vertical panes are created with each top
6
+ # level nest.
7
+ #
8
+ # @param [Array<String>] args
9
+ # Array of comamnds
10
+ # @param [Proc] block
11
+ # Block of code to execute in pane context.
12
+ #
13
+ # @example
14
+ #
15
+ # pane "top"
16
+ # pane { pane "uptime" }
17
+ #
18
+ # @api public
19
+ def pane(*args, &block)
20
+ @_context[:panes] = {} unless @_context.has_key? :panes
21
+ panes = @_context[:panes]
22
+ pane_name = "pane#{panes.keys.size}"
23
+
24
+ if block_given?
25
+ pane_contents = panes[pane_name] = {:commands => []}
26
+ if @_context.has_key? :is_top_pane
27
+ run_context pane_contents[:commands], &block
28
+ else
29
+ pane_contents[:is_top_pane] = true
30
+ run_context pane_contents, &block
31
+ end
32
+ else
33
+ panes[pane_name] = { :commands => args }
34
+ end
35
+ end
36
+
37
+ end
38
+ end
39
+
40
+ Consular::DSL.class_eval { include Consular::ITermDSL }
@@ -0,0 +1,67 @@
1
+ ENV["WATCHR"] = "1"
2
+ system 'clear'
3
+
4
+ def growl(message)
5
+ growlnotify = `which growlnotify`.chomp
6
+ if not growlnotify.empty?
7
+ title = "Watchr Test Results"
8
+ image = message.include?('0 failures, 0 errors') ? "~/.watchr_images/passed.png" : "~/.watchr_images/failed.png"
9
+ options = "-w -n Watchr --image '#{File.expand_path(image)}' -m '#{message}' '#{title}'"
10
+ system %(#{growlnotify} #{options} &)
11
+ else
12
+ puts message
13
+ end
14
+ end
15
+
16
+ def run(cmd)
17
+ puts(cmd)
18
+ `#{cmd}`
19
+ end
20
+
21
+ def run_test_file(file)
22
+ system('clear')
23
+ result = run(%Q(ruby -I"lib:test" -rubygems #{file}))
24
+ growl result.split("\n").last rescue nil
25
+ puts result
26
+ end
27
+
28
+ def run_all_tests
29
+ system('clear')
30
+ result = run "rake spec"
31
+ growl result.split("\n").last rescue nil
32
+ puts result
33
+ end
34
+
35
+ def related_test_files(path)
36
+ Dir['spec/**/*.rb'].select { |file| file =~ /#{File.basename(path).split(".").first}_spec.rb/ }
37
+ end
38
+
39
+ def run_suite
40
+ run_all_tests
41
+ end
42
+
43
+ watch('spec/spec_helper\.rb') { run_all_tests }
44
+ watch('spec/(.*).*_spec\.rb') { |m| run_test_file(m[0]) }
45
+ watch('lib/.*/.*\.rb') { |m| related_test_files(m[0]).map {|tf| run_test_file(tf) } }
46
+
47
+ # Ctrl-\
48
+ Signal.trap 'QUIT' do
49
+ puts " --- Running all tests ---\n\n"
50
+ run_all_tests
51
+ end
52
+
53
+ @interrupted = false
54
+
55
+ # Ctrl-C
56
+ Signal.trap 'INT' do
57
+ if @interrupted then
58
+ @wants_to_quit = true
59
+ abort("\n")
60
+ else
61
+ puts "Interrupt a second time to quit"
62
+ @interrupted = true
63
+ Kernel.sleep 1.5
64
+ # raise Interrupt, nil # let the run loop catch it
65
+ run_suite
66
+ end
67
+ end
@@ -0,0 +1,27 @@
1
+ pane "top"
2
+
3
+ window do
4
+ pane do
5
+ run "ls"
6
+ pane "uptime"
7
+ end
8
+
9
+ pane "ps"
10
+ run "default"
11
+ tab "echo"
12
+
13
+ pane "test"
14
+ end
15
+
16
+ window do
17
+ run 'tab1'
18
+
19
+ pane "second window"
20
+
21
+ pane do
22
+ run "second pane"
23
+ pane "third pane"
24
+ end
25
+
26
+ tab "tab2"
27
+ end
@@ -0,0 +1,58 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe Consular::ITermDSL do
4
+
5
+ before do
6
+ @dsl = Consular::DSL.new File.expand_path('../fixtures/bar.term', __FILE__)
7
+ end
8
+
9
+ it "includes itself into Consular::DSL" do
10
+ assert_includes Consular::DSL.included_modules, Consular::ITermDSL
11
+ end
12
+
13
+ describe ".to_hash" do
14
+ before do
15
+ @result = @dsl.to_hash
16
+ end
17
+
18
+ it "returns the default window pane" do
19
+ assert_equal ['top'], @result[:windows]['default'][:panes]['pane0'][:commands]
20
+ end
21
+
22
+ it "returns the first window first panes" do
23
+ @window1 = @result[:windows]['window1']
24
+
25
+ assert @window1[:panes]['pane0'][:is_top_pane], "that this is marked as top most pane"
26
+ assert_equal ['ls'], @window1[:panes]['pane0'][:commands]
27
+ assert_equal ['uptime'], @window1[:panes]['pane0'][:panes]['pane0'][:commands]
28
+ end
29
+
30
+ it "returns the first window's second pane" do
31
+ @window1 = @result[:windows]['window1']
32
+ assert_equal ['ps'], @window1[:panes]['pane1'][:commands]
33
+ assert_equal ['test'], @window1[:panes]['pane2'][:commands]
34
+ end
35
+
36
+ it "still returns tabs correctly" do
37
+ @window1 = @result[:windows]['window1']
38
+
39
+ assert_equal ['echo'], @window1[:tabs]['tab1'][:commands]
40
+ assert_equal ['default'], @window1[:tabs]['default'][:commands]
41
+ end
42
+
43
+ it "still returns multiple windows" do
44
+ @window2 = @result[:windows]['window2']
45
+
46
+ assert @window2[:panes]['pane1'][:is_top_pane], "that this is marked as top most pane"
47
+
48
+ assert_equal ['second window'], @window2[:panes]['pane0'][:commands]
49
+ assert_equal ['second pane'], @window2[:panes]['pane1'][:commands]
50
+ assert_equal ['third pane'], @window2[:panes]['pane1'][:panes]['pane0'][:commands]
51
+
52
+ assert_equal ['tab1'], @window2[:tabs]['default'][:commands]
53
+ assert_equal ['tab2'], @window2[:tabs]['tab1'][:commands]
54
+ end
55
+
56
+ end
57
+
58
+ end
@@ -0,0 +1,31 @@
1
+ require File.expand_path('../spec_helper', __FILE__)
2
+
3
+ describe Consular::ITerm do
4
+ before do
5
+ @core = Consular::ITerm.new File.expand_path('../fixtures/bar.term', __FILE__)
6
+ end
7
+
8
+ it "should return name of core with #to_s" do
9
+ assert_equal "Consular::ITerm Mac OSX iTerm2", Consular::ITerm.to_s
10
+ end
11
+
12
+ it "should add itself to Consular cores" do
13
+ assert_includes Consular.cores, Consular::ITerm
14
+ end
15
+
16
+ it "should set ivars on .initialize" do
17
+ refute_nil @core.instance_variable_get(:@termfile)
18
+ refute_nil @core.instance_variable_get(:@terminal)
19
+ end
20
+
21
+ it "should prepend commands with .prepend_befores" do
22
+ assert_equal ['ps', 'ls'], @core.prepend_befores(['ls'], ['ps'])
23
+ assert_equal ['ls'], @core.prepend_befores(['ls'])
24
+ end
25
+
26
+ it "should set .set_title" do
27
+ assert_equal ["PS1=\"$PS1\\[\\e]2;hey\\a\\]\"",'ls'], @core.set_title('hey', ['ls'])
28
+ assert_equal ['ls'], @core.set_title(nil, ['ls'])
29
+ end
30
+
31
+ end
@@ -0,0 +1,33 @@
1
+ require 'rubygems'
2
+ gem 'minitest'
3
+ require 'minitest/autorun'
4
+ require File.expand_path('../../lib/consular/iterm', __FILE__)
5
+
6
+
7
+ class ColoredIO
8
+ ESC = "\e["
9
+ NND = "#{ESC}0m"
10
+
11
+ def initialize(io)
12
+ @io = io
13
+ end
14
+
15
+ def print(o)
16
+ case o
17
+ when "."
18
+ @io.send(:print, "#{ESC}32m#{o}#{NND}")
19
+ when "E"
20
+ @io.send(:print, "#{ESC}33m#{o}#{NND}")
21
+ when "F"
22
+ @io.send(:print, "#{ESC}31m#{o}#{NND}")
23
+ else
24
+ @io.send(:print, o)
25
+ end
26
+ end
27
+
28
+ def puts(*o)
29
+ super
30
+ end
31
+ end
32
+
33
+ MiniTest::Unit.output = ColoredIO.new(MiniTest::Unit.output)
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: consular-iterm
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Arthur Chiu
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-02 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: consular
16
+ requirement: &2161515360 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2161515360
25
+ - !ruby/object:Gem::Dependency
26
+ name: minitest
27
+ requirement: &2161514880 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *2161514880
36
+ description: Terminal Automation for ITerm via Consular
37
+ email:
38
+ - mr.arthur.chiu@gmail.com
39
+ executables: []
40
+ extensions: []
41
+ extra_rdoc_files: []
42
+ files:
43
+ - .gitignore
44
+ - Gemfile
45
+ - README.md
46
+ - Rakefile
47
+ - consular-iterm.gemspec
48
+ - lib/consular/iterm.rb
49
+ - lib/consular/iterm_dsl.rb
50
+ - spec.watchr
51
+ - spec/fixtures/bar.term
52
+ - spec/iterm_dsl_spec.rb
53
+ - spec/iterm_spec.rb
54
+ - spec/spec_helper.rb
55
+ homepage: http://www.github.com/achiu/consular-iterm
56
+ licenses: []
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubyforge_project: consular-iterm
75
+ rubygems_version: 1.8.10
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: Automate your ITerm with Consular
79
+ test_files:
80
+ - spec/fixtures/bar.term
81
+ - spec/iterm_dsl_spec.rb
82
+ - spec/iterm_spec.rb
83
+ - spec/spec_helper.rb