command_mapper-gen 0.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +27 -0
  3. data/.gitignore +10 -0
  4. data/.rspec +1 -0
  5. data/.yardopts +1 -0
  6. data/ChangeLog.md +20 -0
  7. data/Gemfile +17 -0
  8. data/LICENSE.txt +20 -0
  9. data/README.md +145 -0
  10. data/Rakefile +15 -0
  11. data/bin/command_mapper-gen +7 -0
  12. data/commnad_mapper-gen.gemspec +61 -0
  13. data/examples/grep.rb +63 -0
  14. data/gemspec.yml +26 -0
  15. data/lib/command_mapper/gen/arg.rb +43 -0
  16. data/lib/command_mapper/gen/argument.rb +53 -0
  17. data/lib/command_mapper/gen/cli.rb +233 -0
  18. data/lib/command_mapper/gen/command.rb +202 -0
  19. data/lib/command_mapper/gen/exceptions.rb +9 -0
  20. data/lib/command_mapper/gen/option.rb +66 -0
  21. data/lib/command_mapper/gen/option_value.rb +23 -0
  22. data/lib/command_mapper/gen/parsers/common.rb +49 -0
  23. data/lib/command_mapper/gen/parsers/help.rb +351 -0
  24. data/lib/command_mapper/gen/parsers/man.rb +80 -0
  25. data/lib/command_mapper/gen/parsers/options.rb +127 -0
  26. data/lib/command_mapper/gen/parsers/usage.rb +141 -0
  27. data/lib/command_mapper/gen/parsers.rb +2 -0
  28. data/lib/command_mapper/gen/task.rb +90 -0
  29. data/lib/command_mapper/gen/types/enum.rb +30 -0
  30. data/lib/command_mapper/gen/types/key_value.rb +34 -0
  31. data/lib/command_mapper/gen/types/list.rb +34 -0
  32. data/lib/command_mapper/gen/types/map.rb +36 -0
  33. data/lib/command_mapper/gen/types/num.rb +18 -0
  34. data/lib/command_mapper/gen/types/str.rb +48 -0
  35. data/lib/command_mapper/gen/types.rb +6 -0
  36. data/lib/command_mapper/gen/version.rb +6 -0
  37. data/lib/command_mapper/gen.rb +2 -0
  38. data/spec/argument_spec.rb +92 -0
  39. data/spec/cli_spec.rb +269 -0
  40. data/spec/command_spec.rb +316 -0
  41. data/spec/option_spec.rb +85 -0
  42. data/spec/option_value_spec.rb +20 -0
  43. data/spec/parsers/common_spec.rb +616 -0
  44. data/spec/parsers/help_spec.rb +612 -0
  45. data/spec/parsers/man_spec.rb +158 -0
  46. data/spec/parsers/options_spec.rb +802 -0
  47. data/spec/parsers/usage_spec.rb +1175 -0
  48. data/spec/spec_helper.rb +6 -0
  49. data/spec/task_spec.rb +69 -0
  50. data/spec/types/enum_spec.rb +45 -0
  51. data/spec/types/key_value_spec.rb +36 -0
  52. data/spec/types/list_spec.rb +36 -0
  53. data/spec/types/map_spec.rb +48 -0
  54. data/spec/types/str_spec.rb +70 -0
  55. metadata +133 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a2eb2af7ffecbe7da0c31bf20a00c712c24a2e9400e12ed825104fcaadd6f020
