Permalink
Browse files

Break out CLI subcommands into own files

  • Loading branch information...
1 parent 2de977e commit aeb537d9a12230b6a07d8608a95ea421b3f67031 @bjeanes committed Apr 19, 2012
View
@@ -2,3 +2,4 @@
._*
pkg/*
Gemfile.lock
+*.gem
View
@@ -29,7 +29,6 @@ task :gemspec do
s.autorequire = "ghost"
s.has_rdoc = false
- s.add_dependency "optparse-subcommand", "1.0.0.pre.2"
s.add_development_dependency "rspec", "2.9.0"
end
View
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
s.description = "Allows you to create, list, and modify local hostnames"
s.email = "me@bjeanes.com"
s.executables = ["ghost"]
- s.files = ["LICENSE", "README.md", "bin/ghost", "lib/ghost", "lib/ghost/cli.rb", "lib/ghost/host.rb", "lib/ghost/store", "lib/ghost/store/dscl_store.rb", "lib/ghost/store/hosts_file_store.rb", "lib/ghost/store.rb", "lib/ghost/version.rb", "lib/ghost.rb", "spec/ghost", "spec/ghost/cli_spec.rb", "spec/ghost/host_spec.rb", "spec/ghost/store", "spec/ghost/store/dscl_store_spec.rb", "spec/ghost/store/hosts_file_store_spec.rb", "spec/ghost/store_spec.rb", "spec/spec_helper.rb"]
+ s.files = ["LICENSE", "README.md", "bin/ghost", "lib/ghost", "lib/ghost/cli", "lib/ghost/cli/add.rb", "lib/ghost/cli/task", "lib/ghost/cli/task/add.rb", "lib/ghost/cli/task/empty.rb", "lib/ghost/cli/task/export.rb", "lib/ghost/cli/task/import.rb", "lib/ghost/cli/task/list.rb", "lib/ghost/cli/task.rb", "lib/ghost/cli.rb", "lib/ghost/host.rb", "lib/ghost/store", "lib/ghost/store/dscl_store.rb", "lib/ghost/store/hosts_file_store.rb", "lib/ghost/store.rb", "lib/ghost/version.rb", "lib/ghost.rb", "spec/ghost", "spec/ghost/cli_spec.rb", "spec/ghost/host_spec.rb", "spec/ghost/store", "spec/ghost/store/dscl_store_spec.rb", "spec/ghost/store/hosts_file_store_spec.rb", "spec/ghost/store_spec.rb", "spec/spec_helper.rb"]
s.homepage = "http://github.com/bjeanes/ghost"
s.require_paths = ["lib"]
s.rubyforge_project = "ghost"
@@ -23,14 +23,11 @@ Gem::Specification.new do |s|
s.specification_version = 3
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
- s.add_runtime_dependency(%q<optparse-subcommand>, ["= 1.0.0.pre.2"])
s.add_development_dependency(%q<rspec>, ["= 2.9.0"])
else
- s.add_dependency(%q<optparse-subcommand>, ["= 1.0.0.pre.2"])
s.add_dependency(%q<rspec>, ["= 2.9.0"])
end
else
- s.add_dependency(%q<optparse-subcommand>, ["= 1.0.0.pre.2"])
s.add_dependency(%q<rspec>, ["= 2.9.0"])
end
end
View
@@ -5,4 +5,5 @@ module Ghost
require 'ghost/version'
require 'ghost/host'
+require 'ghost/store'
View
@@ -1,52 +1,36 @@
require File.expand_path("#{File.dirname(__FILE__)}/../ghost")
-require 'optparse/subcommand'
+require 'optparse'
require 'optparse/version'
module Ghost
class Cli
attr_accessor :out, :parser, :args
def initialize(args, out = STDOUT)
- self.args = args
+ self.args = args.dup
self.out = out
setup_parser
end
def parse
parser.parse! args
+
+ arg = args.shift
+ return unless arg
+
+ if (task = tasks[arg.to_sym])
+ task.perform(*args)
+ else
+ raise "No such task"
+ end
end
private
def setup_parser
self.parser = OptionParser.new do |o|
- o.subcommand 'add' do
- add
- exit
- end
-
- o.subcommand 'list' do
- list
- exit
- end
-
- o.subcommand 'import' do
- import
- exit
- end
-
- o.subcommand 'export' do
- export
- exit
- end
-
- o.subcommand 'empty' do
- empty
- exit
- end
-
o.on_tail '-v', '--version' do
puts parser.ver
end
@@ -56,59 +40,14 @@ def setup_parser
parser.version = Ghost::VERSION
end
- def add
- add_host Ghost::Host.new(*args.take(2))
- end
-
- def add_host(host)
- store.add(host)
- puts " [Adding] #{host.name} -> #{host.ip}"
- end
-
- def list
- hosts = store.list
-
- pad = hosts.map {|h| h.name.length }.max
-
- puts "Listing #{hosts.size} host(s):"
- hosts.each do |host|
- puts "#{host.name.rjust(pad + 2)} -> #{host.ip}"
- end
- end
-
- def export
- store.list.each do |host|
- puts "#{host.ip} #{host.name}"
- end
- end
-
- def import
- files = args
-
- files.each do |file|
- File.readlines(file).each do |line|
- ip, name = *line.split(/\s+/)
- add_host Ghost::Host.new(name, ip)
- end
- end
- end
-
- def empty
- print " [Emptying] "
- store.empty!
- puts "Done."
- end
-
def print(*args)
out.print(*args)
end
def puts(*args)
out.puts(*args)
end
-
- def store
- Ghost.store
- end
end
end
+
+require 'ghost/cli/task'
View
@@ -0,0 +1,6 @@
+Ghost::Cli.task :add do
+ def perform(*)
+ Ghost.store.add(host)
+ puts " [Adding] #{host.name} -> #{host.ip}"
+ end
+end
View
@@ -0,0 +1,42 @@
+module Ghost
+ class Cli
+ class Task
+ attr_accessor :out
+
+ def initialize(out)
+ self.out = out
+ end
+
+ def perform(*); end
+ def description; end
+ def help; end
+
+ private
+
+ def puts(*args)
+ out.puts(*args)
+ end
+
+ def print(*args)
+ out.print(*args)
+ end
+ end
+
+ def tasks
+ @tasks ||= Hash[self.class.tasks.map { |name, task| [name, task.new(out)] }]
+ end
+
+ class << self
+ def task(name, desc = nil, &block)
+ tasks[name] = Class.new(Task, &block)
+ tasks[name]
+ end
+
+ def tasks
+ @tasks ||= {}
+ end
+ end
+ end
+end
+
+Dir[File.dirname(__FILE__) + "/task/*.rb"].each { |f| require(f) }
@@ -0,0 +1,7 @@
+Ghost::Cli.task :add do
+ def perform(*args)
+ host = Ghost::Host.new(*args.take(2))
+ Ghost.store.add(host)
+ puts "[Adding] #{host.name} -> #{host.ip}"
+ end
+end
@@ -0,0 +1,7 @@
+Ghost::Cli.task :empty do
+ def perform(*)
+ print "[Emptying] "
+ Ghost.store.empty
+ puts "Done."
+ end
+end
@@ -0,0 +1,8 @@
+Ghost::Cli.task :export do
+ def perform(*)
+ Ghost.store.all.each do |host|
+ puts "#{host.ip} #{host.name}"
+ end
+ end
+end
+
@@ -0,0 +1,12 @@
+Ghost::Cli.task :import do
+ def perform(*files)
+ files.each do |file|
+ File.readlines(file).each do |line|
+ ip, name = *line.split(/\s+/)
+ host = Ghost::Host.new(name, ip)
+ Ghost.store.add(host)
+ puts "[Adding] #{host.name} -> #{host.ip}"
+ end
+ end
+ end
+end
View
@@ -0,0 +1,12 @@
+Ghost::Cli.task :list do
+ def perform(*)
+ hosts = Ghost.store.all
+
+ pad = hosts.map {|h| h.name.length }.max
+
+ puts "Listing #{hosts.size} host(s):"
+ hosts.each do |host|
+ puts "#{host.name.rjust(pad + 2)} -> #{host.ip}"
+ end
+ end
+end
View
@@ -3,5 +3,8 @@ class << Ghost
end
require 'ghost/store/hosts_file_store'
-require 'ghost/store/dscl_store'
+require 'ghost/store/dscl_store' # TODO: only load on OS X
+
+require 'tempfile'
+Ghost.store = Ghost::Store::HostsFileStore.new(Tempfile.new('hosts'))
View
@@ -38,7 +38,7 @@ def ghost(args)
it "outputs a summary of the operation" do
store.stub(:add)
- ghost("add my-app.local").should == " [Adding] my-app.local -> 127.0.0.1"
+ ghost("add my-app.local").should == "[Adding] my-app.local -> 127.0.0.1"
end
context "when an entry for that hostname already exists" do
@@ -56,7 +56,7 @@ def ghost(args)
it "outputs a summary of the operation" do
store.stub(:add)
- ghost("add my-app.local 192.168.1.1").should == " [Adding] my-app.local -> 192.168.1.1"
+ ghost("add my-app.local 192.168.1.1").should == "[Adding] my-app.local -> 192.168.1.1"
end
end
@@ -71,7 +71,7 @@ def ghost(args)
it "outputs a summary of the operation" do
store.stub(:add)
- ghost("add my-app.local google.com").should == " [Adding] my-app.local -> 74.125.225.99"
+ ghost("add my-app.local google.com").should == "[Adding] my-app.local -> 74.125.225.99"
end
context "when the remote hostname can not be resolved" do
@@ -102,7 +102,7 @@ def ghost(args)
describe "list" do
before do
- store.stub(:list => [
+ store.stub(:all => [
Ghost::Host.new("gist.github.com", "10.0.0.1"),
Ghost::Host.new("google.com", "192.168.1.10")
])
@@ -125,19 +125,19 @@ def ghost(args)
describe "empty" do
it 'empties the list of hosts' do
- store.should_receive(:empty!)
+ store.should_receive(:empty)
ghost("empty")
end
it 'outputs a summary of the operation' do
- store.stub(:empty!)
- ghost("empty").should == " [Emptying] Done."
+ store.stub(:empty)
+ ghost("empty").should == "[Emptying] Done."
end
end
describe "export" do
it "outputs all hosts one-per-line in hosts file format" do
- store.stub(:list => [
+ store.stub(:all => [
Ghost::Host.new("gist.github.com", "10.0.0.1"),
Ghost::Host.new("google.com", "192.168.1.10")
])

0 comments on commit aeb537d

Please sign in to comment.