terminitor 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock ADDED
@@ -0,0 +1,41 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ terminitor (0.0.5)
5
+ github
6
+ rb-appscript
7
+ thor (~> 0.14.0)
8
+
9
+ GEM
10
+ remote: http://rubygems.org/
11
+ specs:
12
+ fakefs (0.2.1)
13
+ github (0.4.3)
14
+ highline (~> 1.5.1)
15
+ json (>= 1.2.0)
16
+ text-format (>= 1.0.0)
17
+ highline (1.5.2)
18
+ json (1.4.6)
19
+ rb-appscript (0.5.3)
20
+ riot (0.11.4)
21
+ rr
22
+ term-ansicolor
23
+ rr (1.0.0)
24
+ term-ansicolor (1.0.5)
25
+ text-format (1.0.0)
26
+ text-hyphen (~> 1.0.0)
27
+ text-hyphen (1.0.0)
28
+ thor (0.14.1)
29
+
30
+ PLATFORMS
31
+ ruby
32
+
33
+ DEPENDENCIES
34
+ bundler (~> 1.0.0)
35
+ fakefs
36
+ github
37
+ rb-appscript
38
+ riot (~> 0.11.0)
39
+ rr
40
+ terminitor!
41
+ thor (~> 0.14.0)
data/README.md CHANGED
@@ -7,7 +7,7 @@ Installation
7
7
  ------------
8
8
 
9
9
  $ gem install terminitor
10
- $ terminitor setup
10
+ $ terminitor init
11
11
 
12
12
  Usage
13
13
  -------
@@ -16,10 +16,12 @@ Usage
16
16
 
17
17
  Using terminitor is quite easy. To define or edit a project file, simply invoke the command:
18
18
 
19
- $ terminitor open foo
19
+ $ terminitor edit foo
20
20
 
21
- This will open your default editor (set through the $EDITOR variable in BASH) and you can proceed to define the commands for that project:
21
+ This will open your default editor (set through the $TERM_EDITOR or $EDITOR variable in BASH) and you can proceed to define the commands for that project with the following syntaxes:
22
22
 
23
+ #### YAML Syntax ( Legacy ) ####
24
+
23
25
  # ~/.terminitor/foo.yml
24
26
  # you can make as many tabs as you wish...
25
27
  # tab names are actually arbitrary at this point too.
@@ -41,6 +43,71 @@ Simply define each tab and declare the commands. Note that the session for each
41
43
  you would manually type in the terminal. Note that the title for each tab(namely tab1, tab2) are arbitrary, and can be named whatever you want.
42
44
  They are simply placeholders for the time being for upcoming features.
43
45
 
46
+ To use the legacy syntax, you can invoke it with terminitor like so:
47
+
48
+ $ terminitor edit foo --syntax yml
49
+
50
+
51
+ #### Ruby DSL Syntax ####
52
+
53
+ setup 'echo "setup"'
54
+
55
+ tab "echo 'default'", "echo 'default tab'"
56
+
57
+ window do
58
+ tab "echo 'first tab'", "echo 'of window'"
59
+
60
+ tab "named tab" do
61
+ run "echo 'named tab'"
62
+ run "ls"
63
+ end
64
+ end
65
+
66
+ The newer Ruby DSL syntax allows for more complicated behavior such as window creation as well as setup blocks that can be executed prior loading a project.
67
+
68
+ ##### Tabs #####
69
+
70
+ to create tabs, we can simply invoke the tab command with either the command arguments like:
71
+
72
+ tab "echo 'hi'", "gitx"
73
+
74
+ or even pass it a block:
75
+
76
+ tab do
77
+ run "echo 'hi'"
78
+ run "mate ."
79
+ end
80
+
81
+ ##### Windows #####
82
+
83
+ to create windows, we can simply invoke the window command with a block containing additional commands like:
84
+
85
+ window do
86
+ tab "echo 'hi'"
87
+ tab "mate ."
88
+ tab do
89
+ run "open http://www.google.com"
90
+ end
91
+ end
92
+
93
+ ##### Setup #####
94
+
95
+ The setup block allows you to store commands that can be ran specifically before a project and can be defined with:
96
+
97
+ the command arguments:
98
+
99
+ setup "bundle install", "gitx"
100
+
101
+ or with a block:
102
+
103
+ setup do
104
+ run "echo 'hi'"
105
+ run "bundle install"
106
+ end
107
+
108
+
109
+ ### Running Terminitor Projects ###
110
+
44
111
  Once the project file has been declared to your satisfaction, simply execute any project defined in the `~/.terminitor` directory with:
