eac_ruby_utils 0.12.0 → 0.13.0

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: b885c805971bcee518de5de56939c08616539d6855742c69e20f70dfd787c552
4
- data.tar.gz: 6abd9b7bce1bd9eac4efee4966ffc4b177dea1ddc88e82e613125b79587a68c4
3
+ metadata.gz: e4e9aaa9db1ea584a76fe7fb476973764399a6fd7d4ffb483b63c40a8c89100d
4
+ data.tar.gz: 5590733b0bacc61fe6cf2b76ce8f2a5e91bcf219218fcb01ed776b9023d10d88
5
5
  SHA512:
6
- metadata.gz: b4600e778c91f1a038fe457e1afb61ac8a7aba5b23e8c77c166afe8b922c872cecffaa8850f6863eb5e11497fd45c84fcc287df4977e9dd0ddfe3e5dffb6a578
7
- data.tar.gz: 1288c11637181bc9fd90cab0be1f9fcefcb9a16562d710676bdb022534835af5e200543df5af7d56f17e636b83f05758cd40d237eb5bf80b8e4f5833d652caec
6
+ metadata.gz: 24104d0f916e17006d40da24b98852c1277f3311782db63f90c0cf4cb50cad5baea4994734a519b6ce685f03d0961ad86579d47d28ed49d1311e4711ad02d6cb
7
+ data.tar.gz: d5be47cc44aaa1927ca3c09760cbc3b1faf113c4b740c228c5ef056810c5fbde6992e91f9f23224855780d361b91850d316f9de60a7782ac40c5086f47b7775a
@@ -7,12 +7,14 @@ module EacRubyUtils
7
7
  require 'eac_ruby_utils/contextualizable'
8
8
  require 'eac_ruby_utils/core_ext'
9
9
  require 'eac_ruby_utils/envs'
10
+ require 'eac_ruby_utils/filesystem_cache'
10
11
  require 'eac_ruby_utils/listable'
11
12
  require 'eac_ruby_utils/options_consumer'
12
13
  require 'eac_ruby_utils/patch'
13
14
  require 'eac_ruby_utils/patches'
14
15
  require 'eac_ruby_utils/paths_hash'
15
16
  require 'eac_ruby_utils/require_sub'
17
+ require 'eac_ruby_utils/rspec'
16
18
  require 'eac_ruby_utils/simple_cache'
17
19
  require 'eac_ruby_utils/yaml'
18
20
  end
@@ -69,6 +69,7 @@ module EacRubyUtils
69
69
 
70
70
  def check_no_more_arguments(arg)
71
71
  return unless @options_found
72
+
72
73
  invalid_argument arg, 'Hash already found - no more positional allowed'
73
74
  end
74
75
 
@@ -55,6 +55,7 @@ module EacRubyUtils
55
55
  def storage_path_uncached
56
56
  path = options[:storage_path] || default_storage_path
57
57
  return path if ::File.exist?(path)
58
+
58
59
  ::FileUtils.mkdir_p(::File.dirname(path))
59
60
  ::File.write(path, {}.to_yaml)
60
61
  path
@@ -45,15 +45,16 @@ module EacRubyUtils
45
45
  stored_value = configs.read_entry(entry_key)
46
46
  return stored_value if stored_value
47
47
  return read_entry_from_console(entry_key, options) unless options[:noinput]
48
+
48
49
  raise "No value found for entry \"#{entry_key}\""
49
50
  end
50
51
 
51
52
  def store_passwords?
52
- 'yes' == read_entry(
53
+ read_entry(
53
54
  STORE_PASSWORDS_KEY,
54
55
  before_input: -> { store_password_banner },
55
56
  validator: ->(entry_value) { %w[yes no].include?(entry_value) }
56
- )
57
+ ) == 'yes'
57
58
  end
58
59
 
59
60
  protected
@@ -80,6 +81,7 @@ module EacRubyUtils
80
81
  entry_value = entry_value_from_input(entry_key, options)
81
82
  next unless entry_value.present?
82
83
  next if options[:validator] && !options[:validator].call(entry_value)
84
+
83
85
  return entry_value
84
86
  end
85
87
  end
@@ -13,6 +13,7 @@ module EacRubyUtils
13
13
  return value if value
14
14
  end
15
15
  return nil unless required
16
+
16
17
  raise "Setting \"#{key}\" not found. Declare #{setting_constant(key, true)} constant, " \
17
18
  "pass #{key.to_sym} option to #{self.class.name}.new() method."
18
19
  end
@@ -16,9 +16,11 @@ module EacRubyUtils
16
16
 
