parse-argv 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +5 -0
- data/LICENSE +28 -0
- data/ReadMe.md +101 -0
- data/examples/ReadMe.md +29 -0
- data/examples/check.rb +109 -0
- data/examples/conversion.rb +47 -0
- data/examples/multi.rb +79 -0
- data/examples/simple.rb +37 -0
- data/lib/parse-argv/conversion.rb +398 -0
- data/lib/parse-argv/version.rb +8 -0
- data/lib/parse-argv.rb +900 -0
- data/lib/parse_argv.rb +3 -0
- data/syntax.md +158 -0
- metadata +70 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '08c6221625a88b034352b5dbb8fb673bf2224ab76c3d535ef1fe43c5b33ae1fa'
|
4
|
+
data.tar.gz: faf7ef2645091f3cf6de86ea23104105830530cfbc03e1237cd0bad16d077658
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: '0486e25acc34d509335f469a30bfb2fb32d038ca7de45a3ab5ff19039f34110f01adade82a47d0c277403c97767182c0881fef734950ff63c22ccaf2d464bdd4'
|
7
|
+
data.tar.gz: a6c629bfd3c6103a1cf09c80b7efbe38036b24051b473d2f488e47b8b4c6b15045ae92910f9583e2be749ddabf5458ecd0db1ddfa6c7e48da55328f32922e580
|
data/.yardopts
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
BSD 3-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2017-2021, Mike Blumtritt. All rights reserved.
|
4
|
+
|
5
|
+
Redistribution and use in source and binary forms, with or without
|
6
|
+
modification, are permitted provided that the following conditions are met:
|
7
|
+
|
8
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
9
|
+
list of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
this list of conditions and the following disclaimer in the documentation
|
13
|
+
and/or other materials provided with the distribution.
|
14
|
+
|
15
|
+
3. Neither the name of the copyright holder nor the names of its
|
16
|
+
contributors may be used to endorse or promote products derived from
|
17
|
+
this software without specific prior written permission.
|
18
|
+
|
19
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
20
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
21
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
22
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
23
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
25
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
26
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
27
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
28
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/ReadMe.md
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# ParseArgv
|
2
|
+
|
3
|
+
A command line parser that only needs your help text.
|
4
|
+
|
5
|
+
- Gem: [rubygems.org](https://rubygems.org/gems/parse-argv)
|
6
|
+
- Source: [github.com](https://github.com/mblumtritt/parse-argv)
|
7
|
+
- Help: [rubydoc.info](https://rubydoc.info/gems/parse-argv)
|
8
|
+
|
9
|
+
## Description
|
10
|
+
|
11
|
+
Just write the help text for your application and ParseArgv will take care of your command line. It works sort of the other way around than OptParse, where you write a lot of code to get a command line parser and generated help text. ParseArgv simply takes your help text and parses the command line and presents you the results.
|
12
|
+
|
13
|
+
You can use ParseArgv for simpler programs just as well as for CLI with multi-level sub-commands (git-like commands). ParseArgv is easy to use, fast and also helps you convert the data types of command line arguments.
|
14
|
+
|
15
|
+
## Example
|
16
|
+
|
17
|
+
The given help text
|
18
|
+
|
19
|
+
```
|
20
|
+
usage: test [options] <infile> [<outfile>]
|
21
|
+
|
22
|
+
This is just a demonstration.
|
23
|
+
|
24
|
+
options:
|
25
|
+
-f, --format <format> specify the format
|
26
|
+
--verbose enable verbose mode
|
27
|
+
-h, --help print this help text
|
28
|
+
```
|
29
|
+
|
30
|
+
will be interpreted as
|
31
|
+
|
32
|
+
- there is a command "test"
|
33
|
+
- which requires and argument "infile"
|
34
|
+
- optionally accepts an second argument "outfile"
|
35
|
+
- accepts an option named "format" when `-f` or `--format` are given
|
36
|
+
- defines the boolean option "verbose" when `--verbose` is given
|
37
|
+
- defines the boolean option "help" when `-h` or `--help` are given
|
38
|
+
|
39
|
+
## How To Use
|
40
|
+
|
41
|
+
Please, see the [Gem's help](https://rubydoc.info/gems/parse-argv) for detailed information, or have a look at the [`./examples`](./examples) directory which contains some commands to play around.
|
42
|
+
|
43
|
+
The supported help text syntax and the command line interface syntax are described in the [syntax help](./syntax.md).
|
44
|
+
|
45
|
+
In general you just specify the help text and get the parsed command line:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
require 'parse-argv'
|
49
|
+
|
50
|
+
args = ParseArgv.from <<~HELP
|
51
|
+
usage: test [options] <infile> [<outfile>]
|
52
|
+
|
53
|
+
This is just a demonstration.
|
54
|
+
|
55
|
+
options:
|
56
|
+
-f, --format <format> specify the format
|
57
|
+
--verbose enable verbose mode
|
58
|
+
-h, --help print this help text
|
59
|
+
HELP
|
60
|
+
|
61
|
+
args.verbose?
|
62
|
+
#=> true, when "--verbose" argument was specified
|
63
|
+
#=> false, when "--verbose" argument was not specified
|
64
|
+
|
65
|
+
args[:infile].as(File, :readable)
|
66
|
+
#=> file name
|
67
|
+
|
68
|
+
args.outfile?
|
69
|
+
#=> true, when second argument was specified
|
70
|
+
args.outfile
|
71
|
+
#=> second argument or nil when not specified
|
72
|
+
```
|
73
|
+
|
74
|
+
## Installation
|
75
|
+
|
76
|
+
Use [Bundler](http://gembundler.com/) to add ParseArgv in your own project:
|
77
|
+
|
78
|
+
Include in your `Gemfile`:
|
79
|
+
|
80
|
+
```ruby
|
81
|
+
gem 'parse-argv'
|
82
|
+
```
|
83
|
+
|
84
|
+
and install it by running Bundler:
|
85
|
+
|
86
|
+
```bash
|
87
|
+
bundle
|
88
|
+
```
|
89
|
+
|
90
|
+
To install the gem globally use:
|
91
|
+
|
92
|
+
```bash
|
93
|
+
gem install parse-argv
|
94
|
+
```
|
95
|
+
|
96
|
+
After that you need only a single line of code in your project to have it on board:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
require 'parse-argv'
|
100
|
+
```
|
101
|
+
|
data/examples/ReadMe.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Examples
|
2
|
+
|
3
|
+
This directory contains some examples for using ParseArgv. Play around and get an impression how an application will handle the command line by using ParseArgv.
|
4
|
+
|
5
|
+
To run an example just start with:
|
6
|
+
|
7
|
+
```shell
|
8
|
+
ruby examples/simple.rb --help
|
9
|
+
```
|
10
|
+
|
11
|
+
## check.rb
|
12
|
+
|
13
|
+
Can be used to test your help text syntax. Try the following to see it in action:
|
14
|
+
|
15
|
+
```shell
|
16
|
+
ruby examples/check.rb examples/multi.rb
|
17
|
+
```
|
18
|
+
|
19
|
+
## conversion.rb
|
20
|
+
|
21
|
+
This example demonstrates the conversion capabilities.
|
22
|
+
|
23
|
+
## multi.rb
|
24
|
+
|
25
|
+
This is an example of a "git-like" command - a command with subcommands.
|
26
|
+
|
27
|
+
## simple.rb
|
28
|
+
|
29
|
+
A simple and very basic demonstration.
|
data/examples/check.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative '../lib/parse-argv'
|
5
|
+
|
6
|
+
ARGS = ParseArgv.from <<~HELP
|
7
|
+
Test the syntax of your help text for ParseArgv.
|
8
|
+
|
9
|
+
Usage: check [options] <files>...
|
10
|
+
|
11
|
+
Options:
|
12
|
+
-f, --format <format> display format: default, json, usage
|
13
|
+
-c, --command <name> display command with <name> only
|
14
|
+
-h, --help display this help
|
15
|
+
-v, --version display version information
|
16
|
+
HELP
|
17
|
+
|
18
|
+
puts(ARGS) or exit if ARGS.help?
|
19
|
+
puts("check v#{ParseArgv::VERSION}") or exit if ARGS.version?
|
20
|
+
|
21
|
+
cmds =
|
22
|
+
begin
|
23
|
+
ParseArgv.parse(ARGS[:files].as(:file_content).join("\n"))
|
24
|
+
rescue ArgumentError => e
|
25
|
+
ARGS.error!("invalid syntax - #{e}")
|
26
|
+
end
|
27
|
+
|
28
|
+
def find_command(all, name)
|
29
|
+
command = all.find { |cmd| cmd[:full_name] == name || cmd[:name] == name }
|
30
|
+
command or ARGS.error!("no such command - #{name}")
|
31
|
+
end
|
32
|
+
|
33
|
+
cmds = [find_command(cmds, ARGS[:name].as(:string))] if ARGS.name?
|
34
|
+
|
35
|
+
module Format
|
36
|
+
class Json
|
37
|
+
def self.show(commands)
|
38
|
+
commands.each { |command| command.delete(:help) }
|
39
|
+
require('json')
|
40
|
+
puts(JSON.dump(commands))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Usage
|
45
|
+
def self.show(commands)
|
46
|
+
puts(commands.map { |command| new(command) }.join("\n"))
|
47
|
+
end
|
48
|
+
|
49
|
+
def initialize(command)
|
50
|
+
@command = command
|
51
|
+
end
|
52
|
+
|
53
|
+
def to_s
|
54
|
+
name, args = @command.fetch_values(:full_name, :arguments)
|
55
|
+
ret = "usage: #{name}"
|
56
|
+
args.each_pair { |arg_name, info| ret << as_str(arg_name, info) }
|
57
|
+
ret
|
58
|
+
end
|
59
|
+
|
60
|
+
def as_str(name, info)
|
61
|
+
case info[:type]
|
62
|
+
when :argument
|
63
|
+
info[:required] ? " <#{name}>" : " [<#{name}>]"
|
64
|
+
when :argument_array
|
65
|
+
info[:required] ? " <#{name}>..." : " [<#{name}>...]"
|
66
|
+
when :option
|
67
|
+
names = info[:names].map { |n| n.size == 1 ? "-#{n}" : "--#{n}" }
|
68
|
+
" [#{names.join(', ')} <#{name}>]"
|
69
|
+
when :switch
|
70
|
+
names = info[:names].map { |n| n.size == 1 ? "-#{n}" : "--#{n}" }
|
71
|
+
" [#{names.join(', ')}]"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class Default < Usage
|
77
|
+
def self.show(commands)
|
78
|
+
puts(commands.map { |command| new(command) }.join("\n\n"))
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_s
|
82
|
+
full_name, name, args =
|
83
|
+
@command.fetch_values(:full_name, :name, :arguments)
|
84
|
+
ret = ["#{full_name == name ? 'Command' : 'Subcommand'}: #{name}"]
|
85
|
+
return ret if args.empty?
|
86
|
+
width = args.keys.max_by(&:size).size
|
87
|
+
args.each_pair do |arg_name, info|
|
88
|
+
ret << " #{arg_name.to_s.ljust(width)} #{as_str(info)}"
|
89
|
+
end
|
90
|
+
ret.join("\n")
|
91
|
+
end
|
92
|
+
|
93
|
+
def as_str(info)
|
94
|
+
case info[:type]
|
95
|
+
when :argument
|
96
|
+
info[:required] ? 'argument: required' : 'argument'
|
97
|
+
when :argument_array
|
98
|
+
info[:required] ? 'arguments array: required' : 'arguments array'
|
99
|
+
when :option, :switch
|
100
|
+
names = info[:names].map { |n| n.size == 1 ? "-#{n}" : "--#{n}" }
|
101
|
+
"#{info[:type]} #{names.join(', ')}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
Format.const_get(
|
108
|
+
ARGS[:format].as(%w[default json usage], default: 'default').capitalize
|
109
|
+
).show(cmds)
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative '../lib/parse-argv'
|
5
|
+
|
6
|
+
ARGS = ParseArgv.from <<~HELP
|
7
|
+
ParseARGS Demo about conversions
|
8
|
+
This example demonstrates the build-in conversions.
|
9
|
+
|
10
|
+
usage: conversion [options]
|
11
|
+
|
12
|
+
options:
|
13
|
+
-s, --string <string> accept any non-empty String
|
14
|
+
-a, --array <array> accept an array of String
|
15
|
+
-r, --regexp <regexp> convert to a regular expression
|
16
|
+
-i, --integer <integer> convert to Integer
|
17
|
+
-f, --float <float> convert to Float
|
18
|
+
-n, --number <number> convert to Numeric (Integer or Float)
|
19
|
+
-b, --byte <byte> convert to number of byte
|
20
|
+
-d, --date <date> convert to Date
|
21
|
+
-t, --time <time> convert to Time
|
22
|
+
-N, --filename <filename> convert to a (relative) file name String
|
23
|
+
-F, --fname <file> accept name of an existing file
|
24
|
+
-D, --dname <dir> accept name of an existing directory
|
25
|
+
-A, --files <files> accept an array of file names
|
26
|
+
-1, --one <oneof> accept one of 'foo', 'bar', 'baz'
|
27
|
+
-h, --help print this help
|
28
|
+
HELP
|
29
|
+
|
30
|
+
puts(ARGS) or exit if ARGS.help?
|
31
|
+
|
32
|
+
puts <<~RESULT
|
33
|
+
string #{ARGS[:string].as(String).inspect}
|
34
|
+
array #{ARGS[:array].as(Array).inspect}
|
35
|
+
filename #{ARGS[:filename].as(:file_name).inspect}
|
36
|
+
regexp #{ARGS[:regexp].as(Regexp).inspect}
|
37
|
+
integer #{ARGS[:integer].as(Integer)}
|
38
|
+
float #{ARGS[:float].as(Float)}
|
39
|
+
number #{ARGS[:number].as(Numeric)}
|
40
|
+
byte #{ARGS[:byte].as(:byte)}
|
41
|
+
date #{ARGS[:date].as(:date)}
|
42
|
+
time #{ARGS[:time].as(Time)}
|
43
|
+
file #{ARGS[:file].as(File).inspect}
|
44
|
+
dir #{ARGS[:dir].as(Dir).inspect}
|
45
|
+
files #{ARGS[:files].as([File]).inspect}
|
46
|
+
oneof #{ARGS[:oneof].as(%w[foo bar baz])}
|
47
|
+
RESULT
|
data/examples/multi.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative '../lib/parse-argv'
|
5
|
+
|
6
|
+
ARGS = ParseArgv.from <<~HELP
|
7
|
+
ParseARGS Demo for a CLI with subcommands
|
8
|
+
This example demonstrates a CLI with subcommands. It processes an imganinary
|
9
|
+
key/value store that can be synchronized with a server.
|
10
|
+
|
11
|
+
usage: multi <command>
|
12
|
+
|
13
|
+
commands:
|
14
|
+
var get a variable
|
15
|
+
var add add a variable
|
16
|
+
var remove remove a variable
|
17
|
+
push push all vars
|
18
|
+
pull pull all vars
|
19
|
+
help show command specific help
|
20
|
+
-h, --help show this help
|
21
|
+
-v, --version show version information
|
22
|
+
|
23
|
+
Play with different command line parameters and options to see how it works!
|
24
|
+
|
25
|
+
usage: multi var <name>
|
26
|
+
|
27
|
+
Get variable <name>.
|
28
|
+
|
29
|
+
usage: multi var add [options] <name> <value>...
|
30
|
+
|
31
|
+
Add a variable <name> with given <value>.
|
32
|
+
|
33
|
+
options:
|
34
|
+
-f, --force allow to overwrite existing variable <name>
|
35
|
+
|
36
|
+
usage: multi var remove <name>
|
37
|
+
|
38
|
+
Remove variable <name>.
|
39
|
+
|
40
|
+
usage: multi push [options] <url>
|
41
|
+
|
42
|
+
Push all variables to server at <url>.
|
43
|
+
|
44
|
+
options:
|
45
|
+
-t, --token <token> user token
|
46
|
+
-f, --force force push
|
47
|
+
|
48
|
+
usage: multi pull [options] <url>
|
49
|
+
|
50
|
+
Pull all variables from server at <url>.
|
51
|
+
|
52
|
+
options:
|
53
|
+
-t, --token <token> user token
|
54
|
+
-f, --force force pull (override local variables)
|
55
|
+
|
56
|
+
usage: multi help [<command>...]
|
57
|
+
|
58
|
+
Show help for given <command>.
|
59
|
+
HELP
|
60
|
+
|
61
|
+
case ARGS.current_command.name
|
62
|
+
when 'multi'
|
63
|
+
puts(ARGS.help? ? ARGS : 'multi sample v1.0.0')
|
64
|
+
when 'help'
|
65
|
+
if ARGS.command?
|
66
|
+
command = ARGS.find_command(ARGS.command)
|
67
|
+
ARGS.error!("unknown command - #{ARGS.command.join(' ')}") if command.nil?
|
68
|
+
puts(command.help)
|
69
|
+
else
|
70
|
+
puts(ARGS.main_command.help)
|
71
|
+
end
|
72
|
+
else
|
73
|
+
puts "command '#{ARGS.current_command}':"
|
74
|
+
arguments = ARGS.to_h
|
75
|
+
width = arguments.keys.max_by(&:size).size + 3
|
76
|
+
arguments.each_pair do |name, value|
|
77
|
+
puts(" #{name.to_s.ljust(width)}#{value.inspect}")
|
78
|
+
end
|
79
|
+
end
|
data/examples/simple.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative '../lib/parse-argv'
|
5
|
+
|
6
|
+
ARGS = ParseArgv.from <<~HELP
|
7
|
+
Simple ParseArgv Demo
|
8
|
+
|
9
|
+
This is a demo for the command `simple`, which requires an <input> argument and
|
10
|
+
accepts optional an <output> argument. It accepts also some options.
|
11
|
+
|
12
|
+
Usage: simple [options] <input> [<output>]
|
13
|
+
|
14
|
+
Options:
|
15
|
+
-f, --format <format> select a format: txt, html, md
|
16
|
+
-c, --count <count> set a count (default 10)
|
17
|
+
|
18
|
+
The command's options can be defined in different paragraphs.
|
19
|
+
|
20
|
+
More Options:
|
21
|
+
-h, --help display this help
|
22
|
+
-v, --version display version information
|
23
|
+
--verbose enable verbose mode
|
24
|
+
|
25
|
+
Play with different command line parameters and options to see how it works!
|
26
|
+
HELP
|
27
|
+
|
28
|
+
puts(ARGS) or exit if ARGS.help?
|
29
|
+
puts('simple v1.0.0') or exit if ARGS.version?
|
30
|
+
puts <<~RESULT
|
31
|
+
arguments:
|
32
|
+
input #{ARGS.input}
|
33
|
+
output #{ARGS.output}
|
34
|
+
format #{ARGS[:format].as(%w[txt html md], default: 'txt')}
|
35
|
+
count #{ARGS[:count].as(Integer, :positive, default: 10)}
|
36
|
+
verbose #{ARGS.verbose}
|
37
|
+
RESULT
|