eco-helpers 3.0.37 → 3.1.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.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/CHANGELOG.md +116 -1
  4. data/lib/eco/api/common/loaders/base.rb +2 -2
  5. data/lib/eco/api/common/loaders/case_base.rb +2 -0
  6. data/lib/eco/api/common/loaders/config/block.rb +78 -0
  7. data/lib/eco/api/common/loaders/config/workflow/mailer.rb +39 -7
  8. data/lib/eco/api/common/loaders/config.rb +3 -26
  9. data/lib/eco/api/common/loaders/error_handler.rb +2 -0
  10. data/lib/eco/api/common/loaders/parser.rb +1 -4
  11. data/lib/eco/api/common/people/entries.rb +23 -6
  12. data/lib/eco/api/common/people/entry_factory.rb +1 -1
  13. data/lib/eco/api/common/people/person_entry.rb +104 -27
  14. data/lib/eco/api/common/people/person_parser.rb +50 -16
  15. data/lib/eco/api/common/people/supervisor_helpers.rb +12 -6
  16. data/lib/eco/api/common/session/base_session.rb +75 -81
  17. data/lib/eco/api/common/session/environment.rb +49 -55
  18. data/lib/eco/api/common/session/file_manager.rb +132 -135
  19. data/lib/eco/api/common/session/helpers/prompt_user.rb +23 -30
  20. data/lib/eco/api/common/session/helpers.rb +10 -15
  21. data/lib/eco/api/common/session/logger/cache.rb +89 -96
  22. data/lib/eco/api/common/session/logger/channels.rb +24 -32
  23. data/lib/eco/api/common/session/logger/log.rb +38 -46
  24. data/lib/eco/api/common/session/logger.rb +50 -54
  25. data/lib/eco/api/common/session/mailer/aws_provider.rb +63 -71
  26. data/lib/eco/api/common/session/mailer/provider_base.rb +43 -48
  27. data/lib/eco/api/common/session/mailer/sendgrid_provider.rb +101 -109
  28. data/lib/eco/api/common/session/mailer.rb +78 -83
  29. data/lib/eco/api/common/session/s3_uploader.rb +132 -138
  30. data/lib/eco/api/common/session/sftp.rb +202 -208
  31. data/lib/eco/api/common.rb +0 -3
  32. data/lib/eco/api/custom/mailer.rb +4 -2
  33. data/lib/eco/api/error/handlers.rb +1 -1
  34. data/lib/eco/api/microcases/people/apply_changes/set_core/core_excluded.rb +8 -2
  35. data/lib/eco/api/microcases/people/manage/search.rb +1 -1
  36. data/lib/eco/api/organization/people/similarity.rb +3 -3
  37. data/lib/eco/api/session/batch/base_policy.rb +42 -27
  38. data/lib/eco/api/session/batch/launcher/mode_size.rb +6 -1
  39. data/lib/eco/api/session/batch/launcher.rb +16 -3
  40. data/lib/eco/api/session/config/api.rb +4 -3
  41. data/lib/eco/api/session/config/apis/one_off.rb +1 -1
  42. data/lib/eco/api/session/config/files.rb +13 -12
  43. data/lib/eco/api/session/config/workflow.rb +1 -373
  44. data/lib/eco/api/session/config.rb +30 -9
  45. data/lib/eco/api/usecases/base_case/model.rb +6 -6
  46. data/lib/eco/api/usecases/base_case.rb +1 -1
  47. data/lib/eco/api/usecases/cli.rb +1 -1
  48. data/lib/eco/api/usecases/default/locations/tagtree_extract_case.rb +8 -9
  49. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +4 -1
  50. data/lib/eco/api/usecases/graphql/samples/location/command/dsl.rb +2 -2
  51. data/lib/eco/api/usecases/lib/base/env.rb +21 -23
  52. data/lib/eco/api/usecases/lib/files/file_pattern.rb +41 -14
  53. data/lib/eco/api/usecases/lib/files/input_file.rb +110 -0
  54. data/lib/eco/api/usecases/lib/files/sftp.rb +5 -2
  55. data/lib/eco/api/usecases/lib/files.rb +1 -0
  56. data/lib/eco/api/usecases/lib/locations/base.rb +23 -0
  57. data/lib/eco/api/usecases/lib/locations/mapping.rb +94 -0
  58. data/lib/eco/api/usecases/lib/locations.rb +7 -0
  59. data/lib/eco/api/usecases/lib/people/base.rb +20 -0
  60. data/lib/eco/api/usecases/lib/people.rb +6 -0
  61. data/lib/eco/api/usecases/lib.rb +2 -0
  62. data/lib/eco/api/usecases/ooze_cases.rb +1 -1
  63. data/lib/eco/api/usecases/ooze_samples/register_export_case.rb +1 -0
  64. data/lib/eco/api/usecases/ooze_samples/register_update_case.rb +1 -0
  65. data/lib/eco/api/usecases/samples/drivers/sftp_sample.rb +2 -0
  66. data/lib/eco/api/usecases/samples/drivers/url_pull_sample.rb +8 -2
  67. data/lib/eco/api/usecases/service/sftp/with_target_config.rb +0 -33
  68. data/lib/eco/api/usecases/service/sftp.rb +7 -1
  69. data/lib/eco/api/usecases/use_case.rb +3 -2
  70. data/lib/eco/api/usecases/workflow.rb +5 -0
  71. data/lib/eco/api/usecases.rb +12 -5
  72. data/lib/eco/cli/scripting/args_helpers.rb +1 -9
  73. data/lib/eco/cli_default/options.rb +98 -68
  74. data/lib/eco/cli_default/workflow/end.rb +22 -0
  75. data/lib/eco/cli_default/workflow/launch_jobs.rb +14 -0
  76. data/lib/eco/cli_default/workflow/load/data.rb +27 -0
  77. data/lib/eco/cli_default/workflow/load/input.rb +28 -0
  78. data/lib/eco/cli_default/workflow/load.rb +13 -0
  79. data/lib/eco/cli_default/workflow/options.rb +10 -0
  80. data/lib/eco/cli_default/workflow/post_launch.rb +65 -0
  81. data/lib/eco/cli_default/workflow/report.rb +17 -0
  82. data/lib/eco/cli_default/workflow/rescued_exception.rb +21 -0
  83. data/lib/eco/cli_default/workflow/usecases.rb +23 -0
  84. data/lib/eco/cli_default/workflow.rb +24 -180
  85. data/lib/eco/data/count_trace.rb +51 -0
  86. data/lib/eco/data/files/content.rb +39 -0
  87. data/lib/eco/data/files/directory.rb +78 -45
  88. data/lib/eco/data/files/encoding.rb +12 -21
  89. data/lib/eco/data/files/file_pattern.rb +15 -8
  90. data/lib/eco/data/files/folder.rb +196 -0
  91. data/lib/eco/data/files/relative_path.rb +54 -0
  92. data/lib/eco/data/files/timestamp.rb +18 -0
  93. data/lib/eco/data/files.rb +46 -5
  94. data/lib/eco/data/fuzzy_match.rb +1 -1
  95. data/lib/eco/data/hashes/array_diff.rb +11 -5
  96. data/lib/eco/data/hashes/diff_result/meta.rb +12 -4
  97. data/lib/eco/data/locations/node_diff/accessors.rb +1 -1
  98. data/lib/eco/data/mapper.rb +5 -1
  99. data/lib/eco/data.rb +1 -0
  100. data/lib/eco/language/delegation/delegating_missing.rb +1 -1
  101. data/lib/eco/language/delegation/delegating_missing_const.rb +1 -1
  102. data/lib/eco/language/delegation/delegating_missing_on_class.rb +1 -1
  103. data/lib/eco/language/delegation/for_delegator/delegated_class.rb +1 -1
  104. data/lib/eco/language/klass/auto_loader.rb +129 -0
  105. data/lib/eco/language/klass/builder.rb +6 -6
  106. data/lib/eco/language/klass/const.rb +19 -0
  107. data/lib/eco/language/klass/helpers_built.rb +3 -1
  108. data/lib/eco/language/klass/hierarchy.rb +5 -1
  109. data/lib/eco/language/klass/naming.rb +5 -2
  110. data/lib/eco/language/klass/resolver.rb +21 -6
  111. data/lib/eco/language/klass/uid.rb +12 -0
  112. data/lib/eco/language/klass/when_inherited.rb +30 -6
  113. data/lib/eco/language/klass.rb +5 -2
  114. data/lib/eco/language/methods/access_modifier.rb +23 -0
  115. data/lib/eco/language/methods/instance_method_helpers.rb +6 -1
  116. data/lib/eco/language/methods.rb +1 -0
  117. data/lib/eco/language/models/hierarchy.rb +41 -0
  118. data/lib/eco/language/models/workflow.rb +385 -0
  119. data/lib/eco/language/models.rb +2 -1
  120. data/lib/eco/version.rb +1 -1
  121. metadata +31 -7
  122. data/lib/eco/api/common/class_auto_loader.rb +0 -114
  123. data/lib/eco/api/common/class_helpers.rb +0 -9
  124. data/lib/eco/api/common/class_hierarchy.rb +0 -45
  125. data/lib/eco/data/files/helpers.rb +0 -152
  126. data/lib/eco/language/models/class_helpers.rb +0 -136