17
17
  def check_subcommands
18
18
  return unless subcommands?
19
+
19
20
  singleton_class.include(SubcommandsSupport)
20
21
  check_subcommands_arg
21
22
  return if singleton_class.method_defined?(:run)
23
+
22
24
  singleton_class.send(:alias_method, :run, :run_with_subcommand)
23
25
  end
24
26
 
@@ -94,6 +96,7 @@ module EacRubyUtils
94
96
 
95
97
  def check_valid_subcommand
96
98
  return if available_subcommands.include?(subcommand_name)
99
+
97
100
  raise ::Docopt::Exit, "\"#{subcommand_name}\" is not a valid subcommand" \
98
101
  " (Valid: #{available_subcommands.join(', ')})"
99
102
  end
@@ -10,7 +10,7 @@ module EacRubyUtils
10
10
  # https://github.com/fazibear/colorize
11
11
  module Speaker
12
12
  def puts(string = '')
13
- STDERR.puts(string.to_s)
13
+ STDERR.puts(string.to_s) # rubocop:disable Style/StderrPuts
14
14
  end
15
15
 
16
16
  def out(string = '')
@@ -96,6 +96,7 @@ module EacRubyUtils
96
96
  loop do
97
97
  input = request_string("#{question} [#{list.valid_labels.join('/')}]", noecho)
98
98
  return list.build_value(input) if list.valid_value?(input)
99
+
99
100
  warn "Invalid input: \"#{input}\" (Valid: #{list.valid_labels.join(', ')})"
100
101
  end
101
102
  end
@@ -11,6 +11,7 @@ module EacRubyUtils
11
11
  def build(list)
12
12
  return List.new(hash_to_values(list)) if list.is_a?(::Hash)
13
13
  return List.new(array_to_values(list)) if list.is_a?(::Array)
14
+
14
15
  raise "Invalid list: #{list} (#{list.class})"
15
16
  end
16
17
 
@@ -7,6 +7,7 @@ module EacRubyUtils
7
7
  current = self
8
8
  while current
9
9
  return current.send(method) if current.respond_to?(method)
10
+
10
11
  current = current.respond_to?(:parent) ? current.parent : nil
11
12
  end
12
13
  raise "Context method \"#{method}\" not found for #{self.class}"
@@ -2,9 +2,11 @@
2
2
 
3
3
  require 'eac_ruby_utils/envs/base_env'
4
4
  require 'eac_ruby_utils/envs/command'
5
+ require 'eac_ruby_utils/envs/file'
5
6
  require 'eac_ruby_utils/envs/local_env'
6
7
  require 'eac_ruby_utils/envs/process'
7
8
  require 'eac_ruby_utils/envs/ssh_env'
9
+ require 'eac_ruby_utils/envs/executable'
8
10
 
9
11
  module EacRubyUtils
10
12
  module Envs
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'eac_ruby_utils/envs/command'
4
+ require 'eac_ruby_utils/envs/executable'
5
+ require 'eac_ruby_utils/envs/file'
4
6
 
5
7
  module EacRubyUtils
6
8
  module Envs
@@ -9,8 +11,17 @@ module EacRubyUtils
9
11
  ::EacRubyUtils::Envs::Command.new(self, args)
10
12
  end
11
13
 
14
+ # <b>DEPRECATED:</b> Please use <tt>file(file).exist?</tt> instead.
12
15
  def file_exist?(file)
13
- command(['stat', file]).execute[:exit_code].zero?
16
+ self.file(file).exist?
17
+ end
18
+
19
+ def executable(*executable_new_args)
20
+ ::EacRubyUtils::Envs::Executable.new(self, *executable_new_args)
21
+ end
22
+
23
+ def file(path)
24
+ ::EacRubyUtils::Envs::File.new(self, path)
14
25
  end
15
26
  end
16
27
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support/core_ext/hash/indifferent_access'
4
+ require 'active_support/core_ext/object/blank'
4
5
  require 'shellwords'
5
6
 