4
+ data.tar.gz: 2a2ffc1f78ba1070a1edfd46be101b4af14892b970827509bdf472db1025945c
5
+ SHA512:
6
+ metadata.gz: 243a76faebe6ec05dd7c1ca71cc6325b1f59226e6c3003244972af1e2bcd4433d6b057b1f9e1d194bebda4b4086e423fdeed79359b669f93894fab343a127603
7
+ data.tar.gz: d8e47e0b6f97a7d19bbfe06c133bb52cb9003970a3823ab9e15124c5715dcaa2ee3d1410f9ad9335722ef40bff4fac82348f76dd08a52ed4962841ccc845dc0d
@@ -0,0 +1,27 @@
1
+ name: CI
2
+
3
+ on: [ push, pull_request ]
4
+
5
+ jobs:
6
+ tests:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ fail-fast: false
10
+ matrix:
11
+ ruby:
12
+ - 2.6
13
+ - 2.7
14
+ - 3.0
15
+ - jruby
16
+ - truffleruby
17
+ name: Ruby ${{ matrix.ruby }}
18
+ steps:
19
+ - uses: actions/checkout@v2
20
+ - name: Set up Ruby
21
+ uses: ruby/setup-ruby@v1
22
+ with:
23
+ ruby-version: ${{ matrix.ruby }}
24
+ - name: Install dependencies
25
+ run: bundle install --jobs 4 --retry 3
26
+ - name: Run tests
27
+ run: bundle exec rake test
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /Gemfile.lock
2
+ /coverage/
3
+ /doc/
4
+ /pkg/
5
+ /vendor/bundle/
6
+ .DS_Store
7
+ .yardoc
8
+ *.log
9
+ *.swp
10
+ *~
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --colour --format documentation
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup markdown --title "CommandMapper::Gen Documentation" --protected --quiet
data/ChangeLog.md ADDED
@@ -0,0 +1,20 @@
1
+ ### 0.1.0 / 2021-11-22
2
+
3
+ * Initial release:
4
+ * Added {CommandMapper::Gen::Types::Str}.
5
+ * Added {CommandMapper::Gen::Types::Num}.
6
+ * Added {CommandMapper::Gen::Types::Map}.
7
+ * Added {CommandMapper::Gen::Types::Enum}.
8
+ * Added {CommandMapper::Gen::Types::KeyValue}.
9
+ * Added {CommandMapper::Gen::Types::List}.
10
+ * Added {CommandMapper::Gen::Arg}.
11
+ * Added {CommandMapper::Gen::Argument}.
12
+ * Added {CommandMapper::Gen::OptionValue}.
13
+ * Added {CommandMapper::Gen::Option}.
14
+ * Added {CommandMapper::Gen::Command}.
15
+ * Added {CommandMapper::Gen::Parsers::Common}.
16
+ * Added {CommandMapper::Gen::Parsers::Usage}.
17
+ * Added {CommandMapper::Gen::Parsers::Options}.
18
+ * Added {CommandMapper::Gen::Parsers::Help}.
19
+ * Added {CommandMapper::Gen::Parsers::Man}.
20
+ * Added {CommandMapper::Gen::CLI}.
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'rake'
7
+ gem 'rubygems-tasks', '~> 0.2'
8
+
9
+ gem 'rspec', '~> 3.0'
10
+ gem 'simplecov', '~> 0.20', require: false
11
+
12
+ gem 'kramdown'
13
+ gem 'yard', '~> 0.9'
14
+ gem 'yard-spellcheck'
15
+
16
+ gem 'dead_end'
17
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2021 Hal Brodigan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ 'Software'), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,145 @@
1
+ # command_mapper-gen
2
+
3
+ [![CI](https://github.com/postmodern/command_mapper-gen.rb/actions/workflows/ruby.yml/badge.svg)](https://github.com/postmodern/command_mapper-gen.rb/actions/workflows/ruby.yml)
4
+
5
+ * [Source](https://github.com/postmodern/command_mapper-gen)
6
+ * [Issues](https://github.com/postmodern/command_mapper-gen/issues)
7
+
8
+ ## Description
9
+
10
+ `command_mapper-gen` parses a command's `--help` output and man-page
11
+ and generates the [command_mapper] Ruby class for the command.
12
+
13
+ ## Features
14
+
15
+ * Parses `--help` output.
16
+ * Parses man pages.
17
+ * Provides the `command_mapper-gen` command.
18
+ * Provides a Rake task.
19
+
20
+ ## Synopsis
21
+
22
+ ```shell
23
+ $ command_mapper-gen grep
24
+ ```
25
+
26
+ Outputs:
27
+
28
+ ```
29
+ Failed to parse line in `grep --help`:
30
+
31
+ -NUM same as --context=NUM
32
+
33
+ Failed to match sequence ((' ' / SPACES) OPTION ','? ([ \\t]{1, } OPTION_SUMMARY)? !.) at line 1 char 5.
34
+
35
+ require 'command_mapper/command'
36
+
37
+ #
38
+ # Represents the `grep` command
39
+ #
40
+ class Grep < CommandMapper::Command
41
+
42
+ command "grep" do
43
+ option "--extended-regexp"
44
+ option "--fixed-strings"
45
+ option "--basic-regexp"
46
+ option "--perl-regexp"
47
+ option "--regexp", equals: true, value: true
48
+ option "--file", equals: true, value: true
49
+ option "--ignore-case"
50
+ option "--no-ignore-case"
51
+ option "--word-regexp"
52
+ option "--line-regexp"
53
+ option "--null-data"
54
+ option "--no-messages"
55
+ option "--invert-match"
56
+ option "--version"
57
+ option "--help"
58
+ option "--max-count", equals: true, value: {type: Num.new}
59
+ option "--byte-offset"
60
+ option "--line-number"
61
+ option "--line-buffered"
62
+ option "--with-filename"
63
+ option "--no-filename"
64
+ option "--label", equals: true, value: true
65
+ option "--only-matching"
66
+ option "--quiet"
67
+ option "--binary-files", equals: true, value: true
68
+ option "--text"
69
+ option "-I", name: # FIXME: name
70
+ option "--directories", equals: true, value: true
71
+ option "--devices", equals: true, value: true
72
+ option "--recursive"
73
+ option "--dereference-recursive"
74
+ option "--include", equals: true, value: true
75
+ option "--exclude", equals: true, value: true
76
+ option "--exclude-from", equals: true, value: true
77
+ option "--exclude-dir", equals: true, value: true
78
+ option "--files-without-match", value: true
79
+ option "--files-with-matches"
80
+ option "--count"
81
+ option "--initial-tab"
82
+ option "--null"
83
+ option "--before-context", equals: true, value: {type: Num.new}
84
+ option "--after-context", equals: true, value: {type: Num.new}
85
+ option "--context", equals: true, value: {type: Num.new}
86
+ option "--group-separator", equals: true, value: true
87
+ option "--no-group-separator"
88
+ option "--color", equals: :optional, value: {required: false}
89
+ option "--colour", equals: :optional, value: {required: false}
90
+ option "--binary"
91
+
92
+ argument :patterns
93
+ argument :file, required: false, repeats: true
94
+ end
95
+
96
+ end
97
+ ```
98
+
99
+ Output can also be written to a file:
100
+
101
+ ```shell
102
+ $ command_mapper-gen -o lib/path/to/grep.rb grep
103
+ ```
104
+
105
+ ## Examples
106
+
107
+ ### Rake Task
108
+
109
+ In `Rakefile`:
110
+
111
+ ```ruby
112
+ require 'command_mapper/gen/task'
113
+ CommandMapper::Gen::Task.new('grep','lib/path/to/grep.rb')
114
+ ```
115
+
116
+ ## Requirements
117
+
118
+ * [ruby] >= 2.0.0
119
+ * [parslet] ~> 2.0
120
+
121
+ ## Install
122
+
123
+ ```shell
124
+ $ gem install command_mapper-gen
125
+ ```
126
+
127
+ ### Gemfile
128
+
129
+ ```ruby
130
+ group :development do
131
+ # ...
132
+
133
+ gem 'command_mapper-gen', '~> 0.1', require: false
134
+ end
135
+ ```
136
+
137
+ ## License
138
+
139
+ Copyright (c) 2021 Hal Brodigan
140
+
141
+ See {file:LICENSE.txt} for license information.
142
+
143
+ [command_mapper]: https://github.com/postmodern/command_mapper.rb#readme
144
+ [ruby]: htt[s://www.ruby-lang.org/
145
+ [parslet]: https://github.com/kschiess/parslet#readme
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+
3
+ require 'rubygems/tasks'
4
+ Gem::Tasks.new
5
+
6
+ require 'rspec/core/rake_task'
7
+ RSpec::Core::RakeTask.new
8
+ task :test => :spec
9
+ task :default => :spec
10
+
11
+ require 'yard'
12
+ YARD::Rake::YardocTask.new
13
+
14
+ require 'command_mapper/gen/task'
15
+ CommandMapper::Gen::Task.new('grep', 'examples/grep.rb')
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib_dir = File.expand_path('../lib',__dir__)
4
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
5
+
6
+ require 'command_mapper/gen/cli'
7
+ exit CommandMapper::Gen::CLI.run
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+
3
+ require 'yaml'
4
+
5
+ Gem::Specification.new do |gem|
6
+ gemspec = YAML.load_file('gemspec.yml')
7
+
8
+ gem.name = gemspec.fetch('name')
9
+ gem.version = gemspec.fetch('version') do
10
+ lib_dir = File.join(File.dirname(__FILE__),'lib')
11
+ $LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
12
+
13
+ require 'command_mapper/gen/version'
14
+ CommandMapper::Gen::VERSION
15
+ end
16
+
17
+ gem.summary = gemspec['summary']
18
+ gem.description = gemspec['description']
19
+ gem.licenses = Array(gemspec['license'])
20
+ gem.authors = Array(gemspec['authors'])
21
+ gem.email = gemspec['email']
22
+ gem.homepage = gemspec['homepage']
23
+ gem.metadata = gemspec['metadata'] if gemspec['metadata']
24
+
25
+ glob = lambda { |patterns| gem.files & Dir[*patterns] }
26
+
27
+ gem.files = `git ls-files`.split($/)
28
+ gem.files = glob[gemspec['files']] if gemspec['files']
29
+
30
+ gem.executables = gemspec.fetch('executables') do
31
+ glob['bin/*'].map { |path| File.basename(path) }
32
+ end
33
+ gem.default_executable = gem.executables.first if Gem::VERSION < '1.7.'
34
+
35
+ gem.extensions = glob[gemspec['extensions'] || 'ext/**/extconf.rb']
36
+ gem.test_files = glob[gemspec['test_files'] || '{test/{**/}*_test.rb']
37
+ gem.extra_rdoc_files = glob[gemspec['extra_doc_files'] || '*.{txt,md}']
38
+
39
+ gem.require_paths = Array(gemspec.fetch('require_paths') {
40
+ %w[ext lib].select { |dir| File.directory?(dir) }
41
+ })
42
+
43
+ gem.requirements = gemspec['requirements']
44
+ gem.required_ruby_version = gemspec['required_ruby_version']
45
+ gem.required_rubygems_version = gemspec['required_rubygems_version']
46
+ gem.post_install_message = gemspec['post_install_message']
47
+
48
+ split = lambda { |string| string.split(/,\s*/) }
49
+
50
+ if gemspec['dependencies']
51
+ gemspec['dependencies'].each do |name,versions|
52
+ gem.add_dependency(name,split[versions])
53
+ end
54
+ end
55
+
56
+ if gemspec['development_dependencies']
57
+ gemspec['development_dependencies'].each do |name,versions|
58
+ gem.add_development_dependency(name,split[versions])
59
+ end
60
+ end
61
+ end
data/examples/grep.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'command_mapper/command'
2
+
3
+ #
4
+ # Represents the `grep` command
5
+ #
6
+ class Grep < CommandMapper::Command
7
+
8
+ command "grep"
9
+
10
+ option "--extended-regexp"
11
+ option "--fixed-strings"
12
+ option "--basic-regexp"
13
+ option "--perl-regexp"
14
+ option "--regexp", equals: true, value: true
15
+ option "--file", equals: true, value: true
16
+ option "--ignore-case"
17
+ option "--no-ignore-case"
18
+ option "--word-regexp"
19
+ option "--line-regexp"
20
+ option "--null-data"
21
+ option "--no-messages"
22
+ option "--invert-match"
23
+ option "--version"
24
+ option "--help"
25
+ option "--max-count", equals: true, value: true
26
+ option "--byte-offset"
27
+ option "--line-number"
28
+ option "--line-buffered"
29
+ option "--with-filename"
30
+ option "--no-filename"
31
+ option "--label", equals: true, value: true
32
+ option "--only-matching"
33
+ option "--quiet"
34
+ option "--binary-files", equals: true, value: true
35
+ option "--text"
36
+ option "-I", name: # FIXME: name
37
+ option "--directories", equals: true, value: true
38
+ option "--devices", equals: true, value: true
39
+ option "--recursive"
40
+ option "--dereference-recursive"
41
+ option "--include", equals: true, value: true
42
+ option "--exclude", equals: true, value: true
43
+ option "--exclude-from", equals: true, value: true
44
+ option "--exclude-dir", equals: true, value: true
45
+ option "--files-without-match", value: true
46
+ option "--files-with-matches"
47
+ option "--count"
48
+ option "--initial-tab"
49
+ option "--null"
50
+ option "--before-context", equals: true, value: true
51
+ option "--after-context", equals: true, value: true
52
+ option "--context", equals: true, value: true
53
+ option "-NUM"
54
+ option "--group-separator", equals: true, value: true
55
+ option "--no-group-separator"
56
+ option "--color", equals: :optional, value: {required: false}
57
+ option "--colour", equals: :optional, value: {required: false}
58
+ option "--binary"
59
+
60
+ argument :patterns
61
+ argument :file, repeats: true, required: false
62
+
63
+ end
data/gemspec.yml ADDED
@@ -0,0 +1,26 @@
1
+ name: command_mapper-gen
2
+ summary: Generates command_mapper Ruby classes for a given command
3
+ description:
4
+ command_mapper-gen parses a command's --help output and man-page, then
5
+ generates the command_mapper Ruby class for the command.
6
+
7
+ license: MIT
8
+ authors: Postmodern
9
+ email: postmodern.mod3@gmail.com
10
+ homepage: https://github.com/postmodern/command_mapper-gen.rb#readme
11
+ has_yard: true
12
+
13
+ metadata:
14
+ documentation_uri: https://rubydoc.info/gems/command_mapper-gen
15
+ source_code_uri: https://github.com/postmodern/command_mapper-gen.rb
16
+ bug_tracker_uri: https://github.com/postmodern/command_mapper-gen.rb/issues
17
+ changelog_uri: https://github.com/postmodern/command_mapper-gen.rb/blob/master/ChangeLog.md
18
+ rubygems_mfa_required: 'true'
19
+
20
+ required_ruby_version: ">= 2.0.0"
21
+
22
+ dependencies:
23
+ parslet: ~> 2.0
24
+
25
+ development_dependencies:
26
+ bundler: ~> 2.0
@@ -0,0 +1,43 @@
1
+ module CommandMapper
2
+ module Gen
3
+ class Arg
4
+
5
+ # @return [Boolean]
6
+ attr_reader :required
7
+
8
+ # The value configuration for the argument.
9
+ #
10
+ # @return [Types::Type, nil]
11
+ attr_reader :type
12
+
13
+ #
14
+ # Initializes the parsed argument.
15
+ #
16
+ # @param [Boolean, nil] required
17
+ #
18
+ # @param [Types::Type, nil] type
19
+ #
20
+ def initialize(required: nil, type: nil)
21
+ @required = required
22
+ @type = type
23
+ end
24
+
25
+ #
26
+ # Converts the parsed argument to Ruby source code.
27
+ #
28
+ # @return [String]
29
+ #
30
+ def to_ruby
31
+ ruby = []
32
+ ruby << "required: #{@required.inspect}" if @required == false
33
+
34
+ if (@type && (type = @type.to_ruby))
35
+ ruby << "type: #{type}"
36
+ end
37
+
38
+ ruby.join(', ')
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,53 @@
1
+ require 'command_mapper/gen/arg'
2
+
3
+ module CommandMapper
4
+ module Gen
5
+ #
6
+ # Represents a mock `CommandMapper::Argument` class.
7
+ #
8
+ class Argument < Arg
9
+
10
+ # The name of the argument.
11
+ #
12
+ # @return [Symbol]
13
+ attr_reader :name
14
+
15
+ # @return [Boolean, nil]
16
+ attr_reader :repeats
17
+
18
+ #
19
+ # Initializes the parsed argument.
20
+ #
21
+ # @param [Symbol] name
22
+ # The argument name.
23
+ #
24
+ # @param [Boolean, nil] repeats
25
+ #
26
+ # @param [Hash{Symbol => Object}] kwargs
27
+ # Additional keyword arguments.
28
+ #
29
+ def initialize(name, repeats: nil, **kwargs)
30
+ super(**kwargs)
31
+
32
+ @name = name
33
+ @repeats = repeats
34
+ end
35
+
36
+ #
37
+ # Converts the parsed argument to Ruby source code.
38
+ #
39
+ # @return [String]
40
+ #
41
+ def to_ruby
42
+ ruby = "argument #{@name.inspect}"
43
+
44
+ keywords = super()
45
+ ruby << ", #{keywords}" unless keywords.empty?
46
+
47
+ ruby << ", repeats: #{@repeats.inspect}" unless @repeats.nil?
48
+ ruby
49
+ end
50
+
51
+ end
52
+ end
53
+ end