sidekick 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.gitmodules +3 -0
- data/README.textile +23 -17
- data/Rakefile +22 -23
- data/VERSION +1 -1
- data/annotated/helpers.html +143 -0
- data/annotated/index.html +155 -0
- data/annotated/lib/sidekick.html +144 -0
- data/annotated/sidekick.html +155 -0
- data/annotated/triggers.html +76 -0
- data/annotated/util.html +74 -0
- data/lib/sidekick.rb +44 -20
- data/lib/sidekick/helpers/compile.rb +34 -0
- data/lib/sidekick/helpers/passenger.rb +14 -0
- data/lib/sidekick/helpers/shell.rb +10 -0
- data/lib/sidekick/helpers/sidekick.rb +12 -0
- data/lib/sidekick/helpers/system.rb +36 -0
- data/lib/sidekick/helpers/user_interaction.rb +15 -0
- data/lib/sidekick/triggers.rb +3 -4
- data/lib/template +1 -3
- metadata +17 -7
- data/lib/sidekick/helpers.rb +0 -71
- data/lib/sidekick/helpers/util.rb +0 -26
- data/sidekick.gemspec +0 -71
data/.gitignore
CHANGED
data/.gitmodules
ADDED
data/README.textile
CHANGED
@@ -1,30 +1,41 @@
|
|
1
1
|
h1. Sidekick
|
2
2
|
|
3
|
+
"Sidekick":http://ibuildlegobricks.tumblr.com/post/1398895151/automate-common-tasks-with-sidekick is a command line tool to automatically trigger actions on certain events, as defined per project, in a local @.sidekick@ file in your project folder:
|
3
4
|
|
4
|
-
|
5
|
+
<pre><code>
|
6
|
+
watch('**/*.rb') { restart_passenger }
|
5
7
|
|
6
|
-
|
8
|
+
auto_compile 'assets/*.sass', 'public/:name.css'
|
9
|
+
|
10
|
+
every(10) { notify sh 'fortune' }
|
11
|
+
</pre></code>
|
12
|
+
|
13
|
+
h3. Sample use cases
|
7
14
|
|
8
15
|
* Restart server when code is changed
|
9
|
-
*
|
16
|
+
* Auto-compile Sass or CoffeeScript templates (and many other languages)
|
10
17
|
* Periodically run commands
|
11
|
-
* Continuous testing,
|
12
|
-
|
13
|
-
You typically run Sidekick in the background to automate this while coding.
|
18
|
+
* Continuous testing, notifications, hooks, you name it
|
14
19
|
|
15
20
|
h3. Features
|
16
21
|
|
17
|
-
* Simple and powerful DSL
|
22
|
+
* Simple and powerful DSL
|
18
23
|
* Easy to extend
|
19
|
-
* Compiles many
|
24
|
+
* Compiles many formats, thanks to "Tilt":http://github.com/rtomayko/tilt.
|
20
25
|
* Powered by "EventMachine":http://github.com/eventmachine/eventmachine
|
21
|
-
*
|
26
|
+
* The core is about 60 lines of code
|
27
|
+
|
28
|
+
You should "read the annotated source code":http://jbe.github.com/sidekick/.
|
22
29
|
|
23
30
|
h2. Basic usage
|
24
31
|
|
25
|
-
Install with @gem install sidekick@ and invoke
|
32
|
+
Install with @gem install sidekick@ and invoke the @sidekick@ command in your project folder. If you do not have a @.sidekick@ file, you will be offered a template.
|
33
|
+
|
34
|
+
For now, look to the source code to see all available
|
26
35
|
|
27
|
-
|
36
|
+
* "triggers":http://jbe.github.com/sidekick/triggers.html
|
37
|
+
|
38
|
+
* "helpers":http://jbe.github.com/sidekick/helpers.html
|
28
39
|
|
29
40
|
h2. Writing extensions
|
30
41
|
|
@@ -47,15 +58,10 @@ They will be available to other helpers and to @.sidekick@ files. When adding a
|
|
47
58
|
|
48
59
|
h3. Writing new triggers
|
49
60
|
|
50
|
-
Have a look at the "existing triggers":http://github.com/
|
61
|
+
Have a look at the "existing triggers":http://jbe.github.com/sidekick/triggers.html, and you will get the idea. Basically, you define new triggers by calling @Sidekick::Triggers.register(:trigger_name) { .. }@, and hooking into EventMachine the same way as in @EM.run { .. }@ from there.
|
51
62
|
|
52
63
|
You can keep your extensions in the @.sidekick@ file itself, or package them in gems, or (better) ask me to merge them into the main repository.
|
53
64
|
|
54
|
-
h3. Similar projects:
|
55
|
-
|
56
|
-
* "Guard":http://github.com/guard/guard
|
57
|
-
|
58
|
-
|
59
65
|
h3. Copyright
|
60
66
|
|
61
67
|
Copyright (c) 2010 Jostein Berre Eliassen. See LICENSE for details.
|
data/Rakefile
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'rake'
|
3
|
+
require 'rake/clean'
|
3
4
|
|
4
5
|
begin
|
5
6
|
require 'jeweler'
|
@@ -19,30 +20,8 @@ rescue LoadError
|
|
19
20
|
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
21
|
end
|
21
22
|
|
22
|
-
require 'rake/testtask'
|
23
|
-
Rake::TestTask.new(:test) do |test|
|
24
|
-
test.libs << 'lib' << 'test'
|
25
|
-
test.pattern = 'test/**/test_*.rb'
|
26
|
-
test.verbose = true
|
27
|
-
end
|
28
|
-
|
29
|
-
begin
|
30
|
-
require 'rcov/rcovtask'
|
31
|
-
Rcov::RcovTask.new do |test|
|
32
|
-
test.libs << 'test'
|
33
|
-
test.pattern = 'test/**/test_*.rb'
|
34
|
-
test.verbose = true
|
35
|
-
end
|
36
|
-
rescue LoadError
|
37
|
-
task :rcov do
|
38
|
-
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
task :test => :check_dependencies
|
43
|
-
|
44
|
-
task :default => :test
|
45
23
|
|
24
|
+
=begin
|
46
25
|
require 'rake/rdoctask'
|
47
26
|
Rake::RDocTask.new do |rdoc|
|
48
27
|
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
@@ -52,3 +31,23 @@ Rake::RDocTask.new do |rdoc|
|
|
52
31
|
rdoc.rdoc_files.include('README*')
|
53
32
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
54
33
|
end
|
34
|
+
=end
|
35
|
+
|
36
|
+
require 'rocco/tasks'
|
37
|
+
Rocco::make 'annotated/'
|
38
|
+
|
39
|
+
desc 'Build docco'
|
40
|
+
task :docs => [:rocco, 'website/index.html']
|
41
|
+
directory 'annotated/'
|
42
|
+
|
43
|
+
# Make index.html a copy of rocco.html
|
44
|
+
file 'website/index.html' => 'website/sidekick.html' do |f|
|
45
|
+
cp 'website/sidekick.html', 'website/index.html', :preserve => true
|
46
|
+
end
|
47
|
+
|
48
|
+
CLEAN.include 'website/index.html'
|
49
|
+
task :doc => :docs
|
50
|
+
|
51
|
+
# GITHUB PAGES ===============================================================
|
52
|
+
|
53
|
+
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.6.0
|
@@ -0,0 +1,143 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
5
|
+
<title>helpers.rb</title>
|
6
|
+
<link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div id='container'>
|
10
|
+
<div id="background"></div>
|
11
|
+
<div id="jump_to">
|
12
|
+
Jump To …
|
13
|
+
<div id="jump_wrapper">
|
14
|
+
<div id="jump_page">
|
15
|
+
<a class="source" href="sidekick.html">sidekick.rb</a>
|
16
|
+
<a class="source" href="helpers.html">helpers.rb</a>
|
17
|
+
<a class="source" href="util.html">util.rb</a>
|
18
|
+
<a class="source" href="triggers.html">triggers.rb</a>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<table cellspacing=0 cellpadding=0>
|
23
|
+
<thead>
|
24
|
+
<tr>
|
25
|
+
<th class=docs><h1>helpers.rb</h1></th>
|
26
|
+
<th class=code></th>
|
27
|
+
</tr>
|
28
|
+
</thead>
|
29
|
+
<tbody>
|
30
|
+
<tr id='section-1'>
|
31
|
+
<td class=docs>
|
32
|
+
<div class="octowrap">
|
33
|
+
<a class="octothorpe" href="#section-1">#</a>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
</td>
|
37
|
+
<td class=code>
|
38
|
+
<div class='highlight'><pre><span class="nb">require</span> <span class="s1">'fileutils'</span>
|
39
|
+
<span class="nb">require</span> <span class="s1">'rbconfig'</span>
|
40
|
+
<span class="nb">require</span> <span class="s1">'tilt'</span></pre></div>
|
41
|
+
</td>
|
42
|
+
</tr>
|
43
|
+
<tr id='section-2'>
|
44
|
+
<td class=docs>
|
45
|
+
<div class="octowrap">
|
46
|
+
<a class="octothorpe" href="#section-2">#</a>
|
47
|
+
</div>
|
48
|
+
<p> default helpers</p>
|
49
|
+
</td>
|
50
|
+
<td class=code>
|
51
|
+
<div class='highlight'><pre><span class="k">module</span> <span class="nn">Sidekick::Helpers</span></pre></div>
|
52
|
+
</td>
|
53
|
+
</tr>
|
54
|
+
<tr id='section-3'>
|
55
|
+
<td class=docs>
|
56
|
+
<div class="octowrap">
|
57
|
+
<a class="octothorpe" href="#section-3">#</a>
|
58
|
+
</div>
|
59
|
+
<p> system</p>
|
60
|
+
</td>
|
61
|
+
<td class=code>
|
62
|
+
<div class='highlight'><pre> <span class="nb">require</span> <span class="s1">'sidekick/helpers/util'</span>
|
63
|
+
<span class="kp">include</span> <span class="no">Util</span>
|
64
|
+
|
65
|
+
<span class="k">def</span> <span class="nf">log</span><span class="p">(</span><span class="n">str</span><span class="p">)</span>
|
66
|
+
<span class="nb">puts</span> <span class="s1">' -> '</span> <span class="o">+</span> <span class="n">str</span>
|
67
|
+
<span class="k">end</span>
|
68
|
+
|
69
|
+
<span class="k">def</span> <span class="nf">stop</span><span class="p">(</span><span class="o">*</span><span class="n">prms</span><span class="p">)</span>
|
70
|
+
<span class="no">Sidekick</span><span class="o">.</span><span class="n">stop</span><span class="p">(</span><span class="o">*</span><span class="n">prms</span><span class="p">)</span>
|
71
|
+
<span class="k">end</span></pre></div>
|
72
|
+
</td>
|
73
|
+
</tr>
|
74
|
+
<tr id='section-4'>
|
75
|
+
<td class=docs>
|
76
|
+
<div class="octowrap">
|
77
|
+
<a class="octothorpe" href="#section-4">#</a>
|
78
|
+
</div>
|
79
|
+
<p> notifications</p>
|
80
|
+
</td>
|
81
|
+
<td class=code>
|
82
|
+
<div class='highlight'><pre> <span class="k">def</span> <span class="nf">notify</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">title</span><span class="o">=</span><span class="s1">'Sidekick'</span><span class="p">)</span>
|
83
|
+
|
84
|
+
<span class="n">gems</span> <span class="o">=</span> <span class="p">{</span><span class="ss">:linux</span> <span class="o">=></span> <span class="s1">'libnotify'</span><span class="p">,</span> <span class="ss">:darwin</span> <span class="o">=></span> <span class="s1">'growl'</span><span class="p">}</span>
|
85
|
+
|
86
|
+
<span class="n">stop</span><span class="p">(</span><span class="s1">'Notifications not supported.'</span><span class="p">)</span> <span class="k">unless</span> <span class="n">platform_load?</span><span class="p">(</span>
|
87
|
+
<span class="n">gems</span><span class="p">,</span> <span class="s1">'notifications'</span><span class="p">)</span>
|
88
|
+
<span class="k">case</span> <span class="n">platform</span>
|
89
|
+
<span class="k">when</span> <span class="ss">:linux</span>
|
90
|
+
<span class="no">Libnotify</span><span class="o">.</span><span class="n">show</span> <span class="ss">:body</span> <span class="o">=></span> <span class="n">message</span><span class="p">,</span> <span class="ss">:summary</span> <span class="o">=></span> <span class="n">title</span>
|
91
|
+
<span class="k">when</span> <span class="ss">:darwin</span>
|
92
|
+
<span class="no">Growl</span><span class="o">.</span><span class="n">notify</span> <span class="n">message</span><span class="p">,</span> <span class="ss">:title</span> <span class="o">=></span> <span class="n">title</span><span class="p">,</span> <span class="ss">:name</span> <span class="o">=></span> <span class="s1">'Sidekick'</span>
|
93
|
+
<span class="k">end</span>
|
94
|
+
<span class="k">end</span>
|
95
|
+
|
96
|
+
<span class="k">def</span> <span class="nf">sh</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>
|
97
|
+
<span class="n">log</span> <span class="n">cmd</span>
|
98
|
+
<span class="nb">puts</span> <span class="n">result</span> <span class="o">=</span> <span class="sb">`</span><span class="si">#{</span><span class="n">cmd</span><span class="si">}</span><span class="sb">`</span>
|
99
|
+
<span class="n">result</span>
|
100
|
+
<span class="k">end</span>
|
101
|
+
|
102
|
+
<span class="k">def</span> <span class="nf">restart_passenger</span>
|
103
|
+
<span class="no">FileUtils</span><span class="o">.</span><span class="n">touch</span> <span class="s1">'./tmp/restart.txt'</span>
|
104
|
+
<span class="n">log</span> <span class="s1">'restarted passenger'</span>
|
105
|
+
<span class="k">end</span></pre></div>
|
106
|
+
</td>
|
107
|
+
</tr>
|
108
|
+
<tr id='section-5'>
|
109
|
+
<td class=docs>
|
110
|
+
<div class="octowrap">
|
111
|
+
<a class="octothorpe" href="#section-5">#</a>
|
112
|
+
</div>
|
113
|
+
<p> watches for changes matching the source glob,
|
114
|
+
compiles using the tilt gem, and saves to
|
115
|
+
target. Target is interpolated for :name</p>
|
116
|
+
|
117
|
+
</td>
|
118
|
+
<td class=code>
|
119
|
+
<div class='highlight'><pre> <span class="k">def</span> <span class="nf">auto_compile</span><span class="p">(</span><span class="n">source</span><span class="p">,</span> <span class="n">target</span><span class="p">)</span>
|
120
|
+
<span class="n">watch</span><span class="p">(</span><span class="n">source</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">files</span><span class="o">|</span>
|
121
|
+
<span class="n">files</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">file</span><span class="o">|</span>
|
122
|
+
<span class="k">if</span> <span class="no">File</span><span class="o">.</span><span class="n">exists?</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
|
123
|
+
<span class="k">begin</span>
|
124
|
+
<span class="n">t</span> <span class="o">=</span> <span class="n">target</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="s1">':name'</span><span class="p">,</span> <span class="no">File</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="n">file</span><span class="p">,</span> <span class="s1">'.*'</span><span class="p">))</span>
|
125
|
+
<span class="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">t</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span>
|
126
|
+
<span class="n">f</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="no">Tilt</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">file</span><span class="p">)</span><span class="o">.</span><span class="n">render</span><span class="p">)</span>
|
127
|
+
<span class="k">end</span>
|
128
|
+
<span class="n">log</span> <span class="s2">"render </span><span class="si">#{</span><span class="n">file</span><span class="si">}</span><span class="s2"> => </span><span class="si">#{</span><span class="n">t</span><span class="si">}</span><span class="s2">"</span>
|
129
|
+
<span class="k">rescue</span> <span class="no">Exception</span> <span class="o">=></span> <span class="n">e</span>
|
130
|
+
<span class="n">notify</span> <span class="s2">"Error in </span><span class="si">#{</span><span class="n">file</span><span class="si">}</span><span class="s2">:</span><span class="se">\n</span><span class="si">#{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span>
|
131
|
+
<span class="n">log</span> <span class="s2">"Error in </span><span class="si">#{</span><span class="n">file</span><span class="si">}</span><span class="s2">:</span><span class="se">\n</span><span class="si">#{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span>
|
132
|
+
<span class="k">end</span>
|
133
|
+
<span class="k">end</span>
|
134
|
+
<span class="k">end</span>
|
135
|
+
<span class="k">end</span>
|
136
|
+
<span class="k">end</span>
|
137
|
+
|
138
|
+
<span class="k">end</span></pre></div>
|
139
|
+
</td>
|
140
|
+
</tr>
|
141
|
+
</table>
|
142
|
+
</div>
|
143
|
+
</body>
|
@@ -0,0 +1,155 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
5
|
+
<title>sidekick.rb</title>
|
6
|
+
<link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div id='container'>
|
10
|
+
<div id="background"></div>
|
11
|
+
<div id="jump_to">
|
12
|
+
Jump To …
|
13
|
+
<div id="jump_wrapper">
|
14
|
+
<div id="jump_page">
|
15
|
+
<a class="source" href="sidekick.html">sidekick.rb</a>
|
16
|
+
<a class="source" href="helpers.html">helpers.rb</a>
|
17
|
+
<a class="source" href="util.html">util.rb</a>
|
18
|
+
<a class="source" href="triggers.html">triggers.rb</a>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<table cellspacing=0 cellpadding=0>
|
23
|
+
<thead>
|
24
|
+
<tr>
|
25
|
+
<th class=docs><h1>sidekick.rb</h1></th>
|
26
|
+
<th class=code></th>
|
27
|
+
</tr>
|
28
|
+
</thead>
|
29
|
+
<tbody>
|
30
|
+
<tr id='section-1'>
|
31
|
+
<td class=docs>
|
32
|
+
<div class="octowrap">
|
33
|
+
<a class="octothorpe" href="#section-1">#</a>
|
34
|
+
</div>
|
35
|
+
<p> <em>Sidekick</em> is a simple event driven background assistant. Among other things, you can use it to automatically compile assets, test code, restart servers and so on – as prescribed per project, in a <code>.sidekick</code> file. It is powered by EventMachine and Tilt.</p>
|
36
|
+
|
37
|
+
<p> This is the annotated source code. See the <a href="http://github.com/jbe/sidekick#readme">README</a> too.</p>
|
38
|
+
|
39
|
+
<hr />
|
40
|
+
|
41
|
+
<p> Sidekick basically helps you do two things:</p>
|
42
|
+
|
43
|
+
<p> — <em>Define</em> named triggers, such as saying that <code>watch(glob)</code> means doing something when a file matching <code>glob</code> changes, or that <code>every(duration)</code> means doing something every <code>duration</code> seconds.</p>
|
44
|
+
|
45
|
+
<p> — <em>Use</em> the defined triggers with callbacks, such as <code>watch(**.rb) { notify 'Code change' }</code></p>
|
46
|
+
</td>
|
47
|
+
<td class=code>
|
48
|
+
<div class='highlight'><pre><span class="nb">require</span> <span class="s1">'fileutils'</span>
|
49
|
+
<span class="nb">require</span> <span class="s1">'eventmachine'</span>
|
50
|
+
|
51
|
+
<span class="k">module</span> <span class="nn">Sidekick</span></pre></div>
|
52
|
+
</td>
|
53
|
+
</tr>
|
54
|
+
<tr id='section-2'>
|
55
|
+
<td class=docs>
|
56
|
+
<div class="octowrap">
|
57
|
+
<a class="octothorpe" href="#section-2">#</a>
|
58
|
+
</div>
|
59
|
+
<p> This core functionality is provided by <code>Sidekick::Triggers</code>.</p>
|
60
|
+
|
61
|
+
<p> New triggers can be defined by calling <code>Sidekick::Triggers.register(:trigger_name) { ... }</code>.</p>
|
62
|
+
|
63
|
+
<p>Basically, the job of a trigger definition is to take the parameters and the block from a call in <code>.sidekick</code> and use it to hook into EventMachine in some way. — Just have a look at the <a href="http://github.com/jbe/sidekick/blob/master/lib/sidekick/triggers.rb">default trigger library</a>.</p>
|
64
|
+
|
65
|
+
<p> By using Ruby’s <code>method_missing</code>, we can forward method calls to the registered trigger definitions. Any module can thereby extend the <code>Triggers</code> module in order to expose the defined triggers as if they were methods.</p>
|
66
|
+
</td>
|
67
|
+
<td class=code>
|
68
|
+
<div class='highlight'><pre> <span class="k">module</span> <span class="nn">Triggers</span>
|
69
|
+
<span class="vc">@@triggers</span> <span class="o">=</span> <span class="p">{}</span>
|
70
|
+
|
71
|
+
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">register</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
|
72
|
+
<span class="vc">@@triggers</span><span class="o">[</span><span class="nb">name</span><span class="o">]</span> <span class="o">=</span> <span class="n">block</span>
|
73
|
+
<span class="k">end</span>
|
74
|
+
|
75
|
+
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">log</span><span class="p">(</span><span class="n">str</span><span class="p">)</span> <span class="c1"># used by triggers</span>
|
76
|
+
<span class="nb">puts</span> <span class="n">str</span>
|
77
|
+
<span class="k">end</span>
|
78
|
+
|
79
|
+
<span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">blk</span><span class="p">)</span>
|
80
|
+
<span class="vc">@@triggers</span><span class="o">[</span><span class="nb">name</span><span class="o">]</span> <span class="p">?</span>
|
81
|
+
<span class="vc">@@triggers</span><span class="o">[</span><span class="nb">name</span><span class="o">].</span><span class="n">call</span><span class="p">(</span><span class="n">blk</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span> <span class="p">:</span> <span class="k">super</span>
|
82
|
+
<span class="k">end</span>
|
83
|
+
|
84
|
+
<span class="k">def</span> <span class="nf">respond_to?</span><span class="p">(</span><span class="nb">method</span><span class="p">)</span>
|
85
|
+
<span class="k">super</span> <span class="o">||</span> <span class="o">!!</span><span class="vc">@@triggers</span><span class="o">[</span><span class="nb">method</span><span class="o">]</span>
|
86
|
+
<span class="k">end</span>
|
87
|
+
|
88
|
+
<span class="k">end</span></pre></div>
|
89
|
+
</td>
|
90
|
+
</tr>
|
91
|
+
<tr id='section-3'>
|
92
|
+
<td class=docs>
|
93
|
+
<div class="octowrap">
|
94
|
+
<a class="octothorpe" href="#section-3">#</a>
|
95
|
+
</div>
|
96
|
+
<p> A default library of triggers and helpers is included..</p>
|
97
|
+
</td>
|
98
|
+
<td class=code>
|
99
|
+
<div class='highlight'><pre> <span class="nb">require</span> <span class="s1">'sidekick/triggers'</span>
|
100
|
+
<span class="nb">require</span> <span class="s1">'sidekick/helpers'</span></pre></div>
|
101
|
+
</td>
|
102
|
+
</tr>
|
103
|
+
<tr id='section-4'>
|
104
|
+
<td class=docs>
|
105
|
+
<div class="octowrap">
|
106
|
+
<a class="octothorpe" href="#section-4">#</a>
|
107
|
+
</div>
|
108
|
+
<p> The <code>.sidekick</code> file is evaluated in a <code>Sidekick::Context</code> module, which exposes DSL style methods by extending <code>Sidekick::Triggers</code> and <code>Sidekick::Helpers</code>.</p>
|
109
|
+
</td>
|
110
|
+
<td class=code>
|
111
|
+
<div class='highlight'><pre> <span class="no">Context</span> <span class="o">=</span> <span class="no">Module</span><span class="o">.</span><span class="n">new</span>
|
112
|
+
<span class="no">Context</span><span class="o">.</span><span class="n">extend</span> <span class="no">Triggers</span>
|
113
|
+
<span class="no">Context</span><span class="o">.</span><span class="n">extend</span> <span class="no">Helpers</span></pre></div>
|
114
|
+
</td>
|
115
|
+
</tr>
|
116
|
+
<tr id='section-5'>
|
117
|
+
<td class=docs>
|
118
|
+
<div class="octowrap">
|
119
|
+
<a class="octothorpe" href="#section-5">#</a>
|
120
|
+
</div>
|
121
|
+
<p> The <code>Sidekick.run!</code> method reads and applies the <code>.sidekick</code> file, wrapping the setup phase inside <code>EM.run { .. }</code>, and thus begins the event loop.</p>
|
122
|
+
|
123
|
+
</td>
|
124
|
+
<td class=code>
|
125
|
+
<div class='highlight'><pre> <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">run!</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="s1">'.sidekick'</span><span class="p">)</span>
|
126
|
+
<span class="n">ensure_config_exists</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
|
127
|
+
|
128
|
+
<span class="no">Signal</span><span class="o">.</span><span class="n">trap</span><span class="p">(</span><span class="ss">:INT</span><span class="p">)</span> <span class="p">{</span> <span class="n">stop</span> <span class="p">}</span>
|
129
|
+
|
130
|
+
<span class="no">EventMachine</span><span class="o">.</span><span class="n">run</span> <span class="k">do</span>
|
131
|
+
<span class="no">Context</span><span class="o">.</span><span class="n">module_eval</span><span class="p">(</span>
|
132
|
+
<span class="nb">open</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> <span class="p">{</span><span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span> <span class="p">},</span> <span class="n">path</span> <span class="p">)</span>
|
133
|
+
<span class="k">end</span>
|
134
|
+
<span class="k">end</span>
|
135
|
+
|
136
|
+
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">ensure_config_exists</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
|
137
|
+
<span class="k">unless</span> <span class="no">File</span><span class="o">.</span><span class="n">exists?</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
|
138
|
+
<span class="nb">puts</span> <span class="s1">'Generate new sidekick file? (Y/n)'</span>
|
139
|
+
<span class="nb">gets</span> <span class="o">=~</span> <span class="sr">/^N|n/</span> <span class="p">?</span> <span class="nb">exit</span> <span class="p">:</span>
|
140
|
+
<span class="no">FileUtils</span><span class="o">.</span><span class="n">cp</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="s1">'../template'</span><span class="p">,</span>
|
141
|
+
<span class="bp">__FILE__</span><span class="p">),</span> <span class="n">path</span><span class="p">)</span>
|
142
|
+
<span class="k">end</span>
|
143
|
+
<span class="k">end</span>
|
144
|
+
|
145
|
+
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">stop</span><span class="p">(</span><span class="n">msg</span><span class="o">=</span><span class="kp">false</span><span class="p">)</span>
|
146
|
+
<span class="no">EventMachine</span><span class="o">.</span><span class="n">stop</span>
|
147
|
+
<span class="nb">puts</span> <span class="s2">"</span><span class="se">\n</span><span class="si">#{</span><span class="n">msg</span><span class="si">}</span><span class="s2">"</span> <span class="k">if</span> <span class="n">msg</span>
|
148
|
+
<span class="k">end</span>
|
149
|
+
|
150
|
+
<span class="k">end</span></pre></div>
|
151
|
+
</td>
|
152
|
+
</tr>
|
153
|
+
</table>
|
154
|
+
</div>
|
155
|
+
</body>
|
@@ -0,0 +1,144 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
5
|
+
<title>sidekick.rb</title>
|
6
|
+
<link rel="stylesheet" href="http://jashkenas.github.com/docco/resources/docco.css">
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div id='container'>
|
10
|
+
<div id="background"></div>
|
11
|
+
<table cellspacing=0 cellpadding=0>
|
12
|
+
<thead>
|
13
|
+
<tr>
|
14
|
+
<th class=docs><h1>sidekick.rb</h1></th>
|
15
|
+
<th class=code></th>
|
16
|
+
</tr>
|
17
|
+
</thead>
|
18
|
+
<tbody>
|
19
|
+
<tr id='section-1'>
|
20
|
+
<td class=docs>
|
21
|
+
<div class="octowrap">
|
22
|
+
<a class="octothorpe" href="#section-1">#</a>
|
23
|
+
</div>
|
24
|
+
<p> <em>Sidekick</em> is a simple event driven background assistant. Among other things, you can use it to automatically compile assets, test code, restart servers and so on – as prescribed per project, in a <code>.sidekick</code> file. It is powered by EventMachine and Tilt.</p>
|
25
|
+
|
26
|
+
<p> This is the annotated source code. See the <a href="http://github.com/jbe/sidekick#readme">README</a> too.</p>
|
27
|
+
|
28
|
+
<hr />
|
29
|
+
|
30
|
+
<p> Sidekick basically helps you do two things:</p>
|
31
|
+
|
32
|
+
<p> — <em>Define</em> named triggers, such as saying that <code>watch(glob)</code> means doing something when a file matching <code>glob</code> changes, or that <code>every(duration)</code> means doing something every <code>duration</code> seconds.</p>
|
33
|
+
|
34
|
+
<p> — <em>Use</em> the defined triggers with callbacks, such as <code>watch(**.rb) { notify 'Code change' }</code></p>
|
35
|
+
</td>
|
36
|
+
<td class=code>
|
37
|
+
<div class='highlight'><pre><span class="nb">require</span> <span class="s1">'fileutils'</span>
|
38
|
+
<span class="nb">require</span> <span class="s1">'eventmachine'</span>
|
39
|
+
|
40
|
+
<span class="k">module</span> <span class="nn">Sidekick</span></pre></div>
|
41
|
+
</td>
|
42
|
+
</tr>
|
43
|
+
<tr id='section-2'>
|
44
|
+
<td class=docs>
|
45
|
+
<div class="octowrap">
|
46
|
+
<a class="octothorpe" href="#section-2">#</a>
|
47
|
+
</div>
|
48
|
+
<p> This core functionality is provided by <code>Sidekick::Triggers</code>.</p>
|
49
|
+
|
50
|
+
<p> New triggers can be defined by calling <code>Sidekick::Triggers.register(:trigger_name) { ... }</code>.</p>
|
51
|
+
|
52
|
+
<p>Basically, the job of a trigger definition is to take the parameters and the block from a call in <code>.sidekick</code> and use it to hook into EventMachine in some way. — Just have a look at the <a href="http://github.com/jbe/sidekick/blob/master/lib/sidekick/triggers.rb">default trigger library</a>.</p>
|
53
|
+
|
54
|
+
<p> By using Ruby’s <code>method_missing</code>, we can forward method calls to the registered trigger definitions. Any module can thereby extend the <code>Triggers</code> module in order to expose the defined triggers as if they were methods.</p>
|
55
|
+
</td>
|
56
|
+
<td class=code>
|
57
|
+
<div class='highlight'><pre> <span class="k">module</span> <span class="nn">Triggers</span>
|
58
|
+
<span class="vc">@@triggers</span> <span class="o">=</span> <span class="p">{}</span>
|
59
|
+
|
60
|
+
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">register</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
|
61
|
+
<span class="vc">@@triggers</span><span class="o">[</span><span class="nb">name</span><span class="o">]</span> <span class="o">=</span> <span class="n">block</span>
|
62
|
+
<span class="k">end</span>
|
63
|
+
|
64
|
+
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">log</span><span class="p">(</span><span class="n">str</span><span class="p">)</span> <span class="c1"># used by triggers</span>
|
65
|
+
<span class="nb">puts</span> <span class="n">str</span>
|
66
|
+
<span class="k">end</span>
|
67
|
+
|
68
|
+
<span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="nb">name</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">blk</span><span class="p">)</span>
|
69
|
+
<span class="vc">@@triggers</span><span class="o">[</span><span class="nb">name</span><span class="o">]</span> <span class="p">?</span>
|
70
|
+
<span class="vc">@@triggers</span><span class="o">[</span><span class="nb">name</span><span class="o">].</span><span class="n">call</span><span class="p">(</span><span class="n">blk</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span> <span class="p">:</span> <span class="k">super</span>
|
71
|
+
<span class="k">end</span>
|
72
|
+
|
73
|
+
<span class="k">def</span> <span class="nf">respond_to?</span><span class="p">(</span><span class="nb">method</span><span class="p">)</span>
|
74
|
+
<span class="k">super</span> <span class="o">||</span> <span class="o">!!</span><span class="vc">@@triggers</span><span class="o">[</span><span class="nb">method</span><span class="o">]</span>
|
75
|
+
<span class="k">end</span>
|
76
|
+
|
77
|
+
<span class="k">end</span></pre></div>
|
78
|
+
</td>
|
79
|
+
</tr>
|
80
|
+
<tr id='section-3'>
|
81
|
+
<td class=docs>
|
82
|
+
<div class="octowrap">
|
83
|
+
<a class="octothorpe" href="#section-3">#</a>
|
84
|
+
</div>
|
85
|
+
<p> A default library of triggers and helpers is included..</p>
|
86
|
+
</td>
|
87
|
+
<td class=code>
|
88
|
+
<div class='highlight'><pre> <span class="nb">require</span> <span class="s1">'sidekick/triggers'</span>
|
89
|
+
<span class="nb">require</span> <span class="s1">'sidekick/helpers'</span></pre></div>
|
90
|
+
</td>
|
91
|
+
</tr>
|
92
|
+
<tr id='section-4'>
|
93
|
+
<td class=docs>
|
94
|
+
<div class="octowrap">
|
95
|
+
<a class="octothorpe" href="#section-4">#</a>
|
96
|
+
</div>
|
97
|
+
<p> The <code>.sidekick</code> file is evaluated in a <code>Sidekick::Context</code> module, which exposes DSL style methods by extending <code>Sidekick::Triggers</code> and <code>Sidekick::Helpers</code>.</p>
|
98
|
+
</td>
|
99
|
+
<td class=code>
|
100
|
+
<div class='highlight'><pre> <span class="no">Context</span> <span class="o">=</span> <span class="no">Module</span><span class="o">.</span><span class="n">new</span>
|
101
|
+
<span class="no">Context</span><span class="o">.</span><span class="n">extend</span> <span class="no">Triggers</span>
|
102
|
+
<span class="no">Context</span><span class="o">.</span><span class="n">extend</span> <span class="no">Helpers</span></pre></div>
|
103
|
+
</td>
|
104
|
+
</tr>
|
105
|
+
<tr id='section-5'>
|
106
|
+
<td class=docs>
|
107
|
+
<div class="octowrap">
|
108
|
+
<a class="octothorpe" href="#section-5">#</a>
|
109
|
+
</div>
|
110
|
+
<p> The <code>Sidekick.run!</code> method reads and applies the <code>.sidekick</code> file, wrapping the setup phase inside <code>EM.run { .. }</code>, and thus begins the event loop.</p>
|
111
|
+
|
112
|
+
</td>
|
113
|
+
<td class=code>
|
114
|
+
<div class='highlight'><pre> <span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">run!</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="s1">'.sidekick'</span><span class="p">)</span>
|
115
|
+
<span class="n">ensure_config_exists</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
|
116
|
+
|
117
|
+
<span class="no">Signal</span><span class="o">.</span><span class="n">trap</span><span class="p">(</span><span class="ss">:INT</span><span class="p">)</span> <span class="p">{</span> <span class="n">stop</span> <span class="p">}</span>
|
118
|
+
|
119
|
+
<span class="no">EventMachine</span><span class="o">.</span><span class="n">run</span> <span class="k">do</span>
|
120
|
+
<span class="no">Context</span><span class="o">.</span><span class="n">module_eval</span><span class="p">(</span>
|
121
|
+
<span class="nb">open</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> <span class="p">{</span><span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="o">.</span><span class="n">read</span> <span class="p">},</span> <span class="n">path</span> <span class="p">)</span>
|
122
|
+
<span class="k">end</span>
|
123
|
+
<span class="k">end</span>
|
124
|
+
|
125
|
+
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">ensure_config_exists</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
|
126
|
+
<span class="k">unless</span> <span class="no">File</span><span class="o">.</span><span class="n">exists?</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>
|
127
|
+
<span class="nb">puts</span> <span class="s1">'Generate new sidekick file? (Y/n)'</span>
|
128
|
+
<span class="nb">gets</span> <span class="o">=~</span> <span class="sr">/^N|n/</span> <span class="p">?</span> <span class="nb">exit</span> <span class="p">:</span>
|
129
|
+
<span class="no">FileUtils</span><span class="o">.</span><span class="n">cp</span><span class="p">(</span><span class="no">File</span><span class="o">.</span><span class="n">expand_path</span><span class="p">(</span><span class="s1">'../template'</span><span class="p">,</span>
|
130
|
+
<span class="bp">__FILE__</span><span class="p">),</span> <span class="n">path</span><span class="p">)</span>
|
131
|
+
<span class="k">end</span>
|
132
|
+
<span class="k">end</span>
|
133
|
+
|
134
|
+
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">stop</span><span class="p">(</span><span class="n">msg</span><span class="o">=</span><span class="kp">false</span><span class="p">)</span>
|
135
|
+
<span class="no">EventMachine</span><span class="o">.</span><span class="n">stop</span>
|
136
|
+
<span class="nb">puts</span> <span class="s2">"</span><span class="se">\n</span><span class="si">#{</span><span class="n">msg</span><span class="si">}</span><span class="s2">"</span> <span class="k">if</span> <span class="n">msg</span>
|
137
|
+
<span class="k">end</span>
|
138
|
+
|
139
|
+
<span class="k">end</span></pre></div>
|
140
|
+
</td>
|
141
|
+
</tr>
|
142
|
+
</table>
|
143
|
+
</div>
|
144
|
+
</body>
|