valet 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +4 -4
- data/CHANGELOG.md +17 -0
- data/README.md +2 -2
- data/bin/valet +14 -0
- data/features/help.feature +2 -2
- data/features/version.feature +5 -103
- data/lib/valet.rb +5 -4
- data/lib/valet/application.rb +9 -17
- data/lib/valet/command.rb +60 -0
- data/lib/valet/commands.rb +7 -0
- data/lib/valet/helpers/type_cast.rb +46 -0
- data/lib/valet/option/common.rb +58 -0
- data/lib/valet/option/flag.rb +44 -0
- data/lib/valet/option/switch.rb +32 -0
- data/lib/valet/options.rb +31 -0
- data/lib/valet/version.rb +1 -1
- data/spec/spec_helper.rb +5 -9
- data/spec/support/shared_examples.rb +54 -0
- data/spec/support/terminal_helper.rb +20 -0
- data/spec/valet/application_spec.rb +57 -27
- data/spec/valet/command_spec.rb +116 -0
- data/spec/valet/commands_spec.rb +5 -0
- data/spec/valet/helpers/type_cast_spec.rb +33 -0
- data/spec/valet/option/flag_spec.rb +73 -0
- data/spec/valet/option/switch_spec.rb +59 -0
- data/spec/valet/options_spec.rb +56 -0
- data/spec/valet/version_spec.rb +4 -4
- data/valet.gemspec +9 -11
- metadata +30 -36
- data/features/step_definitions/command_line_steps.rb +0 -3
- data/features/step_definitions/file_steps.rb +0 -3
- data/features/support/helpers/cli_helper.rb +0 -23
- data/features/support/world_extensions.rb +0 -1
- data/lib/valet/templates/version.mustache +0 -5
- data/lib/valet/view.rb +0 -29
- data/lib/valet/views/version.rb +0 -31
- data/spec/valet/view_spec.rb +0 -20
data/.travis.yml
CHANGED
@@ -3,13 +3,13 @@ script: "bundle exec rspec spec && bundle exec cucumber features"
|
|
3
3
|
rvm:
|
4
4
|
- 1.9.2
|
5
5
|
- 1.9.3
|
6
|
-
-
|
7
|
-
-
|
6
|
+
- jruby-19mode
|
7
|
+
- rbx-19mode
|
8
8
|
|
9
9
|
matrix:
|
10
10
|
allow_failures:
|
11
|
-
- rvm:
|
12
|
-
- rvm:
|
11
|
+
- rvm: jruby-19mode
|
12
|
+
- rvm: rbx-19mode
|
13
13
|
|
14
14
|
branches:
|
15
15
|
only:
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# Valet - CHANGELOG
|
2
2
|
|
3
|
+
### 0.0.8 / 11.07.2012
|
4
|
+
|
5
|
+
Started over with a new approach, designing business objects and API first
|
6
|
+
|
7
|
+
* Made an output notice in bin/valet to notify the user of Valet's current
|
8
|
+
development status
|
9
|
+
* Implemented core classes with basic business rules
|
10
|
+
* Application
|
11
|
+
* Command
|
12
|
+
* Options
|
13
|
+
* Option::Switch
|
14
|
+
* Option::Flag
|
15
|
+
* New RSpec 'expect' syntax and improved support files to help with testing
|
16
|
+
stdout, stderr and stdin streams
|
17
|
+
* Playing around with Travis (JRuby and Rubinius compatibility seems to fail on
|
18
|
+
me because of C-extensions and code coverage...)
|
19
|
+
|
3
20
|
### 0.0.7 / 08.07.2012
|
4
21
|
|
5
22
|
* JRuby and Rubinius still won't build successfully on Travis. Allowed them once
|
data/README.md
CHANGED
@@ -7,8 +7,8 @@ __Git Repository__: <https://github.com/gitkeeper/valet>
|
|
7
7
|
__Author__: Alexander Baumann
|
8
8
|
__Copyright__: 2012
|
9
9
|
__License__: MIT License
|
10
|
-
__Latest Version__: 0.0.
|
11
|
-
__Release Date__:
|
10
|
+
__Latest Version__: 0.0.8
|
11
|
+
__Release Date__: 11.07.2012
|
12
12
|
|
13
13
|
## Introduction
|
14
14
|
|
data/bin/valet
CHANGED
@@ -1 +1,15 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'valet/version'
|
4
|
+
|
5
|
+
puts <<-MESSAGE.gsub(/^ {2}/, '')
|
6
|
+
|
7
|
+
# -------------------------------------------------------------------- #
|
8
|
+
|
9
|
+
Thank you for trying out Valet #{Valet::VERSION::STRING}!
|
10
|
+
|
11
|
+
Valet is still in development and not yet intended to be used.
|
12
|
+
|
13
|
+
# -------------------------------------------------------------------- #
|
14
|
+
|
15
|
+
MESSAGE
|
data/features/help.feature
CHANGED
@@ -30,10 +30,10 @@ Feature: Help (--help)
|
|
30
30
|
http://www.gnu.org/prep/standards/standards.html#g_t_002d_002dhelp
|
31
31
|
|
32
32
|
Scenario: Usage and syntax reference
|
33
|
-
Scenario: Short description about
|
33
|
+
Scenario: Short description about Valet's purpose
|
34
34
|
Scenario: List of examples
|
35
35
|
Scenario: Available global options
|
36
|
-
Scenario: Available sub-commands
|
36
|
+
Scenario: Available (sub-)commands
|
37
37
|
Scenario: Bug reporting address
|
38
38
|
Scenario: Application homepage
|
39
39
|
Scenario: Other commands, options and operands are ignored
|
data/features/version.feature
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
@wip
|
1
2
|
Feature: Version (--version)
|
2
3
|
|
3
|
-
In order to check
|
4
|
-
As a software developer and user of
|
4
|
+
In order to check Valet's version and legal information
|
5
|
+
As a software developer and user of Valet
|
5
6
|
I want to print out its version summary
|
6
7
|
|
7
|
-
|
8
|
+
The version summary should look like this:
|
8
9
|
|
9
10
|
Valet 1.2.3
|
10
11
|
Copyright (c) 2012 Alexander Baumann
|
@@ -15,104 +16,5 @@ Feature: Version (--version)
|
|
15
16
|
GNU Coding Standards:
|
16
17
|
http://www.gnu.org/prep/standards/standards.html#g_t_002d_002dversion
|
17
18
|
|
18
|
-
Scenario:
|
19
|
-
Given a Valet application named "name.rb" with:
|
20
|
-
"""
|
21
|
-
self.name = 'Backup'
|
22
|
-
"""
|
23
|
-
When I successfully run the script `name.rb --version`
|
24
|
-
Then the stdout should contain "Backup"
|
25
|
-
|
26
|
-
Scenario: Print out application name and version
|
27
|
-
Given a Valet application named "name_and_version.rb" with:
|
28
|
-
"""
|
29
|
-
self.name = 'Backup'
|
30
|
-
self.version = '1.2.3'
|
31
|
-
"""
|
32
|
-
When I successfully run the script `name_and_version.rb --version`
|
33
|
-
Then the stdout should contain "Backup 1.2.3"
|
34
|
-
|
35
|
-
Scenario: Print out authors
|
36
|
-
Given a Valet application named "authors.rb" with:
|
37
|
-
"""
|
38
|
-
self.authors = ['Alexander Baumann', 'Bob the Builder']
|
39
|
-
"""
|
40
|
-
When I successfully run the script `authors.rb --version`
|
41
|
-
Then the stdout should contain:
|
42
|
-
"""
|
43
|
-
Written by Alexander Baumann, Bob the Builder
|
44
|
-
"""
|
45
|
-
|
46
|
-
Scenario: Print out copyright notice
|
47
|
-
Given a Valet application named "copyright.rb" with:
|
48
|
-
"""
|
49
|
-
self.copyright = 'Copyright (c) 2012 Free Software Foundation, Inc.'
|
50
|
-
"""
|
51
|
-
When I successfully run the script `copyright.rb --version`
|
52
|
-
Then the stdout should contain:
|
53
|
-
"""
|
54
|
-
Copyright (c) 2012 Free Software Foundation, Inc.
|
55
|
-
"""
|
56
|
-
|
57
|
-
Scenario: Print out legal status
|
58
|
-
Given a Valet application named "legal_status.rb" with:
|
59
|
-
"""
|
60
|
-
self.license = <<-LICENSE.gsub(/^ {4}/, '').strip
|
61
|
-
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
62
|
-
This is free software: You are free to change and redistribute it.
|
63
|
-
There is NO WARRANTY, to the extent permitted by law.
|
64
|
-
LICENSE
|
65
|
-
"""
|
66
|
-
When I successfully run the script `legal_status.rb --version`
|
67
|
-
Then the stdout should contain:
|
68
|
-
"""
|
69
|
-
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
70
|
-
This is free software: You are free to change and redistribute it.
|
71
|
-
There is NO WARRANTY, to the extent permitted by law.
|
72
|
-
"""
|
73
|
-
|
74
|
-
Scenario: Print out the complete version summary
|
75
|
-
Given a Valet application named "version.rb" with:
|
76
|
-
"""
|
77
|
-
self.name = 'Backup'
|
78
|
-
self.version = '1.2.3'
|
79
|
-
self.authors = ['Alexander Baumann', 'Bob the Builder']
|
80
|
-
self.copyright = 'Copyright (c) 2012 Free Software Foundation, Inc.'
|
81
|
-
self.license = <<-LICENSE.gsub(/^ {4}/, '').strip
|
82
|
-
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
83
|
-
This is free software: You are free to change and redistribute it.
|
84
|
-
There is NO WARRANTY, to the extent permitted by law.
|
85
|
-
LICENSE
|
86
|
-
"""
|
87
|
-
When I successfully run the script `version.rb --version`
|
88
|
-
Then the stdout should contain:
|
89
|
-
"""
|
90
|
-
Backup 1.2.3
|
91
|
-
Copyright (c) 2012 Free Software Foundation, Inc.
|
92
|
-
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
93
|
-
This is free software: You are free to change and redistribute it.
|
94
|
-
There is NO WARRANTY, to the extent permitted by law.
|
95
|
-
|
96
|
-
Written by Alexander Baumann, Bob the Builder
|
97
|
-
"""
|
98
|
-
|
99
|
-
Scenario: Customizable/Overridable version summary template
|
100
|
-
Given a file named "templates/version.mustache" with:
|
101
|
-
"""
|
102
|
-
{{name}} {{version}}
|
103
|
-
For more information, please visit http://gitkeeper.github.com/valet
|
104
|
-
"""
|
105
|
-
And a Valet application named "custom_version_template.rb" with:
|
106
|
-
"""
|
107
|
-
self.name = 'Backup'
|
108
|
-
self.version = '1.2.3'
|
109
|
-
"""
|
110
|
-
When I successfully run the script `custom_version_template.rb --version`
|
111
|
-
Then the stdout should contain:
|
112
|
-
"""
|
113
|
-
Backup 1.2.3
|
114
|
-
For more information, please visit http://gitkeeper.github.com/valet
|
115
|
-
"""
|
116
|
-
|
117
|
-
@wip
|
19
|
+
Scenario: The global `--version` option prints out the summary
|
118
20
|
Scenario: Other commands, options and operands are ignored
|
data/lib/valet.rb
CHANGED
@@ -21,9 +21,10 @@
|
|
21
21
|
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
22
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
23
|
|
24
|
-
require 'mustache'
|
25
|
-
|
26
24
|
require 'valet/version'
|
27
25
|
require 'valet/application'
|
28
|
-
require 'valet/
|
29
|
-
require 'valet/
|
26
|
+
require 'valet/command'
|
27
|
+
require 'valet/commands'
|
28
|
+
require 'valet/option/switch'
|
29
|
+
require 'valet/option/flag'
|
30
|
+
require 'valet/options'
|
data/lib/valet/application.rb
CHANGED
@@ -1,22 +1,14 @@
|
|
1
1
|
module Valet
|
2
2
|
class Application
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
def initialize(args)
|
14
|
-
@args = args
|
15
|
-
render_version
|
16
|
-
end
|
17
|
-
|
18
|
-
def render_version
|
19
|
-
puts Views::Version.new(self.class).render.strip
|
3
|
+
attr_reader :arguments, :options, :commands, :examples
|
4
|
+
attr_accessor :name, :version, :authors, :email, :homepage
|
5
|
+
attr_accessor :copyright, :license, :summary, :description
|
6
|
+
|
7
|
+
def initialize(arguments = ARGV)
|
8
|
+
@arguments = arguments
|
9
|
+
@options = Options.new
|
10
|
+
@commands = Commands.new
|
11
|
+
@examples = []
|
20
12
|
end
|
21
13
|
end
|
22
14
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Valet
|
2
|
+
class Command
|
3
|
+
attr_reader :name, :options, :commands, :examples
|
4
|
+
attr_accessor :aliases, :syntax, :summary, :description
|
5
|
+
|
6
|
+
def initialize(name, &block)
|
7
|
+
validate_name(name)
|
8
|
+
@name = name
|
9
|
+
@action = block
|
10
|
+
@options = Options.new
|
11
|
+
@commands = Commands.new
|
12
|
+
@examples = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def action(&block)
|
16
|
+
if block_given?
|
17
|
+
validate_action(block)
|
18
|
+
@action = block
|
19
|
+
end
|
20
|
+
|
21
|
+
@action
|
22
|
+
end
|
23
|
+
|
24
|
+
def execute(*operands)
|
25
|
+
if action.arity == 0
|
26
|
+
action.call
|
27
|
+
elsif action.arity == 1
|
28
|
+
action.call(options)
|
29
|
+
else
|
30
|
+
action.call(operands, options)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def validate_name(name)
|
37
|
+
unless valid_name?(name)
|
38
|
+
raise CommandError,
|
39
|
+
"Name: '#{name}' must be a symbol"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def valid_name?(name)
|
44
|
+
name.is_a?(Symbol)
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate_action(proc)
|
48
|
+
unless valid_action?(proc)
|
49
|
+
raise CommandError,
|
50
|
+
"Action: '#{action}' may not have more than two block parameters"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def valid_action?(proc)
|
55
|
+
proc.arity <= 2 && proc.arity >= 0
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
class CommandError < StandardError; end
|
60
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Valet
|
2
|
+
module Helpers
|
3
|
+
module TypeCast
|
4
|
+
ALLOWED_TYPES = [String, Integer, Float, Array, Hash, Time]
|
5
|
+
|
6
|
+
def string_to(type, string)
|
7
|
+
validate_type(type)
|
8
|
+
|
9
|
+
case
|
10
|
+
when type == String then string
|
11
|
+
when type == Integer then string.to_i
|
12
|
+
when type == Float then string.to_f
|
13
|
+
when type == Array then to_array(string)
|
14
|
+
when type == Hash then to_hash(string)
|
15
|
+
when type == Time then Time.parse(string)
|
16
|
+
else type.new(string)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def validate_type(type)
|
23
|
+
unless valid_type?(type)
|
24
|
+
raise TypeError,
|
25
|
+
"'#{type}' must be one of #{ALLOWED_TYPES.join(', ')}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def valid_type?(type)
|
30
|
+
ALLOWED_TYPES.include?(type)
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_array(string)
|
34
|
+
string.split(/,|\s/)
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_hash(string)
|
38
|
+
string.split(/,|\s/).inject(Hash.new) do |hash, str|
|
39
|
+
key, value = str.split(/:/)
|
40
|
+
hash[key.to_sym] = value
|
41
|
+
hash
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Valet
|
2
|
+
module Option
|
3
|
+
class Common
|
4
|
+
attr_reader :long_name, :short_name
|
5
|
+
attr_accessor :summary, :description
|
6
|
+
|
7
|
+
alias_method :name, :long_name
|
8
|
+
|
9
|
+
def initialize(long_name)
|
10
|
+
validate_long_name(long_name)
|
11
|
+
@long_name = long_name
|
12
|
+
end
|
13
|
+
|
14
|
+
def short_name=(new_short_name)
|
15
|
+
validate_short_name(new_short_name)
|
16
|
+
@short_name = new_short_name
|
17
|
+
end
|
18
|
+
|
19
|
+
def switch?
|
20
|
+
instance_of?(Switch)
|
21
|
+
end
|
22
|
+
|
23
|
+
def flag?
|
24
|
+
instance_of?(Flag)
|
25
|
+
end
|
26
|
+
|
27
|
+
def short_name_to_s
|
28
|
+
"-#{short_name}" if short_name
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def validate_long_name(long_name)
|
34
|
+
unless valid_long_name?(long_name)
|
35
|
+
raise OptionError,
|
36
|
+
"Long Name: '#{long_name}' must be a symbol and longer than one character"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def valid_long_name?(long_name)
|
41
|
+
long_name.is_a?(Symbol) && long_name.length > 1
|
42
|
+
end
|
43
|
+
|
44
|
+
def validate_short_name(short_name)
|
45
|
+
unless valid_short_name?(short_name)
|
46
|
+
raise OptionError,
|
47
|
+
"Short Name: '#{short_name}' must be a symbol and exactly one character long"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def valid_short_name?(short_name)
|
52
|
+
short_name.is_a?(Symbol) && short_name.length == 1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class OptionError < StandardError; end
|
58
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'valet/option/common'
|
2
|
+
require 'valet/helpers/type_cast'
|
3
|
+
|
4
|
+
module Valet
|
5
|
+
module Option
|
6
|
+
class Flag < Common
|
7
|
+
include Helpers::TypeCast
|
8
|
+
|
9
|
+
attr_reader :type, :default, :value
|
10
|
+
attr_writer :arg_name
|
11
|
+
|
12
|
+
def initialize(long_name)
|
13
|
+
super
|
14
|
+
@type = String
|
15
|
+
end
|
16
|
+
|
17
|
+
def type=(new_type)
|
18
|
+
validate_type(new_type)
|
19
|
+
@type = new_type
|
20
|
+
end
|
21
|
+
|
22
|
+
def default=(new_default)
|
23
|
+
@default = new_default
|
24
|
+
@value = @default
|
25
|
+
end
|
26
|
+
|
27
|
+
def value=(new_value)
|
28
|
+
@value = string_to(type, new_value)
|
29
|
+
end
|
30
|
+
|
31
|
+
def arg_name
|
32
|
+
@arg_name or long_name.to_s.gsub(/_/, ' ')
|
33
|
+
end
|
34
|
+
|
35
|
+
def long_name_to_s
|
36
|
+
if default
|
37
|
+
"--#{long_name}[=<#{arg_name}>]".gsub(/_/, '-')
|
38
|
+
else
|
39
|
+
"--#{long_name}=<#{arg_name}>".gsub(/_/, '-')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|