gossip 0.3.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.
Files changed (63) hide show
  1. data/History.txt +9 -0
  2. data/LICENSE.txt +34 -0
  3. data/Manifest.txt +62 -0
  4. data/README.txt +6 -0
  5. data/Rakefile +137 -0
  6. data/examples/all-config-file-choices.yml +36 -0
  7. data/lib/gossip.rb +32 -0
  8. data/lib/gossip/command.rb +122 -0
  9. data/lib/gossip/cronies/campfire.rb +72 -0
  10. data/lib/gossip/cronies/jabber.rb +66 -0
  11. data/lib/gossip/cronies/smtp.rb +121 -0
  12. data/lib/gossip/cronies/stdout.rb +24 -0
  13. data/lib/gossip/cronies/trac.rb +82 -0
  14. data/lib/gossip/cronies/twitter.rb +50 -0
  15. data/lib/gossip/crony.rb +102 -0
  16. data/lib/gossip/multi-exceptions.rb +47 -0
  17. data/lib/gossip/preteen.rb +86 -0
  18. data/lib/gossip/site-config.rb +94 -0
  19. data/lib/gossip/social-universe.rb +18 -0
  20. data/lib/gossip/version.rb +8 -0
  21. data/pages/classes.html +58 -0
  22. data/pages/cronies.html +256 -0
  23. data/pages/css/LICENSE.txt +1 -0
  24. data/pages/css/Thumbs.db +0 -0
  25. data/pages/css/bg2.gif +0 -0
  26. data/pages/css/gossip5-header-flip.jpg +0 -0
  27. data/pages/css/left.gif +0 -0
  28. data/pages/css/left_on.gif +0 -0
  29. data/pages/css/main.css +242 -0
  30. data/pages/css/right.gif +0 -0
  31. data/pages/css/right_on.gif +0 -0
  32. data/pages/css/tvline.gif +0 -0
  33. data/pages/images/campfire.png +0 -0
  34. data/pages/images/classes.png +0 -0
  35. data/pages/images/deployment.png +0 -0
  36. data/pages/images/jabber-big.png +0 -0
  37. data/pages/images/jabber.png +0 -0
  38. data/pages/images/trac-bigger.png +0 -0
  39. data/pages/images/trac-detail.png +0 -0
  40. data/pages/images/twitter.png +0 -0
  41. data/pages/index.html +45 -0
  42. data/pages/installation.html +95 -0
  43. data/pages/scripts.html +166 -0
  44. data/pages/src/classes.graffle +0 -0
  45. data/pages/starting-to-use.html +200 -0
  46. data/pages/writing-new-scripts.html +38 -0
  47. data/scripts/fanout +64 -0
  48. data/scripts/svntell +71 -0
  49. data/scripts/watchdog +86 -0
  50. data/setup.rb +1585 -0
  51. data/test/script/fanout-slowtests.rb +40 -0
  52. data/test/script/svntell-slowtests.rb +40 -0
  53. data/test/script/util.rb +22 -0
  54. data/test/script/watchdog-slowtests.rb +56 -0
  55. data/test/unit/command-crony-interaction-tests.rb +116 -0
  56. data/test/unit/command-tests.rb +119 -0
  57. data/test/unit/crony-tests.rb +46 -0
  58. data/test/unit/multi-exception-tests.rb +70 -0
  59. data/test/unit/preteen-tests.rb +81 -0
  60. data/test/util/bff.rb +45 -0
  61. data/test/util/doghouse.rb +42 -0
  62. data/test/util/silly-little-test-program.rb +6 -0
  63. 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
+
@@ -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
@@ -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
@@ -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