quick_and_ruby 0.2.0 → 0.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e695692e69fbbe9d843e3b31fe830ab5db5b9310ec914a29fe1b57bebac5b49
4
- data.tar.gz: dd2f04a4330b3e1442fcac6b6eaa3fb28511818b7e7ef0affd6d884468b24d08
3
+ metadata.gz: c685bd6937aa82ca104aa4d885bb6cb150e465d61dafe2fc4c5bcd18f2a19cc5
4
+ data.tar.gz: c6e90670c6447c6261fb3c25be94d7617c0c4a4042da22cd302f5c9a9c906481
5
5
  SHA512:
6
- metadata.gz: d94125e0cb6710267077f820264d547da8400b8914106d39061982a2c6b81bd67f65ccbc739999e5a973db28176cc13fcc9e5bdc3a2926397d62f29fdb87226c
7
- data.tar.gz: 765193d18ccf0db661daa0301004867144db799883e016d2e4ebcd07f6e7545fb78dc4faad5604bb968b5ce09194d46d4c3dcfe859cbc7a99c47e786df908907
6
+ metadata.gz: '03189ba3378295c3358c4449d30d6c2c6075f1c292f83b6f5db7f4cedcac775e3bc6cfd0d639cb50d54fcbe56f77aa70df2eaad3fe17263286bb968f34097933'
7
+ data.tar.gz: 00b294e7bc307dbb19947dfc48dd49cdd0b803fc5c69258ddcf6d5596b2df9923fb2be3e86921b3784ccef348d78f2d5865fe13c3a3cba15c5927e42b7f8278d
data/.gitignore CHANGED
@@ -6,6 +6,11 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ /.byebug_history
9
10
 
10
11
  # rspec failure tracking
11
12
  .rspec_status
13
+
14
+ # app
15
+ /Gemfile.lock
16
+ /.ruby-version
data/.reek.yml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+
3
+ detectors:
4
+ IrresponsibleModule:
5
+ enabled: false
6
+
7
+ exclude_paths: []
data/.rubocop.yml ADDED
@@ -0,0 +1,45 @@
1
+ require:
2
+ - rubocop-rake
3
+ - rubocop-rspec
4
+
5
+ AllCops:
6
+ NewCops: enable
7
+ TargetRubyVersion: 2.7
8
+
9
+ Gemspec/DevelopmentDependencies:
10
+ Enabled: false
11
+
12
+ Layout/LineLength:
13
+ Max: 100
14
+
15
+ Metrics/BlockLength:
16
+ Exclude:
17
+ - quick_and_ruby.gemspec
18
+ - spec/**/*.rb
19
+
20
+ Metrics/ClassLength:
21
+ Exclude:
22
+ - test/**/*.rb
23
+
24
+ Metrics/CyclomaticComplexity:
25
+ Max: 10
26
+
27
+ Metrics/MethodLength:
28
+ Max: 25
29
+
30
+ Style/Documentation:
31
+ Enabled: false
32
+
33
+ # Style/StringLiterals:
34
+ # Enabled: true
35
+ # EnforcedStyle: double_quotes
36
+
37
+ # Style/StringLiteralsInInterpolation:
38
+ # Enabled: true
39
+ # EnforcedStyle: double_quotes
40
+
41
+ RSpec/ExampleLength:
42
+ Max: 10
43
+
44
+ RSpec/MultipleExpectations:
45
+ Max: 2
data/README.md CHANGED
@@ -1,43 +1,66 @@
1
1
  # QuickAndRuby
2
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/quick_and_ruby`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ Gem to group utilities in ruby.
4
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:
5
+ ## install
10
6
 
11
7
  ```ruby
12
- gem 'quick_and_ruby'
8
+ gem install quick_and_ruby
13
9
  ```
14
10
 
15
- And then execute:
11
+ ## bins
12
+
13
+ ### proxy
14
+
15
+ ### datetime
16
16
 
17
- $ bundle
17
+ Used to manipulate date:
18
+ - allow to compute all increment between 2 dates.
19
+ - allow to compute a date starting form another/now.
18
20
 
19
- Or install it yourself as:
21
+ Usage:
22
+ ``` shell
23
+ datetime -o <offset> -i <incr> -f "<format>" <from>|now <to>|now
20
24
 
