mvcli 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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +4 -0
- data/Rakefile +6 -0
- data/example/controllers/loadbalancers_controller.rb +10 -0
- data/example/routes.rb +31 -0
- data/lib/mvcli/actions.rb +30 -0
- data/lib/mvcli/app.rb +33 -0
- data/lib/mvcli/command.rb +9 -0
- data/lib/mvcli/middleware.rb +38 -0
- data/lib/mvcli/router.rb +34 -0
- data/lib/mvcli/version.rb +3 -0
- data/lib/mvcli.rb +5 -0
- data/mvcli.gemspec +22 -0
- data/spec/mvcli/actions_spec.rb +30 -0
- data/spec/mvcli/middleware_spec.rb +74 -0
- data/spec/mvcli/router_spec.rb +60 -0
- data/spec/spec_helper.rb +3 -0
- metadata +102 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2af39b708e5b71d002d6734923412e067411c115
|
4
|
+
data.tar.gz: dcdf57432aeb3712a27878088ae4a527728b9ac2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dceaaf28dae8821938e47b2c528330e6cacf7abe51bfddadf0ef94c0b4d201659e55bcf52188280d88fe3f92d01728adb1e2014bc048e78aae49d795f61e3e83
|
7
|
+
data.tar.gz: 4b6586b4eb3b18213257b23122114d66800419d1a1940b79c4c39512ffa33e87800a04feb7610315815f7d6e1187c591e1dc3f54ada6d70c80ac0aa3fecd1a86
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Charles Lowell
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
data/Rakefile
ADDED
data/example/routes.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
collection :loadbalancers do
|
2
|
+
# match "create loadbalancer"
|
3
|
+
# match "show loadbalancers"
|
4
|
+
# match "loadbalancers"
|
5
|
+
# match "show loadbalancer :id" #=> 'loadbalancers#show'
|
6
|
+
# match "update loadbalancer :id #=> loadbalancers#update"
|
7
|
+
# match "destroy loadbalancer :id"
|
8
|
+
collection :nodes do
|
9
|
+
# match "create node on loadbalancer :loadbalancer_id"
|
10
|
+
# match "create loadbalancer :loadbalancer_id node"
|
11
|
+
# match "show nodes on loadbalancer :loadbalancer_id"
|
12
|
+
# match "loadbalancer nodes"
|
13
|
+
# match "show loadbalancer :loadbalancer_id nodes"
|
14
|
+
# match "show loadbalancer :loadbalancer_id node :id"
|
15
|
+
# match "show node :id on loadbalancer :loadbalancer_id"
|
16
|
+
# match "update loadbalancer:node"
|
17
|
+
# match "destroy loadbalancer:node:$id"
|
18
|
+
# match "destroy loadbalancer node $id"
|
19
|
+
# match "destroy loadbalancer:node $id"
|
20
|
+
# match "help "
|
21
|
+
end
|
22
|
+
|
23
|
+
collection :virtual_ips, :only => :index
|
24
|
+
# match "show virtual_ips on loadbalancer :loadbalancer_id"
|
25
|
+
# match "show loadbalancer :loadbalancer_id virtual_ips"
|
26
|
+
# match "loadbalancers"
|
27
|
+
end
|
28
|
+
|
29
|
+
collection :servers do
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module MVCLI
|
2
|
+
class Actions
|
3
|
+
def initialize(loader, renderer)
|
4
|
+
@loader = loader
|
5
|
+
@renderer = renderer
|
6
|
+
end
|
7
|
+
|
8
|
+
def [](key)
|
9
|
+
controller, method = key.split('#')
|
10
|
+
Action.new @loader, @renderer, controller, method
|
11
|
+
end
|
12
|
+
|
13
|
+
class Action
|
14
|
+
def initialize(loader, renderer, controller, method)
|
15
|
+
@loader = loader
|
16
|
+
@renderer = renderer
|
17
|
+
@controller = controller
|
18
|
+
@method = method
|
19
|
+
end
|
20
|
+
|
21
|
+
def call(command)
|
22
|
+
controller = @loader.load :controller, @controller
|
23
|
+
fail LoadError, "no such controller: #{@controller}" unless controller
|
24
|
+
context = controller.send @method
|
25
|
+
path = [@controller, @method].join('/')
|
26
|
+
@renderer.render command.output, path, context
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/mvcli/app.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative "middleware"
|
2
|
+
require_relative "command"
|
3
|
+
require_relative "router"
|
4
|
+
|
5
|
+
module MVCLI
|
6
|
+
class App
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@middleware = Middleware.new
|
10
|
+
@middleware << Router.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(command)
|
14
|
+
@middleware.call command
|
15
|
+
end
|
16
|
+
|
17
|
+
def root
|
18
|
+
self.class.root or fail "Invalid App: undefined application root directory"
|
19
|
+
end
|
20
|
+
|
21
|
+
class << self
|
22
|
+
attr_accessor :root
|
23
|
+
end
|
24
|
+
|
25
|
+
def main(argv = ARGV.dup, input = $stdin, output = $stdout, log = $stderr, env = ENV.dup)
|
26
|
+
call Command.new(argv, input, output, log, env)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.main(*args)
|
30
|
+
new.main *args
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module MVCLI
|
2
|
+
class Middleware
|
3
|
+
def initialize
|
4
|
+
@apps = []
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(command)
|
8
|
+
invoke command, 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def [](idx)
|
12
|
+
@apps[idx]
|
13
|
+
end
|
14
|
+
|
15
|
+
def []=(idx, app)
|
16
|
+
@apps[idx] = app
|
17
|
+
end
|
18
|
+
|
19
|
+
def <<(app)
|
20
|
+
@apps << app
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def invoke(command, index)
|
26
|
+
if app = @apps[index]
|
27
|
+
app.call(command) do |c|
|
28
|
+
if @apps[index + 1]
|
29
|
+
c ||= command
|
30
|
+
invoke c, index + 1
|
31
|
+
end
|
32
|
+
end
|
33
|
+
else
|
34
|
+
return 0
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/mvcli/router.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require "map"
|
2
|
+
|
3
|
+
module MVCLI
|
4
|
+
class Router
|
5
|
+
RoutingError = Class.new StandardError
|
6
|
+
InvalidRoute = Class.new RoutingError
|
7
|
+
|
8
|
+
def initialize(actions = nil)
|
9
|
+
@actions = actions || Map.new
|
10
|
+
@root = Map.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def root(options = {})
|
14
|
+
action = options[:to] or fail InvalidRoute, "root routes must specify an action with ':to =>' E.g. root :to => 'foo#bar'"
|
15
|
+
verbs = [options[:via] || :help].flatten
|
16
|
+
verbs.each do |verb|
|
17
|
+
@root[verb] = action
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def call(command)
|
22
|
+
verb = command.argv.first || 'help'
|
23
|
+
path = command.argv.slice(1..-1) || []
|
24
|
+
if path.empty?
|
25
|
+
if action_name = @root[verb]
|
26
|
+
if action = @actions[action_name]
|
27
|
+
return action.call command
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
fail RoutingError, "#{path.join(':')} does not respond to #{verb}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/mvcli.rb
ADDED
data/mvcli.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'mvcli/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "mvcli"
|
8
|
+
spec.version = MVCLI::VERSION
|
9
|
+
spec.authors = ["Charles Lowell"]
|
10
|
+
spec.email = ["cowboyd@thefrontside.net"]
|
11
|
+
spec.description = %q{MVC Framework for Building Command Line Apps}
|
12
|
+
spec.summary = %q{Local Apps. Remote Apps. They're all at your fingertips}
|
13
|
+
spec.homepage = "https://github.com/cowboyd/mvcli"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "map"
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "mvcli/actions"
|
3
|
+
|
4
|
+
describe "MVCLI::Actions" do
|
5
|
+
Given(:loader) {mock(:Loader)}
|
6
|
+
Given(:renderer) {mock(:Renderer, :render => true)}
|
7
|
+
Given(:actions) {MVCLI::Actions.new loader, renderer}
|
8
|
+
|
9
|
+
context "when the loader cannot find an appropriate controller" do
|
10
|
+
Given {loader.stub(:load)}
|
11
|
+
|
12
|
+
When(:action) {actions['foo']}
|
13
|
+
Then {action.should_not be_nil}
|
14
|
+
|
15
|
+
context ".calling it" do
|
16
|
+
When(:result) {action.call(mock(:Command))}
|
17
|
+
Then {result.should have_failed LoadError}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when the class exists" do
|
22
|
+
Given(:output) {mock(:Output)}
|
23
|
+
Given(:controller) {mock(:Controller)}
|
24
|
+
Given {loader.stub(:load).with(:controller, 'foo') {controller}}
|
25
|
+
Given {controller.stub(:bar) {"the context"}}
|
26
|
+
When {actions['foo#bar'].call(mock(:Command, :output => output))}
|
27
|
+
Then {controller.should have_received(:bar)}
|
28
|
+
And {renderer.should have_received(:render).with(output, 'foo/bar', 'the context')}
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "mvcli/middleware"
|
3
|
+
|
4
|
+
describe "MVCLI::Middleware" do
|
5
|
+
before do
|
6
|
+
@middleware = MVCLI::Middleware.new
|
7
|
+
@command = mock(:Command)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "runs perfectly fine without any apps" do
|
11
|
+
@middleware.call(@command).should eql 0
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "with a single app" do
|
15
|
+
before do
|
16
|
+
@app = proc do |command|
|
17
|
+
@called = command
|
18
|
+
end
|
19
|
+
@middleware << @app
|
20
|
+
@middleware.call @command
|
21
|
+
end
|
22
|
+
it "calls it" do
|
23
|
+
@called.should eql @command
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "with a couple apps" do
|
28
|
+
before do
|
29
|
+
@sequence = []
|
30
|
+
@commands = []
|
31
|
+
@middleware << proc do |command, &block|
|
32
|
+
@commands << command
|
33
|
+
@sequence << "first.before"
|
34
|
+
block.call
|
35
|
+
@sequence << "first.after"
|
36
|
+
end
|
37
|
+
@middleware << proc do |command, &block|
|
38
|
+
@commands << command
|
39
|
+
@sequence << "second"
|
40
|
+
end
|
41
|
+
@middleware.call @command
|
42
|
+
end
|
43
|
+
it "passes the command to all the apps" do
|
44
|
+
@commands.should eql [@command, @command]
|
45
|
+
end
|
46
|
+
it "calls the first app *around* the second app" do
|
47
|
+
@sequence.should eql ["first.before", "second", "first.after"]
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "if the first app does not yield" do
|
51
|
+
before do
|
52
|
+
@sequence.clear
|
53
|
+
@middleware[0] = Proc.new {}
|
54
|
+
@middleware.call @command
|
55
|
+
end
|
56
|
+
it "never calls the second app" do
|
57
|
+
@sequence.should eql []
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "with an app that yields even though there is no next app" do
|
63
|
+
before do
|
64
|
+
app = Object.new
|
65
|
+
def app.call(command)
|
66
|
+
yield
|
67
|
+
end
|
68
|
+
@middleware << @app
|
69
|
+
end
|
70
|
+
it "runs successfully" do
|
71
|
+
@middleware.call(@command).should eql 0
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "mvcli/router"
|
3
|
+
|
4
|
+
describe "MVCLI::Router" do
|
5
|
+
Given(:Router) {MVCLI::Router}
|
6
|
+
Given(:actions) {mock(:Actions)}
|
7
|
+
Given(:router) {self.Router.new actions}
|
8
|
+
|
9
|
+
context "without any routes" do
|
10
|
+
When(:result) {invoke}
|
11
|
+
Then {result.should have_failed self.Router::RoutingError}
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when an invalid root is mapped" do
|
15
|
+
When(:result) {router.root :wat => :tf?}
|
16
|
+
Then {result.should have_failed}
|
17
|
+
end
|
18
|
+
|
19
|
+
context "with its root mapped to a single verb" do
|
20
|
+
Given do
|
21
|
+
actions.stub(:[]).with('logins#create') do
|
22
|
+
proc do |command|
|
23
|
+
@login = command
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
Given {router.root :to => 'logins#create', :via => :login}
|
28
|
+
When {invoke 'login'}
|
29
|
+
Then {@login.argv.should eql ['login']}
|
30
|
+
|
31
|
+
context "when a command comes in for an unmapped verb" do
|
32
|
+
When(:result) {invoke 'fwiff'}
|
33
|
+
Then {result.should have_failed self.Router::RoutingError}
|
34
|
+
end
|
35
|
+
context "and a second verb is mapped to the the root" do
|
36
|
+
Given do
|
37
|
+
actions.stub(:[]).with('logins#destroy') {proc {|c| @logout = c}}
|
38
|
+
end
|
39
|
+
Given {router.root :to => 'logins#destroy', :via => :logout}
|
40
|
+
context "when I access via the original verb" do
|
41
|
+
Given {invoke 'logout' }
|
42
|
+
Then {@logout.should_not be_nil}
|
43
|
+
And {@logout.argv.should eql ['logout']}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "with its root mapped without a specific verb" do
|
49
|
+
Given do
|
50
|
+
actions.stub(:[]).with('something#show') {proc {|c|@something = c}}
|
51
|
+
end
|
52
|
+
Given {router.root :to => 'something#show'}
|
53
|
+
When {invoke 'help'}
|
54
|
+
Then {@something.argv.should eql ['help']}
|
55
|
+
end
|
56
|
+
|
57
|
+
def invoke(*args)
|
58
|
+
router.call mock(:Command, :argv => args)
|
59
|
+
end
|
60
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mvcli
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Charles Lowell
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDPjCCAiagAwIBAgIBADANBgkqhkiG9w0BAQUFADBFMRAwDgYDVQQDDAdjb3di
|
14
|
+
b3lkMRwwGgYKCZImiZPyLGQBGRYMdGhlZnJvbnRzaWRlMRMwEQYKCZImiZPyLGQB
|
15
|
+
GRYDbmV0MB4XDTEzMDEzMDIxMDYwNFoXDTE0MDEzMDIxMDYwNFowRTEQMA4GA1UE
|
16
|
+
AwwHY293Ym95ZDEcMBoGCgmSJomT8ixkARkWDHRoZWZyb250c2lkZTETMBEGCgmS
|
17
|
+
JomT8ixkARkWA25ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO45
|
18
|
+
CUxpETDGYXjCCy2dMg/aIrdrTqBqQW5ZrzhHxF9EkcdmWFr0z/qMz0JSpZ3pF11Z
|
19
|
+
KYaj5PaQQpjZfLPwbuiGGkuSWi+UAac//V18xo6S4lzRBjO+gpzG9f2AOzt9b+SR
|
20
|
+
Uc8UhO7QBZ5edUDxMxw9QstD+U0YBAlzsPJbHuUOqdtxXmNQCds3ZnqTgZaIpdUy
|
21
|
+
CSejtrukSmlthxFzwgMezYQhcYxmkl+Q475JUodnI6Pjc6nja/Or8Y6cEWiLgeUa
|
22
|
+
a+efcPGLDEbwJC7TGRrvk8yassMByBEJ3XueTMzeqWFd+665ptciojYo6BvIAR0N
|
23
|
+
iLwks0x567FZyS8SqTcCAwEAAaM5MDcwCQYDVR0TBAIwADAdBgNVHQ4EFgQUxVgR
|
24
|
+
5TUqf7Hd24ICb3g4FNbM7oYwCwYDVR0PBAQDAgSwMA0GCSqGSIb3DQEBBQUAA4IB
|
25
|
+
AQDdJj+NzZhiYXA56z0wzRUA/Fcf6CYqKB+RFRlPssDEcHTor5SnwdWgQof/gNLi
|
26
|
+
Qel1Om4zO0Shcp89jxaUqtvEdYVhmyfc0vycHmemKttNBT734yMrEJtF8Hhy+Dnz
|
27
|
+
9CzixXLvgGaRH+mf3M0+l+zIDJJr2L+39L8cyTSSRnp/srfI8aSmJKhGshudBKoC
|
28
|
+
Ty6Gi071pwoJXvdMaE/6iPy7bUzlndYdHyYuWSKaO9N47HqQ62oEnBraglw6ghoi
|
29
|
+
UgImJlChAzCoDP9zi9tdm6jAr7ttF25R9PPYr11ILb7dYe3qUzlNlM6zJx/nb31b
|
30
|
+
IhdyRVup4qLcqYSTPsm6u7VA
|
31
|
+
-----END CERTIFICATE-----
|
32
|
+
date: 2013-05-20 00:00:00.000000000 Z
|
33
|
+
dependencies:
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: map
|
36
|
+
requirement: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
type: :runtime
|
42
|
+
prerelease: false
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
description: MVC Framework for Building Command Line Apps
|
49
|
+
email:
|
50
|
+
- cowboyd@thefrontside.net
|
51
|
+
executables: []
|
52
|
+
extensions: []
|
53
|
+
extra_rdoc_files: []
|
54
|
+
files:
|
55
|
+
- .gitignore
|
56
|
+
- Gemfile
|
57
|
+
- LICENSE.txt
|
58
|
+
- README.md
|
59
|
+
- Rakefile
|
60
|
+
- example/controllers/loadbalancers_controller.rb
|
61
|
+
- example/routes.rb
|
62
|
+
- lib/mvcli.rb
|
63
|
+
- lib/mvcli/actions.rb
|
64
|
+
- lib/mvcli/app.rb
|
65
|
+
- lib/mvcli/command.rb
|
66
|
+
- lib/mvcli/middleware.rb
|
67
|
+
- lib/mvcli/router.rb
|
68
|
+
- lib/mvcli/version.rb
|
69
|
+
- mvcli.gemspec
|
70
|
+
- spec/mvcli/actions_spec.rb
|
71
|
+
- spec/mvcli/middleware_spec.rb
|
72
|
+
- spec/mvcli/router_spec.rb
|
73
|
+
- spec/spec_helper.rb
|
74
|
+
homepage: https://github.com/cowboyd/mvcli
|
75
|
+
licenses:
|
76
|
+
- MIT
|
77
|
+
metadata: {}
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - '>='
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubyforge_project:
|
94
|
+
rubygems_version: 2.0.0
|
95
|
+
signing_key:
|
96
|
+
specification_version: 4
|
97
|
+
summary: Local Apps. Remote Apps. They're all at your fingertips
|
98
|
+
test_files:
|
99
|
+
- spec/mvcli/actions_spec.rb
|
100
|
+
- spec/mvcli/middleware_spec.rb
|
101
|
+
- spec/mvcli/router_spec.rb
|
102
|
+
- spec/spec_helper.rb
|