@@ -1,4 +1,3 @@
1
- class Eco::CliDefault::Workflow < Eco::API::Common::Loaders::Workflow
2
1
  # @todo The ones below:
3
2
  # 1. Identify the target model earlier (required_data?),
4
3
  # provided that we can granulate the workflow.
@@ -12,183 +11,28 @@ class Eco::CliDefault::Workflow < Eco::API::Common::Loaders::Workflow
12
11
  # 5. Right on the load:data stage, set the io model
13
12
  # based on (1).
14
13
  #
15
- class << self
16
- attr_accessor :rescued
17
- end
18
-
19
- # default rescue
20
- exception do |err, io|
21
- next io if rescued
22
-
23
- self.rescued = true
24
- log(:debug) { err.patch_full_message }
25
-
26
- workflow.run(:close, io: io)
27
- rescue StandardError => e
28
- puts "Some problem in workflow.rescue: #{e}"
29
- end
30
-
31
- on(:options) do
32
- cli_usecases.cli_apply(io: io)
33
- io.new(options: cli.config.options_set.process(io: io))
34
- end
35
-
36
- with(:load) do |wf_load|
37
- wf_load.with(:input) do |wf_in|
38
- wf_in.on(:get) do
39
- input_is_required = some_input_case?(io) || options.dig(:input, :entries_from)
40
- missing_input = !input || input.empty?
41
- next unless missing_input && input_is_required
42
-
43
- if options.dig(:input, :entries_from)
44
- io.new(input: cli.config.input.get(io: io))
45
- else
46
- opt_case = cli_input_cases(io).values.first.option
47
- io.new(input: cli.config.input.get(io: io, option: opt_case))
48
- end
49
- end
50
-
51
- wf_in.on(:filter) do
52
- next unless input && !input.empty?
53
-
54
- io.new(input: cli.config.input_filters.process(io: io))
55
- end
56
- end
57
-
58
- wf_load.before(:data) do
59
- # @todo model should be set to the target model
60
- # based on the main use case that requires data!
61
- io.new(model: :people)
62
- end
63
-
64
- wf_load.with(:data) do |wf_peo|
65
- wf_peo.on(:get) do
66
- next unless some_data_case?(io) || options.dig(:people, :get)
67
-
68
- io.new(data: cli.config.people(io: io))
69
- end
70
-
71
- wf_peo.on(:filter) do
72
- next unless data && !data.empty?
73
-
74
- io.new(data: cli.config.people_filters.process(io: io))
75
- end
76
- end
77
- end
78
-
79
- before(:usecases) do
80
- # save partial entries -> should be native to session.workflow
81
- get_people = options.dig(:people, :get)
82
- partial_update = get_people && get_people[:type] == :partial
83
-
84
- if !options[:dry_run] && partial_update
85
- partial_file = session.config.people.partial_cache
86
- session.file_manager.save_json(io.data, partial_file, :timestamp)
87
- end
88
- end
89
-
90
- on(:usecases) do
91
- next if cli_usecases.process(io: io)
92
-
93
- log(:info) { 'No update operation specified... quitting' }
94
- exit 0
95
- end
96
-
97
- before(:launch_jobs) do
98
- available_args = cli.config.available_option_args
99
- SCR.stop_on_unknown!(all_available: available_args)
100
- end
101
-
102
- on(:launch_jobs) do
103
- session.jobs_launch(simulate: options[:dry_run])
104
- end
105
-
106
- before(:post_launch) do |wf_post|
107
- next wf_post.skip! if session.post_launch.empty?
108
-
109
- run_it = !options[:dry_run] || options.dig(:post_launch, :run)
110
- unless run_it
111
- wf_post.skip!
112
-
113
- log(:info) {
114
- msg = 'Although there are post_launch cases, they will NOT be RUN'
115
- msg << ', because we are in dry-run (simulate).' if options[:dry_run]
116
- msg
117
- }
118
-
119
- next
120
- end
121
-
122
- get_people = options.dig(:people, :get)
123
- partial_update = get_people && get_people[:type] == :partial
124
- refresh_data = !options[:dry_run] && partial_update
125
-
126
- unless refresh_data
127
- log(:info) {
128
- msg = 'Although there are post_launch cases, data will not be refreshed before their run'
129
- if io.options[:dry_run]
130
- msg << ', because we are in dry-run (simulate).'
131
- elsif !partial_update
132
- msg << ', because it is not a partial update (-get-partial option not present).'
133
- end
134
- msg
135
- }
136
-
137
- next
138
- end
139
-
140
- # get target people afresh
141
- peo_aux = session.micro.people_refresh(
142
- people: data,
143
- include_created: true
144
- )
145
- io.base.new(data: peo_aux)
146
- end
147
-
148
- with(:post_launch) do |wf_post|
149
- wf_post.on(:usecases) do |_wf_pu, io|
150
- session.post_launch.each do |use|
151
- use.launch(io: io).base
152
- rescue Eco::API::UseCases::BaseIO::MissingParameter => err
153
- raise unless err.required == :people
154
-
155
- log(:debug) {
156
- "Skipping use case '#{use.name}' -- no base people detected for the current run"
157
- }
158
- end
159
- end
160
-
161
- wf_post.on(:launch_jobs) do |_wf_pl, _io|
162
- session.jobs_launch(simulate: options[:dry_run])
163
- end
164
- end
165
-
166
- on(:report) do |_wf_rep, io|
167
- if (file = options.dig(:report, :people, :csv))
168
- options.deep_merge!(export: {
169
- options: {internal_names: true, nice_header: true, split_schemas: true},
170
- file: {name: file, format: :csv}
171
- })
172
-
173
- aux_io = io.new(data: data.updated_or_created)
174
- session.process_case('to-csv', io: aux_io, type: :export)
175
- end
176
- end
177
-
178
- on(:end) do
179
- get_people = options.dig(:people, :get)
180
- partial_update = get_people && get_people[:type] == :partial
181
-
182
- unless !options[:end_get] || options[:dry_run] || partial_update
183
- if !some_update_case?(io)
184
- # Prevent getting people when there were no use cases that used them
185
- log(:info) {
186
- "Won't be recaching people, as there haven't been any targetted updates"
187
- }
188
- elsif !people
189
- people = session.micro.people_cache
190
- io.new(data: people)
191
- end
192
- end
193
- end
14
+ class Eco::CliDefault::Workflow < Eco::API::Common::Loaders::Workflow
15
+ require_relative 'workflow/rescued_exception'
16
+ require_relative 'workflow/options'
17
+ require_relative 'workflow/load'
18
+ require_relative 'workflow/usecases'
19
+ require_relative 'workflow/launch_jobs'
20
+ require_relative 'workflow/post_launch'
21
+ require_relative 'workflow/report'
22
+ require_relative 'workflow/end'
23
+
24
+ [
25
+ RescuedException,
26
+ Options,
27
+ Load,
28
+ Usecases,
29
+ LaunchJobs,
30
+ PostLaunch,
31
+ Report,
32
+ End
33
+ ].each do |wf_config|
34
+ wf_config.config_copy(to: self, all: true)
35
+ end
36
+
37
+ config_apply!(all: true)
194
38
  end
