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
@@ -0,0 +1,47 @@
|
|
1
|
+
#! /opt/local/bin/ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-09-15.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
|
7
|
+
|
8
|
+
require 'thread'
|
9
|
+
|
10
|
+
class Queue # :nodoc:
|
11
|
+
def to_a
|
12
|
+
result = []
|
13
|
+
until empty?
|
14
|
+
result << self.pop
|
15
|
+
end
|
16
|
+
result
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module Gossip
|
21
|
+
# This collects exceptions from several threads and packages them up
|
22
|
+
# into a single exception.
|
23
|
+
class MultiException < StandardError
|
24
|
+
|
25
|
+
attr_reader :traces
|
26
|
+
|
27
|
+
def initialize(exceptions)
|
28
|
+
messages = exceptions.collect { | ex | "#{ex.to_s} (#{ex.class})" }
|
29
|
+
super(messages.join("\n"))
|
30
|
+
@traces = exceptions.collect { | ex | ex.backtrace }
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.reraise_with_combined_backtrace
|
34
|
+
yield
|
35
|
+
rescue MultiException => ex
|
36
|
+
ex.traces.each_with_index { | trace, index |
|
37
|
+
trace.unshift("Trace number #{index}:\n")
|
38
|
+
}
|
39
|
+
ex.set_backtrace(ex.traces.flatten)
|
40
|
+
raise
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#! /opt/local/bin/ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-09-15.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
require 'gossip/multi-exceptions'
|
7
|
+
require 'gossip/crony'
|
8
|
+
|
9
|
+
module Gossip
|
10
|
+
|
11
|
+
# A Preteen is someone who tells her Best Friends Forever some gossip.
|
12
|
+
# Each BFF is a Crony, but some Cronies can be out of favor during a
|
13
|
+
# particular invocation of a script. A Crony who's out of favor is not
|
14
|
+
# told the gossip.
|
15
|
+
class Preteen
|
16
|
+
include Gossip
|
17
|
+
|
18
|
+
attr_reader :cronies
|
19
|
+
|
20
|
+
# The second and third arguments are symbols that name Crony subclasses.
|
21
|
+
# (See Crony#symbol.) The first
|
22
|
+
# set will hear gossip; the second will not. The _cronymaker_ is a hash.
|
23
|
+
# It is indexed by crony symbol. The values are blocks that first load
|
24
|
+
# the Crony subclass's source, then return a new crony of that class.
|
25
|
+
def initialize(cronymaker = {}, bff =[], on_the_outs_forever_and_ever_until_tomorrow=[])
|
26
|
+
@cronies = []
|
27
|
+
(bff+on_the_outs_forever_and_ever_until_tomorrow).each do | name |
|
28
|
+
user_claims(cronymaker.has_key?(name)) {
|
29
|
+
"#{name.inspect} is not a known crony."
|
30
|
+
}
|
31
|
+
crony = cronymaker[name].call
|
32
|
+
crony.is_bff_by_default = bff.include?(name)
|
33
|
+
accept(crony)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def accept(*cronies) # :nodoc:
|
38
|
+
@cronies += cronies
|
39
|
+
end
|
40
|
+
|
41
|
+
# Tell Crony objects who are in favor (best friends forever) a _scandal_
|
42
|
+
# and its _details_. The _scandal_ should be short - think an email
|
43
|
+
# Subject line.
|
44
|
+
def tell_bffs(scandal, details)
|
45
|
+
simultaneously do | crony |
|
46
|
+
crony.hear(scandal, details) if crony.is_bff?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def annotate(exception, crony)
|
55
|
+
# Note: cannot raise exception.class because on Windows the
|
56
|
+
# exception message for Net errors will contain duplicate errors.
|
57
|
+
# This is annoying because with_pleasant_exceptions appends the
|
58
|
+
# exception class. So we have to append it ourselves.
|
59
|
+
annotated = StandardError.new("Complaint from #{crony.name}: #{exception.to_s} (#{exception.class})")
|
60
|
+
annotated.set_backtrace(exception.backtrace)
|
61
|
+
annotated
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def simultaneously # execute block in thread
|
66
|
+
Thread.abort_on_exception = false
|
67
|
+
queue = Queue.new
|
68
|
+
threads = @cronies.collect do | crony |
|
69
|
+
Thread.new(crony) do | crony |
|
70
|
+
begin
|
71
|
+
yield(crony)
|
72
|
+
rescue Exception => ex
|
73
|
+
queue << annotate(ex, crony)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
threads.each { | thread | thread.join }
|
78
|
+
# This peculiarness is the way to set the exception's
|
79
|
+
# backtrace with the combination of the backtraces of
|
80
|
+
# all saved exceptions (if any)
|
81
|
+
MultiException.reraise_with_combined_backtrace {
|
82
|
+
raise MultiException.new(queue.to_a) if queue.length > 0
|
83
|
+
}
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-09-23.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
# Suppose you want to use many of these example programs. Chances are, you
|
7
|
+
# want each one to use the same site-wide defaults. Change this config file,
|
8
|
+
# put it somewhere, and change the examples you use to load it.
|
9
|
+
|
10
|
+
# CHANGE: These arrays describe the destinations for gossip messages.
|
11
|
+
# Unless defaults are overridden, output will go only to the BFFS
|
12
|
+
# The difference between ON_THE_OUTS and TOTAL_OUTSIDERS is that the
|
13
|
+
# user can override ON_THE_OUTS. For example, the -j command-line
|
14
|
+
# option will cause messages to be sent to Jabber. A TOTAL_OUTSIDER
|
15
|
+
# can never be sent a message. This is useful because, for example,
|
16
|
+
# you don't even need to have the twitter gem on your system when
|
17
|
+
# :twitter is a TOTAL_OUTSIDER.
|
18
|
+
|
19
|
+
BFFS = [:standard_output] # By default, gossip with these
|
20
|
+
ON_THE_OUTS = [:mail, :jabber, :campfire, :twitter, :trac] # By default, do not gossip with these.
|
21
|
+
TOTAL_OUTSIDERS = [] # These will never ever gossiped with.
|
22
|
+
|
23
|
+
|
24
|
+
# CHANGE: The following sets those values the program will use unless the
|
25
|
+
# invoker overrides them on either (or both) the command line or YAML
|
26
|
+
# configuration file. If you do not intend to use one of the destinations
|
27
|
+
# (twitter, say), you can just ignore the values.
|
28
|
+
|
29
|
+
when_not_TOTALLY_out_of_the_social_scene :jabber do
|
30
|
+
require 'gossip/cronies/jabber'
|
31
|
+
JabberCrony.new(:default_to => ['listener@example.com', 'other@example.com'],
|
32
|
+
:default_account => 'watchdog@example.com',
|
33
|
+
:default_password => 'jabber password')
|
34
|
+
end
|
35
|
+
|
36
|
+
when_not_TOTALLY_out_of_the_social_scene :mail do
|
37
|
+
require 'gossip/cronies/smtp'
|
38
|
+
SmtpCrony.new(:default_to => ['listener@example.com', 'other@example.com'],
|
39
|
+
:default_from => 'watchdog@example.com',
|
40
|
+
:default_from_domain => 'localhost',
|
41
|
+
:default_smtp_server => 'example.com',
|
42
|
+
:default_smtp_port => 25,
|
43
|
+
:default_smtp_account => 'watchdog',
|
44
|
+
:default_smtp_password => 'mail password',
|
45
|
+
:default_smtp_authentication => 'login')
|
46
|
+
end
|
47
|
+
|
48
|
+
when_not_TOTALLY_out_of_the_social_scene :campfire do
|
49
|
+
require 'gossip/cronies/campfire'
|
50
|
+
CampfireCrony.new(:default_login => 'watchdog@example.com',
|
51
|
+
:default_password => 'campfire password',
|
52
|
+
:default_subdomain => 'project',
|
53
|
+
:default_room => 'activity')
|
54
|
+
end
|
55
|
+
|
56
|
+
when_not_TOTALLY_out_of_the_social_scene :trac do
|
57
|
+
require 'gossip/cronies/trac'
|
58
|
+
TracCrony.new(:default_trac_admin_path => '/usr/local/bin/trac-admin',
|
59
|
+
:default_environment_path => '/home/user/trac_env1',
|
60
|
+
:default_page_name => 'AnnouncingSuccessfulDeployment',
|
61
|
+
:default_content_file => '/home/user/tmp/deployment')
|
62
|
+
end
|
63
|
+
|
64
|
+
when_not_TOTALLY_out_of_the_social_scene :twitter do
|
65
|
+
require 'gossip/cronies/twitter'
|
66
|
+
TwitterCrony.new(:default_login => 'marick@exampler.com',
|
67
|
+
:default_password => 'twitter password')
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
when_not_TOTALLY_out_of_the_social_scene :standard_output do
|
72
|
+
require 'gossip/cronies/stdout'
|
73
|
+
StdoutCrony.new
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
|
78
|
+
# CHANGE: add_sources if, for example, you want to override defaults using an
|
79
|
+
# XML file instead of a YAML file.
|
80
|
+
|
81
|
+
class GossipCommand
|
82
|
+
|
83
|
+
# This is the name (in the home directory) of the config file that
|
84
|
+
# applies to all Gossip scripts.
|
85
|
+
def gossip_config_file; ".gossiprc"; end
|
86
|
+
|
87
|
+
|
88
|
+
# Determine how the user can override defaults.
|
89
|
+
def add_sources(builder)
|
90
|
+
builder.add_source(PosixCommandLineSource, :usage, *describe_all_but_options)
|
91
|
+
builder.add_source(YamlConfigFileSource, :from_file, script_config_file)
|
92
|
+
builder.add_source(YamlConfigFileSource, :from_file, gossip_config_file)
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# Created by Brian Marick on 2007-09-17.
|
4
|
+
# Copyright (c) 2007. All rights reserved.
|
5
|
+
|
6
|
+
module Gossip
|
7
|
+
|
8
|
+
CronyMaker = {}
|
9
|
+
|
10
|
+
# Syntactic sugar to associate a symbol naming a Crony subclass
|
11
|
+
# with a block that knows how to load that class and create an object
|
12
|
+
# from it. The symbol must be one returned by Crony#symbol.
|
13
|
+
|
14
|
+
def when_not_TOTALLY_out_of_the_social_scene(crony, &crony_maker)
|
15
|
+
CronyMaker[crony] = crony_maker
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/pages/classes.html
ADDED
@@ -0,0 +1,58 @@
|
|
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="all" 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><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>The pieces</h2>
|
32
|
+
<p>
|
33
|
+
<img alt="A class diagram of sorts" src="images/classes.png" class="right" />
|
34
|
+
A gossip script doesn't do much more than configure a GossipCommand subclass and then tell it what to do. See "Using Bundled Scripts" for how configuration works.
|
35
|
+
</p>
|
36
|
+
<p>
|
37
|
+
Gossip uses preteens as its <a href="http://c2.com/xp/SystemMetaphor.html" title="System Metaphor">system metaphor</a>. However, the reader should not assume that the metaphor was inspired by any <em>particular</em> 11-year-old and her social circle. Nor does the use of the variable <code>sophie</code> in the tests mean anything at all. No sirree.
|
38
|
+
</p>
|
39
|
+
|
40
|
+
<p>
|
41
|
+
In any case, the GossipCommand's <code>execute</code> sends a Preteen a tell_bff message to have her tell some scandal and its details to her Best Friends Forever (her bffs). These bffs have names like <code>:twitter</code>, <code>:jabber</code>, or <code>:trac</code>. They are instances of the Crony class (more precisely, of a Crony subclass).
|
42
|
+
</p>
|
43
|
+
|
44
|
+
<p>
|
45
|
+
Notice that the "best" in "Best Friends Forever" is not to be taken literally. It is quite typical to have more than one bff. Similarly, "forever" is more an an aspiration than a literal fact. The set of bffs can change from one invocation of the script to another (according to changes in configuration files or command-line options).
|
46
|
+
</p>
|
47
|
+
<p>
|
48
|
+
Cronies who are not currently in the set of bffs do not hear the gossip.
|
49
|
+
</p>
|
50
|
+
<p>
|
51
|
+
Outside the world of the Preteen and her Cronies, there are—theoretically—other people. However, it is inconceivable that they could ever become a Crony, so they can be ignored. (That means that a person writing a script could provide no <code>--trac</code> option. You might do that if you don't use Trac on your project.)
|
52
|
+
</p>
|
53
|
+
</div>
|
54
|
+
</div>
|
55
|
+
</div>
|
56
|
+
</body>
|
57
|
+
</html>
|
58
|
+
|
data/pages/cronies.html
ADDED
@@ -0,0 +1,256 @@
|
|
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
|
+
<h2>The different cronies</h2>
|
56
|
+
|
57
|
+
<p>
|
58
|
+
Here are the capsule descriptions:
|
59
|
+
</p>
|
60
|
+
|
61
|
+
<ul>
|
62
|
+
<li>
|
63
|
+
<p>
|
64
|
+
The <strong><a href="#campfire">campfire crony</a></strong> talks to <a href="http://campfirenow.com/" title="Business chat for groups: Campfire">Campfire</a>, a browser-based chat room.
|
65
|
+
</p>
|
66
|
+
</li>
|
67
|
+
<li>
|
68
|
+
<p>
|
69
|
+
The <strong><a href="#jabber">jabber crony</a></strong> talks <a href="http://www.jabber.org/" title="Jabber: Open Instant Messaging and a Whole Lot More, Powered by XMPP">Jabber</a>, a chat protocol with servers that are easy to set up, making it nice for workgroups.
|
70
|
+
</p>
|
71
|
+
</li>
|
72
|
+
<li>
|
73
|
+
<p>
|
74
|
+
The <strong><a href="#mail">mail crony</a></strong> speaks to email servers via the SMTP protocol. SSL is not supported.
|
75
|
+
</p>
|
76
|
+
</li>
|
77
|
+
<li>
|
78
|
+
<p>
|
79
|
+
The <strong><a href="#stdout">standard output crony</a></strong> just sends mail to standard output (the current window). It's useful checking whether (for example), you're using <code>watchdog</code> correctly before blasting the results to the entire world.
|
80
|
+
</p>
|
81
|
+
</li>
|
82
|
+
<li>
|
83
|
+
<p>
|
84
|
+
The <strong><a href="#trac">trac crony</a></strong> puts a notice in a <a href="http://trac.edgewall.org/" title="The Trac Project - Trac">Trac</a> timeline.
|
85
|
+
</p>
|
86
|
+
</li>
|
87
|
+
<li>
|
88
|
+
<p>
|
89
|
+
The <strong><a href="#twitter">twitter crony</a></strong> sends an update to a <a href="http://twitter.com/home" title="Twitter">Twitter</a> account.
|
90
|
+
</p>
|
91
|
+
</li>
|
92
|
+
</ul>
|
93
|
+
|
94
|
+
<h2><a name="campfire">Campfire</a></h2>
|
95
|
+
<p>My configuration file turns the <code>campfile</code> crony off. I can turn it on with the <code>-c</code> (or <code>--campfire</code>) option, like this:
|
96
|
+
|
97
|
+
<pre>
|
98
|
+
% watchdog -c rake
|
99
|
+
</pre>
|
100
|
+
|
101
|
+
<p>
|
102
|
+
The result at wevouchfor.campfirenow.com looks like this:
|
103
|
+
</p>
|
104
|
+
|
105
|
+
<img class="center" src="images/campfire.png" />
|
106
|
+
|
107
|
+
|
108
|
+
<p>
|
109
|
+
The scandal is the first line of the message; the details are the rest.
|
110
|
+
</p>
|
111
|
+
<p>
|
112
|
+
To use the <code>campfire</code> crony, you must have a <a href="http://campfirenow.com/" title="Business chat for groups: Campfire">Campfire</a> account with a chat room set up. Set the following in a configuration file or on the command line:
|
113
|
+
</p>
|
114
|
+
|
115
|
+
<ul>
|
116
|
+
<li><strong>campfire-login</strong>: Usually an email address.</li>
|
117
|
+
<li><strong>campfire-password</strong></li>
|
118
|
+
<li><strong>campfire-subdomain</strong>: Each campfire group gets its own subdomain. Mine is <a href="http://wevouchfor.campfirenow.com/" title="We Vouch For...">http://wevouchfor.campfirenow.com</a>. So my value for this choice is <code>wevouchfor</code>.</li>
|
119
|
+
<li><strong>campfire-room</strong>: A group can have multiple rooms, each with its own name. The one I've used in this case is <code>wevouchfor activity</code>.</li>
|
120
|
+
</ul>
|
121
|
+
|
122
|
+
<h2><a name="jabber">Jabber</a></h2>
|
123
|
+
<p>
|
124
|
+
Here is an example of a continuous build server telling jabber (and perhaps other cronies) about a broken build:
|
125
|
+
</p>
|
126
|
+
|
127
|
+
<img class="center" src="images/jabber-big.png" />
|
128
|
+
|
129
|
+
<p>
|
130
|
+
The scandal is the first line of the message; the details are the rest.
|
131
|
+
</p>
|
132
|
+
|
133
|
+
<p>
|
134
|
+
To use the <code>jabber</code> crony, you must have an account on some <a href="http://www.jabber.org/" title="Jabber: Open Instant Messaging and a Whole Lot More, Powered by XMPP">Jabber</a> server. In this example, Jabber messages come from <code>huivoufor@jabber.se</code>.
|
135
|
+
</p>
|
136
|
+
|
137
|
+
|
138
|
+
<ul>
|
139
|
+
<li><strong>jabber-account</strong>: <code>huivoufor@jabber.se</code>, in this case.</li>
|
140
|
+
<li><strong>jabber-password</strong></li>
|
141
|
+
<li><strong>jabber-to</strong>: One or more accounts to sent to. In YAML, that would look like this:
|
142
|
+
<pre>
|
143
|
+
jabber-to:
|
144
|
+
- brianmarick@jabberplace.org
|
145
|
+
- someone@xmpphost.org
|
146
|
+
</pre>
|
147
|
+
|
148
|
+
<p>If you only want one account to receive the message, you can abbreviate
|
149
|
+
the YAML to this:
|
150
|
+
</p>
|
151
|
+
<pre>
|
152
|
+
jabber-to: brianmarick@jabberplace.org
|
153
|
+
</pre>
|
154
|
+
|
155
|
+
<p>One the command line, multiple accounts are separated by commas, like this:
|
156
|
+
<pre>
|
157
|
+
--jabber-to=fred@example.com,brianmarick@example.com
|
158
|
+
</pre>
|
159
|
+
|
160
|
+
</li>
|
161
|
+
</ul>
|
162
|
+
|
163
|
+
<h2><a name="mail">Mail</a></h2>
|
164
|
+
<p>
|
165
|
+
When mail is sent, the scandal is used as the subject line and the details are put into the body. Here are the choices you have to make:
|
166
|
+
</p>
|
167
|
+
<ul>
|
168
|
+
<li><strong>mail-from</strong>: What's put in the From line of the mail message.</li>
|
169
|
+
<li><strong>mail-to</strong>: The intended recipients.
|
170
|
+
<pre>
|
171
|
+
mail-to:
|
172
|
+
- marick@example.com
|
173
|
+
- person@example.org
|
174
|
+
</pre>
|
175
|
+
|
176
|
+
<p>If you only want one account to receive the mail, you can abbreviate
|
177
|
+
the YAML to this:
|
178
|
+
</p>
|
179
|
+
<pre>
|
180
|
+
mail-to: marick@example.com
|
181
|
+
</pre>
|
182
|
+
|
183
|
+
<p>One the command line, multiple accounts are separated by commas, like this:
|
184
|
+
<pre>
|
185
|
+
--mail-to=marick@example.com,person@example.com
|
186
|
+
</pre>
|
187
|
+
</li>
|
188
|
+
<li><strong>mail-server</strong>: An SMTP server.</li>
|
189
|
+
<li><strong>mail-port</strong></li>
|
190
|
+
<li><strong>mail-from-domain</strong>: The domain the mail claims to be from. Some SMTP servers look at this. The default is localhost.</li>
|
191
|
+
<li><strong>mail-account</strong>: An account on the server. Not necessarily the same as <code>mail-from</code>.</li>
|
192
|
+
<li><strong>mail-authentication</strong>: One of <code>plain</code>, <code>login</code>, or <code>cram_md5</code>.</li>
|
193
|
+
<li><strong>mail-password</strong></li>
|
194
|
+
</ul>
|
195
|
+
|
196
|
+
<h2><a name="stdout">Standard output</a></h2>
|
197
|
+
<p>This crony just prints the scandal and details to the current terminal window. There are no options.</p>
|
198
|
+
<h2><a name="trac">Trac</a></h2>
|
199
|
+
<p>
|
200
|
+
The <code>trac</code> crony puts a notice in the <a href="http://trac.edgewall.org/" title="The Trac Project - Trac">Trac</a> timeline, where it looks like this:
|
201
|
+
</p>
|
202
|
+
|
203
|
+
<img class="center" src="images/trac-bigger.png" />
|
204
|
+
|
205
|
+
<p>
|
206
|
+
The mechanism is a hack. To do it right, you'd have to write a plugin and enable XMP/RPC and whatnot. So the implementation is to edit a Wiki page, turning the scandal into a header and putting the details below it. That looks like this:
|
207
|
+
</p>
|
208
|
+
|
209
|
+
<img class="center" src="images/trac-detail.png" />
|
210
|
+
|
211
|
+
<p>
|
212
|
+
Then, if the Trac timeline is set to display changes to Wiki pages (configurable per-user on the Timeline page), the changed page's title will appear in the Timeline. You have to click through to see the scandal and details.
|
213
|
+
</p>
|
214
|
+
|
215
|
+
<p>
|
216
|
+
To further ease the implementation, the editing of the Wiki page is done on the server with the <code>trac-admin</code> command. That means the Gossip script has to run on the server too.
|
217
|
+
</p>
|
218
|
+
|
219
|
+
<p>It would be swell if someone were to contribute a less hackish implementation.
|
220
|
+
</p>
|
221
|
+
<p>
|
222
|
+
To use this implementation, you have to set the following:
|
223
|
+
</p>
|
224
|
+
<ul>
|
225
|
+
<li><strong>trac-admin-path</strong>: The full path of the <code>trac-admin</code> program.</li>
|
226
|
+
<li><strong>trac-environment-path</strong>: The full path of the Trac environment you're using (such as <code>/home/user/trac_env1</code>).</li>
|
227
|
+
<li><strong>trac-page-name</strong>: The name of the wiki page to change.</li>
|
228
|
+
<li><strong>trac-content-file</strong>: The wiki page is changed by copying this file over its contents. Before the Trac crony does that, it puts the scandal and details at the beginning.</li>
|
229
|
+
</ul>
|
230
|
+
|
231
|
+
<h2><a name="twitter">Twitter</a></h2>
|
232
|
+
<p>
|
233
|
+
Because <a href="http://twitter.com/home" title="Twitter">Twitter</a> is meant for short messages, only the scandal is sent:
|
234
|
+
</p>
|
235
|
+
<img class="center" src="images/twitter.png" />
|
236
|
+
|
237
|
+
<p>
|
238
|
+
To use the <code>twitter</code> crony, you need a Twitter account. Messages are sent to that account for others to view. The configuration options are:
|
239
|
+
</p>
|
240
|
+
<ul>
|
241
|
+
<li><strong>twitter-login</strong></li>
|
242
|
+
<li><strong>twitter-password</strong></li>
|
243
|
+
</ul>
|
244
|
+
|
245
|
+
<p style="text-align: center">
|
246
|
+
<a href="scripts.html">Next</a>: All scripts<br />
|
247
|
+
</p>
|
248
|
+
|
249
|
+
|
250
|
+
</div>
|
251
|
+
</div>
|
252
|
+
</div>
|
253
|
+
|
254
|
+
</body>
|
255
|
+
</html>
|
256
|
+
|