martin 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|