6
7
  module EacRubyUtils
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/simple_cache'
4
+
5
+ module EacRubyUtils
6
+ module Envs
7
+ class Executable
8
+ include ::EacRubyUtils::SimpleCache
9
+
10
+ attr_reader :env, :name, :check_args
11
+
12
+ def initialize(env, name, *check_args)
13
+ @env = env
14
+ @name = name
15
+ @check_args = check_args
16
+ end
17
+
18
+ def exist?
19
+ exist
20
+ end
21
+
22
+ def validate
23
+ return nil if exist?
24
+
25
+ "Program \"#{name}\" not found in environment #{env}"
26
+ end
27
+
28
+ def validate!
29
+ message = validate
30
+
31
+ raise ProgramNotFoundError, message if message
32
+ end
33
+
34
+ def command
35
+ validate!
36
+ env.command(name)
37
+ end
38
+
39
+ private
40
+
41
+ def exist_uncached
42
+ env.command(name, *check_args).execute!
43
+ true
44
+ rescue Errno::ENOENT
45
+ false
46
+ end
47
+
48
+ class ProgramNotFoundError < ::StandardError; end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRubyUtils
4
+ module Envs
5
+ class File
6
+ attr_reader :env, :path
7
+
8
+ def initialize(env, path)
9
+ @env = env
10
+ @path = path
11
+ end
12
+
13
+ def exist?
14
+ env.command('stat', path).execute[:exit_code].zero?
15
+ end
16
+
17
+ def read
18
+ env.command('cat', path).execute!
19
+ end
20
+ end
21
+ end
22
+ end
@@ -8,26 +8,34 @@ require 'shellwords'
8
8
  module EacRubyUtils
9
9
  module Envs
10
10
  class SshEnv < ::EacRubyUtils::Envs::BaseEnv