@@ -0,0 +1,51 @@
1
+ module Eco
2
+ module Data
3
+ class CountTrace
4
+ include Eco::Language::Delegation::DelegatingMissing
5
+
6
+ delegating_missing_to :subject
7
+
8
+ attr_reader :trace
9
+
10
+ def initialize(subject)
11
+ @subject = subject
12
+ @trace = {}
13
+ end
14
+
15
+ def reset!
16
+ @trace.clear
17
+ end
18
+
19
+ def trace!(value, count: 1)
20
+ trace[value] ||= 0
21
+ trace[value] += count
22
+ end
23
+
24
+ def report!(msg: nil, level: :warn)
25
+ str_report(msg: msg).tap do |str|
26
+ log(level.to_sym) { str }
27
+
28
+ reset!
29
+ end
30
+ end
31
+
32
+ def str_report(msg: nil)
33
+ return if trace.empty?
34
+
35
+ msg ||= ''
36
+ sorted = trace.sort_by {|value, count| [count * -1, value]}
37
+
38
+ msg << "\n * "
39
+ msg << sorted.map.with_index do |(value, count), idx|
40
+ "#{idx}. (#{count}) '#{value}'"
41
+ end.join("\n * ")
42
+
43
+ msg
44
+ end
45
+
46
+ private
47
+
48
+ attr_reader :subject
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,39 @@
1
+ module Eco
2
+ module Data
3
+ module Files
4
+ module Content
5
+ include Eco::Language::AuxiliarLogger
6
+ include Encoding
7
+
8
+ # It offers a resilient way to read content from a file
9
+ # @tolerance [Integer] the number of allowed encoding errors.
10
+ # @return [String] the content of the file
11
+ def get_file_content(file, encoding: nil, tolerance: 5)
12
+ read_with_tolerance(file, encoding: encoding, tolerance: tolerance)
13
+ end
14
+
15
+ def read_with_tolerance(file, encoding:, tolerance: 5)
16
+ content = get_file_content_with_encoding(file, encoding: encoding)
17
+ return unless content
18
+
19
+ content.scrub do |bytes|
20
+ replacement = "<#{bytes.unpack1('H*')}>"
21
+
22
+ if tolerance <= 0
23
+ log(:error) {
24
+ "There were more than 5 encoding errors in the file '#{file}'."
25
+ }
26
+ return content
27
+ else
28
+ tolerance -= 1
29
+ log(:error) {
30
+ "Encoding problem in file '#{file}': '#{replacement}'."
31
+ }
32
+ replacement
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -3,45 +3,43 @@ module Eco
3
3
  module Files
