quick_and_ruby 0.4.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: 6c0817c5dc3e4a34622553992b9ff3158e437d9df32915d2cf4307fceb841229
4
- data.tar.gz: 7c7bc9b6cda4974e464f8232616da0f58064b53ce494436ce3242991ec03ae54
3
+ metadata.gz: c685bd6937aa82ca104aa4d885bb6cb150e465d61dafe2fc4c5bcd18f2a19cc5
4
+ data.tar.gz: c6e90670c6447c6261fb3c25be94d7617c0c4a4042da22cd302f5c9a9c906481
5
5
  SHA512:
6
- metadata.gz: 9c4fe131c66dcbc054838b5b7f84f983656d188158f7b2552a0d6791f28851d91e400ef7fab68425cec1a64030f35ca025c95df555c12860ab6e1a449bb3ddb9
7
- data.tar.gz: 12c49deb386a0241060d6e01e5f5d4df0317c1d0c3eae65f9f56065c41d9939cbd1273c962de7ab7c424cb82053f719c47f16ccc333463d366d8237a1b1c9374
6
+ metadata.gz: '03189ba3378295c3358c4449d30d6c2c6075f1c292f83b6f5db7f4cedcac775e3bc6cfd0d639cb50d54fcbe56f77aa70df2eaad3fe17263286bb968f34097933'
7
+ data.tar.gz: 00b294e7bc307dbb19947dfc48dd49cdd0b803fc5c69258ddcf6d5596b2df9923fb2be3e86921b3784ccef348d78f2d5865fe13c3a3cba15c5927e42b7f8278d
data/.rubocop.yml CHANGED
@@ -6,6 +6,9 @@ AllCops:
6
6
  NewCops: enable
7
7
  TargetRubyVersion: 2.7
8
8
 
9
+ Gemspec/DevelopmentDependencies:
10
+ Enabled: false
11
+
9
12
  Layout/LineLength:
10
13
  Max: 100
11
14
 
@@ -14,21 +17,29 @@ Metrics/BlockLength:
14
17
  - quick_and_ruby.gemspec
15
18
  - spec/**/*.rb
16
19
 
20
+ Metrics/ClassLength:
21
+ Exclude:
22
+ - test/**/*.rb
23
+
24
+ Metrics/CyclomaticComplexity:
25
+ Max: 10
26
+
17
27
  Metrics/MethodLength:
18
28
  Max: 25
19
29
 
30
+ Style/Documentation:
31
+ Enabled: false
32
+
20
33
  # Style/StringLiterals:
21
34
  # Enabled: true
22
35
  # EnforcedStyle: double_quotes
23
36
 
24
- Style/Documentation:
25
- Enabled: false
26
-
27
- Style/StringLiteralsInInterpolation:
28
- Enabled: true
29
- EnforcedStyle: double_quotes
37
+ # Style/StringLiteralsInInterpolation:
38
+ # Enabled: true
39
+ # EnforcedStyle: double_quotes
30
40
 
31
- # RSpec
41
+ RSpec/ExampleLength:
42
+ Max: 10
32
43
 
33
44
  RSpec/MultipleExpectations:
34
45
  Max: 2
data/bin/datetime CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require "quick_and_ruby/date"
4
+ require 'quick_and_ruby/date'
5
5
 
6
6
  QuickAndRuby::Date::DateTimeCli.new(ARGV).run
@@ -20,15 +20,15 @@ end
20
20
 
21
21
  option_parser.parse!(argv)
22
22
  if argv.empty?
23
- STDERR.puts 'error: you must supply a distinguished_name'
24
- STDERR.puts
25
- STDERR.puts option_parser.help
23
+ warn 'error: you must supply a distinguished_name'
24
+ $stderr.puts
25
+ warn option_parser.help
26
26
  exit 2
27
27
  else
28
- distinguished_name = argv.clone.join(" ")
28
+ distinguished_name = argv.clone.join(' ')
29
29
  end
30
30
 
31
- dn = QuickAndRuby::DistinguishedName.from_string(distinguished_name)
31
+ dn = QuickAndRuby::DistinguishedName.from_s(distinguished_name)
32
32
  dn = dn.reverse if options[:reverse]
33
33
 
34
34
  puts dn.to_s
