usage_by_example 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fa6ff28e421846106e76d35e80132c514df0308c59506428c884b7fd0b5ff702
4
+ data.tar.gz: dee35110be4a6d05480e067e12f913def3d52459b455232ddfc686b70a0670aa
5
+ SHA512:
6
+ metadata.gz: 2305c27d269773f2ea7ef8112bfd618385442cc59e31b1450ee741693c8254df323f129bd10ff7e8913afc05afc57ac58be154f485f5599f8b4df3422df7064b
7
+ data.tar.gz: 28d398dcb1d4c5f71fa3aa14e43e646836d47bcf39c3287c7b109dbf773e80bdf75d13b04c05682553754f0378d392d04b3f7d8d1c5e79fba8cf89d317d5f4a1
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in usage_by_example.gemspec
6
+ gemspec
7
+
8
+ gem "rake", "~> 13.0"
data/Gemfile.lock ADDED
@@ -0,0 +1,19 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ usage_by_example (0.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ rake (13.0.6)
10
+
11
+ PLATFORMS
12
+ x86_64-darwin-19
13
+
14
+ DEPENDENCIES
15
+ rake (~> 13.0)
16
+ usage_by_example!
17
+
18
+ BUNDLED WITH
19
+ 2.3.7
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # UsageByExample
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/usage_by_example`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'usage_by_example'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install usage_by_example
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/usage_by_example.
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class UsageByExample
4
+ VERSION = "0.0.0"
5
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "usage_by_example/version"
4
+
5
+
6
+ class UsageByExample
7
+
8
+ def self.read(data)
9
+ return new data.read
10
+ end
11
+
12
+ def initialize(text)
13
+ @usage = text.gsub('$0', File.basename($0)).gsub(/\n+\Z/, "\n\n")
14
+
15
+ # ---- 1) Parse argument names ------------------------------------
16
+ #
17
+ # Parse the usage string and extract both optional argument names
18
+ # and required argument names, for example:
19
+ #
20
+ # Usage: connect [options] [mode] host port
21
+
22
+ text =~ /Usage: (\w+|\$0) \[options\](( \[\w+\])*)(( \w+)*)/
23
+ raise RuntimeError, "Expected usage string, got none" unless $1
24
+ @argument_names_optional = $2.to_s.split.map { |match| match.tr('[]', '').downcase }
25
+ @argument_names_required = $4.to_s.split.map(&:downcase)
26
+
27
+ # ---- 2) Parse option names --------------------------------------
28
+ #
29
+ # Parse the usage message and extract option names, their short and
30
+ # long forms, and the associated argument name (if any), eg:
31
+ #
32
+ # Options:
33
+ # -s, --secure Use secure connection
34
+ # -v, --verbose Enable verbose output
35
+ # -r, --retries NUM Number of connection retries (default 3)
36
+ # -t, --timeout NUM Connection timeout in seconds (default 10)
37
+
38
+ @option_names = {}
39
+ text.scan(/((--?\w+)(, --?\w+)*) ?(\w+)?/) do
40
+ opts = $1.split(", ")
41
+ opts.each { |each| @option_names[each] = [opts.last.tr('-', ''), $4&.downcase] }
42
+ end
43
+
44
+ # ---- 3) Include help option by default --------------------------
45
+
46
+ @option_names.update("-h" => :help, "--help" => :help)
47
+ end
48
+
49
+ def parse(argv)
50
+ array = argv.dup
51
+ @arguments = {}
52
+ @options = {}
53
+
54
+ # --- 1) Parse options --------------------------------------------
55
+
56
+ most_recent_option = nil
57
+ until array.empty? do
58
+ break unless array.first.start_with?(?-)
59
+ most_recent_option = option = array.shift
60
+ option_name, argument_name = @option_names[option]
61
+ raise "Got unknown option #{option}" if option_name.nil?
62
+ raise if option_name == :help # Show usage without error message
63
+ @options[option_name] = true
64
+
65
+ # Consume argument, if expected by most recent option
66
+ if argument_name
67
+ argument = array.shift
68
+ raise "Expected argument for option #{option}" unless /^[^-]/ === argument
69
+ @arguments[option_name] = argument
70
+ most_recent_option = nil
71
+ end
72
+ end
73
+
74
+ # --- 2) Parse optional arguments ---------------------------------
75
+
76
+ stash = array.pop(@argument_names_required.length)
77
+ @argument_names_optional.each do |argument_name|
78
+ break if array.empty?
79
+ argument = array.shift
80
+ raise "Expected more arguments, got option #{option}" unless /^[^-]/ === argument
81
+ @arguments[argument_name] = argument
82
+ end
83
+
84
+ # --- 3) Parse required arguments ---------------------------------
85
+
86
+ @argument_names_required.each do |argument_name|
87
+ raise "Expected required argument #{argument_name.upcase}, got none" if stash.empty?
88
+ argument = stash.shift
89
+ raise "Expected more arguments, got option #{option}" unless /^[^-]/ === argument
90
+ @arguments[argument_name] = argument
91
+ end
92
+
93
+ # --- 4) Expect to be done ----------------------------------------
94
+
95
+ if not array.empty?
96
+ # Custom error message if most recent option did not require argument
97
+ raise "Got unexpected argument for option #{most_recent_option}" if most_recent_option
98
+ min_length = @argument_names.length
99
+ max_length = @argument_names.length + @argument_names_optional.length
100
+ raise "Expected #{min_length}#{"-#{max_length}" if max_length > min_length} arguments, got more"
101
+ end
102
+
103
+ return self
104
+
105
+ rescue RuntimeError => err
106
+ puts "ERROR: #{err.message}\n\n" unless err.message.empty?
107
+ puts @usage
108
+ exit
109
+ end
110
+
111
+ def method_missing(sym, *args, &block)
112
+ case sym
113
+ when /^argument_(.*)$/
114
+ val = @arguments[$1]
115
+ block && val ? block.call(val) : val
116
+ when /^include_(.*)\?$/
117
+ @options[$1]
118
+ else
119
+ super
120
+ end
121
+ end
122
+ end
123
+
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: usage_by_example
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Adrian Kuhn
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-04-26 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description:
14
+ email:
15
+ - akuhn@iam.unibe.ch
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".rspec"
21
+ - Gemfile
22
+ - Gemfile.lock
23
+ - README.md
24
+ - lib/usage_by_example.rb
25
+ - lib/usage_by_example/version.rb
26
+ homepage: https://github.com/akuhn/usage_by_example
27
+ licenses:
28
+ - MIT
29
+ metadata:
30
+ homepage_uri: https://github.com/akuhn/usage_by_example
31
+ source_code_uri: https://github.com/akuhn/usage_by_example
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 2.6.0
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubygems_version: 3.3.7
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: No-code options parser that extracts arguments directly from usage text.
51
+ test_files: []