4
4
  class Directory
5
5
  class << self
6
- def create(path, includes_file: false)
7
- return true if Files.file_exists?(path)
8
-
9
- parts = Files.split(File.expand_path(path))
10
- filename = parts.pop if includes_file
11
-
12
- return true if Files.dir_exists?(File.join(*parts))
13
-
14
- subpath = nil
15
- begin
16
- parts.each do |curr|
17
- subpath = subpath ? File.join(subpath, curr) : curr
18
- Dir.mkdir(subpath) unless Files.dir_exists?(subpath)
19
- end
20
- rescue Exception => e
21
- pp e
22
- return false
23
- end
24
- true
6
+ # rubocop:disable Style/SpecialGlobalVars
7
+
8
+ def script_subfolder
9
+ basename = File.basename($0, File.extname($0))
10
+ path = File.dirname($0)
11
+
12
+ File.join(path, basename)
25
13
  end
14
+
15
+ # rubocop:enable Style/SpecialGlobalVars
26
16
  end
27
17
 
28
18
  attr_reader :dir_path
29
19
 
30
20
  def initialize(dir_path = Dir.pwd)
31
- dir_path = script_subfolder if dir_path == :script
32
- raise "Cannot initialize with directory: '#{dir_path.to_s}'" if !dir_path || dir_path.is_a?(Symbol)
21
+ dir_path = self.class.script_subfolder if dir_path == :script
22
+
23
+ msg = "Cannot initialize with directory: '#{dir_path}'"
24
+ raise ArgumentError, msg if !dir_path || dir_path.is_a?(Symbol)
25
+
33
26
  @dir_path = dir_path
