history_commander 0.0.1

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.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,22 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+ *.swo
16
+
17
+ ## PROJECT::GENERAL
18
+ coverage
19
+ rdoc
20
+ pkg
21
+
22
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Jeremy Deininger
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ = history_commander
2
+
3
+ == Quick Start
4
+
5
+ 'gem install history_commander'
6
+ Installs the history_commander gem. To run 'hc' you must rubygems bin directory in your path
7
+
8
+ 'hc_setup_bashrc'
9
+ This installs bash history tweaks to your .bashrc
10
+
11
+ 'hc configure --help'
12
+ This will setup the .history_commander config file with your selected options
13
+
14
+ 'hc start'
15
+ Starts history_commander
16
+
17
+ == Note on Patches/Pull Requests
18
+
19
+ * Fork the project.
20
+ * Make your feature addition or bug fix.
21
+ * Add tests for it. This is important so I don't break it in a
22
+ future version unintentionally.
23
+ * Commit, do not mess with rakefile, version, or history.
24
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
25
+ * Send me a pull request. Bonus points for topic branches.
26
+
27
+ == Copyright
28
+
29
+ Copyright (c) 2010 Jeremy Deininger. See LICENSE for details.
@@ -0,0 +1,52 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "history_commander"
8
+ gem.summary = %Q{Take command of your shell history!}
9
+ gem.description = %Q{History Commander is a program designed to keep your shell history in sync across all your nodes. }
10
+ gem.email = "jeremy@rubyonlinux.org"
11
+ gem.homepage = "http://github.com/jeremyd/history_commander"
12
+ gem.authors = ["Jeremy Deininger"]
13
+ gem.add_dependency "eventmachine"
14
+ gem.add_dependency "eventmachine-tail"
15
+ gem.add_dependency "amqp"
16
+ gem.add_dependency "json"
17
+ gem.add_dependency "simple-daemon"
18
+ gem.add_dependency "trollop"
19
+ gem.add_dependency "highline"
20
+ gem.add_development_dependency "rspec", ">= 1.2.9"
21
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
26
+ end
27
+
28
+ require 'spec/rake/spectask'
29
+ Spec::Rake::SpecTask.new(:spec) do |spec|
30
+ spec.libs << 'lib' << 'spec'
31
+ spec.spec_files = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
35
+ spec.libs << 'lib' << 'spec'
36
+ spec.pattern = 'spec/**/*_spec.rb'
37
+ spec.rcov = true
38
+ end
39
+
40
+ task :spec => :check_dependencies
41
+
42
+ task :default => :spec
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "history_commander #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
data/bin/hc ADDED
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ## Development ENV only
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ ###
6
+
7
+ require 'rubygems'
8
+ require 'history_commander'
9
+ require 'trollop'
10
+ require 'tmpdir'
11
+
12
+ command = ARGV.shift
13
+ unless ["start", "stop", "configure"].include?(command)
14
+ puts "Syntax: hc <command> [args] [--help]"
15
+ puts " command can be 'start', 'stop', or 'configure'"
16
+ end
17
+
18
+ @@options = Trollop::options do
19
+ opt :config, "configuration file to use", :default => File.join(File.expand_path("~"), ".history_commander"), :type => :string
20
+ opt :foreground, "run in foreground (daemonize is the default)", :default => false
21
+ opt :amqp_host, "hostname of AMQP server", :type => :string
22
+ opt :mode, "operate in 'full' read/write (sync) mode -or in 'writeonly' (no sync) mode. This requires the proper AMQP permissions.", :type => :string
23
+ opt :user, "AMQP username", :type => :string
24
+ opt :pass, "AMQP pass", :type => :string
25
+ opt :vhost, "AMQP vhost", :type => :string
26
+ opt :amqp_log, "AMQP verbose logging", :default => false, :short => "-l"
27
+ end
28
+
29
+ def check_options
30
+ [:user, :pass, :vhost, :amqp_host, :mode].each do |req|
31
+ unless @@options[req]
32
+ puts "FATAL: you must specify --#{req} in your history_commander config file or on the command line, see --help"
33
+ exit 1
34
+ end
35
+ end
36
+ end
37
+
38
+ if command == "configure"
39
+ check_options
40
+ config_file = @@options[:config]
41
+ @@options.reject! { |k, v| k.to_s.include?("given") || k == :help || k == :save || k == :config }
42
+ writeme = @@options.dup
43
+ File.open(config_file, "w") {|f| f.write(writeme.to_json(:indent => " ", :object_nl => "\n"))}
44
+ File.chmod 0600, config_file
45
+ puts "wrote config to #{config_file}"
46
+ exit
47
+ end
48
+
49
+ if File.exists?(@@options[:config])
50
+ @@options.reject! { |k, v| v == nil }
51
+ saved_opts = JSON::parse(IO.read(@@options[:config])).to_mash
52
+ passed_in_opts = @@options.to_mash
53
+ @@options = saved_opts.merge passed_in_opts
54
+ end
55
+
56
+ check_options
57
+
58
+ if @@options[:foreground]
59
+ puts "History Commander running in foreground mode. CTRL-C to interrupt"
60
+ EM.run do
61
+ AMQP.start(:host => @@options[:amqp_host], :user => @@options[:user], :pass => @@options[:pass], :vhost => @@options[:vhost], :logging => @@options[:amqp_log]) do
62
+ HistWatch.start(@@options[:mode])
63
+ end
64
+ end
65
+ else
66
+ puts "Logging to #{Dir.tmpdir}/HistoryCommanderDaemon.log"
67
+ require 'simple-daemon'
68
+ class HistoryCommanderDaemon < SimpleDaemon::Base
69
+ SimpleDaemon::WORKING_DIRECTORY = Dir.tmpdir
70
+ def self.start
71
+ EM.run do
72
+ AMQP.start(:host => @@options[:amqp_host], :user => @@options[:user], :pass => @@options[:pass], :vhost => @@options[:vhost], :logging => @@options[:amqp_log]) do
73
+ HistWatch.start(@@options[:mode])
74
+ end
75
+ end
76
+ end
77
+
78
+ def self.stop
79
+ EM.stop
80
+ puts "Stopping History Commander"
81
+ end
82
+ end
83
+ HistoryCommanderDaemon.daemonize
84
+ end
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ## Development ENV only
4
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
5
+ ###
6
+ require 'rubygems'
7
+ require 'history_commander/setup_bashrc'
8
+
9
+ options = Trollop::options do
10
+ opt :yes, "Do not prompt", :default => false
11
+ end
12
+
13
+ SetupBashrc.install(options[:yes])
@@ -0,0 +1,80 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{history_commander}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Jeremy Deininger"]
12
+ s.date = %q{2010-08-01}
13
+ s.description = %q{History Commander is a program designed to keep your shell history in sync across all your nodes. }
14
+ s.email = %q{jeremy@rubyonlinux.org}
15
+ s.executables = ["hc", "hc_setup_bashrc"]
16
+ s.extra_rdoc_files = [
17
+ "LICENSE",
18
+ "README.rdoc"
19
+ ]
20
+ s.files = [
21
+ ".document",
22
+ ".gitignore",
23
+ "LICENSE",
24
+ "README.rdoc",
25
+ "Rakefile",
26
+ "VERSION",
27
+ "bin/hc",
28
+ "bin/hc_setup_bashrc",
29
+ "history_commander.gemspec",
30
+ "lib/history_commander.rb",
31
+ "lib/history_commander/setup_bashrc.rb",
32
+ "spec/history_commander_spec.rb",
33
+ "spec/spec.opts",
34
+ "spec/spec_helper.rb"
35
+ ]
36
+ s.homepage = %q{http://github.com/jeremyd/history_commander}
37
+ s.rdoc_options = ["--charset=UTF-8"]
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.3.7}
40
+ s.summary = %q{Take command of your shell history!}
41
+ s.test_files = [
42
+ "spec/history_commander_spec.rb",
43
+ "spec/spec_helper.rb"
44
+ ]
45
+
46
+ if s.respond_to? :specification_version then
47
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
48
+ s.specification_version = 3
49
+
50
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
51
+ s.add_runtime_dependency(%q<eventmachine>, [">= 0"])
52
+ s.add_runtime_dependency(%q<eventmachine-tail>, [">= 0"])
53
+ s.add_runtime_dependency(%q<amqp>, [">= 0"])
54
+ s.add_runtime_dependency(%q<json>, [">= 0"])
55
+ s.add_runtime_dependency(%q<simple-daemon>, [">= 0"])
56
+ s.add_runtime_dependency(%q<trollop>, [">= 0"])
57
+ s.add_runtime_dependency(%q<highline>, [">= 0"])
58
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
59
+ else
60
+ s.add_dependency(%q<eventmachine>, [">= 0"])
61
+ s.add_dependency(%q<eventmachine-tail>, [">= 0"])
62
+ s.add_dependency(%q<amqp>, [">= 0"])
63
+ s.add_dependency(%q<json>, [">= 0"])
64
+ s.add_dependency(%q<simple-daemon>, [">= 0"])
65
+ s.add_dependency(%q<trollop>, [">= 0"])
66
+ s.add_dependency(%q<highline>, [">= 0"])
67
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
68
+ end
69
+ else
70
+ s.add_dependency(%q<eventmachine>, [">= 0"])
71
+ s.add_dependency(%q<eventmachine-tail>, [">= 0"])
72
+ s.add_dependency(%q<amqp>, [">= 0"])
73
+ s.add_dependency(%q<json>, [">= 0"])
74
+ s.add_dependency(%q<simple-daemon>, [">= 0"])
75
+ s.add_dependency(%q<trollop>, [">= 0"])
76
+ s.add_dependency(%q<highline>, [">= 0"])
77
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
78
+ end
79
+ end
80
+
@@ -0,0 +1,86 @@
1
+ require 'rubygems'
2
+ require 'json'
3
+ require 'eventmachine'
4
+ require 'eventmachine-tail'
5
+ require 'mq'
6
+ require 'uuidtools'
7
+ require 'mash'
8
+ require 'fileutils'
9
+
10
+ class HistoryCommander < EventMachine::FileTail
11
+ attr_accessor :uuid
12
+ attr_accessor :pause
13
+
14
+ def safe_path
15
+ "#{path}_safe"
16
+ end
17
+
18
+ # path <~String> File path to monitor
19
+ # mode <~String> Can be set to "full" for read/write mode, and any other value for write only mode.
20
+ # startpos <~Integer> File position to start tailing the file. Default of -1 starts at the end of the file
21
+ def initialize(path, startpos=-1, mode="full")
22
+ super(path, startpos)
23
+ FileUtils.cp(path, safe_path)
24
+ @buffer = BufferedTokenizer.new
25
+ @global_history_fanout = MQ.new.fanout('global_history')
26
+ @uuid = UUIDTools::UUID.random_create.to_s
27
+ @host = `hostname`.chomp
28
+ @user = `whoami`.chomp
29
+ @pause = false
30
+ subscribe if mode == "full"
31
+ end
32
+
33
+ # Receive data from the FileTail and submit it
34
+ # to the MQ
35
+ def receive_data(data)
36
+ @buffer.extract(data).each do |line|
37
+ payload = { :uuid => @uuid,
38
+ :message => line,
39
+ :host => @host,
40
+ :user => @user }
41
+ @global_history_fanout.publish(payload.to_json)
42
+ end
43
+ end
44
+
45
+ def schedule_next_read
46
+ unless @pause
47
+ EventMachine::add_timer(@naptime) do
48
+ read
49
+ end
50
+ end
51
+ end
52
+
53
+ def skip_ahead
54
+ def skip_ahead
55
+ @pos = @file.sysseek(0, IO::SEEK_END)
56
+ end
57
+ end
58
+
59
+ # Subscribe to the global history exchange and sync the history file with any new inbound global history. Pauses FileTail and skips the output when writing to the history file.
60
+ def subscribe
61
+ @subscription = MQ.new
62
+ @subscription.queue(@uuid).bind(@subscription.fanout('global_history')).subscribe do |result|
63
+ x = Mash.new(JSON::parse(result))
64
+ puts "received: #{x[:uuid]} #{x[:user]}@#{x[:host]}$ #{x[:message]}"
65
+ if x[:uuid] != @uuid
66
+ @pause = true
67
+ File.open(path, "a") {|f| f.puts(x[:message])}
68
+ skip_ahead
69
+ @pause = false
70
+ schedule_next_read
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ # HistWatch is a wrapper class for starting EM and loading configuration information for History Commander
77
+ class HistWatch
78
+ # starts
79
+ def self.start(mode="full", file = File.join(File.expand_path('~'), ".bash_history"))
80
+ @hist_file_watch = EventMachine::file_tail(file, HistoryCommander, -1, mode)
81
+ end
82
+
83
+ def self.stop
84
+ EM.stop
85
+ end
86
+ end
@@ -0,0 +1,65 @@
1
+ require 'rubygems'
2
+ require 'fileutils'
3
+ require 'trollop'
4
+ require 'highline/import'
5
+
6
+ class SetupBashrc
7
+ # Install necessary .bashrc customization for optimal history commander usage.
8
+ def self.install(force = false)
9
+ my_home = File.expand_path('~')
10
+ my_bashrc = File.join(my_home, ".bashrc")
11
+ unless File.exists?(my_bashrc)
12
+ if File.exists?("/etc/bashrc")
13
+ FileUtils.cp("/etc/bashrc", my_bashrc)
14
+ elsif File.exists?("/usr/etc/bashrc")
15
+ FileUtils.cp("/usr/etc/bashrc", my_bashrc)
16
+ else
17
+ `touch #{my_bashrc}`
18
+ end
19
+ end
20
+ say "using .bashrc in #{my_bashrc}"
21
+ self.apply_change(my_bashrc, force)
22
+ end
23
+
24
+ def self.goodies
25
+ <<eoh
26
+ shopt -s histappend
27
+ export HIST_CONTROL=ignoreboth
28
+ export PROMPT_COMMAND="history -a; history -n"
29
+ export HISTSIZE=1000000
30
+ export HISTFILESIZE=1000000
31
+ eoh
32
+ end
33
+
34
+ def self.do_warnings(file_contents)
35
+ if file_contents =~ /#{self.goodies}/
36
+ say "*** WARNING: modifications already installed!"
37
+ end
38
+ if file_contents =~ /PROMPT_COMMAND/
39
+ say "*** WARNING: your .bashrc already has a PROMPT_COMMAND. This setting will be overridden!"
40
+ end
41
+ end
42
+
43
+ # *file <~String>: bashrc file to detect and optionally apply changes to.
44
+ def self.apply_change(file, force = false)
45
+ say("Thanks for installing History Commander!\nThe following modifications will be applied to your ~/.bashrc file:")
46
+ say("+++\n#{self.goodies}")
47
+ self.do_warnings(IO.read(file))
48
+ unless force
49
+ confirm = ask("+++ Apply changes (y/n)?", lambda { |ans| true if (ans =~ /^[y,Y]{1}/) })
50
+ unless confirm
51
+ say "Aborting."
52
+ exit
53
+ end
54
+ end
55
+ backup = "#{file}_hc_backup#{rand(10000)}"
56
+ say "Creating backup of .bashrc in #{backup}"
57
+ FileUtils.cp(file, backup)
58
+ File.open(file, "a") { |f| f.puts(self.goodies)}
59
+ say "done installing history customization."
60
+ say "***"
61
+ say "Now you MUST load your new bash history config:"
62
+ say "Open a new terminal -or-"
63
+ say "'source #{file}'"
64
+ end
65
+ end
@@ -0,0 +1,43 @@
1
+ # This Spec requires a running AMQP server.
2
+ # Configure your AMQP server first and enter access information below before running this spec.
3
+
4
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
5
+ require 'tmpdir'
6
+
7
+ describe "HistoryCommander" do
8
+ before(:all) do
9
+ @watch_files = []
10
+ 2.times do |x|
11
+ @watch_files << File.join(Dir.tmpdir, "#{x}unique-history_commander_spec_candelete")
12
+ end
13
+ @watch_files.each {|w| `rm #{w}; touch #{w}`}
14
+ end
15
+ it "runs multiple history commanders and checks for all files to contain all history" do
16
+ EM.run do
17
+ AMQP.start(:host => "ec2-184-72-19-157.us-west-1.compute.amazonaws.com") do
18
+ EM.next_tick do
19
+ @watch_files.each do |w|
20
+ HistWatch.start(w)
21
+ end
22
+ end
23
+ EM.add_timer(2) do
24
+ @first_value = "first_command: #{rand(10000000)}"
25
+ File.open(@watch_files.first, "a") {|f| f.puts @first_value }
26
+ end
27
+ EM.add_timer(3) do
28
+ @second_value = "second_command: #{rand(10000000)}"
29
+ File.open(@watch_files.last, "a") {|f| f.puts @second_value }
30
+ end
31
+ EM.add_timer(10) do
32
+ @watch_files.each do |w|
33
+ IO.read(w).should =~ /^#{@first_value}/
34
+ IO.read(w).should =~ /^#{@second_value}/
35
+ end
36
+ end
37
+ EM.add_timer(12) do
38
+ EM.stop
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'history_commander'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,196 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: history_commander
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Jeremy Deininger
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-01 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: eventmachine
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: eventmachine-tail
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: amqp
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: json
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :runtime
76
+ version_requirements: *id004
77
+ - !ruby/object:Gem::Dependency
78
+ name: simple-daemon
79
+ prerelease: false
80
+ requirement: &id005 !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ type: :runtime
90
+ version_requirements: *id005
91
+ - !ruby/object:Gem::Dependency
92
+ name: trollop
93
+ prerelease: false
94
+ requirement: &id006 !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ hash: 3
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ type: :runtime
104
+ version_requirements: *id006
105
+ - !ruby/object:Gem::Dependency
106
+ name: highline
107
+ prerelease: false
108
+ requirement: &id007 !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ type: :runtime
118
+ version_requirements: *id007
119
+ - !ruby/object:Gem::Dependency
120
+ name: rspec
121
+ prerelease: false
122
+ requirement: &id008 !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ hash: 13
128
+ segments:
129
+ - 1
130
+ - 2
131
+ - 9
132
+ version: 1.2.9
133
+ type: :development
134
+ version_requirements: *id008
135
+ description: "History Commander is a program designed to keep your shell history in sync across all your nodes. "
136
+ email: jeremy@rubyonlinux.org
137
+ executables:
138
+ - hc
139
+ - hc_setup_bashrc
140
+ extensions: []
141
+
142
+ extra_rdoc_files:
143
+ - LICENSE
144
+ - README.rdoc
145
+ files:
146
+ - .document
147
+ - .gitignore
148
+ - LICENSE
149
+ - README.rdoc
150
+ - Rakefile
151
+ - VERSION
152
+ - bin/hc
153
+ - bin/hc_setup_bashrc
154
+ - history_commander.gemspec
155
+ - lib/history_commander.rb
156
+ - lib/history_commander/setup_bashrc.rb
157
+ - spec/history_commander_spec.rb
158
+ - spec/spec.opts
159
+ - spec/spec_helper.rb
160
+ has_rdoc: true
161
+ homepage: http://github.com/jeremyd/history_commander
162
+ licenses: []
163
+
164
+ post_install_message:
165
+ rdoc_options:
166
+ - --charset=UTF-8
167
+ require_paths:
168
+ - lib
169
+ required_ruby_version: !ruby/object:Gem::Requirement
170
+ none: false
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ hash: 3
175
+ segments:
176
+ - 0
177
+ version: "0"
178
+ required_rubygems_version: !ruby/object:Gem::Requirement
179
+ none: false
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ hash: 3
184
+ segments:
185
+ - 0
186
+ version: "0"
187
+ requirements: []
188
+
189
+ rubyforge_project:
190
+ rubygems_version: 1.3.7
191
+ signing_key:
192
+ specification_version: 3
193
+ summary: Take command of your shell history!
194
+ test_files:
195
+ - spec/history_commander_spec.rb
196
+ - spec/spec_helper.rb