martin 0.1.2 → 0.1.3
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/.document +1 -1
- data/VERSION +1 -1
- data/examples/simple/simple.rb +36 -0
- data/examples/simple/users.yml +3 -0
- data/lib/martin.rb +9 -5
- data/lib/martin/application.rb +11 -33
- data/lib/martin/base.rb +86 -70
- data/lib/martin/delegator.rb +19 -0
- data/lib/martin/dsl.rb +30 -38
- data/martin.gemspec +7 -3
- data/test/helper.rb +0 -3
- metadata +7 -3
data/.document
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
@@ -0,0 +1,36 @@
|
|
1
|
+
libdir = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
3
|
+
|
4
|
+
require 'martin'
|
5
|
+
require 'highline/import'
|
6
|
+
require 'yaml'
|
7
|
+
require 'pp'
|
8
|
+
|
9
|
+
class SavedArray < Array
|
10
|
+
attr_accessor :filename
|
11
|
+
def initialize(filename)
|
12
|
+
load(filename)
|
13
|
+
end
|
14
|
+
def load(filename)
|
15
|
+
@filename = filename unless filename.nil?
|
16
|
+
replace YAML.load_file(@filename) if File.exist?(@filename)
|
17
|
+
end
|
18
|
+
def save
|
19
|
+
File.open(@filename, 'w+') do |f|
|
20
|
+
f.puts self.to_yaml
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
configure do
|
26
|
+
@users = SavedArray.new('users.yml')
|
27
|
+
end
|
28
|
+
|
29
|
+
command(/create (.+)/) do |name|
|
30
|
+
@users << name
|
31
|
+
@users.save
|
32
|
+
end
|
33
|
+
|
34
|
+
command(/list/)do |name|
|
35
|
+
puts @users
|
36
|
+
end
|
data/lib/martin.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
-
libdir = File.dirname(__FILE__)
|
2
|
-
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
3
|
-
|
4
|
-
require 'martin/
|
5
|
-
require 'martin/
|
1
|
+
libdir = File.dirname(__FILE__)
|
2
|
+
$LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
|
3
|
+
|
4
|
+
require 'martin/application'
|
5
|
+
require 'martin/delegator'
|
6
|
+
include Martin
|
7
|
+
|
8
|
+
Delegator.delegate Application, :configure, :command, :error, :run
|
9
|
+
Application.run
|
data/lib/martin/application.rb
CHANGED
@@ -1,33 +1,11 @@
|
|
1
|
-
require File.dirname(__FILE__)
|
2
|
-
|
3
|
-
module Martin
|
4
|
-
#
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def #{method_name}(*args, &b)
|
13
|
-
::Martin::Application.send(#{method_name.inspect}, *args, &b)
|
14
|
-
end
|
15
|
-
private #{method_name.inspect}
|
16
|
-
RUBY
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
delegate :configure, :command, :error, :run
|
21
|
-
end
|
22
|
-
|
23
|
-
# This is the class that gets loaded if you just require 'martin'
|
24
|
-
class Application < Base
|
25
|
-
error do |input|
|
26
|
-
puts 'Could not find method ' + input.split.first
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
at_exit { Application.run }
|
31
|
-
end
|
32
|
-
|
33
|
-
include Martin::Delegator
|
1
|
+
require File.join(File.dirname(__FILE__), 'base')
|
2
|
+
|
3
|
+
module Martin
|
4
|
+
# This is the class that gets loaded if you
|
5
|
+
# just require 'martin' AKA 'classic' style
|
6
|
+
class Application < Base
|
7
|
+
error do |input|
|
8
|
+
puts 'Could not find method ' + input.split.first
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/martin/base.rb
CHANGED
@@ -1,71 +1,87 @@
|
|
1
|
-
require File.dirname(__FILE__)
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
#
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
1
|
+
require File.join(File.dirname(__FILE__), 'dsl')
|
2
|
+
|
3
|
+
# TODO:
|
4
|
+
# DSL::Route - to handle all configure, command, and error blocks
|
5
|
+
# DSL::Router - To handle all of the routes
|
6
|
+
#
|
7
|
+
# When Martin::Base.run('some input here') is called:
|
8
|
+
# Run all of the configure blocks
|
9
|
+
# Check to see if the input matches any of the command blocks
|
10
|
+
# if it matches any then
|
11
|
+
# run the first matched block
|
12
|
+
# if the first matched block uses the method 'pass' then
|
13
|
+
# run the next matched block
|
14
|
+
# else
|
15
|
+
# Check to see if input matches any of the error blocks
|
16
|
+
# if it matches any then
|
17
|
+
# run the first error block
|
18
|
+
# if the first error block uses the method 'pass' then
|
19
|
+
# run the next error block
|
20
|
+
# end
|
21
|
+
|
22
|
+
# An ode to the Rat Pack (Dean Martin) with a Sinatra style DSL for creating
|
23
|
+
# Command Line Interfaces to your applications
|
24
|
+
module Martin
|
25
|
+
module InstanceMethods
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
module ClassMethods
|
30
|
+
Configures, Commands, Errors = [], [], []
|
31
|
+
|
32
|
+
# Runs once, at the beginning of the application
|
33
|
+
# If there are multiple configure blocks, then each one will run in the
|
34
|
+
# order the were created.
|
35
|
+
#
|
36
|
+
# @param [Regexp] cmd the regexp you want to match to run the command
|
37
|
+
def configure(&block)
|
38
|
+
Configures << DSL::Configure.new(block)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Adds a command
|
42
|
+
#
|
43
|
+
# @param [Regexp] cmd the regexp you want to match to run the command
|
44
|
+
def command(regexp, &block)
|
45
|
+
Commands << DSL::Command.new(regexp, block)
|
46
|
+
end
|
47
|
+
|
48
|
+
# When the user input matches non of the user's commands then this
|
49
|
+
# method will run
|
50
|
+
# If there are multiple error blocks, then each one will run in the
|
51
|
+
# order the were created.
|
52
|
+
#
|
53
|
+
# @param [Regexp] cmd the regexp you want to match to run the command
|
54
|
+
def error(&block)
|
55
|
+
Errors << DSL::Error.new(block)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Runs the application on the given arguments
|
59
|
+
#
|
60
|
+
# @param [String] args The arguments to run the application on. Default is ARGV.join(' ')
|
61
|
+
def run(args = ARGV.join(' '))
|
62
|
+
Configures.each do |configure|
|
63
|
+
configure.block.call
|
64
|
+
end
|
65
|
+
Commands.each do |command|
|
66
|
+
match = command.regexp.match(args)
|
67
|
+
unless match.nil?
|
68
|
+
command.block.call(*match.captures)
|
69
|
+
else
|
70
|
+
Errors.each do |error|
|
71
|
+
error.block.call(args)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
self
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# The base class for command line applications
|
80
|
+
# Subclass this class for the functionality
|
81
|
+
class Base
|
82
|
+
def self.inherited(base)
|
83
|
+
extend ClassMethods
|
84
|
+
include InstanceMethods
|
85
|
+
end
|
86
|
+
end
|
71
87
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Martin
|
2
|
+
# Martin delegation mixin. Mixing this module into an object causes all
|
3
|
+
# methods to be delegated to the Martin::Application class. Used primarily
|
4
|
+
# at the top-level.
|
5
|
+
#
|
6
|
+
# 92% ripped from Sinatra::Delegator
|
7
|
+
module Delegator #:nodoc:
|
8
|
+
def self.delegate(mod, *methods)
|
9
|
+
methods.each do |method_name|
|
10
|
+
eval <<-RUBY, binding, '(__DELEGATE__)', 1
|
11
|
+
def #{method_name}(*args, &b)
|
12
|
+
mod.send(#{method_name.inspect}, *args, &b)
|
13
|
+
end
|
14
|
+
private #{method_name.inspect}
|
15
|
+
RUBY
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/martin/dsl.rb
CHANGED
@@ -1,39 +1,31 @@
|
|
1
|
-
class Object
|
2
|
-
# Throw a TypeError unless this object's type is cls
|
3
|
-
#
|
4
|
-
# @param cls The class this object should be
|
5
|
-
def should_be_a(cls)
|
6
|
-
raise(TypeError, "#{self.to_s} must be of type #{cls.to_s}") unless self.is_a?(cls)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
module Martin
|
11
|
-
module DSL
|
12
|
-
|
13
|
-
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
class Method
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
class
|
30
|
-
|
31
|
-
def initialize(regexp, block)
|
32
|
-
super(block)
|
33
|
-
regexp.should_be_a(Regexp)
|
34
|
-
@regexp = regexp
|
35
|
-
end
|
36
|
-
end
|
37
|
-
class Error < Method; end
|
38
|
-
end
|
1
|
+
class Object
|
2
|
+
# Throw a TypeError unless this object's type is cls
|
3
|
+
#
|
4
|
+
# @param cls The class this object should be
|
5
|
+
def should_be_a(cls)
|
6
|
+
raise(TypeError, "#{self.to_s} must be of type #{cls.to_s}") unless self.is_a?(cls)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Martin
|
11
|
+
module DSL
|
12
|
+
class Method
|
13
|
+
attr_accessor :block
|
14
|
+
def initialize(block)
|
15
|
+
block.should_be_a(Proc)
|
16
|
+
@block = block
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Configure < Method; end
|
21
|
+
class Command < Method
|
22
|
+
attr_accessor :regexp
|
23
|
+
def initialize(regexp, block)
|
24
|
+
super(block)
|
25
|
+
regexp.should_be_a(Regexp)
|
26
|
+
@regexp = regexp
|
27
|
+
end
|
28
|
+
end
|
29
|
+
class Error < Method; end
|
30
|
+
end
|
39
31
|
end
|
data/martin.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{martin}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ryan Lewis"]
|
12
|
-
s.date = %q{2010-04-
|
12
|
+
s.date = %q{2010-04-19}
|
13
13
|
s.description = %q{An ode to the Rat Pack (Dean Martin) with a Sinatra style DSL for creating command line interfaces to your applications}
|
14
14
|
s.email = %q{c00lryguy@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -23,9 +23,12 @@ Gem::Specification.new do |s|
|
|
23
23
|
"README.md",
|
24
24
|
"Rakefile",
|
25
25
|
"VERSION",
|
26
|
+
"examples/simple/simple.rb",
|
27
|
+
"examples/simple/users.yml",
|
26
28
|
"lib/martin.rb",
|
27
29
|
"lib/martin/application.rb",
|
28
30
|
"lib/martin/base.rb",
|
31
|
+
"lib/martin/delegator.rb",
|
29
32
|
"lib/martin/dsl.rb",
|
30
33
|
"martin.gemspec",
|
31
34
|
"test/helper.rb",
|
@@ -38,7 +41,8 @@ Gem::Specification.new do |s|
|
|
38
41
|
s.summary = %q{A Sinatra style DSL for creating command line applications}
|
39
42
|
s.test_files = [
|
40
43
|
"test/helper.rb",
|
41
|
-
"test/test_martin.rb"
|
44
|
+
"test/test_martin.rb",
|
45
|
+
"examples/simple/simple.rb"
|
42
46
|
]
|
43
47
|
|
44
48
|
if s.respond_to? :specification_version then
|
data/test/helper.rb
CHANGED
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 3
|
9
|
+
version: 0.1.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Ryan Lewis
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-04-
|
17
|
+
date: 2010-04-19 00:00:00 -04:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -45,9 +45,12 @@ files:
|
|
45
45
|
- README.md
|
46
46
|
- Rakefile
|
47
47
|
- VERSION
|
48
|
+
- examples/simple/simple.rb
|
49
|
+
- examples/simple/users.yml
|
48
50
|
- lib/martin.rb
|
49
51
|
- lib/martin/application.rb
|
50
52
|
- lib/martin/base.rb
|
53
|
+
- lib/martin/delegator.rb
|
51
54
|
- lib/martin/dsl.rb
|
52
55
|
- martin.gemspec
|
53
56
|
- test/helper.rb
|
@@ -85,3 +88,4 @@ summary: A Sinatra style DSL for creating command line applications
|
|
85
88
|
test_files:
|
86
89
|
- test/helper.rb
|
87
90
|
- test/test_martin.rb
|
91
|
+
- examples/simple/simple.rb
|