sidekick 0.5.1 → 0.6.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.
data/.gitignore CHANGED
@@ -18,5 +18,6 @@ coverage
18
18
  rdoc
19
19
  pkg
20
20
  test/output
21
+ sidekick.gemspec
21
22
 
22
23
  ## PROJECT::SPECIFIC
@@ -0,0 +1,3 @@
1
+ [submodule "website"]
2
+ path = website
3
+ url = git@github.com:jbe/sidekick.git
@@ -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
- "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.
5
+ <pre><code>
6
+ watch('**/*.rb') { restart_passenger }
5
7
 
6
- h3. Use cases
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
- * Compile Sass and CoffeeScript templates when they are updated
16
+ * Auto-compile Sass or CoffeeScript templates (and many other languages)
10
17
  * Periodically run commands
11
- * Continuous testing, with notifications and flexible hooks
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 ("examples":http://github.com/jbe/sidekick/blob/master/lib/template).
22
+ * Simple and powerful DSL
18
23
  * Easy to extend
19
- * Compiles many languages, thanks to "Tilt":http://github.com/rtomayko/tilt.
24
+ * Compiles many formats, thanks to "Tilt":http://github.com/rtomayko/tilt.
20
25
  * Powered by "EventMachine":http://github.com/eventmachine/eventmachine
21
- * Short "core library":http://github.com/jbe/sidekick/blob/master/lib/sidekick.rb -- about 70 lines of code.
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 using the @sidekick@ command in your project folder. If you do not have a @.sidekick@ file, you will be offered a template.
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
- Read the source to see all available "triggers":http://github.com/jbe/sidekick/blob/master/lib/sidekick/triggers.rb and "helpers":http://github.com/jbe/sidekick/blob/master/lib/sidekick/helpers.rb.
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/jbe/sidekick/blob/master/lib/sidekick/triggers.rb, 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 { .. }@.
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.5.1
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 &hellip;
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">&#39;fileutils&#39;</span>
39
+ <span class="nb">require</span> <span class="s1">&#39;rbconfig&#39;</span>
40
+ <span class="nb">require</span> <span class="s1">&#39;tilt&#39;</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">&#39;sidekick/helpers/util&#39;</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">&#39; -&gt; &#39;</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">&#39;Sidekick&#39;</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">=&gt;</span> <span class="s1">&#39;libnotify&#39;</span><span class="p">,</span> <span class="ss">:darwin</span> <span class="o">=&gt;</span> <span class="s1">&#39;growl&#39;</span><span class="p">}</span>
85
+
86
+ <span class="n">stop</span><span class="p">(</span><span class="s1">&#39;Notifications not supported.&#39;</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">&#39;notifications&#39;</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">=&gt;</span> <span class="n">message</span><span class="p">,</span> <span class="ss">:summary</span> <span class="o">=&gt;</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">=&gt;</span> <span class="n">title</span><span class="p">,</span> <span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s1">&#39;Sidekick&#39;</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">&#39;./tmp/restart.txt&#39;</span>
104
+ <span class="n">log</span> <span class="s1">&#39;restarted passenger&#39;</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">&#39;:name&#39;</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">&#39;.*&#39;</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">&#39;w&#39;</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">&quot;render </span><span class="si">#{</span><span class="n">file</span><span class="si">}</span><span class="s2"> =&gt; </span><span class="si">#{</span><span class="n">t</span><span class="si">}</span><span class="s2">&quot;</span>
129
+ <span class="k">rescue</span> <span class="no">Exception</span> <span class="o">=&gt;</span> <span class="n">e</span>
130
+ <span class="n">notify</span> <span class="s2">&quot;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">&quot;</span>
131
+ <span class="n">log</span> <span class="s2">&quot;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">&quot;</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 &hellip;
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 &ndash; 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> &mdash; <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> &mdash; <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">&#39;fileutils&#39;</span>
49
+ <span class="nb">require</span> <span class="s1">&#39;eventmachine&#39;</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. &mdash; 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&rsquo;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">&amp;</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">&amp;</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">&#39;sidekick/triggers&#39;</span>
100
+ <span class="nb">require</span> <span class="s1">&#39;sidekick/helpers&#39;</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">&#39;.sidekick&#39;</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">&#39;Generate new sidekick file? (Y/n)&#39;</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">&#39;../template&#39;</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">&quot;</span><span class="se">\n</span><span class="si">#{</span><span class="n">msg</span><span class="si">}</span><span class="s2">&quot;</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 &ndash; 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> &mdash; <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> &mdash; <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">&#39;fileutils&#39;</span>
38
+ <span class="nb">require</span> <span class="s1">&#39;eventmachine&#39;</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. &mdash; 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&rsquo;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">&amp;</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">&amp;</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">&#39;sidekick/triggers&#39;</span>
89
+ <span class="nb">require</span> <span class="s1">&#39;sidekick/helpers&#39;</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">&#39;.sidekick&#39;</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">&#39;Generate new sidekick file? (Y/n)&#39;</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">&#39;../template&#39;</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">&quot;</span><span class="se">\n</span><span class="si">#{</span><span class="n">msg</span><span class="si">}</span><span class="s2">&quot;</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>