45
112
 
46
113
  $ terminitor start foo
@@ -48,15 +115,24 @@ Once the project file has been declared to your satisfaction, simply execute any
48
115
  This will execute the steps and create the tabs defined and run the various options as expected. That's it. Create as many project files with as many tabs
49
116
  as you would like and automate your workflow.
50
117
 
51
- If you no longer need a particular project, you can easily remove the yml file for the project:
118
+ ### Removing Terminitor Projects ###
119
+
120
+ If you no longer need a particular project, you can easily remove the terminitor file for the project:
52
121
 
53
122
  $ terminitor delete foo
123
+
124
+ to remove a legacy yml syntax file you can run:
125
+
126
+ $ terminitor delete foo -s=yml
127
+
128
+
129
+ ### Listing Terminitor Projects ###
54
130
 
55
131
  You can also see a full list of available projects with:
56
132
 
57
133
  $ terminitor list
58
134
 
59
- This will print out the available project files that you can execute.
135
+ This will print out the available project files that you can execute. The list also returns whatever text you have in the first comment of each terminitor script.
60
136
 
61
137
  ### Creating Termfile for Repo ###
62
138
 
@@ -71,7 +147,7 @@ which contains the ideal development setup for OSX. To generate this file, invok
71
147
  $ terminitor create
72
148
 
73
149
  This will generate a 'Termfile' in the current project directory and open the file to be edited in the default text editor. The format
74
- of the file is still YAML as described above in the previous section. You should *note* that the project directory is automatically
150
+ of the file is using the new Ruby DSL as described above in the previous section. You should *note* that the project directory is automatically
75
151
  the working directory for each tab so you can just say `mate .` and the project directory containing the `Termfile` will open.
76
152
 
77
153
  Now, when you or another developer clones a project, you could simply:
@@ -91,16 +167,44 @@ In addition, you are in the project folder and you wish to remove the Termfile,
91
167
 
92
168
  This will clear the `Termfile` for the particular project.
93
169
 
