dracula 0.2.0 → 0.2.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 +4 -4
- data/README.md +221 -14
- data/lib/dracula/command.rb +34 -8
- data/lib/dracula/flag.rb +20 -2
- data/lib/dracula/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b6c602659c7e89af0bb4cbc3f0ec4a8a1a55c4b4
|
4
|
+
data.tar.gz: e34ed6c3b948eb8e26b258fad6dbd42ea93ec878
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8a72ba7fc5a3dff0ddba48eb98bc572555582986ac0e17746b067eb87d013cbaab58c6ccb047d5b7911c20703b2a9efbdacaeb8fc8b480d276d074e90302cb0
|
7
|
+
data.tar.gz: 44c776e24136257cc0d299a852e6264ea7e77db1114bc9ab578768800253834ff08435b38aefbf0e18a1262150f630f392c6728250f74f1cdd4b7c2d6dc08454
|
data/README.md
CHANGED
@@ -1,27 +1,234 @@
|
|
1
|
-
# Dracula
|
1
|
+
# Dracula — CLI Framework
|
2
2
|
|
3
3
|
[](https://semaphoreci.com/renderedtext/dracula)
|
4
|
+
[](https://badge.fury.io/rb/dracula)
|
4
5
|
|
5
|
-
|
6
|
+
Dracula is a framework for creating command line application.
|
6
7
|
|
7
|
-
|
8
|
+
The structure of the framework is heavily inspired by Thor, and can be even used
|
9
|
+
as a drop in replacement for the Thor framework.
|
10
|
+
|
11
|
+
Opposed to Thor, Dracula generates a Heroku like interface. For example, a task
|
12
|
+
management app would have the following interface:
|
13
|
+
|
14
|
+
``` txt
|
15
|
+
app tasks:list
|
16
|
+
app tasks:info
|
17
|
+
app calendar:show
|
18
|
+
app calendar:events:list
|
19
|
+
app calendar:events:add
|
20
|
+
```
|
21
|
+
|
22
|
+
For help, you can always invoke:
|
23
|
+
|
24
|
+
``` txt
|
25
|
+
app help <command-name>
|
26
|
+
```
|
27
|
+
|
28
|
+
## Hello world example
|
8
29
|
|
9
30
|
``` ruby
|
10
|
-
class
|
11
|
-
flag :username, :short => "u", :required => true
|
12
|
-
flag :password, :short => "p", :required => true
|
13
|
-
flag :verbose, :short => "v", :type => :boolean
|
14
|
-
|
15
|
-
def run
|
16
|
-
if flags[:vebose]
|
17
|
-
puts "Running verbosely"
|
18
|
-
end
|
31
|
+
class CLI < Dracula
|
19
32
|
|
20
|
-
|
33
|
+
desc "hello", "displays hello messages"
|
34
|
+
def hello(message)
|
35
|
+
puts "Hi #{message}!"
|
21
36
|
end
|
37
|
+
|
22
38
|
end
|
39
|
+
|
40
|
+
CLI.start(ARGV)
|
41
|
+
```
|
42
|
+
|
43
|
+
```
|
44
|
+
$ cli hello dracula
|
45
|
+
|
46
|
+
Hi dracula!
|
23
47
|
```
|
24
48
|
|
49
|
+
Every method in your class represents a command.
|
50
|
+
|
51
|
+
## Command line options
|
52
|
+
|
53
|
+
A command can have one or more command line options.
|
54
|
+
|
25
55
|
``` ruby
|
26
|
-
|
56
|
+
class CLI < Dracula
|
57
|
+
|
58
|
+
option :name
|
59
|
+
desc "hello", "displays hello messages"
|
60
|
+
def hello
|
61
|
+
puts "Hi #{options[:name]}!"
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
CLI.start(ARGV)
|
67
|
+
```
|
68
|
+
|
69
|
+
```
|
70
|
+
$ cli hello --name "Peter"
|
71
|
+
|
72
|
+
Hi Peter!
|
73
|
+
```
|
74
|
+
|
75
|
+
The options are defined above the method.
|
76
|
+
|
77
|
+
#### Default values
|
78
|
+
|
79
|
+
Options can have default values:
|
80
|
+
|
81
|
+
``` ruby
|
82
|
+
class CLI < Dracula
|
83
|
+
|
84
|
+
option :name, :default => "there"
|
85
|
+
desc "hello", "displays hello messages"
|
86
|
+
def hello
|
87
|
+
puts "Hi #{options[:name]}!"
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
CLI.start(ARGV)
|
93
|
+
```
|
94
|
+
|
95
|
+
```
|
96
|
+
$ cli hello
|
97
|
+
|
98
|
+
Hi there!
|
99
|
+
|
100
|
+
$ cli hello --name Peter
|
101
|
+
|
102
|
+
Hi Peter!
|
103
|
+
```
|
104
|
+
|
105
|
+
#### Required options
|
106
|
+
|
107
|
+
By default, every parameter is optional. You can pass set required to true to
|
108
|
+
make the option compulsory.
|
109
|
+
|
110
|
+
``` ruby
|
111
|
+
class CLI < Dracula
|
112
|
+
|
113
|
+
option :name, :default => "there", :required => true
|
114
|
+
desc "hello", "displays hello messages"
|
115
|
+
def hello
|
116
|
+
puts "Hi #{options[:name]}!"
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
CLI.start(ARGV)
|
27
122
|
```
|
123
|
+
|
124
|
+
```
|
125
|
+
$ cli hello
|
126
|
+
|
127
|
+
Missing option: --name NAME
|
128
|
+
|
129
|
+
$ cli hello --name Peter
|
130
|
+
|
131
|
+
Hi Peter!
|
132
|
+
```
|
133
|
+
|
134
|
+
#### Boolean options
|
135
|
+
|
136
|
+
By default, the options expect a value to be passed. However, if you set the
|
137
|
+
type of the option to boolean, only the flag need to be passed:
|
138
|
+
|
139
|
+
``` ruby
|
140
|
+
class CLI < Dracula
|
141
|
+
|
142
|
+
option :json, :type => :boolean
|
143
|
+
option :name, :required => true
|
144
|
+
desc "hello", "displays hello messages"
|
145
|
+
def hello
|
146
|
+
if options[:json]
|
147
|
+
puts '{ "message": "Hi #{options[:name]}!" }'
|
148
|
+
else
|
149
|
+
puts "Hi #{options[:name]}!"
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
CLI.start(ARGV)
|
156
|
+
```
|
157
|
+
|
158
|
+
```
|
159
|
+
$ cli hello --name Peter
|
160
|
+
|
161
|
+
Hi Peter!
|
162
|
+
|
163
|
+
$ cli hello --name Peter --json
|
164
|
+
|
165
|
+
{ "message": "Hi Peter!" }
|
166
|
+
```
|
167
|
+
|
168
|
+
## Namespaces
|
169
|
+
|
170
|
+
A CLI application can have subcommands and subnamespaces. For example:
|
171
|
+
|
172
|
+
``` ruby
|
173
|
+
class Greetings < Dracula
|
174
|
+
|
175
|
+
desc "hello", "displays a hello message"
|
176
|
+
def hello
|
177
|
+
puts "Hi!"
|
178
|
+
end
|
179
|
+
|
180
|
+
desc "bye", "displays a bye message"
|
181
|
+
def bye
|
182
|
+
puts "Bye!"
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
class CLI < Dracula
|
188
|
+
|
189
|
+
desc "suck_blood", "suck blood from innocent victims"
|
190
|
+
def suck_blood
|
191
|
+
puts "BLOOD!"
|
192
|
+
end
|
193
|
+
|
194
|
+
subcommand "greetings", "shows various greetings", Greetings
|
195
|
+
end
|
196
|
+
|
197
|
+
CLI.start(ARGV)
|
198
|
+
```
|
199
|
+
|
200
|
+
```
|
201
|
+
$ cli suck_blood
|
202
|
+
BLOOD!
|
203
|
+
|
204
|
+
$ cli greetings:hello
|
205
|
+
Hi!
|
206
|
+
|
207
|
+
$ cli greetings:bye
|
208
|
+
Bye!
|
209
|
+
```
|
210
|
+
|
211
|
+
## Development
|
212
|
+
|
213
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then,
|
214
|
+
run `rake spec` to run the tests. You can also run `bin/console` for an
|
215
|
+
interactive prompt that will allow you to experiment.
|
216
|
+
|
217
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
218
|
+
To release a new version, update the version number in `version.rb`, and then
|
219
|
+
run `bundle exec rake release`, which will create a git tag for the version,
|
220
|
+
push git commits and tags, and push the `.gem` file
|
221
|
+
to [rubygems.org](https://rubygems.org).
|
222
|
+
|
223
|
+
## Contributing
|
224
|
+
|
225
|
+
Bug reports and pull requests are welcome on GitHub at
|
226
|
+
<https://github.com/renderedtext/dracula>. This project is intended
|
227
|
+
to be a safe, welcoming space for collaboration, and contributors are expected
|
228
|
+
to adhere to the [Contributor Covenant](http://contributor-covenant.org) code
|
229
|
+
of conduct.
|
230
|
+
|
231
|
+
## License
|
232
|
+
|
233
|
+
The gem is available as open source under the terms of
|
234
|
+
the [MIT License](http://opensource.org/licenses/MIT).
|
data/lib/dracula/command.rb
CHANGED
@@ -22,9 +22,20 @@ class Dracula
|
|
22
22
|
desc.name
|
23
23
|
end
|
24
24
|
|
25
|
+
def arguments
|
26
|
+
@klass.instance_method(@method_name).parameters.select { |p| p[0] == :req }.map { |p| p[1].to_s.upcase }
|
27
|
+
end
|
28
|
+
|
29
|
+
def banner
|
30
|
+
namespace = @klass.namespace.name ? "#{@klass.namespace.name}:" : ""
|
31
|
+
args = arguments.count > 0 ? " #{arguments.join(" ")}" : ""
|
32
|
+
|
33
|
+
"#{namespace}#{desc.name}#{args}"
|
34
|
+
end
|
35
|
+
|
25
36
|
def help
|
26
37
|
msg = [
|
27
|
-
"Usage: #{Dracula.program_name} #{
|
38
|
+
"Usage: #{Dracula.program_name} #{banner}",
|
28
39
|
"",
|
29
40
|
"#{desc.description}",
|
30
41
|
""
|
@@ -46,19 +57,34 @@ class Dracula
|
|
46
57
|
end
|
47
58
|
|
48
59
|
def run(params)
|
49
|
-
args
|
50
|
-
flags = parse_flags(params.drop_while { |p| p[0] != "-" })
|
60
|
+
args = params.take_while { |p| p[0] != "-" }
|
51
61
|
|
52
|
-
|
62
|
+
if args.count != arguments.count
|
63
|
+
puts "Missing arguments"
|
64
|
+
puts ""
|
65
|
+
help
|
66
|
+
exit(1)
|
67
|
+
end
|
68
|
+
|
69
|
+
parsed_flags = parse_flags(params.drop_while { |p| p[0] != "-" })
|
53
70
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
puts "Required Parameter:
|
71
|
+
missing_flags = missing_required_flags(parsed_flags)
|
72
|
+
|
73
|
+
unless missing_flags.empty?
|
74
|
+
puts "Required Parameter: #{missing_flags.first.banner}"
|
58
75
|
puts ""
|
59
76
|
help
|
60
77
|
exit(1)
|
61
78
|
end
|
79
|
+
|
80
|
+
@klass.new(parsed_flags).public_send(method_name, *args)
|
81
|
+
rescue OptionParser::MissingArgument => ex
|
82
|
+
flag = flags.find { |f| "--#{f.name}" == ex.args.first }
|
83
|
+
|
84
|
+
puts "Parameter has no value: #{flag.banner}"
|
85
|
+
puts ""
|
86
|
+
help
|
87
|
+
exit(1)
|
62
88
|
end
|
63
89
|
|
64
90
|
private
|
data/lib/dracula/flag.rb
CHANGED
@@ -32,10 +32,28 @@ class Dracula
|
|
32
32
|
alias_method :short_name, :alias_name
|
33
33
|
|
34
34
|
def banner
|
35
|
-
if
|
35
|
+
if short_name_banner
|
36
|
+
"#{short_name_banner}, #{long_name_banner}"
|
37
|
+
else
|
38
|
+
long_name_banner
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def short_name_banner
|
43
|
+
return nil if short_name.nil?
|
44
|
+
|
45
|
+
if boolean?
|
46
|
+
"-#{short_name}"
|
47
|
+
else
|
48
|
+
"-#{short_name} #{name.upcase}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def long_name_banner
|
53
|
+
if boolean?
|
36
54
|
"--#{name}"
|
37
55
|
else
|
38
|
-
"
|
56
|
+
"--#{name} #{name.upcase}"
|
39
57
|
end
|
40
58
|
end
|
41
59
|
|
data/lib/dracula/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dracula
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Šarčević
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-08-
|
11
|
+
date: 2017-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|