34
27
  end
35
28
 
36
- def exists?
37
- Files.dir_exists?(@dir_path)
29
+ def exist?
30
+ Dir.exist?(@dir_path)
38
31
  end
39
32
 
40
- def create
41
- return self.full_path if self.exists?
42
- if succeed = Directory.create(File.expand_path(@dir_path))
43
- return self.full_path
44
- end
33
+ def create(exception: false)
34
+ return full_path if exist?
35
+
36
+ FileUtils.mkdir_p(@dir_path)
37
+
38
+ true
39
+ rescue StandardError => err
40
+ raise if exception
41
+ pp err
42
+ false
45
43
  end
46
44
 
47
45
  def full_path
@@ -49,29 +47,48 @@ module Eco
49
47
  end
50
48
 
51
49
  def dir_files(file: nil, pattern: dir_pattern)
52
- find = !!file ? file_pattern(file) : file_pattern(pattern)
53
- Dir.glob(find).sort
50
+ find = file_pattern(file || pattern)
51
+ Dir.glob(find).sort # rubocop:disable Lint/RedundantDirGlobSort
54
52
  end
55
53
 
54
+ # @params files_list [Array]
55
+ # @params file [String]
56
+ # @return [String] the last modified file.
56
57
  def newest_file(files_list = nil, file: nil)