data/bin/json2yaml CHANGED
@@ -10,7 +10,7 @@ end
10
10
 
11
11
  from = ARGV[0]
12
12
  if from && File.exist?(from)
13
- to = ARGV[1] || "#{from.chomp(".json")}.yaml"
13
+ to = ARGV[1] || "#{from.chomp('.json')}.yaml"
14
14
 
15
15
  File.write(to, json2yaml(File.read(from)))
16
16
  elsif from
data/bin/proxy CHANGED
@@ -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 CHANGED
@@ -5,12 +5,12 @@ require 'json'
5
5
  require 'yaml'
6
6
 
7
7
  def yaml2json(str)
8
- JSON.pretty_generate(YAML.safe_load(str))
8
+ JSON.pretty_generate(YAML.safe_load(str, aliases: true))
9
9
  end
10
10
 
11
11
  from = ARGV[0]
12
12
  if from && File.exist?(from)
13
- to = ARGV[1] || "#{from.chomp(".yaml").chomp(".yml")}.json"
13
+ to = ARGV[1] || "#{from.chomp('.yaml').chomp('.yml')}.json"
14
14
 
15
15
  File.write(to, yaml2json(File.read(from)))
16
16
  elsif from
@@ -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
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'distinguished_name/attribute'
4
+ require_relative 'distinguished_name/rfc_format'
5
+ require_relative 'distinguished_name/openssl_format'
6
+
3
7
  module QuickAndRuby
4
8
  class DistinguishedName
5
9
  attr_reader :attributes
@@ -8,51 +12,54 @@ module QuickAndRuby
8
12
  @attributes = attributes
9
13
  end
10
14
 
11
- def to_s
12
- attributes.map(&:to_s).join(',')
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)
13
22
  end
14
23
 
15
24
  def size
16
- @attributes.size
25
+ attributes.size
17
26
  end
18
27
  alias length size
19
28
 
20
- def reverse
21
- self.class.new(attributes.reverse)
29
+ def get_format(label = :rfc)
30
+ self.class.get_format(label)
22
31
  end
23
32
 
24
- def self.from_string(dn_str)
25
- attributes = dn_str.split(/(?<!\\),/).map do |dn_component|
26
- unless (match = /^([^=]+)=(.*)$/.match(dn_component.strip))
27
- raise "#{dn_component} is not a valid DistinguishedName component"
28
- end
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)
29
42
 
30
- Attribute.new(*match.captures)
43
+ new(attributes)
31
44
  end
32
45
 
33
- new(attributes)
34
- end
46
+ def rfc_format
47
+ get_format(:rfc)
48
+ end
35
49
 
36
- class Attribute
37
- # DC domainComponent
38
- # CN commonName
39
- # OU organizationalUnitName
40
- # O organizationName
41
- # STREET streetAddress
42
- # L localityName
43
- # ST stateOrProvinceName
44
- # C countryName
45
- # UID userid
46
-
47
- attr_reader :attribute, :value
48
-
49
- def initialize(attribute, value)
50
- @attribute = attribute
51
- @value = value
50
+ def openssl_format
51
+ get_format(:openssl)
52
52
  end
53
53
 
54
- def to_s
55
- "#{attribute}=#{value}"
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
56
63
  end
57
64
  end
58
65
  end
@@ -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.4.0'.freeze
2
+ VERSION = '0.5.1'.freeze
3
3
  end
data/scripts/console CHANGED
@@ -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,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quick_and_ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - ttych
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-01-19 00:00:00.000000000 Z
11
+ date: 2024-12-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bump
@@ -207,9 +207,14 @@ files:
207
207
  - lib/quick_and_ruby/date/date_time_args.rb
208
208
  - lib/quick_and_ruby/date/date_time_cli.rb
209
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
210
213
  - lib/quick_and_ruby/proxy/arg_parser.rb
211
214
  - lib/quick_and_ruby/proxy/env_parser.rb
212
215
  - lib/quick_and_ruby/proxy/proxy.rb
216
+ - lib/quick_and_ruby/string.rb
217
+ - lib/quick_and_ruby/string/case.rb
213
218
  - lib/quick_and_ruby/version.rb
214
219
  - man/distinguished_name.1.ronn
215
220
  - quick_and_ruby.gemspec