consular-osx 1.0.0.rc1
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.
- data/.gitignore +4 -0
- data/Gemfile +7 -0
- data/Rakefile +8 -0
- data/consular-osx.gemspec +24 -0
- data/lib/consular/osx.rb +245 -0
- data/spec.watchr +67 -0
- data/spec/fixtures/bar.term +0 -0
- data/spec/osx_spec.rb +85 -0
- data/spec/spec_helper.rb +53 -0
- metadata +137 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "consular-osx"
|
6
|
+
s.version = '1.0.0.rc1'
|
7
|
+
s.authors = ["Arthur Chiu"]
|
8
|
+
s.email = ["mr.arthur.chiu@gmail.com"]
|
9
|
+
s.homepage = ""
|
10
|
+
s.summary = %q{Mac OSX Terminal core for Consular}
|
11
|
+
s.description = %q{Automate Mac OSX Terminal with Consular}
|
12
|
+
|
13
|
+
s.rubyforge_project = "consular-osx"
|
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
|
+
s.add_dependency 'rb-appscript'
|
22
|
+
s.add_development_dependency 'minitest'
|
23
|
+
s.add_development_dependency 'mocha'
|
24
|
+
end
|
data/lib/consular/osx.rb
ADDED
@@ -0,0 +1,245 @@
|
|
1
|
+
require 'consular'
|
2
|
+
require 'appscript'
|
3
|
+
|
4
|
+
module Consular
|
5
|
+
# Consular Core to interact with Mac OS X Terminal.
|
6
|
+
#
|
7
|
+
class OSX < Core
|
8
|
+
include Appscript
|
9
|
+
|
10
|
+
Consular.add_core self
|
11
|
+
|
12
|
+
# The acceptable options that OSX Terminal will register.
|
13
|
+
#
|
14
|
+
ALLOWED_OPTIONS = {
|
15
|
+
:window => [:bounds, :visible, :miniaturized],
|
16
|
+
:tab => [:settings, :selected]
|
17
|
+
} unless defined?(ALLOWED_OPTIONS)
|
18
|
+
|
19
|
+
class << self
|
20
|
+
|
21
|
+
# Checks to see if the current system is on darwin.
|
22
|
+
# TODO: strengthen this system check.
|
23
|
+
#
|
24
|
+
# @api public
|
25
|
+
def valid_system?
|
26
|
+
RUBY_PLATFORM.downcase =~ /darwin/
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
# Initializes a reference to the Terminal.app via appscript
|
32
|
+
#
|
33
|
+
# @param [String] path
|
34
|
+
# path to Termfile.
|
35
|
+
#
|
36
|
+
# @api public
|
37
|
+
def initialize(path)
|
38
|
+
super
|
39
|
+
@terminal = app('Terminal')
|
40
|
+
end
|
41
|
+
|
42
|
+
# Method called by runner to Execute Termfile setup.
|
43
|
+
#
|
44
|
+
# @api public
|
45
|
+
def setup!
|
46
|
+
@termfile[:setup].each { |cmd| execute_command(cmd, :in => active_window) }
|
47
|
+
end
|
48
|
+
|
49
|
+
# Method called by runner to execute Termfile.
|
50
|
+
#
|
51
|
+
# @api public
|
52
|
+
def process!
|
53
|
+
windows = @termfile[:windows]
|
54
|
+
default = windows.delete('default')
|
55
|
+
execute_window(default, :default => true) unless default[:tabs].empty?
|
56
|
+
windows.each_pair { |_, cont| execute_window(cont) }
|
57
|
+
end
|
58
|
+
|
59
|
+
# Executes the commands for each designated window.
|
60
|
+
# .run_windows will iterate through each of the tabs in
|
61
|
+
# sorted order to execute the tabs in the order they were set.
|
62
|
+
# The logic follows this:
|
63
|
+
#
|
64
|
+
# If the content is for the 'default' window,
|
65
|
+
# then use the current active window and generate the commands.
|
66
|
+
#
|
67
|
+
# If the content is for a new window,
|
68
|
+
# then generate a new window and activate the windows.
|
69
|
+
#
|
70
|
+
# Otherwise, open a new tab and execute the commands.
|
71
|
+
#
|
72
|
+
# @param [Hash] content
|
73
|
+
# The hash contents of the window from the Termfile.
|
74
|
+
# @param [Hash] options
|
75
|
+
# Addional options to pass. You can use:
|
76
|
+
# :default - Whether this is being run as the default window.
|
77
|
+
#
|
78
|
+
# @example
|
79
|
+
# @core.execute_window contents, :default => true
|
80
|
+
# @core.execute_window contents, :default => true
|
81
|
+
#
|
82
|
+
# @api public
|
83
|
+
def execute_window(content, options = {})
|
84
|
+
window_options = content[:options]
|
85
|
+
_contents = content[:tabs]
|
86
|
+
_first_run = true
|
87
|
+
|
88
|
+
_contents.keys.sort.each do |key|
|
89
|
+
_content = _contents[key]
|
90
|
+
_options = content[:options]
|
91
|
+
_name = options[:name]
|
92
|
+
|
93
|
+
_tab =
|
94
|
+
if _first_run && !options[:default]
|
95
|
+
open_window options.merge(window_options)
|
96
|
+
else
|
97
|
+
key == 'default' ? active_window : open_tab(_options)
|
98
|
+
end
|
99
|
+
|
100
|
+
_first_run = false
|
101
|
+
commands = prepend_befores _content[:commands], _contents[:befores]
|
102
|
+
commands = set_title _name, commands
|
103
|
+
commands.each { |cmd| execute_command cmd, :in => _tab }
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
# Prepend a title setting command prior to the other commands.
|
109
|
+
#
|
110
|
+
# @param [String] title
|
111
|
+
# The title to set for the context of the commands.
|
112
|
+
# @param [Array<String>] commands
|
113
|
+
# The context of commands to preprend to.
|
114
|
+
#
|
115
|
+
# @api public
|
116
|
+
def set_title(title, commands)
|
117
|
+
cmd = "PS1=\"$PS1\\[\\e]2;#{title}\\a\\]\""
|
118
|
+
title ? commands.insert(0, cmd) : commands
|
119
|
+
end
|
120
|
+
|
121
|
+
# Prepends the :before commands to the current context's
|
122
|
+
# commands if it exists.
|
123
|
+
#
|
124
|
+
# @param [Array<String>] commands
|
125
|
+
# The current tab commands
|
126
|
+
# @param [Array<String>] befores
|
127
|
+
# The current window's :befores
|
128
|
+
#
|
129
|
+
# @return [Array<String>]
|
130
|
+
# The current context commands with the :before commands prepended
|
131
|
+
#
|
132
|
+
# @api public
|
133
|
+
def prepend_befores(commands, befores = nil)
|
134
|
+
unless befores.nil? || befores.empty?
|
135
|
+
commands.insert(0, befores).flatten!
|
136
|
+
else
|
137
|
+
commands
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
# Execute the given command in the context of the
|
142
|
+
# active window.
|
143
|
+
#
|
144
|
+
# @param [String] cmd
|
145
|
+
# The command to execute.
|
146
|
+
# @param [Hash] options
|
147
|
+
# Additional options to pass into appscript for the context.
|
148
|
+
#
|
149
|
+
# @example
|
150
|
+
# @osx.execute_command 'ps aux', :in => @tab_object
|
151
|
+
#
|
152
|
+
# @api public
|
153
|
+
def execute_command(cmd, options = {})
|
154
|
+
active_window.do_script cmd, options
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
# Opens a new tab and return the last instantiated tab(itself).
|
159
|
+
#
|
160
|
+
# @param [Hash] options
|
161
|
+
# Options to further customize the window. You can use:
|
162
|
+
# :settings -
|
163
|
+
# :selected -
|
164
|
+
#
|
165
|
+
# @return
|
166
|
+
# Returns a refernce to the last instantiated tab of the
|
167
|
+
# window.
|
168
|
+
#
|
169
|
+
# @api public
|
170
|
+
def open_tab(options = nil)
|
171
|
+
open_terminal_with 't', options
|
172
|
+
end
|
173
|
+
|
174
|
+
# Opens a new window and returns its
|
175
|
+
# last instantiated tab.(The first 'tab' in the window).
|
176
|
+
#
|
177
|
+
# @param [Hash] options
|
178
|
+
# Options to further customize the window. You can use:
|
179
|
+
# :bound - Set the bounds of the windows
|
180
|
+
# :visible - Set whether or not the current window is visible
|
181
|
+
# :miniaturized - Set whether or not the window is minimized
|
182
|
+
#
|
183
|
+
# @return
|
184
|
+
# Returns a refernce to the last instantiated tab of the
|
185
|
+
# window.
|
186
|
+
#
|
187
|
+
# @api public
|
188
|
+
def open_window(options = nil)
|
189
|
+
open_terminal_with 'n', options
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
# Sets the options for the windows/tabs. Will filter options
|
194
|
+
# based on what options can be set for either windows or tabs.
|
195
|
+
#
|
196
|
+
# @param [Hash] options
|
197
|
+
# Options to set for the window/tab
|
198
|
+
#
|
199
|
+
# @api semipublic
|
200
|
+
def set_options(options = {})
|
201
|
+
# raise NotImplementedError
|
202
|
+
end
|
203
|
+
|
204
|
+
# Returns the current terminal process.
|
205
|
+
# We need this method to workaround appscript so that we can
|
206
|
+
# instantiate new tabs and windows. Otherwise it would have
|
207
|
+
# looked something like # window.make(:new => :tab) but that
|
208
|
+
# doesn't work.
|
209
|
+
#
|
210
|
+
# @api semipublic
|
211
|
+
def terminal_process
|
212
|
+
app('System Events').application_processes['Terminal.app']
|
213
|
+
end
|
214
|
+
|
215
|
+
# Returns the last instantiated tab from active window
|
216
|
+
#
|
217
|
+
# @api semipublic
|
218
|
+
def active_tab
|
219
|
+
window = active_window
|
220
|
+
tabs = window.tabs if window
|
221
|
+
tabs.last.get if tabs
|
222
|
+
end
|
223
|
+
|
224
|
+
# Returns the currently active window by
|
225
|
+
# checking to see if it is the :frontmost window.
|
226
|
+
#
|
227
|
+
# @api semipublic
|
228
|
+
def active_window
|
229
|
+
windows = @terminal.windows.get
|
230
|
+
windows.detect do |window|
|
231
|
+
window.properties_.get[:frontmost] rescue false
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
private
|
236
|
+
|
237
|
+
# @api private
|
238
|
+
def open_terminal_with(key, options = nil)
|
239
|
+
terminal_process.keystroke(key, :using => :command_down)
|
240
|
+
set_options options
|
241
|
+
active_tab
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
245
|
+
end
|
data/spec.watchr
ADDED
@@ -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
|
File without changes
|
data/spec/osx_spec.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __FILE__)
|
2
|
+
require File.expand_path('../../lib/consular/osx',__FILE__)
|
3
|
+
|
4
|
+
describe Consular::OSX do
|
5
|
+
before do
|
6
|
+
@core = Consular::OSX.new File.expand_path('../fixtures/bar.term', __FILE__)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have ALLOWED_OPTIONS" do
|
10
|
+
options = Consular::OSX::ALLOWED_OPTIONS
|
11
|
+
|
12
|
+
assert_equal [:bounds, :visible, :miniaturized], options[:window]
|
13
|
+
assert_equal [:settings, :selected], options[:tab]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should be added as a core to Consular" do
|
17
|
+
assert_includes Consular.cores, Consular::OSX
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should set ivars on .initialize" do
|
21
|
+
refute_nil @core.instance_variable_get(:@termfile)
|
22
|
+
refute_nil @core.instance_variable_get(:@terminal)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should set .set_title" do
|
26
|
+
assert_equal ["PS1=\"$PS1\\[\\e]2;hey\\a\\]\"",'ls'], @core.set_title('hey', ['ls'])
|
27
|
+
assert_equal ['ls'], @core.set_title(nil, ['ls'])
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should prepend commands with .prepend_befores" do
|
31
|
+
assert_equal ['ps', 'ls'], @core.prepend_befores(['ls'], ['ps'])
|
32
|
+
assert_equal ['ls'], @core.prepend_befores(['ls'])
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should .execute_command" do
|
36
|
+
window = mock()
|
37
|
+
window.expects(:do_script).with('ls',{}).returns(true)
|
38
|
+
@core.expects(:active_window).returns(window)
|
39
|
+
assert @core.execute_command('ls', {}), "that core executes do_script"
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should executes setup block with .setup!" do
|
43
|
+
@core.termfile[:setup] = ['ls','ls']
|
44
|
+
@core.expects(:execute_command).with('ls', anything).twice
|
45
|
+
assert @core.setup!
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should executes window context with .process!" do
|
49
|
+
@core.termfile[:windows] = {
|
50
|
+
'default' => { :tabs => {'default' => {:commands => ['ls']}}},
|
51
|
+
'window1' => { :tabs => {'default' => {:commands => ['whoami']}}},
|
52
|
+
'window2' => { :tabs => {'default' => {:commands => ['whoami']}}},
|
53
|
+
}
|
54
|
+
|
55
|
+
@core.expects(:execute_window).with(@core.termfile[:windows]['default'], :default => true).once
|
56
|
+
@core.expects(:execute_window).with(@core.termfile[:windows]['window1']).twice
|
57
|
+
assert @core.process!
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should .open_tab" do
|
61
|
+
@core.expects(:open_terminal_with).with('t', nil).returns(true)
|
62
|
+
assert @core.open_tab
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should .open_window" do
|
66
|
+
@core.expects(:open_terminal_with).with('n', nil).returns(true)
|
67
|
+
assert @core.open_window
|
68
|
+
end
|
69
|
+
|
70
|
+
describe ".execute_window" do
|
71
|
+
it "should use the current active window with 'default' window" do
|
72
|
+
skip
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should use the open a new window if its teh first run and not the 'default' window" do
|
76
|
+
skip
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should open a new tab if its not the 'default' window" do
|
80
|
+
skip
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
gem 'minitest'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'mocha'
|
5
|
+
require File.expand_path('../../lib/consular/osx', __FILE__)
|
6
|
+
|
7
|
+
|
8
|
+
class ColoredIO
|
9
|
+
ESC = "\e["
|
10
|
+
NND = "#{ESC}0m"
|
11
|
+
|
12
|
+
def initialize(io)
|
13
|
+
@io = io
|
14
|
+
end
|
15
|
+
|
16
|
+
def print(o)
|
17
|
+
case o
|
18
|
+
when "."
|
19
|
+
@io.send(:print, "#{ESC}32m#{o}#{NND}")
|
20
|
+
when "E"
|
21
|
+
@io.send(:print, "#{ESC}33m#{o}#{NND}")
|
22
|
+
when "F"
|
23
|
+
@io.send(:print, "#{ESC}31m#{o}#{NND}")
|
24
|
+
else
|
25
|
+
@io.send(:print, o)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def puts(*o)
|
30
|
+
super
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
MiniTest::Unit.output = ColoredIO.new(MiniTest::Unit.output)
|
35
|
+
|
36
|
+
# This is to silence the 'task' warning for the mocks.
|
37
|
+
#
|
38
|
+
class Thor
|
39
|
+
class << self
|
40
|
+
def create_task(meth) #:nodoc:
|
41
|
+
if @usage && @desc
|
42
|
+
base_class = @hide ? Thor::HiddenTask : Thor::Task
|
43
|
+
tasks[meth] = base_class.new(meth, @desc, @long_desc, @usage, method_options)
|
44
|
+
@usage, @desc, @long_desc, @method_options, @hide = nil
|
45
|
+
true
|
46
|
+
elsif self.all_tasks[meth] || meth == "method_missing"
|
47
|
+
true
|
48
|
+
else
|
49
|
+
false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: consular-osx
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 15424055
|
5
|
+
prerelease: 6
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
- rc
|
11
|
+
- 1
|
12
|
+
version: 1.0.0.rc1
|
13
|
+
platform: ruby
|
14
|
+
authors:
|
15
|
+
- Arthur Chiu
|
16
|
+
autorequire:
|
17
|
+
bindir: bin
|
18
|
+
cert_chain: []
|
19
|
+
|
20
|
+
date: 2011-10-09 00:00:00 -07:00
|
21
|
+
default_executable:
|
22
|
+
dependencies:
|
23
|
+
- !ruby/object:Gem::Dependency
|
24
|
+
name: consular
|
25
|
+
prerelease: false
|
26
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
28
|
+
requirements:
|
29
|
+
- - ">="
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
hash: 3
|
32
|
+
segments:
|
33
|
+
- 0
|
34
|
+
version: "0"
|
35
|
+
type: :runtime
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rb-appscript
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 3
|
46
|
+
segments:
|
47
|
+
- 0
|
48
|
+
version: "0"
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: minitest
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
type: :development
|
64
|
+
version_requirements: *id003
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: mocha
|
67
|
+
prerelease: false
|
68
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
hash: 3
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
type: :development
|
78
|
+
version_requirements: *id004
|
79
|
+
description: Automate Mac OSX Terminal with Consular
|
80
|
+
email:
|
81
|
+
- mr.arthur.chiu@gmail.com
|
82
|
+
executables: []
|
83
|
+
|
84
|
+
extensions: []
|
85
|
+
|
86
|
+
extra_rdoc_files: []
|
87
|
+
|
88
|
+
files:
|
89
|
+
- .gitignore
|
90
|
+
- Gemfile
|
91
|
+
- Rakefile
|
92
|
+
- consular-osx.gemspec
|
93
|
+
- lib/consular/osx.rb
|
94
|
+
- spec.watchr
|
95
|
+
- spec/fixtures/bar.term
|
96
|
+
- spec/osx_spec.rb
|
97
|
+
- spec/spec_helper.rb
|
98
|
+
has_rdoc: true
|
99
|
+
homepage: ""
|
100
|
+
licenses: []
|
101
|
+
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
hash: 3
|
113
|
+
segments:
|
114
|
+
- 0
|
115
|
+
version: "0"
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ">"
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
hash: 25
|
122
|
+
segments:
|
123
|
+
- 1
|
124
|
+
- 3
|
125
|
+
- 1
|
126
|
+
version: 1.3.1
|
127
|
+
requirements: []
|
128
|
+
|
129
|
+
rubyforge_project: consular-osx
|
130
|
+
rubygems_version: 1.6.2
|
131
|
+
signing_key:
|
132
|
+
specification_version: 3
|
133
|
+
summary: Mac OSX Terminal core for Consular
|
134
|
+
test_files:
|
135
|
+
- spec/fixtures/bar.term
|
136
|
+
- spec/osx_spec.rb
|
137
|
+
- spec/spec_helper.rb
|