57
- files_list = files_list || dir_files(file: file)
58
- return nil unless files_list && files_list.is_a?(Array) && (files_list.length > 0) # files available?
58
+ files_list ||= dir_files(file: file)
59
+
60
+ return unless files_list.is_a?(Array)
61
+ return unless files_list.length.positive?
62
+
59
63
  files_list.max_by {|f| File.mtime(f) }
60
64
  end
61
65
 
66
+ # Resolves the `filename` path.
67
+ # @return [String] the file path (relative or absolute)
62
68
  def file(filename, should_exist: false)
63
- return nil if !filename
69
+ return unless filename
70
+
71
+ # as incoming absolute path
64
72
  if File.expand_path(filename) == filename
65
- return filename if !should_exist || Files.file_exists?(filename)
73
+ return filename unless should_exist
74
+ return filename if File.exist?(filename)
66
75
  end
67
76
 
68
- file = FilePattern.new(filename).resolve(dir: @dir_path)
69
- return file if !should_exist || Files.file_exists?(file)
77
+ # as relative path to this directory
78
+ file = to_relative_path(filename)
79
+ return file unless should_exist
80
+ return file if File.exist?(file)
70
81
 
82
+ # as interpreted to be an absolute path
71
83
  file = File.expand_path(filename)
72
- return file if !should_exist || Files.file_exists?(file)
84
+ return file unless should_exist
85
+ file if File.exist?(file)
86
+ end
73
87
 
74
- nil
88
+ def file?(filename)
89
+ return true if file_abolute_path_exist?(filename)
90
+
91
+ file_relative_path_exist?(filename)
75
92
  end
76
93
 
77
94
  def join(*args)
@@ -81,21 +98,37 @@ module Eco
81
98
 
82
99
  private
83
100
 
101
+ def to_relative_path(filename)
102
+ return unless filename
103
+
104
+ FilePattern.new(
105
+ filename
106
+ ).resolve(dir: @dir_path)
107
+ end
108
+
109
+ def file_abolute_path_exist?(filename)
110
+ return false unless filename
111
+
112
+ File.exist?(filename)
113
+ end
114
+
115
+ def file_relative_path_exist?(filename)
116
+ return false unless filename
117
+
118
+ File.exist?(to_relative_path(filename))
119
+ end
120
+
84
121
  def file_pattern(value)
85
122
  case value
86
- when Files::FilePattern
123
+ when FilePattern
87
124
  value
88
125
  else
89
- Files::FilePattern.new(value).pattern(@dir_path)
126
+ FilePattern.new(value).pattern(@dir_path)
90
127
  end
91
128
  end
92
129
 
93
130
  def dir_pattern
94
- Files::FilePattern.new.pattern(@dir_path)
95
- end
96
-
97
- def script_subfolder
98
- Files.script_subfolder
131
+ FilePattern.new.pattern(@dir_path)
99
132
  end
100
133
  end
101
134
  end
