eac_ruby_utils 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
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