11
+ USER_PATTERN = /[a-z_][a-z0-9_-]*/.freeze
12
+ HOSTNAME_PATTERN = /[^@]+/.freeze
13
+ USER_HOSTNAME_PATTERN = /\A(?:(#{USER_PATTERN})@)?(#{HOSTNAME_PATTERN})\z/.freeze
14
+
11
15
  class << self
12
16
  def parse_uri(uri)
13
- r = parse_user_hostname(uri) || ::Addressable::URI.parse(uri)
14
- return r if r.scheme == 'ssh'
15
-
16
- raise "URI has no SSH scheme: #{uri}"
17
+ uri_by_url(uri) || uri_by_user_hostname(uri) || raise("URI has no SSH scheme: #{uri}")
17
18
  end
18
19
 
19
20
  private
20
21
 
21
- def parse_user_hostname(user_hostname)
22
- m = /\A([^@]+)@([^@]+)\z/.match(user_hostname)
22
+ def uri_by_url(url)
23
+ r = ::Addressable::URI.parse(url)
24
+ r.scheme == 'ssh' && r.host.present? ? r : nil
25
+ end
26
+
27
+ def uri_by_user_hostname(user_hostname)
28
+ m = USER_HOSTNAME_PATTERN.match(user_hostname)
23
29
  m ? ::Addressable::URI.new(scheme: 'ssh', host: m[2], user: m[1]) : nil
24
30
  rescue Addressable::URI::InvalidURIError
25
31
  nil
26
32
  end
27
33
  end
28
34
 
35
+ attr_reader :uri
36
+
29
37
  def initialize(uri)
30
- @uri = self.class.parse_uri(uri)
38
+ @uri = self.class.parse_uri(uri).freeze
31
39
  end
32
40
 
33
41
  def to_s
@@ -40,13 +48,11 @@ module EacRubyUtils
40
48
 
41
49
  private
42
50
 
43
- attr_reader :uri
44
-
45
51
  def ssh_command_line
46
52
  r = %w[ssh]
47
53
  r += ['-p', uri.port] if uri.port.present?
48
54
  r += ssh_command_line_options
49
- r << "#{uri.user}@#{uri.host}"
55
+ r << user_hostname_uri
50
56
  r.map { |a| Shellwords.escape(a) }.join(' ')
51
57
  end
52
58
 
@@ -55,6 +61,12 @@ module EacRubyUtils
55
61
  uri.query_values&.each { |k, v| r += ['-o', "#{k}=#{v}"] }
56
62
  r
57
63
  end
64
+
65
+ def user_hostname_uri
66
+ r = uri.host
67
+ r = "#{uri.user}@#{r}" if uri.user.present?
68
+ r
69
+ end
58
70
  end
59
71
  end
60
72
  end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacRubyUtils
4
+ class FilesystemCache
5
+ CONTENT_FILE_NAME = '__content__'
6
+
7
+ attr_reader :path
8
+
9
+ def initialize(*path_parts)
10
+ raise ArgumentError, "\"#{path_parts}\" is empty" if path_parts.empty?
11
+
12
+ @path = ::File.expand_path(::File.join(*path_parts.map(&:to_s)))
13
+ end
14
+
15
+ def clear
16
+ return unless cached?
17
+
18
+ ::File.unlink(content_path)
19
+ end
20
+
21
+ def read
22
+ return nil unless cached?
23
+
24
+ ::File.read(content_path)
25
+ end
26
+
27
+ def write(value)
28
+ assert_directory_on_path
29
+ ::File.write(content_path, value)
30
+ value
31
+ end
32
+
33
+ def child(*child_path_parts)
34
+ self.class.new(path, *child_path_parts)
35
+ end
36
+
37
+ def cached?
38
+ ::File.exist?(content_path)
39
+ end
40
+
41
+ def content_path
42
+ ::File.join(path, CONTENT_FILE_NAME)
43
+ end
44
+
45
+ private
46
+
47
+ def assert_directory_on_path
48
+ raise "#{path} is a file" if ::File.file?(path)
49
+
50
+ ::FileUtils.mkdir_p(path)
51
+ end
52
+ end
53
+ end
@@ -22,7 +22,7 @@ module EacRubyUtils
22
22
 
23
23
  def method_missing(name, *args, &block)
24
24
  list = find_list_by_method(name)
25
- list ? list : super
25
+ list || super
26
26
  end
27
27
 
28
28
  def respond_to_missing?(name, include_all = false)
@@ -36,6 +36,7 @@ module EacRubyUtils
36
36
  def instance_value(instance)
37
37
  v = instance.send(item)
38
38
  return @values[v] if @values.key?(v)
39
+
39
40
  raise "List value unkown: #{v} (Source: #{@lists.source}, Item: #{item})"
40
41
  end
41
42
 
@@ -30,7 +30,7 @@ module EacRubyUtils
30
30
 
31
31
  def method_missing(name, *args, &block)
32
32
  list = find_list_by_method(name)
33
- list ? list : super
33
+ list || super
34
34
  end
35
35
 
36
36
  def respond_to_missing?(name, include_all = false)
@@ -45,6 +45,7 @@ module EacRubyUtils
45
45
 
46
46
  def check_acts_as_listable_new_item(item)
47
47
  return unless acts_as_listable_items.key?(item)
48
+
48
49
  raise "Item já adicionado anteriormente: #{item} em #{self} " \
49
50
  "(#{acts_as_listable_items.keys})"
50
51
  end
@@ -4,6 +4,7 @@ module EacRubyUtils
4
4
  class << self
5
5
  def patch(target, patch)
6
6
  return if target.included_modules.include?(patch)
7
+
7
8
  target.send(:include, patch)
8
9
  end
9
10
  end
@@ -6,6 +6,7 @@ class Object
6
6
  # @return +self+
7
7
  def assert_argument(klass, argument_name = 'unknown_argument_name')
8
8
  return self if is_a?(klass)
9
+
9
10
  raise ::ArgumentError,
10
11
  "Argument \"#{argument_name}\" is not a #{klass}" \
11
12
  "(Actual class: #{self.class}, actual value: #{self})"
@@ -6,6 +6,7 @@ class Object
6
6
  # @return +block.call(self)+ if +self+ is present, +default_value+ otherwise.
7
7
  def if_present(default_value = nil)
8
8
  return default_value unless present?
9
+
9
10
  block_given? ? yield(self) : self
10
11
  end
11
12
  end
@@ -10,9 +10,11 @@ module EacRubyUtils
10
10
  r = entry_key.to_s.strip
11
11
  raise EntryKeyError, 'Entry key cannot start or end with dot' if
12
12
  r.start_with?('.') || r.end_with?('.')
13
+
13
14
  r = r.split('.').map(&:strip)
14
15
  raise EntryKeyError, "Entry key \"#{entry_key}\" is empty" if r.empty?
15
16
  return r.map(&:to_sym) unless r.any?(&:blank?)
17
+
16
18
  raise EntryKeyError, "Entry key \"#{entry_key}\" has at least one blank part"
17
19
  end
18
20
  end
@@ -59,6 +61,7 @@ module EacRubyUtils
59
61
  return (node.is_a?(Node) ? node.to_h : node) if path.empty?
60
62
  return nil if node.blank?
61
63
  return node.read_entry(path, current + [node_key]) if node.is_a?(Node)
64
+
62
65
  raise(EntryKeyError,
63
66
  "Path #{current.join(',')} is not a Node and path continues (#{current + path})")
64
67
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/require_sub'
4
+ ::EacRubyUtils.require_sub(__FILE__)
5
+
6
+ module EacRubyUtils
7
+ module Rspec
8
+ end
9
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/object/blank'
4
+ require 'eac_ruby_utils/console/speaker'
5
+
6
+ module EacRubyUtils
7
+ module Rspec
8
+ class Conditional
9
+ include ::EacRubyUtils::Console::Speaker
10
+
11
+ def self.default
12
+ @default ||= new
13
+ end
14
+
15
+ def initialize
16
+ @tags = {}
17
+ end
18
+
19
+ def add(tag, &condition)
20
+ tags[tag] = condition
21
+ end
22
+
23
+ def configure(rspec_config)
24
+ tags.each do |tag, condition|
25
+ message = condition.call
26
+ if message.present?
27
+ warn("Excluded tag: #{tag}: #{message}")
28
+ rspec_config.filter_run_excluding tag
29
+ end
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ attr_reader :tags
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/object/blank'
4
+ require 'eac_ruby_utils/envs/ssh_env'
5
+ require 'eac_ruby_utils/patches/object/if_present'
6
+
7
+ module EacRubyUtils
8
+ module Rspec
9
+ class StubbedSsh
10
+ DEFAULT_ENVVAR_NAME = 'STUBBED_SSH_URL'
11
+
12
+ class << self
13
+ def default
14
+ @default ||= new(DEFAULT_ENVVAR_NAME)
15
+ end
16
+ end
17
+
18
+ attr_reader :envvar_name
19
+
20
+ def initialize(envvar_name)
21
+ @envvar_name = envvar_name
22
+ end
23
+
24
+ def validate
25
+ return nil if provided_url.present?
26
+
27
+ "Environment variable \"#{envvar_name}\" unprovided or blank"
28
+ end
29
+
30
+ def validate!
31
+ validate.if_present { |v| raise v }
32
+ end
33
+
34
+ def provided_url
35
+ ENV[envvar_name]
36
+ end
37
+
38
+ def build_env
39
+ validate!
40
+ ::EacRubyUtils::Envs::SshEnv.new(provided_url)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module EacRubyUtils
4
4
  module SimpleCache
5
- UNCACHED_METHOD_PATTERN = /\A(\s+)_uncached\z/
5
+ UNCACHED_METHOD_PATTERN = /\A(\s+)_uncached\z/.freeze
6
6
 
7
7
  def method_missing(method, *args, &block)
8
8
  uncached_method = "#{method}_uncached"
@@ -29,6 +29,7 @@ module EacRubyUtils
29
29
 
30
30
  def call_method_with_cache(method, args, &block)
31
31
  raise 'Não é possível realizar o cache de métodos com bloco' if block
32
+
32
33
  key = ([method] + args).join('@@@')
33
34
  cache_keys[key] = send(method, *args) unless cache_keys.key?(key)
34
35
  cache_keys[key]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EacRubyUtils
4
- VERSION = '0.12.0'
4
+ VERSION = '0.13.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eac_ruby_utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esquilo Azul Company
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-25 00:00:00.000000000 Z
11
+ date: 2019-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '3.8'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.74.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.74.0
97
111
  description:
98
112
  email:
99
113
  executables: []
@@ -119,9 +133,12 @@ files:
119
133
  - lib/eac_ruby_utils/envs/base_env.rb
120
134
  - lib/eac_ruby_utils/envs/command.rb
121
135
  - lib/eac_ruby_utils/envs/command/extra_options.rb
136
+ - lib/eac_ruby_utils/envs/executable.rb
137
+ - lib/eac_ruby_utils/envs/file.rb
122
138
  - lib/eac_ruby_utils/envs/local_env.rb
123
139
  - lib/eac_ruby_utils/envs/process.rb
124
140
  - lib/eac_ruby_utils/envs/ssh_env.rb
141
+ - lib/eac_ruby_utils/filesystem_cache.rb
125
142
  - lib/eac_ruby_utils/listable.rb
126
143
  - lib/eac_ruby_utils/listable/class_methods.rb
127
144
  - lib/eac_ruby_utils/listable/instance_methods.rb
@@ -146,6 +163,9 @@ files:
146
163
  - lib/eac_ruby_utils/patches/object/if_present.rb
147
164
  - lib/eac_ruby_utils/paths_hash.rb
148
165
  - lib/eac_ruby_utils/require_sub.rb
166
+ - lib/eac_ruby_utils/rspec.rb
167
+ - lib/eac_ruby_utils/rspec/conditional.rb
168
+ - lib/eac_ruby_utils/rspec/stubbed_ssh.rb
149
169
  - lib/eac_ruby_utils/simple_cache.rb
150
170
  - lib/eac_ruby_utils/version.rb
151
171
  - lib/eac_ruby_utils/yaml.rb