@@ -6,9 +6,12 @@ module Eco
6
6
 
7
7
  BOM_BYTES = [239, 187, 191].freeze
8
8
 
9
- def has_bom?(path)
10
- return false if !path || file_empty?(path)
11
- File.open(path, "rb") do |f|
9
+ def bom?(path)
10
+ return false unless path
11
+ return false unless File.file?(path)
12
+ return false if File.empty?(path)
13
+
14
+ File.open(path, 'rb') do |f|
12
15
  bytes = f.read(3)
13
16
  return bytes.unpack('C*') == BOM_BYTES
14
17
  end
@@ -24,7 +27,7 @@ module Eco
24
27
  end
25
28
 
26
29
  bom_enc = encoding && encoding.split('|')[0] == 'bom'
27
- if has_bom?(file) || bom_enc
30
+ if bom?(file) || bom_enc
28
31
  content = remove_bom(File.read(file, encoding: 'utf-8'))
29
32
  encoding = 'utf-8'
30
33
  else
@@ -33,7 +36,7 @@ module Eco
33
36
 
34
37
  return unless content
35
38
 
36
- content = content.encode("utf-8") unless encoding.include?('utf-8')
39
+ content = content.encode('utf-8') unless encoding.include?('utf-8')
37
40
  content
38
41
  end
39
42
 
@@ -50,32 +53,20 @@ module Eco
50
53
  end
51
54
 
52
55
  def encoding(path)
53
- has_bom?(path) ? "bom" : "utf-8"
56
+ bom?(path) ? 'bom' : 'utf-8'
54
57
  end
55
58
 
56
59
  # Gives the parameter as it should
57
60
  def scoped_encoding(path)
58
- unless file_exists?(path)
61
+ unless File.exist?(path)
59
62
  log(:error) { "File does not exist: #{path}" }
60
- return nil
63
+ return
61
64
  end
62
65
 
63
66
  encoding ||= encoding(path)
64
- encoding = "#{encoding}|utf-8" if encoding == "bom"
67
+ encoding = "#{encoding}|utf-8" if encoding == 'bom'
65
68
  encoding
66
69
  end
67
-
68
- def file_exists?(file)
69
- return false unless file
70
-
71
- File.exist?(file) || File.exist?(File.expand_path(file))
72
- end
73
-
74
- def file_empty?(path)
75
- return true unless File.file?(path)
76
-
77
- File.zero?(path)
78
- end
79
70
  end
80
71
  end
81
72
  end
@@ -1,30 +1,37 @@
1
1
  module Eco
2
2
  module Data
3
3
  module Files
4
+ # Helper class to build regex patterns relative to a source folder.
4
5
  class FilePattern
5
- def initialize(file = "")
6
+ def initialize(file = '')
6
7
  @source_file = file
7
8
  end
8
9
 
9
- def resolve(dir: nil, start: "")
10
+ def resolve(dir: nil, start: '')
10
11
  pattern(dir).gsub('*', start)
11
12
  end
12
13
 
13
14
  def match?(file, dir: nil)
14
- /#{Regexp.escape(self.pattern(dir))}/i.match?(file)
15
+ /#{Regexp.escape(pattern(dir))}/i.match?(file)
15
16
  end
16
17
 
17
18
  def any?(files, dir: nil)
18
19
  return false unless files.is_a?(Array)
19
- files.any? { |file| match?(file, dir: dir) }
20
+
21
+ files.any? { |file| match?(file, dir: dir) }
20
22
  end
21
23
 
22
24
  def pattern(dir = nil)
23
- return File.join(dir, "*") if @source_file.to_s.empty?
25
+ return File.join(dir, '*') if @source_file.to_s.empty?
26
+
24
27
  filename = File.basename(@source_file)
25
- path = File.dirname(@source_file)
26
- path = File.join(dir, path) if dir
27
- wildcard = (filename =~ /\*/)? "" : "*"
28
+ path = File.dirname(@source_file)
29
+
30
+ path = File.join(dir, path) if dir
31
+
32
+ wildcard = '*'
33
+ wildcard = '' if filename =~ /\*/
34
+
28
35
  File.join(path, wildcard + filename)
29
36
  end
30
37
  end