21
- $ gem install quick_and_ruby
25
+ datetime -o <offset> -i <incr> -f "<format>" <from>|now
26
+ ```
27
+
28
+ ### yaml2json
22
29
 
23
- ## Usage
30
+ Convert yaml formated string, file or stdin to json format.
24
31
 
25
- TODO: Write usage instructions here
32
+ usage:
26
33
 
27
- ## Development
34
+ ``` shell
35
+ yaml2json file.json
36
+ # ... generates file.json
28
37
 
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.
38
+ yaml2json 'msg: test'
39
+ # {
40
+ # "msg": "test"
41
+ # }
30
42
 
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 tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
43
+ echo 'msg: test' | yaml2json
44
+ # {
45
+ # "msg": "test"
46
+ # }
47
+ ```
32
48
 
33
- ## Contributing
49
+ ### json2yaml
34
50
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/quick_and_ruby. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
51
+ Convert json formated string, file or stdin to yaml format.
36
52
 
37
- ## License
53
+ usage:
38
54
 
39
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
55
+ ``` shell
56
+ json2yaml file.json
57
+ # ... generates file.yaml
40
58
 
41
- ## Code of Conduct
59
+ json2yaml '{"msg": "test"}'
60
+ # ---
61
+ # msg: test
42
62
 
43
- Everyone interacting in the QuickAndRuby project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/quick_and_ruby/blob/master/CODE_OF_CONDUCT.md).
63
+ echo '{"msg": "test"}' | json2yaml
64
+ # ---
65
+ # msg: test
66
+ ```
data/Rakefile CHANGED
@@ -1,6 +1,15 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'bundler/gem_tasks'
4
+
2
5
  require 'rspec/core/rake_task'
3
6
 
4
7
  RSpec::Core::RakeTask.new(:spec)
5
8
 
6
- task default: :spec
9
+ require 'rubocop/rake_task'
10
+
11
+ RuboCop::RakeTask.new
12
+
13
+ require 'bump/tasks'
14
+
15
+ task default: %i[spec rubocop]
data/bin/cat.rb ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ puts ARGF.read
data/bin/datetime ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'quick_and_ruby/date'
5
+
6
+ QuickAndRuby::Date::DateTimeCli.new(ARGV).run
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'optparse'
5
+ require 'quick_and_ruby/distinguished_name'
6
+
7
+ argv = ARGV.clone
8
+
9
+ options = {}
10
+ option_parser = OptionParser.new do |opts|
11
+ executable_name = File.basename($PROGRAM_NAME)
12
+ opts.banner = "Format Distinguished Name.\n" \
13
+ "\n" \
14
+ "Usage: #{executable_name} [options] distinguished_name"
15
+
16
+ opts.on('-r', '--reverse', 'Reverse Distinguished Name') do |reverse|
17
+ options[:reverse] = reverse
18
+ end
19
+ end
20
+
21
+ option_parser.parse!(argv)
22
+ if argv.empty?
23
+ warn 'error: you must supply a distinguished_name'
24
+ $stderr.puts
25
+ warn option_parser.help
26
+ exit 2
27
+ else
28
+ distinguished_name = argv.clone.join(' ')
29
+ end
30
+
31
+ dn = QuickAndRuby::DistinguishedName.from_s(distinguished_name)
32
+ dn = dn.reverse if options[:reverse]
33
+
34
+ puts dn.to_s
data/bin/jb ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'optparse'
5
+ require 'quick_and_ruby/data'
6
+
7
+ option_parser = OptionParser.new do |opts|
8
+ executable_name = File.basename($PROGRAM_NAME)
9
+ opts.banner = "Interactively browse a JSON file\n" \
10
+ "\n" \
11
+ "Usage: #{executable_name} [json_file]"
12
+ end
13
+ option_parser.parse!
14
+
15
+ json_context = QuickAndRuby::Data::Context.from_json(ARGF.read)
16
+ browser = QuickAndRuby::Data::Browser.new(json_context)
17
+ browser.main
data/bin/json2yaml ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'json'
5
+ require 'yaml'
6
+
7
+ def json2yaml(str)
8
+ YAML.dump(JSON.parse(str))
9
+ end
10
+
11
+ from = ARGV[0]
12
+ if from && File.exist?(from)
13
+ to = ARGV[1] || "#{from.chomp('.json')}.yaml"
14
+
15
+ File.write(to, json2yaml(File.read(from)))
16
+ elsif from
17
+ puts json2yaml(from)
18
+ elsif !$stdin.tty? && !$stdin.closed?
19
+ puts json2yaml($stdin.read)
20
+ end
data/{exe → bin}/proxy RENAMED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  # -*- mode: Ruby -*-
3
5
 
4
6
  require 'quick_and_ruby'
data/bin/yaml2json ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'json'
5
+ require 'yaml'
6
+
7
+ def yaml2json(str)
8
+ JSON.pretty_generate(YAML.safe_load(str, aliases: true))
9
+ end
10
+
11
+ from = ARGV[0]
12
+ if from && File.exist?(from)
13
+ to = ARGV[1] || "#{from.chomp('.yaml').chomp('.yml')}.json"
14
+
15
+ File.write(to, yaml2json(File.read(from)))
16
+ elsif from
17
+ puts yaml2json(from)
18
+ elsif !$stdin.tty? && !$stdin.closed?
19
+ puts yaml2json($stdin.read)
20
+ end
data/bin/yb ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'optparse'
5
+ require 'quick_and_ruby/data'
6
+
7
+ option_parser = OptionParser.new do |opts|
8
+ executable_name = File.basename($PROGRAM_NAME)
9
+ opts.banner = "Interactively browse a Yaml file\n" \
10
+ "\n" \
11
+ "Usage: #{executable_name} [yaml_file]"
12
+ end
13
+ option_parser.parse!
14
+
15
+ yaml_context = QuickAndRuby::Data::Context.from_yaml(ARGF.read)
16
+ browser = QuickAndRuby::Data::Browser.new(yaml_context)
17
+ browser.main
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'reline'
4
+
5
+ module QuickAndRuby
6
+ module Data
7
+ class Browser
8
+ attr_reader :root_context
9
+
10
+ def initialize(root_context)
11
+ @root_context = root_context
12
+ end
13
+
14
+ def main
15
+ command = nil
16
+ current_context = root_context
17
+
18
+ Reline.completion_proc = lambda { |input|
19
+ current_context.completions(input)
20
+ }
21
+
22
+ while command != 'exit'
23
+ command = Reline.readline("#{current_context.pwd}> ", true)
24
+ break if command.nil?
25
+
26
+ current_context = execute_command(command.strip, current_context)
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def execute_command(command, context)
33
+ case command
34
+ when /^ls$/
35
+ puts context
36
+ when /^cd (.*$)/
37
+ new_context = context.cd(::Regexp.last_match(1))
38
+ if new_context.nil?
39
+ puts "No such key #{::Regexp.last_match(1)}"
40
+ else
41
+ context = new_context
42
+ end
43
+ when /^cat (.*)$/
44
+ item = context.cat(::Regexp.last_match(1))
45
+ if item.nil?
46
+ puts "No such item #{::Regexp.last_match(1)}"
47
+ else
48
+ puts item.inspect
49
+ end
50
+ when /^pwd$/
51
+ puts context.pwd
52
+ when /^help$/
53
+ puts 'cat <item> - print the contents of <item> in the current context'
54
+ puts 'cd <item> - change context to the context of <item>'
55
+ puts 'cd .. - change up one level'
56
+ puts 'ls - list available items in the current context'
57
+ puts 'pwd - print context path'
58
+ end
59
+ context
60
+ end
61
+
62
+ def complete_command(input, context)
63
+ require 'byebug'
64
+ byebug
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'json'
5
+
6
+ module QuickAndRuby
7
+ module Data
8
+ class Context
9
+ attr_reader :here, :id, :parent
10
+
11
+ def initialize(here, id: nil, parent: nil)
12
+ @here = here
13
+ @id = id
14
+ @parent = parent
15
+ end
16
+
17
+ def to_s
18
+ if here.is_a? Array
19
+ indices = []
20
+ here.each_index { |i| indices << i }
21
+ indices.join(' ')
22
+ elsif here.is_a? Hash
23
+ here.keys.join(' ')
24
+ else
25
+ here.to_s
26
+ end
27
+ end
28
+
29
+ def pwd
30
+ pwd_parts = []
31
+ pwd_cur = self
32
+ while pwd_cur
33
+ pwd_parts.unshift pwd_cur.id if pwd_cur.id
34
+ pwd_cur = pwd_cur.parent
35
+ end
36
+ "/" + pwd_parts.join('/')
37
+ end
38
+
39
+ def cat(path)
40
+ item_at(path)
41
+ end
42
+
43
+ def cd(path)
44
+ if path == '..'
45
+ parent
46
+ else
47
+ item = item_at(path)
48
+ if item.nil?
49
+ nil
50
+ else
51
+ Context.new(item, id: path, parent: self)
52
+ end
53
+ end
54
+ end
55
+
56
+ def completions(input)
57
+ to_s.split(/\s+/).grep(/^#{input}/)
58
+ end
59
+
60
+ private
61
+
62
+ def item_at(path)
63
+ if path == '..'
64
+ parent.here
65
+ elsif here.is_a? Array
66
+ here[path.to_i]
67
+ elsif here.is_a? Hash
68
+ here[path]
69
+ end
70
+ end
71
+
72
+ def self.from_yaml(yaml_data)
73
+ new(YAML.parse(yaml_data))
74
+ end
75
+
76
+ def self.from_json(json_data)
77
+ new(JSON.parse(json_data))
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'data/browser'
4
+ require_relative 'data/context'
5
+
6
+ module QuickAndRuby
7
+ module Data
8
+ # namespace
9
+ end
10
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'date'
4
+ require 'optparse'
5
+
6
+ require 'quick_and_ruby/version'
7
+
8
+ module QuickAndRuby
9
+ module Date
10
+ # argv parser for datetime utility
11
+ # parsing example:
12
+ # - datetime -z <zone> -i <incr> -f "<format>" <from>|now <to>|now
13
+ # - datetime -z <zone> -i <incr> -f "<format>" <from>|now
14
+ class DateTimeArgs
15
+ DEFAULT_FORMAT = '%Y-%m-%dT%H:%M:%S.%3NZ'
16
+ DEFAULT_INCR = '1d'
17
+ DEFAULT_ZONE = DateTime.now.zone
18
+
19
+ attr_reader :date_begin, :date_end, :incr, :format, :zone
20
+
21
+ def initialize(date_begin: DateTime.now, date_end: nil,
22
+ incr: DEFAULT_INCR,
23
+ format: DEFAULT_FORMAT,
24
+ zone: DEFAULT_ZONE)
25
+ @date_begin = date_begin
26
+ @date_end = date_end
27
+ @incr = incr
28
+ @format = format
29
+ @zone = zone
30
+ end
31
+
32
+ def want_range?
33
+ date_begin && date_end
34
+ end
35
+
36
+ def want_incr?
37
+ date_begin && !date_end
38
+ end
39
+
40
+ class << self
41
+ def load(argv = ARGV)
42
+ options = new
43
+ parser(options).parse!(argv.clone)
44
+ puts options
45
+ options
46
+ end
47
+
48
+ private
49
+
50
+ def parser(options)
51
+ @parser ||= OptionParser.new do |opts|
52
+ opts.banner = 'Usage: daterange [options] time-begin time-end'
53
+ opts.on_tail('-h', '--help', 'Show this message') do
54
+ puts opts
55
+ exit
56
+ end
57
+
58
+ opts.on_tail('--version', 'Show version') do
59
+ puts ::QuickAndRuby::VERSION
60
+ exit
61
+ end
62
+
63
+ opts.on_tail('-f', '--format=FORMAT', 'FORMAT for printing date') do |format|
64
+ options.format = format
65
+ end
66
+
67
+ opts.on_tail('-i', '--incr=INCR', 'Increment by INCR') do |incr|
68
+ options.incr = incr
69
+ end
70
+
71
+ opts.on_tail('-z', '--zone=ZONE', 'Timezone ZONE') do |zone|
72
+ options.zone = zone
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'date_time_args'
4
+
5
+ module QuickAndRuby
6
+ module Date
7
+ # cli / main class for datetime utility
8
+ # usage example:
9
+ # - datetime -z <zone> -i <incr> -f "<format>" <from>|now <to>|now
10
+ # - datetime -z <zone> -i <incr> -f "<format>" <from>|now
11
+ class DateTimeCli
12
+ def initialize(argv = ARGV, args_loader = QuickAndRuby::Date::DateTimeArgs)
13
+ @argv = argv || []
14
+ @args_loader = args_loader
15
+ end
16
+
17
+ def run
18
+ run_range if args.want_range?
19
+ run_incr if args.want_incr?
20
+ end
21
+
22
+ def run_range
23
+ puts :RUN_RANGE
24
+ time_cursor = args.date_begin
25
+ while time_cursor <= args.date_end
26
+ puts time_cursor.strftime(args.format)
27
+ time_cursor.increment(**args.incr)
28
+ end
29
+ end
30
+
31
+ def run_incr
32
+ puts :RUN_INCR
33
+ end
34
+
35
+ def args
36
+ @args ||= args_loader.load(argv)
37
+ end
38
+
39
+ private
40
+
41
+ attr_reader :argv, :args_loader
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'version'
4
+ require_relative 'date/date_time_cli'
5
+
6
+ module QuickAndRuby
7
+ # Date module
8
+ # provides namespace
9
+ module Date
10
+ end
11
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module QuickAndRuby
4
+ class DistinguishedName
5
+ class Attribute
6
+ # DC domainComponent
7
+ # CN commonName
8
+ # OU organizationalUnitName
9
+ # O organizationName
10
+ # STREET streetAddress
11
+ # L localityName
12
+ # ST stateOrProvinceName
13
+ # C countryName
14
+ # UID userid
15
+
16
+ SPLIT_RE = /^(\w+)=((?:\\.|[^\\])+)$/.freeze
17
+
18
+ attr_reader :name, :value
19
+
20
+ def initialize(name, value)
21
+ @name = name
22
+ @value = value
23
+ end
24
+
25
+ def to_s(escaper: nil)
26
+ escaped_value = value
27
+ escaped_value = escaper.call(escaped_value) if escaper
28
+
29
+ "#{name}=#{escaped_value}"
30
+ end
31
+
32
+ def self.from_s(part, unescaper: nil)
33
+ unless (match = SPLIT_RE.match(part))
34
+ raise "Invalid DN part: '#{part}'"
35
+ end
36
+
37
+ key = match[1].strip
38
+ value = match[2].strip
39
+ unescaped_value = value
40
+ unescaped_value = unescaper.call(unescaped_value) if unescaper
41
+ new(key, unescaped_value)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'attribute'
4
+
5
+ module QuickAndRuby
6
+ class DistinguishedName
7
+ class OpensslFormat
8
+ LABEL = :openssl
9
+ SEPARATOR = '/'
10
+ SPLIT_RE = %r{(?<!\\)/}.freeze
11
+
12
+ def escape(value)
13
+ value.gsub(%r{([/\\])}, '\\\\\1')
14
+ end
15
+
16
+ def unescape(value)
17
+ value.gsub(%r{\\([/\\])}, '\1')
18
+ end
19
+
20
+ def recognize?(dn_str)
21
+ return true if !dn_str || dn_str.empty?
22
+ return true if dn_str.start_with?(SEPARATOR)
23
+
24
+ false
25
+ end
26
+
27
+ def split(dn_str)
28
+ dn_str = dn_str[1..] if dn_str.start_with?(SEPARATOR)
29
+
30
+ parts = dn_str.split(SPLIT_RE)
31
+ parts.map do |part|
32
+ part = part.strip if part
33
+ next if !part || part.empty?
34
+
35
+ Attribute.from_s(part, unescaper: method(:unescape))
36
+ end.compact
37
+ end
38
+
39
+ def join(attributes)
40
+ SEPARATOR + attributes.map do |attribute|
41
+ attribute.to_s(escaper: method(:escape))
42
+ end.join(SEPARATOR)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'attribute'
4
+
5
+ module QuickAndRuby
6
+ class DistinguishedName
7
+ class RfcFormat
8
+ LABEL = :rfc
9
+ SEPARATOR = ','
10
+ SPLIT_RE = /(?<!\\),/.freeze
11
+
12
+ UNESCAPE_ALL_RE = /\\(.)/.freeze
13
+
14
+ def escape(value)
15
+ # value.gsub(/([,\\+<>;"= ])/, '\\\1')
16
+ value.gsub(/([,\\+<>;"=])/, '\\\\\1')
17
+ end
18
+
19
+ def unescape(value)
20
+ # .gsub(UNESCAPE_ALL_RE, '\1')
21
+ value.gsub(/\\([,\\+<>;"= ])/, '\1')
22
+ end
23
+
24
+ def recognize?(dn_str)
25
+ return true if !dn_str || dn_str.empty?
26
+
27
+ true
28
+ end
29
+
30
+ def split(dn_str)
31
+ parts = dn_str.split(SPLIT_RE)
32
+ parts.map do |part|
33
+ part = part.strip if part
34
+ next if !part || part.empty?
35
+
36
+ Attribute.from_s(part, unescaper: method(:unescape))
37
+ end.compact
38
+ end
39
+
40
+ def join(attributes)
41
+ attributes.map do |attribute|
42
+ attribute.to_s(escaper: method(:escape))
43
+ end.join(SEPARATOR)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'distinguished_name/attribute'
4
+ require_relative 'distinguished_name/rfc_format'
5
+ require_relative 'distinguished_name/openssl_format'
6
+
7
+ module QuickAndRuby
8
+ class DistinguishedName
9
+ attr_reader :attributes
10
+
11
+ def initialize(attributes = [])
12
+ @attributes = attributes
13
+ end
14
+
15
+ def to_s(format: :rfc)
16
+ formatter = get_format(format)
17
+ formatter.join(attributes)
18
+ end
19
+
20
+ def reverse
21
+ self.class.new(attributes.reverse)
22
+ end
23
+
24
+ def size
25
+ attributes.size
26
+ end
27
+ alias length size
28
+
29
+ def get_format(label = :rfc)
30
+ self.class.get_format(label)
31
+ end
32
+
33
+ class << self
34
+ def from_s(dn_str, format: nil)
35
+ return new if !dn_str || dn_str.empty?
36
+
37
+ formatter ||= get_format(format) if format
38
+ formatter ||= openssl_format if openssl_format.recognize?(dn_str)
39
+ formatter ||= rfc_format
40
+
41
+ attributes = formatter.split(dn_str)
42
+
43
+ new(attributes)
44
+ end
45
+
46
+ def rfc_format
47
+ get_format(:rfc)
48
+ end
49
+
50
+ def openssl_format
51
+ get_format(:openssl)
52
+ end
53
+
54
+ def get_format(label = :rfc)
55
+ case label.to_sym
56
+ when :rfc
57
+ RfcFormat.new
58
+ when :openssl
59
+ OpensslFormat.new
60
+ else
61
+ raise ArgumentError, "Unsupported format #{label}"
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -1,6 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'optparse'
2
4
  require 'optparse/time'
3
- require 'ostruct'
4
5
 
5
6
  module QuickAndRuby
6
7
  module Proxy
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module QuickAndRuby
4
+ module String
5
+ module Case
6
+ def snakecase
7
+ gsub(/\s+/, '_').gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase
8
+ end
9
+
10
+ # def snakecase2
11
+ # return downcase if match(/\A[A-Z]+\z/)
12
+ # gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
13
+ # gsub(/([a-z])([A-Z])/, '\1_\2').
14
+ # downcase
15
+ # end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'string/case'
4
+
5
+ String.include QuickAndRuby::String::Case
@@ -1,3 +1,3 @@
1
1
  module QuickAndRuby
2
- VERSION = '0.2.0'.freeze
2
+ VERSION = '0.5.1'.freeze
3
3
  end
@@ -0,0 +1,26 @@
1
+ distinguished_name(1) -- utility to manipulate DN formated string
2
+ =================================================================
3
+
4
+ ## SYNOPSIS
5
+
6
+ `distinguished_name` <dn>
7
+ `distinguished_name` `-r`|`--reverse` <dn>
8
+
9
+ ## DESCRIPTION
10
+
11
+ **distinguished_name** is a simple command-line tool for modifying a dn string.
12
+
13
+ ## FILES
14
+
15
+ No files are used for the moment.
16
+
17
+ ## OPTIONS
18
+
19
+ * `-r`, `--reverse`:
20
+ Do a reverse of each attribute in the distinguished name (dn).
21
+
22
+ ## EXAMPLES
23
+
24
+ Print in reverse order the dn:
25
+
26
+ $ distinguished_name --reverse "C=CountryCode, ST=State, CN=CommonName"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  lib = File.expand_path('lib', __dir__)
2
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
5
  require 'quick_and_ruby/version'
@@ -10,20 +12,24 @@ Gem::Specification.new do |spec|
10
12
 
11
13
  spec.summary = 'Quick and Ruby utilities.'
12
14
  spec.description = 'Set of small and standalone utilities in Ruby.'
13
- spec.homepage = 'https://github.com/ttych/quick-and-ruby'
15
+ spec.homepage = 'https://github.com/ttych/quick_and_ruby'
14
16
  spec.license = 'MIT'
15
17
 
18
+ spec.required_ruby_version = '> 2.7'
19
+
16
20
  if spec.respond_to?(:metadata)
17
21
  spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18
22
 
19
23
  spec.metadata['homepage_uri'] = spec.homepage
20
- spec.metadata['source_code_uri'] = 'https://github.com/ttych/quick_and_ruby'
21
- spec.metadata['changelog_uri'] = 'https://github.com/ttych/quick_and_ruby'
24
+ spec.metadata['source_code_uri'] = spec.homepage
25
+ spec.metadata['changelog_uri'] = "#{spec.homepage}/CHANGELOG.md"
22
26
  else
23
27
  raise 'RubyGems 2.0 or newer is required to protect against ' \
24
- 'public gem pushes.'
28
+ 'public gem pushes.'
25
29
  end
26
30
 
31
+ spec.metadata['rubygems_mfa_required'] = 'true'
32
+
27
33
  # Specify which files should be added to the gem when it is released.
28
34
  # The `git ls-files -z` loads the files in the RubyGem
29
35
  # that have been added into git.
@@ -32,12 +38,17 @@ Gem::Specification.new do |spec|
32
38
  f.match(%r{^(test|spec|features)/})
33
39
  end
34
40
  end
35
- spec.bindir = 'exe'
36
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
41
+ spec.bindir = 'bin'
42
+ spec.executables = spec.files.grep(%r{^#{spec.bindir}/}) { |f| File.basename(f) }
37
43
  spec.require_paths = ['lib']
38
44
 
39
- spec.add_development_dependency 'bundler', '~> 2.0'
40
- spec.add_development_dependency 'rake', '~> 10.0'
41
- spec.add_development_dependency 'rspec', '~> 3.0'
42
- spec.add_development_dependency 'rubocop', '~> 0.66.0'
45
+ spec.add_development_dependency 'bump', '~> 0.10.0'
46
+ spec.add_development_dependency 'bundler', '~> 2.2', '>= 2.2.31'
47
+ spec.add_development_dependency 'byebug', '~> 11.1', '>= 11.1.3'
48
+ spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.6'
49
+ spec.add_development_dependency 'reek', '~> 6.0', '>= 6.0.6'
50
+ spec.add_development_dependency 'rspec', '~> 3.10'
51
+ spec.add_development_dependency 'rubocop', '~> 1.22', '>= 1.22.3'
52
+ spec.add_development_dependency 'rubocop-rake', '~> 0.6.0'
53
+ spec.add_development_dependency 'rubocop-rspec', '~> 2.6'
43
54
  end
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require 'bundler/setup'
4
5
  require 'quick_and_ruby'
metadata CHANGED
@@ -1,122 +1,251 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quick_and_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ttych
8
- autorequire:
9
- bindir: exe
8
+ autorequire:
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-09 00:00:00.000000000 Z
11
+ date: 2024-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bump
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.10.0
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - "~>"
18
32
  - !ruby/object:Gem::Version
19
- version: '2.0'
33
+ version: '2.2'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 2.2.31
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '2.2'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 2.2.31
47
+ - !ruby/object:Gem::Dependency
48
+ name: byebug
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '11.1'
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 11.1.3
20
57
  type: :development
21
58
  prerelease: false
22
59
  version_requirements: !ruby/object:Gem::Requirement
23
60
  requirements:
24
61
  - - "~>"
25
62
  - !ruby/object:Gem::Version
26
- version: '2.0'
63
+ version: '11.1'
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: 11.1.3
27
67
  - !ruby/object:Gem::Dependency
28
68
  name: rake
29
69
  requirement: !ruby/object:Gem::Requirement
30
70
  requirements:
31
71
  - - "~>"
32
72
  - !ruby/object:Gem::Version
33
- version: '10.0'
73
+ version: '13.0'
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 13.0.6
34
77
  type: :development
35
78
  prerelease: false
36
79
  version_requirements: !ruby/object:Gem::Requirement
37
80
  requirements:
38
81
  - - "~>"
39
82
  - !ruby/object:Gem::Version
40
- version: '10.0'
83
+ version: '13.0'
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: 13.0.6
87
+ - !ruby/object:Gem::Dependency
88
+ name: reek
89
+ requirement: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - "~>"
92
+ - !ruby/object:Gem::Version
93
+ version: '6.0'
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 6.0.6
97
+ type: :development
98
+ prerelease: false
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '6.0'
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: 6.0.6
41
107
  - !ruby/object:Gem::Dependency
42
108
  name: rspec
43
109
  requirement: !ruby/object:Gem::Requirement
44
110
  requirements:
45
111
  - - "~>"
46
112
  - !ruby/object:Gem::Version
47
- version: '3.0'
113
+ version: '3.10'
48
114
  type: :development
49
115
  prerelease: false
50
116
  version_requirements: !ruby/object:Gem::Requirement
51
117
  requirements:
52
118
  - - "~>"
53
119
  - !ruby/object:Gem::Version
54
- version: '3.0'
120
+ version: '3.10'
55
121
  - !ruby/object:Gem::Dependency
56
122
  name: rubocop
57
123
  requirement: !ruby/object:Gem::Requirement
58
124
  requirements:
59
125
  - - "~>"
60
126
  - !ruby/object:Gem::Version
61
- version: 0.66.0
127
+ version: '1.22'
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: 1.22.3
62
131
  type: :development
63
132
  prerelease: false
64
133
  version_requirements: !ruby/object:Gem::Requirement
65
134
  requirements:
66
135
  - - "~>"
67
136
  - !ruby/object:Gem::Version
68
- version: 0.66.0
137
+ version: '1.22'
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: 1.22.3
141
+ - !ruby/object:Gem::Dependency
142
+ name: rubocop-rake
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - "~>"
146
+ - !ruby/object:Gem::Version
147
+ version: 0.6.0
148
+ type: :development
149
+ prerelease: false
150
+ version_requirements: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - "~>"
153
+ - !ruby/object:Gem::Version
154
+ version: 0.6.0
155
+ - !ruby/object:Gem::Dependency
156
+ name: rubocop-rspec
157
+ requirement: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - "~>"
160
+ - !ruby/object:Gem::Version
161
+ version: '2.6'
162
+ type: :development
163
+ prerelease: false
164
+ version_requirements: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - "~>"
167
+ - !ruby/object:Gem::Version
168
+ version: '2.6'
69
169
  description: Set of small and standalone utilities in Ruby.
70
170
  email:
71
171
  - thomas.tych@gmail.com
72
172
  executables:
173
+ - cat.rb
174
+ - datetime
175
+ - distinguished_name
176
+ - jb
177
+ - json2yaml
73
178
  - proxy
179
+ - yaml2json
180
+ - yb
74
181
  extensions: []
75
182
  extra_rdoc_files: []
76
183
  files:
77
184
  - ".gitignore"
185
+ - ".reek.yml"
78
186
  - ".rspec"
187
+ - ".rubocop.yml"
79
188
  - ".travis.yml"
80
189
  - CODE_OF_CONDUCT.md
81
190
  - Gemfile
82
- - Gemfile.lock
83
191
  - LICENSE.txt
84
192
  - README.md
85
193
  - Rakefile
86
- - bin/console
87
- - bin/setup
88
- - exe/proxy
194
+ - bin/cat.rb
195
+ - bin/datetime
196
+ - bin/distinguished_name
197
+ - bin/jb
198
+ - bin/json2yaml
199
+ - bin/proxy
200
+ - bin/yaml2json
201
+ - bin/yb
89
202
  - lib/quick_and_ruby.rb
203
+ - lib/quick_and_ruby/data.rb
204
+ - lib/quick_and_ruby/data/browser.rb
205
+ - lib/quick_and_ruby/data/context.rb
206
+ - lib/quick_and_ruby/date.rb
207
+ - lib/quick_and_ruby/date/date_time_args.rb
208
+ - lib/quick_and_ruby/date/date_time_cli.rb
209
+ - lib/quick_and_ruby/distinguished_name.rb
210
+ - lib/quick_and_ruby/distinguished_name/attribute.rb
211
+ - lib/quick_and_ruby/distinguished_name/openssl_format.rb
212
+ - lib/quick_and_ruby/distinguished_name/rfc_format.rb
90
213
  - lib/quick_and_ruby/proxy/arg_parser.rb
91
214
  - lib/quick_and_ruby/proxy/env_parser.rb
92
215
  - lib/quick_and_ruby/proxy/proxy.rb
216
+ - lib/quick_and_ruby/string.rb
217
+ - lib/quick_and_ruby/string/case.rb
93
218
  - lib/quick_and_ruby/version.rb
219
+ - man/distinguished_name.1.ronn
94
220
  - quick_and_ruby.gemspec
95
- homepage: https://github.com/ttych/quick-and-ruby
221
+ - scripts/console
222
+ - scripts/setup
223
+ homepage: https://github.com/ttych/quick_and_ruby
96
224
  licenses:
97
225
  - MIT
98
226
  metadata:
99
227
  allowed_push_host: https://rubygems.org
100
- homepage_uri: https://github.com/ttych/quick-and-ruby
228
+ homepage_uri: https://github.com/ttych/quick_and_ruby
101
229
  source_code_uri: https://github.com/ttych/quick_and_ruby
102
- changelog_uri: https://github.com/ttych/quick_and_ruby
103
- post_install_message:
230
+ changelog_uri: https://github.com/ttych/quick_and_ruby/CHANGELOG.md
231
+ rubygems_mfa_required: 'true'
232
+ post_install_message:
104
233
  rdoc_options: []
105
234
  require_paths:
106
235
  - lib
107
236
  required_ruby_version: !ruby/object:Gem::Requirement
108
237
  requirements:
109
- - - ">="
238
+ - - ">"
110
239
  - !ruby/object:Gem::Version
111
- version: '0'
240
+ version: '2.7'
112
241
  required_rubygems_version: !ruby/object:Gem::Requirement
113
242
  requirements:
114
243
  - - ">="
115
244
  - !ruby/object:Gem::Version
116
245
  version: '0'
117
246
  requirements: []
118
- rubygems_version: 3.0.3
119
- signing_key:
247
+ rubygems_version: 3.1.6
248
+ signing_key:
120
249
  specification_version: 4
121
250
  summary: Quick and Ruby utilities.
122
251
  test_files: []
data/Gemfile.lock DELETED
@@ -1,53 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- quick_and_ruby (0.2.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- ast (2.4.0)
10
- diff-lcs (1.3)
11
- jaro_winkler (1.5.2)
12
- parallel (1.17.0)
13
- parser (2.6.2.0)
14
- ast (~> 2.4.0)
15
- psych (3.1.0)
16
- rainbow (3.0.0)
17
- rake (10.5.0)
18
- rspec (3.8.0)
19
- rspec-core (~> 3.8.0)
20
- rspec-expectations (~> 3.8.0)
21
- rspec-mocks (~> 3.8.0)
22
- rspec-core (3.8.0)
23
- rspec-support (~> 3.8.0)
24
- rspec-expectations (3.8.2)
25
- diff-lcs (>= 1.2.0, < 2.0)
26
- rspec-support (~> 3.8.0)
27
- rspec-mocks (3.8.0)
28
- diff-lcs (>= 1.2.0, < 2.0)
29
- rspec-support (~> 3.8.0)
30
- rspec-support (3.8.0)
31
- rubocop (0.66.0)
32
- jaro_winkler (~> 1.5.1)
33
- parallel (~> 1.10)
34
- parser (>= 2.5, != 2.5.1.1)
35
- psych (>= 3.1.0)
36
- rainbow (>= 2.2.2, < 4.0)
37
- ruby-progressbar (~> 1.7)
38
- unicode-display_width (>= 1.4.0, < 1.6)
39
- ruby-progressbar (1.10.0)
40
- unicode-display_width (1.5.0)
41
-
42
- PLATFORMS
43
- ruby
44
-
45
- DEPENDENCIES
46
- bundler (~> 2.0)
47
- quick_and_ruby!
48
- rake (~> 10.0)
49
- rspec (~> 3.0)
50
- rubocop (~> 0.66.0)
51
-
52
- BUNDLED WITH
53
- 2.0.1
File without changes