mister_bin 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +147 -4
- data/lib/mister_bin/command.rb +3 -3
- data/lib/mister_bin/commands.rb +7 -12
- data/lib/mister_bin/docopt_maker.rb +25 -8
- data/lib/mister_bin/runner.rb +1 -12
- data/lib/mister_bin/script.rb +9 -0
- data/lib/mister_bin/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 145d72d39990c48d376b0090537d3ddd682ea2288fdea8ef96028f0745ecd60d
|
4
|
+
data.tar.gz: bc3bc649a79b06e746a260d7d0e0c19c973b3c29cf76bf966b4f621b261743c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e83d1905b8bfdc7e9d1e66a402fc3eaaf87ecf8a240a535d08a4b1d67b11b76062fcd78b2df06c84cae1a738c866fa0ab5081413f83fec5b70a64fb386de7f4
|
7
|
+
data.tar.gz: 7e1a2a406f3245786f36d2662532e17976f4e5f0b348febf303ef65b5f13c00b35465be6e9c86aa6ba9aa3304b13440a24d244cf3fd1a75e940af16a464ba33a
|
data/README.md
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Mister Bin
|
2
2
|
==================================================
|
3
3
|
|
4
|
-
[![Gem](https://
|
5
|
-
[![Build](https://
|
6
|
-
[![Maintainability](https://
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/mister_bin.svg)](https://badge.fury.io/rb/mister_bin)
|
5
|
+
[![Build Status](https://travis-ci.org/DannyBen/mister_bin.svg?branch=master)](https://travis-ci.org/DannyBen/mister_bin)
|
6
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/ae82443a99c2839d8ba8/maintainability)](https://codeclimate.com/github/DannyBen/mister_bin/maintainability)
|
7
7
|
|
8
8
|
---
|
9
9
|
|
@@ -30,4 +30,147 @@ Design Goals
|
|
30
30
|
Usage
|
31
31
|
--------------------------------------------------
|
32
32
|
|
33
|
-
|
33
|
+
Creating a command line utility with Mister Bin involves at least two files:
|
34
|
+
|
35
|
+
1. The main "app" file. This is the actual "executable".
|
36
|
+
2. One or more subcommand files. These files use the DSL.
|
37
|
+
|
38
|
+
For example, assuming we would like to create a command line tool similar
|
39
|
+
to `git`, we will create two files:
|
40
|
+
|
41
|
+
The `git` executable:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
# git
|
45
|
+
#!/usr/bin/env ruby
|
46
|
+
require 'mister_bin'
|
47
|
+
|
48
|
+
exit MisterBin::Runner.run __FILE__, ARGV
|
49
|
+
```
|
50
|
+
|
51
|
+
The file to handle the `git push` command:
|
52
|
+
```ruby
|
53
|
+
# git-push.rb
|
54
|
+
version "0.1.0"
|
55
|
+
help "Push git repo"
|
56
|
+
|
57
|
+
usage "git push [--all]"
|
58
|
+
|
59
|
+
option "--all", "Push all branches"
|
60
|
+
|
61
|
+
action do |args|
|
62
|
+
if args['--all']
|
63
|
+
puts "pushing all"
|
64
|
+
else
|
65
|
+
puts "pushing, some..."
|
66
|
+
end
|
67
|
+
end
|
68
|
+
```
|
69
|
+
|
70
|
+
Mister Bin also provides support for secondary subcommands. For example,
|
71
|
+
if you want to create a command line that responds to the below commands:
|
72
|
+
|
73
|
+
```
|
74
|
+
$ git status
|
75
|
+
$ git repo create
|
76
|
+
$ git repo delete
|
77
|
+
```
|
78
|
+
|
79
|
+
You will need to create these files:
|
80
|
+
|
81
|
+
1. `git`
|
82
|
+
2. `git-status.rb`
|
83
|
+
3. `git-repo-create.rb`
|
84
|
+
4. `git-repo-delete.rb`
|
85
|
+
|
86
|
+
Alternatively, if you prefer to handle all `repo` subcommands in a single,
|
87
|
+
file, simple implement these instead:
|
88
|
+
|
89
|
+
1. `git`
|
90
|
+
2. `git-status.rb`
|
91
|
+
3. `git-repo.rb`
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
Creating the Main Executable
|
96
|
+
--------------------------------------------------
|
97
|
+
|
98
|
+
The main executable is usually simple, and contains this code:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
# git
|
102
|
+
#!/usr/bin/env ruby
|
103
|
+
require 'mister_bin'
|
104
|
+
|
105
|
+
exit MisterBin::Runner.run __FILE__, ARGV
|
106
|
+
```
|
107
|
+
|
108
|
+
This code will start the execution chain based on the arguments provided
|
109
|
+
when running it.
|
110
|
+
|
111
|
+
The `Runner.run` method requires two parameters:
|
112
|
+
|
113
|
+
1. The path to the base executable file (usually, `__FILE__` is what you
|
114
|
+
need).
|
115
|
+
2. An array of arguments (usually `ARGV` is what you need).
|
116
|
+
|
117
|
+
|
118
|
+
|
119
|
+
Creating Subcommands
|
120
|
+
--------------------------------------------------
|
121
|
+
|
122
|
+
When the main executable is executed, it will look for files matching a
|
123
|
+
specific pattern in the same directory.
|
124
|
+
|
125
|
+
Assuming the main executable is called `myapp`, it will look for
|
126
|
+
`myapp-*.rb` files (e.g. `myapp-status.rb`)
|
127
|
+
|
128
|
+
These files do not need to be executables, and should use the DSL to define
|
129
|
+
their actions.
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
The DSL
|
134
|
+
--------------------------------------------------
|
135
|
+
|
136
|
+
The DSL is designed to create a [docopt][1] document. Most commands are
|
137
|
+
optional.
|
138
|
+
|
139
|
+
The below example outlines all available DSL commands.
|
140
|
+
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
# Optional help string
|
144
|
+
help "A short sentence or paragraph describing the command"
|
145
|
+
|
146
|
+
# Version string for the command
|
147
|
+
version "0.1.1"
|
148
|
+
|
149
|
+
# Usage patterns. You can use either a compact docopt notation, or provide
|
150
|
+
# multiple usage calls.
|
151
|
+
# The first two will create the same result as the last one.
|
152
|
+
usage "app ls"
|
153
|
+
usage "app ls --all"
|
154
|
+
usage "app ls [--all]"
|
155
|
+
usage "app new NAME"
|
156
|
+
|
157
|
+
# Describe any flags
|
158
|
+
option "--all", "Also show hidden files"
|
159
|
+
option "-f --force", "Force delete"
|
160
|
+
|
161
|
+
# Describe any parameters
|
162
|
+
param "NAME", "The name of the repository"
|
163
|
+
|
164
|
+
# Provide examples
|
165
|
+
example "app ls"
|
166
|
+
example "app ls --all"
|
167
|
+
|
168
|
+
# Define the actual action to execute when the command is called
|
169
|
+
# All arguments will be provided to your block.
|
170
|
+
action do |args|
|
171
|
+
puts args['--all'] ? "success --all" : "success"
|
172
|
+
end
|
173
|
+
```
|
174
|
+
|
175
|
+
|
176
|
+
[1]: http://docopt.org/
|
data/lib/mister_bin/command.rb
CHANGED
data/lib/mister_bin/commands.rb
CHANGED
@@ -14,20 +14,15 @@ module MisterBin
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def names
|
17
|
-
all.keys
|
17
|
+
all.keys.sort
|
18
18
|
end
|
19
19
|
|
20
|
-
def find(
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def find_one(query)
|
29
|
-
result = find query
|
30
|
-
result.size == 1 ? result.values.first : false
|
20
|
+
def find(command, subcommand=nil)
|
21
|
+
if subcommand and names.include? "#{command} #{subcommand}"
|
22
|
+
all["#{command} #{subcommand}"]
|
23
|
+
else
|
24
|
+
all["#{command}"]
|
25
|
+
end
|
31
26
|
end
|
32
27
|
|
33
28
|
private
|
@@ -9,7 +9,7 @@ module MisterBin
|
|
9
9
|
include Singleton
|
10
10
|
include Colsole
|
11
11
|
|
12
|
-
attr_reader :usages, :options, :examples
|
12
|
+
attr_reader :usages, :options, :examples, :params
|
13
13
|
attr_accessor :help, :version
|
14
14
|
|
15
15
|
def initialize
|
@@ -19,29 +19,32 @@ module MisterBin
|
|
19
19
|
def reset
|
20
20
|
@usages = []
|
21
21
|
@options = []
|
22
|
+
@params = []
|
22
23
|
@examples = []
|
23
24
|
@version = '0.0.0'
|
24
25
|
@help = nil
|
25
26
|
end
|
26
27
|
|
27
28
|
def docopt
|
28
|
-
[help_string, usage_string, options_string,
|
29
|
+
[help_string, usage_string, options_string,
|
30
|
+
params_string, examples_string].compact.join "\n"
|
29
31
|
end
|
30
32
|
|
31
33
|
private
|
32
34
|
|
33
35
|
def help_string
|
34
|
-
word_wrap
|
36
|
+
help ? word_wrap(help) + "\n" : nil
|
35
37
|
end
|
36
38
|
|
37
39
|
def usage_string
|
38
|
-
result = ["
|
40
|
+
result = ["Usage:"]
|
39
41
|
usages.each { |text| result << word_wrap(" #{text}") }
|
42
|
+
result << ""
|
40
43
|
result.join "\n"
|
41
44
|
end
|
42
45
|
|
43
46
|
def options_string
|
44
|
-
result = ["
|
47
|
+
result = ["Options:"]
|
45
48
|
options.each do |option|
|
46
49
|
result << " #{option[0]}"
|
47
50
|
result << word_wrap(" #{option[1]}")
|
@@ -51,15 +54,29 @@ module MisterBin
|
|
51
54
|
result << " -h --help"
|
52
55
|
result << " Show this help\n"
|
53
56
|
result << " --version"
|
54
|
-
result << " Show version number"
|
57
|
+
result << " Show version number\n"
|
58
|
+
result.join "\n"
|
59
|
+
end
|
60
|
+
|
61
|
+
def params_string
|
62
|
+
return nil if params.empty?
|
63
|
+
|
64
|
+
result = ["Parameters:"]
|
65
|
+
params.each do |param|
|
66
|
+
result << " #{param[0]}"
|
67
|
+
result << word_wrap(" #{param[1]}")
|
68
|
+
result << ""
|
69
|
+
end
|
70
|
+
|
55
71
|
result.join "\n"
|
56
72
|
end
|
57
73
|
|
58
74
|
def examples_string
|
59
|
-
return
|
75
|
+
return nil if examples.empty?
|
60
76
|
|
61
|
-
result = ["
|
77
|
+
result = ["Examples:"]
|
62
78
|
examples.each { |text| result << word_wrap(" #{text}") }
|
79
|
+
result << ""
|
63
80
|
result.join "\n"
|
64
81
|
end
|
65
82
|
end
|
data/lib/mister_bin/runner.rb
CHANGED
@@ -23,8 +23,7 @@ module MisterBin
|
|
23
23
|
private
|
24
24
|
|
25
25
|
def execute(argv)
|
26
|
-
|
27
|
-
command = commands.find_one argv[0..1]
|
26
|
+
command = commands.find argv[0], argv[1]
|
28
27
|
|
29
28
|
if command
|
30
29
|
execute_command command, argv
|
@@ -52,15 +51,5 @@ module MisterBin
|
|
52
51
|
def commands
|
53
52
|
@commands ||= Commands.new name, basedir
|
54
53
|
end
|
55
|
-
|
56
|
-
def expand_argv(argv)
|
57
|
-
command = commands.find_one argv[0..1]
|
58
|
-
if command
|
59
|
-
argv.shift command.argv.size
|
60
|
-
command.argv + argv
|
61
|
-
else
|
62
|
-
argv
|
63
|
-
end
|
64
|
-
end
|
65
54
|
end
|
66
55
|
end
|
data/lib/mister_bin/script.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
require 'docopt'
|
2
|
+
require 'colsole'
|
2
3
|
|
3
4
|
module MisterBin
|
4
5
|
class Script
|
6
|
+
# We are in cluding colsole to allow the evaluated script to use its
|
7
|
+
# functions
|
8
|
+
include Colsole
|
9
|
+
|
5
10
|
attr_reader :file, :action_block
|
6
11
|
|
7
12
|
def initialize(file)
|
@@ -41,6 +46,10 @@ module MisterBin
|
|
41
46
|
DocoptMaker.instance.options << [flags, text]
|
42
47
|
end
|
43
48
|
|
49
|
+
def param(param, text)
|
50
|
+
DocoptMaker.instance.params << [param, text]
|
51
|
+
end
|
52
|
+
|
44
53
|
def example(text)
|
45
54
|
DocoptMaker.instance.examples << text
|
46
55
|
end
|
data/lib/mister_bin/version.rb
CHANGED