170
+
171
+ ### Fetching Github Projects with Terminitor ###
172
+
173
+ Terminitor can also fetch code repositories off Skynet, I mean Github. This will have terminitor clone the repo into the current directory:
174
+
175
+ $ terminitor fetch achiu terminitor
176
+
177
+ After the repo has been fetched, terminitor will go ahead and run the setup block from the Termfile included in the repository. In the event you wouldn't want the setup block to be executed, simply set setup to false:
178
+
179
+ $ terminitor fetch achiu terminitor --setup=false
180
+
181
+ Some notes. Terminitor's fetch command is dependent on the ([github-gem](http://github.com/defunkt/github-gem)) at the current moment. It will try to fetch the repository with read/write access first if you have rights, if not, it will default to git read only. Happy fetching!
182
+
183
+
184
+ Cores
185
+ -----
186
+
187
+ Cores allow Terminitor to operate on a variety of platforms. They abstract the general behavior that terminitor needs to run the commands. Each core would inherit from an ([AbstractCore](http://github.com/achiu/terminitor/blob/master/lib/terminitor/abstract_core.rb)) and define the needed methods. At the moment the following Cores are supported:
188
+
189
+ * MacCore - Mac OS X Terminal
190
+ * KonsoleCore - KDE Konsole
191
+
192
+ Feel free to contribute more cores so that Terminitor can support your terminal of choice :)
193
+
194
+
94
195
  Limitations
95
196
  -----------
96
197
 
97
- This only works on OS X because of the dependency on applescript. It would presumably not be impossible to port this to Linux or Windows, and
98
- of course patches and suggestions are welcome.
198
+ #### MacCore ####
99
199
 
100
- Another issue is that right now tabs are created by invoking keystrokes which means there are limitations with the terminal being in
200
+ Right now the Mac OS X Terminal tabs are created by invoking keystrokes which means there are limitations with the terminal being in
101
201
  focus during execution of these commands. Obviously the long term goal is to solve this issue as well but in all honesty,
102
202
  this solution works well enough most of the time.
103
203
 
204
+ #### Fetching ####
205
+
206
+ The fetch task only pulls off Github repositories at the moment(which is cool). Later on, this functionality will be extended to non github repository(probably later this week.)
207
+
104
208
  Authors
105
209
  -------
106
210
 
@@ -113,14 +217,17 @@ Contributors
113
217
  Thanks to the following people for their contributions so far:
114
218
 
115
219
  * Pat George ([pcg79](http://github.com/pcg79)) for contributing a patch for when a project is not found.
220
+ * Flavio Castelli ([flavio](http://github.com/flavio)) for contributing Konsole(KDE) core.
116
221
 
117
222
  Acknowledgements
118
223
  -----------------
119
224
 
120
- This code came originally years ago from: [ELCTech](http://blog.elctech.com/2008/01/16/script-terminal-with-terminit/).
121
- This was a great start and made terminal automation easy. However, the repository is dead, but we had continued using the code for a while.
122
- Finally, we decided the time had come to release this code back to the world as a gem. Thanks to ELC for creating the original
123
- source for this project.
225
+
226
+
227
+ The core terminal scripting code was initially developed by [Jeff Emminger](http://workingwithrails.com/person/2412-jeff-emminger) years ago. The original introduction was made on the [ELCTech Blog](http://blog.elctech.com/2008/01/16/script-terminal-with-terminit/) and a lot of that code was adapted from [Scripting the Terminal in Leopard](http://onrails.org/articles/2007/11/28/scripting-the-leopard-terminal).
228
+
229
+ This was a great start and made terminal automation easy. However, the repository died long ago, and we had continued using the code for a while.
230
+ Finally, we decided the time had come to release this code back to the world as a gem. Thanks to ELC for creating the original source for this project.
124
231
 
125
232
  Also, we didn't take any code from [Project](http://github.com/joshnesbitt/project) by Josh but that project did inspire us to setup terminit
126
233
  as a gem. Basically, project is a great gem but there were a couple issues with the fact that the terminal doesn't save the session state in some cases.
data/Termfile CHANGED
@@ -1,11 +1,11 @@
1
- # COMMENT OF SCRIPT HERE
2
- # you can make as many tabs as you wish...
3
- # tab names are actually arbitrary at this point too.
4
- ---
5
- - tab1:
6
- - gitx
7
- - tab2:
8
- - mate .
9
- - irb
10
- - tab3:
11
- - open 'http://github.com/achiu/terminitor'
1
+ # Terminitor Termfile
2
+
3
+ setup do
4
+ run 'bundle install'
5
+ end
6
+
7
+ window do
8
+ tab 'watchr test.watchr'
9
+ tab "gitx", "irb"
10
+ tab "open 'http://www.github.com/achiu/terminitor/issues'"
11
+ end
@@ -0,0 +1,17 @@
1
+ # COMMENT OF SCRIPT HERE
2
+ # you can make as many tabs as you wish...
3
+ # tab names are actually arbitrary at this point too.
4
+
5
+ setup 'echo "setup"'
6
+
7
+ tab "echo 'default'", "echo 'default tab'"
8
+
9
+ window do
10
+ tab "echo 'first tab'", "echo 'of window'"
11
+
12
+ tab "named tab" do
13
+ run "echo 'named tab'"
14
+ run "ls"
15
+ end
16
+ end
17
+
data/lib/terminitor.rb CHANGED
@@ -1,74 +1,18 @@
1
1
  require 'rubygems'
2
- require 'thor'
3
- require 'appscript'
4
- require 'yaml'
5
- require File.expand_path('../terminitor/runner',__FILE__)
2
+ require File.expand_path('../terminitor/yaml', __FILE__)
3
+ require File.expand_path('../terminitor/dsl', __FILE__)
4
+ require File.expand_path('../terminitor/runner', __FILE__)
5
+ require File.expand_path('../terminitor/abstract_core', __FILE__)
6
+ require File.expand_path('../terminitor/cli', __FILE__)
6
7
 
7
8
  module Terminitor
8
- class Cli < Thor
9
- include Thor::Actions
10
- include Terminitor::Runner
11
- include Appscript
12
-
13
- def self.source_root; File.dirname(__FILE__); end
14
-
15
- desc "start PROJECT_NAME", "runs the terminitor project"
16
- method_option :root, :type => :string, :default => '.', :aliases => '-r'
17
- def start(project="")
18
- path = resolve_path(project)
19
- if File.exists?(path)
20
- do_project(path)
21
- else
22
- if project
23
- say "'#{File.basename(path)}' doesn't exist! Please run 'terminitor open #{project}'"
24
- else
25
- say "Termfile doesn't exist! Please run 'terminitor open' in project directory"
26
- end
27
- end
28
- end
29
-
30
- desc "list", "lists all terminitor scripts"
31
- def list
32
- say "Global scripts: \n"
33
- Dir.glob("#{ENV['HOME']}/.terminitor/*").each do |file|
34
- say " * #{File.basename(file).gsub('.yml','')} #{grab_comment_for_file(file)}"
35
- end
36
- end
37
-
38
- desc "setup", "create initial root terminitor folder"
39
- def setup
40
- empty_directory "#{ENV['HOME']}/.terminitor"
41
- end
42
-
43
- desc "open PROJECT_NAME", "open project yaml"
44
- method_option :root, :type => :string, :default => '.', :aliases => '-r'
45
- method_option :editor, :type => :string, :default => nil, :aliases => '-c'
46
- def open(project="")
47
- path = resolve_path(project)
48
- template "templates/example.yml.tt", path, :skip => true
49
- open_in_editor(path,options[:editor])
50
- end
51
-
52
- desc "generate", "create a Termfile in directory"
53
- method_option :root, :type => :string, :default => '.', :aliases => '-r'
54
- def create
55
- invoke :open, [], :root => options[:root]
56
- end
57
-
58
- desc "delete PROJECT", "delete project script"
59
- method_option :root, :type => :string, :default => '.', :aliases => '-r'
60
- def delete(project="")
61
- path = resolve_path(project)
62
- remove_file path
63
- end
64
-
65
- no_tasks do
66
-
67
- def grab_comment_for_file(file)
68
- first_line = File.read(file).first
69
- first_line =~ /^\s*?#/ ? ("-" + first_line.gsub("#","")) : "\n"
70
- end
71
- end
72
-
9
+ autoload :Version, File.expand_path('../terminitor/version', __FILE__)
10
+ case RUBY_PLATFORM.downcase
11
+ when %r{darwin}
12
+ require 'appscript'
13
+ autoload :MacCore, File.expand_path('../terminitor/cores/mac_core', __FILE__)
14
+ when %r{linux}
15
+ require 'dbus'
16
+ autoload :KonsoleCore, File.expand_path('../terminitor/cores/konsole_core', __FILE__)
73
17
  end
74
18
  end
@@ -0,0 +1,68 @@
1
+ module Terminitor
2
+ # This AbstractCore defines the basic methods that the Core should inherit
3
+ class AbstractCore
4
+ attr_accessor :terminal, :windows, :working_dir, :termfile
5
+
6
+ # set the terminal object, windows, and load the Termfile.
7
+ def initialize(path)
8
+ @termfile = load_termfile(path)
9
+ end
10
+
11
+ # Run the setup block in Termfile
12
+ def setup!
13
+ @working_dir = Dir.pwd
14
+ commands = @termfile[:setup].insert(0, "cd #{working_dir}")
15
+ commands.each { |cmd| execute_command(cmd, :in => active_window) }
16
+ end
17
+
18
+ # Executes the Termfile
19
+ def process!
20
+ term_windows = @termfile[:windows]
21
+ run_in_window(term_windows['default'], :default => true) unless term_windows['default'].to_s.empty?
22
+ term_windows.delete('default')
23
+ term_windows.each_pair { |window_name, tabs| run_in_window(tabs) }
24
+ end
25
+
26
+ # this command will run commands in the designated window
27
+ # run_in_window {:tab1 => ['ls','ok']}
28
+ def run_in_window(tabs, options = {})
29
+ open_window unless options[:default]
30
+ tabs.each_pair do |tab_name,commands|
31
+ tab = open_tab
32
+ commands.insert(0, "cd \"#{@working_dir}\"") unless @working_dir.to_s.empty?
33
+ commands.each do |cmd|
34
+ execute_command(cmd, :in => tab)
35
+ end
36
+ end
37
+ end
38
+
39
+ # Loads commands via the termfile and returns them as a hash
40
+ # if it matches legacy yaml, parse as yaml, else use new dsl
41
+ def load_termfile(path)
42
+ File.extname(path) == '.yml' ? Terminitor::Yaml.new(path).to_hash : Terminitor::Dsl.new(path).to_hash
43
+ end
44
+
45
+
46
+ ## These methods are core specific methods that need to be defined.
47
+ # yay.
48
+
49
+ # Executes the Command
50
+ # execute_command 'cd /path/to', {}
51
+ def execute_command(cmd, options = {})
52
+ end
53
+
54
+ # Opens a new tab and returns itself.
55
+ def open_tab
56
+ @working_dir = Dir.pwd # pass in current directory.
57
+ end
58
+
59
+ # Returns the current window
60
+ def active_window
61
+ end
62
+
63
+ # Opens a new window and returns the tab object.
64
+ def open_window
65
+ end
66
+
67
+ end
68
+ end
@@ -0,0 +1,77 @@
1
+ require 'thor'
2
+
3
+ module Terminitor
4
+ class Cli < Thor
5
+ include Thor::Actions
6
+ include Terminitor::Runner
7
+
8
+ def self.source_root; File.expand_path('../../',__FILE__); end
9
+
10
+ desc "start PROJECT_NAME", "runs the terminitor script"
11
+ method_option :root, :type => :string, :default => '.', :aliases => '-r'
12
+ def start(project="")
13
+ execute_core :process!, project
14
+ end
15
+
16
+ desc "setup PROJECT_NAME", "execute setup in the terminitor script"
17
+ method_option :root, :type => :string, :default => '.', :aliases => '-r'
18
+ def setup(project="")
19
+ execute_core :setup!, project
20
+ end
21
+
22
+ desc "fetch USERNAME PROJECT_NAME", "clone the designated repo and run setup"
23
+ method_option :root, :type => :string, :default => '.', :aliases => '-r'
24
+ method_option :setup, :type => :boolean, :default => true
25
+ def fetch(username, project)
26
+ fetch_repo username, project, options
27
+ end
28
+
29
+ desc "list", "lists all terminitor scripts"
30
+ def list
31
+ say "Global scripts: \n"
32
+ Dir.glob("#{ENV['HOME']}/.terminitor/*").each do |file|
33
+ say " * #{File.basename(file).gsub('.yml','')} #{grab_comment_for_file(file)}"
34
+ end
35
+ end
36
+
37
+ desc "init", "create initial root terminitor folder"
38
+ def init
39
+ empty_directory "#{ENV['HOME']}/.terminitor"
40
+ end
41
+
42
+ desc "edit PROJECT_NAME", "open termitor script"
43
+ method_option :root, :type => :string, :default => '.', :aliases => '-r'
44
+ method_option :editor, :type => :string, :default => nil, :aliases => '-c'
45
+ method_option :syntax, :type => :string, :default => 'term', :aliases => '-s'
46
+ def edit(project="")
47
+ syntax = project.empty? ? 'term' : options[:syntax] # force Termfile to use term syntax
48
+ path = config_path(project, syntax.to_sym)
49
+ template "templates/example.#{syntax}.tt", path, :skip => true
50
+ open_in_editor(path,options[:editor])
51
+ end
52
+
53
+ desc "open PROJECT_NAME", "this is deprecated. please use 'edit' instead"
54
+ method_option :root, :type => :string, :default => '.', :aliases => '-r'
55
+ method_option :syntax, :type => :string, :default => 'term', :aliases => '-s'
56
+ def open(project="")
57
+ say "'open' is now deprecated. Please use 'edit' instead"
58
+ invoke :edit, [project], options
59
+ end
60
+
61
+
62
+ desc "create", "create a Termfile in directory"
63
+ method_option :root, :type => :string, :default => '.', :aliases => '-r'
64
+ def create
65
+ invoke :edit, [], options
66
+ end
67
+
68
+ desc "delete PROJECT_NAME", "delete terminitor script"
69
+ method_option :root, :type => :string, :default => '.', :aliases => '-r'
70
+ method_option :syntax, :type => :string, :default => 'term', :aliases => '-s'
71
+ def delete(project="")
72
+ path = config_path(project, options[:syntax].to_sym)
73
+ remove_file path
74
+ end
75
+
76
+ end
77
+ end