gossip 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +9 -0
- data/LICENSE.txt +34 -0
- data/Manifest.txt +62 -0
- data/README.txt +6 -0
- data/Rakefile +137 -0
- data/examples/all-config-file-choices.yml +36 -0
- data/lib/gossip.rb +32 -0
- data/lib/gossip/command.rb +122 -0
- data/lib/gossip/cronies/campfire.rb +72 -0
- data/lib/gossip/cronies/jabber.rb +66 -0
- data/lib/gossip/cronies/smtp.rb +121 -0
- data/lib/gossip/cronies/stdout.rb +24 -0
- data/lib/gossip/cronies/trac.rb +82 -0
- data/lib/gossip/cronies/twitter.rb +50 -0
- data/lib/gossip/crony.rb +102 -0
- data/lib/gossip/multi-exceptions.rb +47 -0
- data/lib/gossip/preteen.rb +86 -0
- data/lib/gossip/site-config.rb +94 -0
- data/lib/gossip/social-universe.rb +18 -0
- data/lib/gossip/version.rb +8 -0
- data/pages/classes.html +58 -0
- data/pages/cronies.html +256 -0
- data/pages/css/LICENSE.txt +1 -0
- data/pages/css/Thumbs.db +0 -0
- data/pages/css/bg2.gif +0 -0
- data/pages/css/gossip5-header-flip.jpg +0 -0
- data/pages/css/left.gif +0 -0
- data/pages/css/left_on.gif +0 -0
- data/pages/css/main.css +242 -0
- data/pages/css/right.gif +0 -0
- data/pages/css/right_on.gif +0 -0
- data/pages/css/tvline.gif +0 -0
- data/pages/images/campfire.png +0 -0
- data/pages/images/classes.png +0 -0
- data/pages/images/deployment.png +0 -0
- data/pages/images/jabber-big.png +0 -0
- data/pages/images/jabber.png +0 -0
- data/pages/images/trac-bigger.png +0 -0
- data/pages/images/trac-detail.png +0 -0
- data/pages/images/twitter.png +0 -0
- data/pages/index.html +45 -0
- data/pages/installation.html +95 -0
- data/pages/scripts.html +166 -0
- data/pages/src/classes.graffle +0 -0
- data/pages/starting-to-use.html +200 -0
- data/pages/writing-new-scripts.html +38 -0
- data/scripts/fanout +64 -0
- data/scripts/svntell +71 -0
- data/scripts/watchdog +86 -0
- data/setup.rb +1585 -0
- data/test/script/fanout-slowtests.rb +40 -0
- data/test/script/svntell-slowtests.rb +40 -0
- data/test/script/util.rb +22 -0
- data/test/script/watchdog-slowtests.rb +56 -0
- data/test/unit/command-crony-interaction-tests.rb +116 -0
- data/test/unit/command-tests.rb +119 -0
- data/test/unit/crony-tests.rb +46 -0
- data/test/unit/multi-exception-tests.rb +70 -0
- data/test/unit/preteen-tests.rb +81 -0
- data/test/util/bff.rb +45 -0
- data/test/util/doghouse.rb +42 -0
- data/test/util/silly-little-test-program.rb +6 -0
- metadata +181 -0
Binary file
|
@@ -0,0 +1,200 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
4
|
+
<head>
|
5
|
+
<title>Gossip</title>
|
6
|
+
<meta http-equiv="Content-Type" content="application/xhtml+xml" />
|
7
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
8
|
+
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css" />
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<div id="pageBody">
|
12
|
+
<div id="outer-container">
|
13
|
+
<div id="container">
|
14
|
+
<div id="header">
|
15
|
+
<div id="headerLeft"></div>
|
16
|
+
<div id="headerRight"><h1>Gossip</h1><span class="highlight"><h2>tools for telling people things</h2></span></div>
|
17
|
+
</div>
|
18
|
+
<div id="headerNav">
|
19
|
+
<div id="centerNav">
|
20
|
+
<ul>
|
21
|
+
<li><a href="index.html">Home</a></li>
|
22
|
+
<li><a href="installation.html">Installation</a></li>
|
23
|
+
<li id="current"><a href="starting-to-use.html">Using Bundled Scripts</a></li>
|
24
|
+
<li><a href="writing-new-scripts.html">Writing Scripts</a></li>
|
25
|
+
<li><a href="rdoc">RDoc</a></li>
|
26
|
+
<li><a href="http://rubyforge.org/frs/?group_id=4455">Download</a></li>
|
27
|
+
</ul>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
<div id="content">
|
31
|
+
<div id="inlineTOC">
|
32
|
+
<ul>
|
33
|
+
<li><a href="starting-to-use.html">Getting started</a></li>
|
34
|
+
<ul>
|
35
|
+
<li><a href="starting-to-use.html#definitions">Three important words</a></li>
|
36
|
+
<li><a href="starting-to-use.html#config">Your own private configuration</a></li>
|
37
|
+
</ul>
|
38
|
+
<li><a href="cronies.html">All cronies</a></li>
|
39
|
+
<ul>
|
40
|
+
<li><a href="cronies.html#campfire">campfire</a></li>
|
41
|
+
<li><a href="cronies.html#jabber">jabber</a></li>
|
42
|
+
<li><a href="cronies.html#mail">mail</a></li>
|
43
|
+
<li><a href="cronies.html#stdout">standard output</a></li>
|
44
|
+
<li><a href="cronies.html#trac">trac</a></li>
|
45
|
+
<li><a href="cronies.html#twitter">twitter</a></li>
|
46
|
+
</ul>
|
47
|
+
<li><a href="scripts.html">All scripts</a></li>
|
48
|
+
<ul>
|
49
|
+
<li><a href="scripts.html#fanout">fanout: broadcast a message</a></li>
|
50
|
+
<li><a href="scripts.html#watchdog">watchdog: report on a script</a></li>
|
51
|
+
<li><a href="scripts.html#svntell">svntell: Subversion post-commit</a></li>
|
52
|
+
</ul>
|
53
|
+
</ul>
|
54
|
+
</div>
|
55
|
+
|
56
|
+
<h2><a name="definitions">Three important words</a></h2>
|
57
|
+
<p>
|
58
|
+
All of the scripts do two things: they <em>learn</em> a <strong>scandal</strong> and its <strong>details</strong> from somewhere, then they <em>send</em> what they've learned to one or more <strong>cronies</strong>. Decoding the cutesy metaphor:
|
59
|
+
</p>
|
60
|
+
|
61
|
+
<ul>
|
62
|
+
<li>
|
63
|
+
<p>
|
64
|
+
A <strong>scandal</strong> is a short piece of text, like the Subject line of an email message.
|
65
|
+
</p>
|
66
|
+
</li>
|
67
|
+
<li>
|
68
|
+
<p>
|
69
|
+
The <strong>details</strong> are, usually, a longer piece of text, like the body of an email message. The distinction is important because some cronies, like Twitter, only get the scandal and not the details.
|
70
|
+
</p>
|
71
|
+
</li>
|
72
|
+
<li>
|
73
|
+
<p>
|
74
|
+
<strong>Cronies</strong> represent a destination for the information. Cronies can be sites like <a href="http://twitter.com">Twitter</a> or <a href="http://www.campfirenow.com">Campfire</a>, or they can be programs like email or <a href="http://jabber.org">Jabber</a>.
|
75
|
+
</p>
|
76
|
+
</li>
|
77
|
+
</ul>
|
78
|
+
|
79
|
+
<h2><a name="config">Your own private configuration</a></h2>
|
80
|
+
<p>
|
81
|
+
Unless someone's already done it for you, there's a little work to do before you can use one of the Gossip scripts. You have to tell them where, by default, their messages should go. You <em>can</em> give all that information on the command line, but you likely don't want to. Instead, you want to put it in a configuration file.
|
82
|
+
</p>
|
83
|
+
|
84
|
+
<p>
|
85
|
+
The main Gossip configuration file is named <code>.gossip</code> (note the leading period) in your home directory. The home directory is defined as being whatever <a href="http://www.rubygems.org/read/chapter/12">RubyGems thinks
|
86
|
+
</a> it is. Entries in the configuration file apply to all Gossip scripts. You can override them with a script-specific configuration file. (You don't have to: you can put even script-specific configuration entries in <code>.gossip</code>.)
|
87
|
+
</p>
|
88
|
+
|
89
|
+
<p>Here is a sample configuration file, valid as of this writing. You can find the latest version in <code>examples/all-config-file-choices.yml</code> in the distribution. The file is in <a href="http://www.yaml.org/" title="YAML Ain't Markup Language">YAML</a> format.
|
90
|
+
</p>
|
91
|
+
<pre>
|
92
|
+
# Turn cronies (destinations) on or off.
|
93
|
+
|
94
|
+
standard-output: true
|
95
|
+
jabber: false
|
96
|
+
mail: false
|
97
|
+
campfire: false
|
98
|
+
trac: false
|
99
|
+
twitter: false
|
100
|
+
|
101
|
+
# Configurations for each destination.
|
102
|
+
# You can delete or ignore ones you don't plan to use.
|
103
|
+
|
104
|
+
jabber-account: jabber@example.com
|
105
|
+
jabber-password: not-the-real-one
|
106
|
+
jabber-to:
|
107
|
+
- brianmarick@example.com
|
108
|
+
|
109
|
+
mail-to:
|
110
|
+
- marick@example.com
|
111
|
+
- dawn@example.com
|
112
|
+
|
113
|
+
mail-from: bmarick@mac.com
|
114
|
+
mail-server: smtp.mac.com
|
115
|
+
mail-port: 587
|
116
|
+
mail-from-domain: localhost.localdomain
|
117
|
+
mail-account: bmarick
|
118
|
+
mail-password: not-the-real-one
|
119
|
+
mail-authentication: login
|
120
|
+
|
121
|
+
campfire-login: marick@example.com
|
122
|
+
campfire-password: not-the-real-one
|
123
|
+
campfire-subdomain: example
|
124
|
+
campfire-room: room
|
125
|
+
|
126
|
+
twitter-login: twittername
|
127
|
+
twitter-password: some password
|
128
|
+
</pre>
|
129
|
+
|
130
|
+
<p>
|
131
|
+
With luck, the names alone are enough for you to know what values to use. If not, <a href="cronies.html">look here</a> or ask for command-line help:
|
132
|
+
</p>
|
133
|
+
<pre>
|
134
|
+
$ scripts/fanout --help
|
135
|
+
Usage: ruby scripts/fanout [options] program args...
|
136
|
+
Site-wide defaults are noted below.
|
137
|
+
Override them in the '.fanoutrc' or '.gossiprc' files in your home folder.
|
138
|
+
|
139
|
+
Options:
|
140
|
+
--[no-]choices Show all configuration choices.
|
141
|
+
-s, --[no-]standard-output Control display to terminal (standard output).
|
142
|
+
Defaults to true.
|
143
|
+
-m, --[no-]mail Control mail notification.
|
144
|
+
Defaults to false.
|
145
|
+
-j, --[no-]jabber Control IM notification.
|
146
|
+
Defaults to false.
|
147
|
+
-c, --[no-]campfire Control display to Campfire chat room.
|
148
|
+
Defaults to false.
|
149
|
+
-t, --[no-]twitter Control whether Twitter updates are made.
|
150
|
+
Defaults to false.
|
151
|
+
--mail-to RECIPIENTS <strong>Recipients of mail.</strong>
|
152
|
+
This can be a comma-separated list.
|
153
|
+
Defaults to ["listener@example.com"].
|
154
|
+
--mail-from SENDER <strong>The sender of the mail (appears in From line).</strong>
|
155
|
+
Defaults to "watchdog@example.com".
|
156
|
+
--mail-server HOSTNAME <strong>SMTP server.</strong> Defaults to "example.com".
|
157
|
+
--mail-port NUMBER <strong>Mail port on that server.</strong>
|
158
|
+
Defaults to 25.
|
159
|
+
<em>...</em>
|
160
|
+
</pre>
|
161
|
+
|
162
|
+
<p>If you make a typo in the configuration file, Gossip will not complain. So it's useful to use the <code>--choices</code> argument to see that it's gotten the values you want:</p>
|
163
|
+
<pre>
|
164
|
+
$ scripts/fanout --choices
|
165
|
+
Looking for configuration information in:
|
166
|
+
/Users/marick/.fanoutrc
|
167
|
+
/Users/marick/.gossiprc
|
168
|
+
Choices gathered from all sources:
|
169
|
+
:arglist=>[]
|
170
|
+
:campfire=>false
|
171
|
+
:campfire_login=>"marick@example.com"
|
172
|
+
:campfire_password=>"not the real one"
|
173
|
+
:campfire_room=>"room"
|
174
|
+
:campfire_subdomain=>"example"
|
175
|
+
:choices=>true
|
176
|
+
:jabber=>false
|
177
|
+
:jabber_account=>"something@jabber.com"
|
178
|
+
:jabber_password=>"not the real one"
|
179
|
+
:jabber_to=>["brianmarick@jabber.se"]
|
180
|
+
...
|
181
|
+
</pre>
|
182
|
+
|
183
|
+
<p>
|
184
|
+
You can always override the configuration file from the command line.
|
185
|
+
</p>
|
186
|
+
|
187
|
+
<p style="text-align: center">
|
188
|
+
<a href="cronies.html">Next</a>: All cronies<br />
|
189
|
+
<a href="scripts.html">After that</a>: All scripts<br />
|
190
|
+
</p>
|
191
|
+
|
192
|
+
|
193
|
+
</div>
|
194
|
+
|
195
|
+
</div>
|
196
|
+
</div>
|
197
|
+
|
198
|
+
</body>
|
199
|
+
</html>
|
200
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
4
|
+
<head>
|
5
|
+
<title>Gossip</title>
|
6
|
+
<meta http-equiv="Content-Type" content="application/xhtml+xml" />
|
7
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
8
|
+
<link rel="stylesheet" type="text/css" media="screen" href="css/main.css" />
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<div id="pageBody">
|
12
|
+
<div id="outer-container">
|
13
|
+
<div id="container">
|
14
|
+
<div id="header">
|
15
|
+
<div id="headerLeft"></div>
|
16
|
+
<div id="headerRight"><h1>Gossip</h1><span class="highlight"><h2>tools for telling people things</h2></span></div>
|
17
|
+
</div>
|
18
|
+
<div id="headerNav">
|
19
|
+
<div id="centerNav">
|
20
|
+
<ul>
|
21
|
+
<li><a href="index.html">Home</a></li>
|
22
|
+
<li><a href="installation.html">Installation</a></li>
|
23
|
+
<li><a href="starting-to-use.html">Using Bundled Scripts</a></li>
|
24
|
+
<li id="current"><a href="writing-new-scripts.html">Writing Scripts</a></li>
|
25
|
+
<li><a href="rdoc">RDoc</a></li>
|
26
|
+
<li><a href="http://rubyforge.org/frs/?group_id=4455">Download</a></li>
|
27
|
+
</ul>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
<div id="content">
|
31
|
+
<h2>Writing new scripts</h2>
|
32
|
+
<p>There is nothing here yet. You might find an <a href="classes.html">annotated picture of the important classes helpful</a>.
|
33
|
+
</div>
|
34
|
+
</div>
|
35
|
+
</div>
|
36
|
+
</body>
|
37
|
+
</html>
|
38
|
+
|
data/scripts/fanout
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Created by Brian Marick on 2007-09-15.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
require 's4t-utils'
|
7
|
+
include S4tUtils
|
8
|
+
set_script_lib_path(__FILE__)
|
9
|
+
|
10
|
+
require 'gossip'
|
11
|
+
include Gossip
|
12
|
+
|
13
|
+
# You may want to replace this. See the installation documentation.
|
14
|
+
require 'gossip/site-config'
|
15
|
+
|
16
|
+
class Fanout < GossipCommand
|
17
|
+
|
18
|
+
def script_config_file; ".fanoutrc"; end
|
19
|
+
|
20
|
+
def usage
|
21
|
+
["Usage: ruby #{$0} arg... < details",
|
22
|
+
"The arguments are the scandal to gossip about."]
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
FANOUT_DEFAULT = true
|
28
|
+
def add_choices_specific_to_script(builder)
|
29
|
+
builder.add_choice(:fanout_details,
|
30
|
+
:type => :boolean,
|
31
|
+
:default => FANOUT_DEFAULT) { | command_line |
|
32
|
+
command_line.uses_switch("--details",
|
33
|
+
"Collect details from standard input?",
|
34
|
+
"Defaults to #{FANOUT_DEFAULT}.",
|
35
|
+
"If false, standard input is not read.")
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def postprocess_user_choices
|
41
|
+
super
|
42
|
+
|
43
|
+
# This is checked here, instead of giving a range to uses_arglist,
|
44
|
+
# so that the actual choices can be printed out with -c without
|
45
|
+
# having to give an argument.
|
46
|
+
if @user_choices.has_key?(:arglist) && @user_choices[:arglist].empty?
|
47
|
+
raise "You need to give some sort of summary on the command line."
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def execute
|
52
|
+
scandal = @user_choices[:arglist].join(' ')
|
53
|
+
details = @user_choices[:fanout_details] ? $stdin.read : ''
|
54
|
+
preteen.tell_bffs(scandal, details)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
if $0 == __FILE__
|
60
|
+
# You can replace "with" with "without" to get full stack traces.
|
61
|
+
with_pleasant_exceptions do
|
62
|
+
Fanout.new(Preteen.new(CronyMaker, BFFS, ON_THE_OUTS)).execute
|
63
|
+
end
|
64
|
+
end
|
data/scripts/svntell
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-09-15.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
require 's4t-utils'
|
7
|
+
include S4tUtils
|
8
|
+
set_script_lib_path(__FILE__)
|
9
|
+
|
10
|
+
require 'gossip'
|
11
|
+
include Gossip
|
12
|
+
|
13
|
+
# You may want to replace this. See the installation documentation.
|
14
|
+
require 'gossip/site-config'
|
15
|
+
BFFS.delete(:trac) # Don't use this to post svn logs - trac does that better already.
|
16
|
+
|
17
|
+
require 'snitch'
|
18
|
+
|
19
|
+
|
20
|
+
class SvnTell < GossipCommand
|
21
|
+
|
22
|
+
def script_config_file; ".svntellrc"; end
|
23
|
+
|
24
|
+
def usage
|
25
|
+
"Usage: ruby #{$0} --repository PATH --revision REV"
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def add_choices_specific_to_script(builder)
|
30
|
+
builder.add_choice(:svn_repository) { | command_line |
|
31
|
+
command_line.uses_option("--repository REP",
|
32
|
+
"Absolute path of subversion repository.")
|
33
|
+
}
|
34
|
+
|
35
|
+
builder.add_choice(:svn_revision) { | command_line |
|
36
|
+
command_line.uses_option("--revision REV",
|
37
|
+
"Revision number of interest.")
|
38
|
+
}
|
39
|
+
|
40
|
+
svnlook_default = "/usr/bin/svnlook"
|
41
|
+
builder.add_choice(:svnlook_path,
|
42
|
+
:default => svnlook_default) { | command_line |
|
43
|
+
command_line.uses_option("--svnlook-path PATH",
|
44
|
+
"Absolute path of svnlook(1).",
|
45
|
+
"Default is #{svnlook_default}.")
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def execute
|
50
|
+
repository = @user_choices[:svn_repository]
|
51
|
+
revision = @user_choices[:svn_revision]
|
52
|
+
svnlook_path = @user_choices[:svnlook_path]
|
53
|
+
|
54
|
+
user_claims(repository) { "You must choose a repository."}
|
55
|
+
user_claims(revision) { "You must choose a revision."}
|
56
|
+
user_claims(File.exists?(svnlook_path)) {
|
57
|
+
"svnlook path '#{svnlook_path}' does not exist."
|
58
|
+
}
|
59
|
+
|
60
|
+
svnlook = Snitch::SvnLook.new(repository, revision, svnlook_path)
|
61
|
+
preteen.tell_bffs("Commit by #{svnlook.author}", svnlook.to_s)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
if $0 == __FILE__
|
67
|
+
# You can replace "with" with "without" to get full stack traces.
|
68
|
+
with_pleasant_exceptions do
|
69
|
+
SvnTell.new(Preteen.new(CronyMaker, BFFS, ON_THE_OUTS)).execute
|
70
|
+
end
|
71
|
+
end
|
data/scripts/watchdog
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-09-15.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
require 's4t-utils'
|
7
|
+
include S4tUtils
|
8
|
+
set_script_lib_path(__FILE__)
|
9
|
+
|
10
|
+
require 'gossip'
|
11
|
+
include Gossip
|
12
|
+
|
13
|
+
require 'open3'
|
14
|
+
|
15
|
+
# You may want to replace this. See the installation documentation.
|
16
|
+
require 'gossip/site-config'
|
17
|
+
|
18
|
+
class Watchdog < GossipCommand
|
19
|
+
|
20
|
+
def usage
|
21
|
+
"Usage: ruby #{$0} [options] program args..."
|
22
|
+
end
|
23
|
+
|
24
|
+
def script_config_file; '.watchdogrc'; end
|
25
|
+
|
26
|
+
def postprocess_user_choices
|
27
|
+
super
|
28
|
+
|
29
|
+
# This is checked here, instead of giving a range to uses_arglist,
|
30
|
+
# so that the actual choices can be printed out with -c without
|
31
|
+
# having to give an argument.
|
32
|
+
if @user_choices.has_key?(:arglist) && @user_choices[:arglist].empty?
|
33
|
+
raise "No command to run was given."
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
def execute
|
39
|
+
scandal = "Program #{self.command_name} finished."
|
40
|
+
duration, details = time {
|
41
|
+
`#{self.command_string} 2>&1`
|
42
|
+
}
|
43
|
+
preteen.tell_bffs(scandal, message(duration, details))
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# Only tests should call from outside.
|
48
|
+
|
49
|
+
def time
|
50
|
+
start = Time.now
|
51
|
+
retval = yield
|
52
|
+
duration = Time.now - start
|
53
|
+
[duration, retval]
|
54
|
+
end
|
55
|
+
|
56
|
+
def command_string(command_to_watch =
|
57
|
+
@user_choices[:arglist])
|
58
|
+
command_to_watch.join(' ')
|
59
|
+
end
|
60
|
+
|
61
|
+
def command_name(command_to_watch = @user_choices[:arglist])
|
62
|
+
progname = if command_to_watch[0] == 'ruby'
|
63
|
+
command_to_watch[1]
|
64
|
+
else
|
65
|
+
command_to_watch[0]
|
66
|
+
end
|
67
|
+
File.basename(progname)
|
68
|
+
end
|
69
|
+
|
70
|
+
def message(duration, text)
|
71
|
+
[
|
72
|
+
"Duration: #{duration} seconds.",
|
73
|
+
"Command: #{command_string}",
|
74
|
+
"Output:",
|
75
|
+
text.indent_by(2),
|
76
|
+
].join($/)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
if $0 == __FILE__
|
82
|
+
# You can replace "with" with "without" to get full stack traces.
|
83
|
+
with_pleasant_exceptions do
|
84
|
+
Watchdog.new(Preteen.new(CronyMaker, BFFS, ON_THE_OUTS)).execute
|
85
|
+
end
|
86
|
+
end
|