jabber-tee 0.1.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/README.markdown ADDED
@@ -0,0 +1,47 @@
1
+ # Jabber TEE
2
+
3
+ This is a simple command line tool for writing input from the client to a remote jabber server and outputting to the console.
4
+
5
+ # Installing
6
+
7
+ The command line tool can be installed with:
8
+
9
+ gem install jabber-tee
10
+
11
+ # Using
12
+
13
+ The general idea is that you can pipe anything from the console into this, and it will be sent to the remote jabber server:
14
+
15
+ cat huge_text_file.txt | jabber-tee -u peon@bigcorp.com --room working-hard@rooms.bigcorp.com --nick 'Worker Drone'
16
+
17
+ # Configuration
18
+
19
+ Because entering the same information on the command line for this thing can be tedious, you can create a ~/.jabber-tee.yml file that fills in all of the basic configuration. This file also allows you to further customize the output that is sent to the jabber server.
20
+
21
+ An example configuration file:
22
+
23
+ # Global configuration values:
24
+ username: my.name@jabber.org
25
+ nick: 'Gabe'
26
+
27
+ # Individual profiles that customize global variables
28
+ profiles:
29
+ new-hotness:
30
+ # Uses the standard username, above
31
+ nick: 'Mr. Super Cool'
32
+ room: 'HipCentral'
33
+
34
+ somebody.else:
35
+ username: supercooldude@gmail.com
36
+ nick: 'Rocksteady Gabe'
37
+ to: somebody.else@gmail.com
38
+
39
+ work-stuff:
40
+ username: peon@bigcorp.com
41
+ nick: 'Worker Drone'
42
+ room: working-hard@rooms.bigcorp.com
43
+
44
+ You can then activate these individual profiles from the command line with the '-P' flag. So, the above command could be replaced with:
45
+
46
+ cat huge_text_file.txt | jabber-tee -P work-stuff
47
+
data/Rakefile ADDED
@@ -0,0 +1,55 @@
1
+ $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift File.expand_path("../spec", __FILE__)
3
+
4
+ require 'fileutils'
5
+ require 'rake'
6
+ require 'rubygems'
7
+ require 'spec/rake/spectask'
8
+ require 'jabber-tee/version'
9
+
10
+ task :default => :spec
11
+
12
+ desc "Run the RSpec tests"
13
+ Spec::Rake::SpecTask.new(:spec) do |t|
14
+ t.spec_files = FileList['spec/**/*_spec.rb']
15
+ t.spec_opts = ['-b', '-c', '-f', 'p']
16
+ t.fail_on_error = false
17
+ end
18
+
19
+ begin
20
+ require 'jeweler'
21
+ Jeweler::Tasks.new do |gem|
22
+ gem.name = 'jabber-tee'
23
+ gem.version = JabberTee::Version.to_s
24
+ gem.executables = %W{jabber-tee}
25
+ gem.summary = 'Simple command line utility for piping the output from one command to both the console and a remote jabber server.'
26
+ gem.description = "Installs the 'jabber-pipe' utility for sending messages to a remote jabber server. Instead of a standard client, it reads from standard in and continues to write to the console."
27
+ gem.email = ['madeonamac@gmail.com']
28
+ gem.authors = ['Gabe McArthur']
29
+ gem.homepage = 'http://github.com/gabemc/jabber-tee'
30
+ gem.files = FileList["[A-Z]*", "{bin,lib,spec}/**/*"]
31
+
32
+ gem.add_dependency 'highline', '>=1.5.2'
33
+ gem.add_dependency 'xmpp4r', '>=0.5'
34
+
35
+ gem.add_development_dependency 'rspec', '>=1.3.0'
36
+ end
37
+ rescue LoadError
38
+ puts "Jeweler or dependencies are not available. Install it with: sudo gem install jeweler"
39
+ end
40
+
41
+ desc "Deploys the gem to rubygems.org"
42
+ task :gem => :release do
43
+ system("gem build jabber-tee.gemspec")
44
+ system("gem push jabber-tee-#{JabberTee::Version.to_s}.gem")
45
+ end
46
+
47
+ desc "Does the full release cycle."
48
+ task :deploy => [:gem, :clean] do
49
+ end
50
+
51
+ desc "Cleans the gem files up."
52
+ task :clean do
53
+ FileUtils.rm(Dir.glob('*.gemspec'))
54
+ FileUtils.rm(Dir.glob('*.gem'))
55
+ end
data/bin/jabber-tee ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
3
+
4
+ require 'jabber-tee/cli'
5
+ JabberTee::CLI.new(ARGV).execute!
data/lib/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,156 @@
1
+ require 'optparse'
2
+ require 'jabber-tee/errors'
3
+ require 'jabber-tee/version'
4
+ require 'jabber-tee/client'
5
+ require 'jabber-tee/configuration'
6
+
7
+ module JabberTee
8
+ class CLI
9
+ attr_reader :options, :args
10
+
11
+ def initialize(args)
12
+ @args = args
13
+ end
14
+
15
+ def execute!
16
+ begin
17
+ parse!(@args.dup)
18
+ config = load_configuration
19
+
20
+ if config.destination_missing?
21
+ raise JabberTee::ConfigurationError.new("Either the --to or --room flag is required.")
22
+ end
23
+
24
+ client = Client.new(config)
25
+ client.pump!
26
+ rescue SystemExit => e
27
+ raise
28
+ rescue JabberTee::ConfigurationError => e
29
+ print_error(e.message)
30
+ rescue OptionParser::InvalidOption => e
31
+ print_error(e.message)
32
+ rescue Exception => e
33
+ STDERR.puts e.backtrace
34
+ print_error(e.message)
35
+ end
36
+ end
37
+
38
+ def parse!(args)
39
+ parse_options(args)
40
+ validate_args(args)
41
+ end
42
+
43
+ def parse_options(args)
44
+ @options ||= {}
45
+ @parsed_options ||= OptionParser.new do |opts|
46
+ opts.banner = "Usage: #{File.basename($0)} [OPTIONS] "
47
+ opts.separator <<DESC
48
+ Description:
49
+ This is a simple tool for reading from STDIN and writing
50
+ to both STDOUT and a remote jabber server. It does not handle
51
+ reading from STDERR, so you will need to re-direct 2>&1 before
52
+ piping it to this tool.
53
+
54
+ The configuration file should live under ~/.jabber-tee.yml.
55
+ Please see http://github.com/gabemc/jabber-tee for more
56
+ information.
57
+
58
+ Options:
59
+ DESC
60
+ opts.separator " Connecting:"
61
+ opts.on('-u', '--username USERNAME',
62
+ "The user@host.org name to connect to the jabber server.") do |u|
63
+ options[:username] = u
64
+ end
65
+ opts.on('-p', '--password PASSWORD',
66
+ "The password for the user to connect to the jabber server.",
67
+ "If not given or defined in the .jabber-tee.yml file,",
68
+ "it will be asked during runtime.") do |p|
69
+ options[:password] = p
70
+ end
71
+ opts.on('-n', '--nick NICKNAME',
72
+ "The nickname to use when connecting to the server.") do |n|
73
+ options[:nick] = n
74
+ end
75
+ opts.on('-a', '--anonymous',
76
+ "Disregards the username information and logs in using anonymous",
77
+ "authentication. Either the --username or the --authentication",
78
+ "flag are required.") do |a|
79
+ options[:anonymous] = true
80
+ end
81
+ opts.on('-P', '--profile PROFILE',
82
+ "The name of the profile, as defined in the .jabber-tee.yml",
83
+ "file to use to connect with.") do |p|
84
+ options[:profile] = p
85
+ end
86
+ opts.on('--sasl',
87
+ "By default, the connection does not use SASL authentication.",
88
+ "This enables SASL connections") do |s|
89
+ options[:sasl] = true
90
+ end
91
+ opts.on('--digest',
92
+ "When not using SASL, you can use the digest",
93
+ "authentication mechanism.") do |d|
94
+ options[:digest] = true
95
+ end
96
+ opts.separator ""
97
+
98
+ opts.separator " Output: (One required)"
99
+ opts.on('-t', '--to TO',
100
+ "Who to send the message to.") do |t|
101
+ options[:to] = t
102
+ end
103
+ opts.on('-r', '--room ROOM',
104
+ "The room to send the messages to.") do |r|
105
+ options[:room] = r
106
+ end
107
+ opts.separator ""
108
+
109
+ opts.separator " Informative:"
110
+ opts.on('-v', '--version',
111
+ "Show the version information") do |v|
112
+ puts "#{File.basename($0)} version: #{JabberTee::Version.to_s}"
113
+ exit
114
+ end
115
+ opts.on('-h', '--help',
116
+ "Show this help message") do
117
+ puts opts
118
+ exit
119
+ end
120
+ opts.separator ""
121
+
122
+ end.parse!(args)
123
+ end
124
+
125
+ def validate_args(args)
126
+ if args.length > 0
127
+ raise JabberTee::ConfigurationError.new("This command takes no extra arguments: #{args[0]}")
128
+ end
129
+ end
130
+
131
+ private
132
+ def print_error(e)
133
+ STDERR.puts "#{File.basename($0)}: #{e}"
134
+ STDERR.puts "#{File.basename($0)}: Try '--help' for more information"
135
+ exit 1
136
+ end
137
+
138
+ JABBER_FILE = '.jabber-tee.yml'
139
+
140
+ def load_configuration
141
+ home = ENV['HOME'] # TODO: Windows users?
142
+ config_file = File.join(home, JABBER_FILE)
143
+
144
+ if File.exists?(config_file)
145
+ reader = ConfigurationReader.new(config_file)
146
+ if options.has_key?(:profile)
147
+ reader.profile(options[:profile]).merge(options)
148
+ else
149
+ reader.profile.merge(options)
150
+ end
151
+ else
152
+ Configuration.new(options)
153
+ end
154
+ end
155
+ end # CLI
156
+ end
@@ -0,0 +1,46 @@
1
+ require 'jabber-tee/errors'
2
+
3
+ require 'rubygems'
4
+ require 'xmpp4r'
5
+ require 'xmpp4r/muc'
6
+
7
+ module JabberTee
8
+ class Client
9
+ attr_reader :config, :client
10
+
11
+ def initialize(config)
12
+ @config = config
13
+ @client = Jabber::Client.new(Jabber::JID.new("#{config.username}/#{config.nick}"))
14
+ client.connect
15
+ client.auth(config.password)
16
+
17
+ if config.in_room?
18
+ @muc = Jabber::MUC::SimpleMUCClient.new(client)
19
+ @muc.join(Jabber::JID.new("#{config.room}/#{config.nick}"))
20
+ end
21
+ end
22
+
23
+ def pump!
24
+ if $stdin.tty?
25
+ $STDERR.puts "Unable to pipe jabber-tee from a TTY"
26
+ exit(1)
27
+ else
28
+ $stdin.each do |line|
29
+ line.chomp!
30
+ say(line)
31
+ puts line
32
+ end
33
+ end
34
+ end
35
+
36
+ def say(message)
37
+ if config.in_room?
38
+ @muc.say(message)
39
+ else
40
+ msg = Jabber::Message.new(config.to, message)
41
+ msg.type = :chat
42
+ client.send(msg)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,90 @@
1
+ require 'jabber-tee/errors'
2
+
3
+ require 'rubygems'
4
+ require 'highline/import'
5
+ require 'yaml'
6
+
7
+ module JabberTee
8
+
9
+ class ConfigurationReader
10
+ def initialize(yaml_file)
11
+ if !File.exists?(yaml_file)
12
+ raise JabberTee::ConfigurationError.new("Unable to locate the configuration file.")
13
+ end
14
+
15
+ yaml = nil
16
+ file = File.open(yaml_file) {|f| yaml = f.read }
17
+ @config = YAML::load(yaml)
18
+ end
19
+
20
+ def profile(name=nil)
21
+ if name.nil?
22
+ Configuration.new(@config)
23
+ else
24
+ config = Configuration.new(@config)
25
+ profiles = @config['profiles']
26
+ if profiles.nil?
27
+ raise JabberTee::ConfigurationError.new("Unable to load an profiles from your home configuration.")
28
+ end
29
+ profile = profiles[name]
30
+ if config.nil?
31
+ raise JabberTee::ConfigurationError.new("Unable to load the #{name} profile from your home configuration.")
32
+ end
33
+ config.merge(profile)
34
+ end
35
+ end
36
+ end
37
+
38
+ class Configuration
39
+ ATTRIBUTES = ['username', 'nick', 'password', 'anonymous', 'sasl', 'digest', 'room', 'to']
40
+
41
+ attr_reader :username, :nick, :to, :room
42
+
43
+ def initialize(options=nil)
44
+ if !options.nil?
45
+ merge(options)
46
+ end
47
+ end
48
+
49
+ def merge(options)
50
+ ATTRIBUTES.each do |attr|
51
+ if options.has_key?(attr.to_sym) || options.has_key?(attr)
52
+ value = options[attr.to_sym] || options[attr]
53
+ instance_variable_set("@#{attr}", value)
54
+ end
55
+ end
56
+ self
57
+ end
58
+
59
+ def password
60
+ if @password.nil?
61
+ @password = ask("#{username}: password: ") {|q| q.echo = false }
62
+ end
63
+ @password
64
+ end
65
+
66
+ def anonymous?
67
+ !@anonymous.nil? && username.nil?
68
+ end
69
+
70
+ def sasl?
71
+ !@sasl.nil?
72
+ end
73
+
74
+ def digest?
75
+ !@digest.nil?
76
+ end
77
+
78
+ def in_room?
79
+ !@room.nil?
80
+ end
81
+
82
+ def destination_missing?
83
+ @room.nil? && @to.nil?
84
+ end
85
+
86
+ def to_s
87
+ "<JabberTee::Configuration{:username => '#{username}', :room => '#{room}', :to => '#{to}', :anonymous => #{anonymous?}, :sasl => #{sasl?}}>"
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,6 @@
1
+
2
+ module JabberTee
3
+ Error = Class.new(RuntimeError)
4
+
5
+ ConfigurationError = Class.new(JabberTee::Error)
6
+ end
@@ -0,0 +1,12 @@
1
+ require 'scanf'
2
+
3
+ module JabberTee
4
+ class Version
5
+ CURRENT = File.read(File.dirname(__FILE__) + '/../VERSION')
6
+ MAJOR, MINOR, TINY = CURRENT.scanf('%d.%d.%d')
7
+
8
+ def self.to_s
9
+ CURRENT
10
+ end
11
+ end
12
+ end
data/spec/cli_spec.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'helpers'
2
+ require 'jabber-tee/cli'
3
+
4
+ module JabberTee
5
+
6
+ module CLIHelper
7
+ def parse(*args)
8
+ cli = CLI.new(args)
9
+ cli.parse_options(args)
10
+ cli
11
+ end
12
+
13
+ def validate(*args)
14
+ cli = CLI.new(args)
15
+ cli.parse_options(args)
16
+ cli.validate_args(args)
17
+ cli
18
+ end
19
+
20
+ def check(sym, flags, value)
21
+ flags.each do |flag|
22
+ if value.is_a?(String)
23
+ parse(flag, value).options[sym].should eql(value)
24
+ else
25
+ parse(flag).options[sym].should eql(value)
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "Jabber Tee CLI interface" do
32
+ include CLIHelper
33
+
34
+ describe "when just checking arguments" do
35
+ it "should parse the username correctly" do
36
+ check(:username, ['-u', '--username'], 'someuser')
37
+ end
38
+
39
+ it "should parse the password correctly" do
40
+ check(:password, ['-p', '--password'], 'super_!!_secret')
41
+ end
42
+
43
+ it "should parse the sasl flag correctly" do
44
+ check(:sasl, ['--sasl'], true)
45
+ end
46
+
47
+ it "should parse the digest flag correctly" do
48
+ check(:digest, ['--digest'], true)
49
+ end
50
+
51
+ it "should parse the anonymous flag correctly" do
52
+ check(:anonymous, ['-a', '--anonymous'], true)
53
+ end
54
+
55
+ it "should parse the room flag correctly" do
56
+ check(:room, ['-r', '--room'], 'ROOM')
57
+ end
58
+
59
+ it "should parse the nickname flag correctly" do
60
+ check(:nick, ['-n', '--nick'], 'nickname!')
61
+ end
62
+ end
63
+
64
+ describe "while validating the arguments" do
65
+ CE = JabberTee::ConfigurationError
66
+
67
+ it "should fail when there are extra arguments" do
68
+ attempting_to { validate('extra-arg') }.should raise_error(CE, /extra/)
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,91 @@
1
+ require 'jabber-tee/configuration'
2
+ require 'helpers'
3
+
4
+ module JabberTee
5
+ describe "ConfigurationReader" do
6
+ it "should fail when the yaml file doesn't exist" do
7
+ attempting_to { ConfigurationReader.new('doesnt-exist.yml') }.should raise_error(ConfigurationError, /locate/)
8
+ end
9
+
10
+ it "should load a yaml file and pull the default profile" do
11
+ r = ConfigurationReader.new('spec/test-config-1.yaml')
12
+ c = r.profile
13
+
14
+ c.username.should eql('gabe@someplace.org')
15
+ c.room.should be(nil)
16
+ end
17
+
18
+ it "should be able to load sub-profiles" do
19
+ r = ConfigurationReader.new('spec/test-config-1.yaml')
20
+ c = r.profile('standard')
21
+
22
+ c.room.should eql('cudos@rooms.someplace.org')
23
+ end
24
+
25
+ it "should fail when the profiles section doesn't exist" do
26
+ r = ConfigurationReader.new('spec/test-config-2.yaml')
27
+ attempting_to { r.profile('standard') }.should raise_error(ConfigurationError, /profiles/)
28
+ end
29
+
30
+ it "should fail when the profile doesn't exist" do
31
+ r = ConfigurationReader.new('spec/test-config-1.yaml')
32
+ attempting_to { r.profile('non-existant') }.should raise_error(ConfigurationError, /non-existant/)
33
+ end
34
+ end
35
+
36
+ describe "The Configuration" do
37
+ it "should initialize default values to nil" do
38
+ c = Configuration.new
39
+ c.username.should be(nil)
40
+ end
41
+
42
+ it "should set anonymous to false by default" do
43
+ c = Configuration.new
44
+ c.anonymous?.should be(false)
45
+ end
46
+
47
+ it "should set SASL mode to false by default" do
48
+ c = Configuration.new
49
+ c.sasl?.should be(false)
50
+ end
51
+
52
+ it "should set the digest mode to false by default" do
53
+ c = Configuration.new
54
+ c.digest?.should be(false)
55
+ end
56
+
57
+ it "should se the 'in_room?' attribute to false by default" do
58
+ c = Configuration.new
59
+ c.in_room?.should be(false)
60
+ end
61
+
62
+ it "should merge options correctly" do
63
+ options = {:username => 'gabe', :password => 'supersecret'}
64
+ c = Configuration.new(options)
65
+ c.username.should eql('gabe')
66
+ c.password.should eql('supersecret')
67
+ end
68
+
69
+ it "should set 'anonymous' to false when a username is provided" do
70
+ options = {:username => 'gabe' }
71
+ c = Configuration.new(options)
72
+ c.anonymous?.should be(false)
73
+ end
74
+
75
+ it "should merge options correctly more than once" do
76
+ init = {:username => 'gabe', :password => 'supersecret'}
77
+ options = {:room => 'rc@someplace'}
78
+ c = Configuration.new(init)
79
+ c.merge(options)
80
+ c.in_room?.should be(true)
81
+ c.room.should eql('rc@someplace')
82
+ end
83
+
84
+ it "should set the 'to' field correctly" do
85
+ c = Configuration.new
86
+ c.merge({:to => 'to-me'})
87
+ c.in_room?.should be(false)
88
+ c.to.should eql('to-me')
89
+ end
90
+ end
91
+ end
data/spec/helpers.rb ADDED
@@ -0,0 +1,9 @@
1
+
2
+
3
+ def attempting(&block)
4
+ lambda &block
5
+ end
6
+
7
+ def attempting_to(&block)
8
+ lambda &block
9
+ end
@@ -0,0 +1,13 @@
1
+ username: 'gabe@someplace.org'
2
+ password: 'pinchme!Imsecret!'
3
+ nick: 'Gabe'
4
+
5
+ profiles:
6
+ standard:
7
+ room: 'cudos@rooms.someplace.org'
8
+ sasl: true
9
+ weird:
10
+ username: 'weirdo@someplaceelse.org'
11
+ password: 'notsosecret'
12
+ nick: 'Jabberwocky Slayer'
13
+ to: 'jabber-monster@someplaceelse.org'
@@ -0,0 +1,5 @@
1
+
2
+ username: 'gabe@someplace.org'
3
+ password: 'pinchme!Imsecret!'
4
+ nick: 'Gabe'
5
+
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jabber-tee
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Gabe McArthur
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-09-23 00:00:00 -07:00
19
+ default_executable: jabber-tee
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: highline
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 7
30
+ segments:
31
+ - 1
32
+ - 5
33
+ - 2
34
+ version: 1.5.2
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: xmpp4r
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 1
46
+ segments:
47
+ - 0
48
+ - 5
49
+ version: "0.5"
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: rspec
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 27
61
+ segments:
62
+ - 1
63
+ - 3
64
+ - 0
65
+ version: 1.3.0
66
+ type: :development
67
+ version_requirements: *id003
68
+ description: Installs the 'jabber-pipe' utility for sending messages to a remote jabber server. Instead of a standard client, it reads from standard in and continues to write to the console.
69
+ email:
70
+ - madeonamac@gmail.com
71
+ executables:
72
+ - jabber-tee
73
+ extensions: []
74
+
75
+ extra_rdoc_files:
76
+ - README.markdown
77
+ files:
78
+ - README.markdown
79
+ - Rakefile
80
+ - bin/jabber-tee
81
+ - lib/VERSION
82
+ - lib/jabber-tee/cli.rb
83
+ - lib/jabber-tee/client.rb
84
+ - lib/jabber-tee/configuration.rb
85
+ - lib/jabber-tee/errors.rb
86
+ - lib/jabber-tee/version.rb
87
+ - spec/cli_spec.rb
88
+ - spec/configuration_spec.rb
89
+ - spec/helpers.rb
90
+ - spec/test-config-1.yaml
91
+ - spec/test-config-2.yaml
92
+ has_rdoc: true
93
+ homepage: http://github.com/gabemc/jabber-tee
94
+ licenses: []
95
+
96
+ post_install_message:
97
+ rdoc_options:
98
+ - --charset=UTF-8
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ hash: 3
107
+ segments:
108
+ - 0
109
+ version: "0"
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ hash: 3
116
+ segments:
117
+ - 0
118
+ version: "0"
119
+ requirements: []
120
+
121
+ rubyforge_project:
122
+ rubygems_version: 1.3.7
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: Simple command line utility for piping the output from one command to both the console and a remote jabber server.
126
+ test_files:
127
+ - spec/helpers.rb
128
+ - spec/configuration_spec.rb
129
+ - spec/cli_spec.rb