polishgeeks-dev-tools 1.0.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 +7 -0
- data/.gitignore +22 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +193 -0
- data/README.md +112 -0
- data/Rakefile +20 -0
- data/config/haml-lint.yml +74 -0
- data/config/rubocop.yml +35 -0
- data/config/yardopts +7 -0
- data/lib/polishgeeks-dev-tools.rb +43 -0
- data/lib/polishgeeks/dev-tools/command/allowed_extensions.rb +62 -0
- data/lib/polishgeeks/dev-tools/command/base.rb +73 -0
- data/lib/polishgeeks/dev-tools/command/brakeman.rb +46 -0
- data/lib/polishgeeks/dev-tools/command/coverage.rb +43 -0
- data/lib/polishgeeks/dev-tools/command/examples_comparator.rb +75 -0
- data/lib/polishgeeks/dev-tools/command/expires_in.rb +74 -0
- data/lib/polishgeeks/dev-tools/command/haml_lint.rb +28 -0
- data/lib/polishgeeks/dev-tools/command/readme.rb +32 -0
- data/lib/polishgeeks/dev-tools/command/rspec.rb +38 -0
- data/lib/polishgeeks/dev-tools/command/rspec_files_names.rb +58 -0
- data/lib/polishgeeks/dev-tools/command/rspec_files_structure.rb +134 -0
- data/lib/polishgeeks/dev-tools/command/rubocop.rb +50 -0
- data/lib/polishgeeks/dev-tools/command/rubycritic.rb +17 -0
- data/lib/polishgeeks/dev-tools/command/simplecov.rb +32 -0
- data/lib/polishgeeks/dev-tools/command/tasks_files_names.rb +76 -0
- data/lib/polishgeeks/dev-tools/command/yard.rb +35 -0
- data/lib/polishgeeks/dev-tools/command/yml_parser.rb +85 -0
- data/lib/polishgeeks/dev-tools/config.rb +91 -0
- data/lib/polishgeeks/dev-tools/hash.rb +24 -0
- data/lib/polishgeeks/dev-tools/logger.rb +63 -0
- data/lib/polishgeeks/dev-tools/output_storer.rb +17 -0
- data/lib/polishgeeks/dev-tools/runner.rb +27 -0
- data/lib/polishgeeks/dev-tools/shell.rb +16 -0
- data/lib/polishgeeks/dev-tools/tasks/dev-tools.rake +15 -0
- data/lib/polishgeeks/dev-tools/version.rb +8 -0
- data/polishgeeks_dev_tools.gemspec +36 -0
- data/spec/lib/polishgeeks-dev-tools_spec.rb +35 -0
- data/spec/lib/polishgeeks/dev-tools/command/allowed_extensions_spec.rb +66 -0
- data/spec/lib/polishgeeks/dev-tools/command/base_spec.rb +127 -0
- data/spec/lib/polishgeeks/dev-tools/command/brakeman_spec.rb +95 -0
- data/spec/lib/polishgeeks/dev-tools/command/coverage_spec.rb +121 -0
- data/spec/lib/polishgeeks/dev-tools/command/examples_comparator_spec.rb +171 -0
- data/spec/lib/polishgeeks/dev-tools/command/expires_in_spec.rb +69 -0
- data/spec/lib/polishgeeks/dev-tools/command/haml_lint_spec.rb +79 -0
- data/spec/lib/polishgeeks/dev-tools/command/readme_spec.rb +38 -0
- data/spec/lib/polishgeeks/dev-tools/command/rspec_files_names_spec.rb +91 -0
- data/spec/lib/polishgeeks/dev-tools/command/rspec_files_structure_spec.rb +262 -0
- data/spec/lib/polishgeeks/dev-tools/command/rspec_spec.rb +63 -0
- data/spec/lib/polishgeeks/dev-tools/command/rubocop_spec.rb +127 -0
- data/spec/lib/polishgeeks/dev-tools/command/rubycritic_spec.rb +27 -0
- data/spec/lib/polishgeeks/dev-tools/command/simplecov_spec.rb +53 -0
- data/spec/lib/polishgeeks/dev-tools/command/tasks_files_names_spec.rb +108 -0
- data/spec/lib/polishgeeks/dev-tools/command/yard_spec.rb +86 -0
- data/spec/lib/polishgeeks/dev-tools/command/yml_parser_spec.rb +104 -0
- data/spec/lib/polishgeeks/dev-tools/config_spec.rb +78 -0
- data/spec/lib/polishgeeks/dev-tools/hash_spec.rb +37 -0
- data/spec/lib/polishgeeks/dev-tools/logger_spec.rb +162 -0
- data/spec/lib/polishgeeks/dev-tools/output_storer_spec.rb +20 -0
- data/spec/lib/polishgeeks/dev-tools/runner_spec.rb +57 -0
- data/spec/lib/polishgeeks/dev-tools/shell_spec.rb +13 -0
- data/spec/lib/polishgeeks/dev-tools/version_spec.rb +7 -0
- data/spec/spec_helper.rb +28 -0
- metadata +330 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
module PolishGeeks
|
2
|
+
module DevTools
|
3
|
+
module Command
|
4
|
+
# Command wrapper for Haml lint validation
|
5
|
+
# It informs us if haml is formatted in a proper way
|
6
|
+
# @see https://github.com/causes/haml-lint
|
7
|
+
class HamlLint < Base
|
8
|
+
self.type = :validator
|
9
|
+
|
10
|
+
# Executes this command
|
11
|
+
# @return [String] command output
|
12
|
+
def execute
|
13
|
+
loc_config = File.join(DevTools.gem_root, 'config', 'haml-lint.yml')
|
14
|
+
app_config = File.join(DevTools.app_root, '.haml-lint.yml')
|
15
|
+
|
16
|
+
config = File.exist?(app_config) ? app_config : loc_config
|
17
|
+
|
18
|
+
@output = Shell.new.execute("bundle exec haml-lint -c #{config} app/views")
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Boolean] true if there were no Rubocop offenses detected
|
22
|
+
def valid?
|
23
|
+
@output.to_s.empty?
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module PolishGeeks
|
2
|
+
module DevTools
|
3
|
+
module Command
|
4
|
+
# Checks README.rb exists
|
5
|
+
class Readme < Base
|
6
|
+
self.type = :validator
|
7
|
+
|
8
|
+
# Executes this command
|
9
|
+
# @return [String] command output
|
10
|
+
def execute
|
11
|
+
readme = File.join(::PolishGeeks::DevTools.app_root, 'README.md')
|
12
|
+
@output = File.exist?(readme)
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return [String] label with this validator description
|
16
|
+
def label
|
17
|
+
'README.rb required'
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [String] error message
|
21
|
+
def error_message
|
22
|
+
"README.rb doesn't exist!"
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Boolean] true if README.rb exist
|
26
|
+
def valid?
|
27
|
+
@output
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module PolishGeeks
|
2
|
+
module DevTools
|
3
|
+
module Command
|
4
|
+
# Command wrapper for Rspec validation
|
5
|
+
# It informs us if our specs are working in a proper way
|
6
|
+
class Rspec < Base
|
7
|
+
self.type = :validator
|
8
|
+
|
9
|
+
# Regexp used to match Rspec examples count
|
10
|
+
EXAMPLES_REGEXP = /(\d+) examples/
|
11
|
+
# Regexp used to match Rspec failures
|
12
|
+
FAILURES_REGEXP = /(\d+) failures/
|
13
|
+
# Regexp used to match Rspec pendings
|
14
|
+
PENDING_REGEXP = /(\d+) pending/
|
15
|
+
|
16
|
+
# Executes this command
|
17
|
+
# @return [String] command output
|
18
|
+
def execute
|
19
|
+
@output = Shell.new.execute('bundle exec rspec spec')
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [Boolean] true if there were no Rspec failures, false otherwise
|
23
|
+
def valid?
|
24
|
+
output.include?('0 failures')
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [String] default label for this command
|
28
|
+
def label
|
29
|
+
examples = output.scan(EXAMPLES_REGEXP).flatten.first.to_i
|
30
|
+
failures = output.scan(FAILURES_REGEXP).flatten.first.to_i
|
31
|
+
pending = output.scan(PENDING_REGEXP).flatten.first.to_i
|
32
|
+
|
33
|
+
"Rspec (#{examples} ex, #{failures} fa, #{pending} pe)"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module PolishGeeks
|
2
|
+
module DevTools
|
3
|
+
module Command
|
4
|
+
# Validator used to check if all the rspec spec files have a proper
|
5
|
+
# sufix (_spec.rb)
|
6
|
+
class RspecFilesNames < Base
|
7
|
+
self.type = :validator
|
8
|
+
|
9
|
+
attr_reader :counter
|
10
|
+
|
11
|
+
# List of dirs in spec/ dir that we will check for
|
12
|
+
# _spec.rb naming
|
13
|
+
CHECKED_DIRS = %w(
|
14
|
+
aggregators controllers helpers lib libs models decorators
|
15
|
+
presenters services workers mailers requests polishgeeks*
|
16
|
+
)
|
17
|
+
|
18
|
+
# Regexp used to check names in spec files
|
19
|
+
CHECK_REGEXP = /(\_spec\.rb)$/
|
20
|
+
|
21
|
+
# Executes this command
|
22
|
+
# @return [Array] command output array with list of spec files
|
23
|
+
# that dont have a proper name
|
24
|
+
def execute
|
25
|
+
@output = []
|
26
|
+
@counter = 0
|
27
|
+
|
28
|
+
CHECKED_DIRS.each do |name|
|
29
|
+
path = File.join(::PolishGeeks::DevTools.app_root, 'spec', name)
|
30
|
+
files = Dir.glob("#{path}/**/*").select { |f| File.file? f }
|
31
|
+
|
32
|
+
@counter += files.count
|
33
|
+
|
34
|
+
files.each do |file|
|
35
|
+
@output << file unless file =~ CHECK_REGEXP
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# @return [Boolean] true if all specs have a proper sufix (_spec.rb)
|
41
|
+
def valid?
|
42
|
+
output.empty?
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [String] default label for this command
|
46
|
+
def label
|
47
|
+
"Rspec files names: #{counter} files checked"
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [String] message that should be printed when some files have
|
51
|
+
# invalid name
|
52
|
+
def error_message
|
53
|
+
"Following files have invalid name: \n #{output.join("\n")}\n"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module PolishGeeks
|
2
|
+
module DevTools
|
3
|
+
module Command
|
4
|
+
# Checks if there are are rb files that don't have corresponding rspec
|
5
|
+
# spec files defined
|
6
|
+
# This will validate that the names are the same (no typos, etc) and no
|
7
|
+
# file are without spec files (even just with pending)
|
8
|
+
class RspecFilesStructure < Base
|
9
|
+
self.type = :validator
|
10
|
+
|
11
|
+
# Files in directories that we want to check against their rspec
|
12
|
+
# corresponding files
|
13
|
+
FILES_CHECKED = %w(
|
14
|
+
app/**/*.rb
|
15
|
+
lib/**/*.rb
|
16
|
+
)
|
17
|
+
|
18
|
+
# From where should we take spec files
|
19
|
+
RSPEC_FILES = %w(
|
20
|
+
spec/**/*_spec.rb
|
21
|
+
)
|
22
|
+
|
23
|
+
# Executes this command
|
24
|
+
# @return [Array<String>] empty array if all the files have corresponding
|
25
|
+
# rspec files, otherwise array will contain files that doesn't
|
26
|
+
def execute
|
27
|
+
@output = {
|
28
|
+
app: analyzed_files - rspec_files,
|
29
|
+
rspec: rspec_files - analyzed_files
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Boolean] true if everything is ok and all the files have
|
34
|
+
# rspec corresponding files
|
35
|
+
def valid?
|
36
|
+
@output[:app].empty? && @output[:rspec].empty?
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [String] label with this validator description
|
40
|
+
def label
|
41
|
+
"Rspec files structure (#{analyzed_files.count} checked)"
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [String] error message that will be displayed if something
|
45
|
+
# goes wrong
|
46
|
+
def error_message
|
47
|
+
err = files_error_message + rspec_error_message
|
48
|
+
err
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
# @return [Array<String>] array with list of files that we want to compare with
|
54
|
+
# those from Rspec that should exist
|
55
|
+
def analyzed_files
|
56
|
+
files = FILES_CHECKED.map do |dir|
|
57
|
+
Dir[File.join(DevTools.app_root, dir)]
|
58
|
+
end
|
59
|
+
|
60
|
+
files.flatten!
|
61
|
+
files.uniq!
|
62
|
+
|
63
|
+
files.delete_if do |file|
|
64
|
+
excludes.any? { |exclude| file.include?(exclude) }
|
65
|
+
end
|
66
|
+
|
67
|
+
files.map! { |file| sanitize(file) }
|
68
|
+
|
69
|
+
files
|
70
|
+
end
|
71
|
+
|
72
|
+
# @return [Array<String>] rspec files that should correspond with analyzed_files
|
73
|
+
def rspec_files
|
74
|
+
files = RSPEC_FILES.map { |dir| Dir[File.join(DevTools.app_root, dir)] }
|
75
|
+
|
76
|
+
files.flatten!
|
77
|
+
|
78
|
+
files.delete_if do |file|
|
79
|
+
excludes.any? { |exclude| file =~ /#{exclude}/ }
|
80
|
+
end
|
81
|
+
|
82
|
+
files.map! { |file| sanitize(file) }
|
83
|
+
files.uniq!
|
84
|
+
|
85
|
+
files
|
86
|
+
end
|
87
|
+
|
88
|
+
# @param [String] file name that we want to sanitize
|
89
|
+
# @return [String] sanitized file name
|
90
|
+
# @example
|
91
|
+
# file = /home/something/app/models/user.rb
|
92
|
+
# sanitize(file) #=> models/user.rb
|
93
|
+
def sanitize(file)
|
94
|
+
file.gsub!(DevTools.app_root + '/', '')
|
95
|
+
file.gsub!('_spec.rb', '.rb')
|
96
|
+
file.gsub!('spec/', '')
|
97
|
+
file.gsub!('app/', '')
|
98
|
+
file
|
99
|
+
end
|
100
|
+
|
101
|
+
# @return [String] return message with files which don't
|
102
|
+
# have corresponding Rspec files
|
103
|
+
def files_error_message
|
104
|
+
return '' if @output[:app].empty?
|
105
|
+
err = 'Following files don\'t have corresponding Rspec files:'
|
106
|
+
err << "\n\n"
|
107
|
+
err << @output[:app].join("\n")
|
108
|
+
err << "\n"
|
109
|
+
err
|
110
|
+
end
|
111
|
+
|
112
|
+
# @return [String] return message with Rspec files which don't
|
113
|
+
# have corresponding files
|
114
|
+
def rspec_error_message
|
115
|
+
return '' if @output[:rspec].empty?
|
116
|
+
err = "\n\n"
|
117
|
+
err << 'Following Rspec don\'t have corresponding files:'
|
118
|
+
err << "\n\n"
|
119
|
+
err << @output[:rspec].map! { |file| file.gsub!('.rb', '_spec.rb') }.join("\n")
|
120
|
+
err << "\n"
|
121
|
+
err
|
122
|
+
end
|
123
|
+
|
124
|
+
# @return [Array<String>] list of files/directories that
|
125
|
+
# should be excluded from checking
|
126
|
+
# @note This should be set in the initializer for this gem
|
127
|
+
# in the place where it is going to be used
|
128
|
+
def excludes
|
129
|
+
DevTools.config.rspec_files_structure_ignored || []
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module PolishGeeks
|
2
|
+
module DevTools
|
3
|
+
module Command
|
4
|
+
# Command wrapper for Rubocop validation
|
5
|
+
# It informs us if code is formatted in a proper way
|
6
|
+
class Rubocop < Base
|
7
|
+
self.type = :validator
|
8
|
+
|
9
|
+
# Regexp used to get number of inspected files
|
10
|
+
FILES_REGEXP = /(\d+) files inspected/
|
11
|
+
# Regexp used to get number of offenses detected
|
12
|
+
OFFENSES_REGEXP = /(\d+) offense.* detected/
|
13
|
+
|
14
|
+
# Executes this command
|
15
|
+
# @return [String] command output
|
16
|
+
def execute
|
17
|
+
loc_config = File.join(DevTools.gem_root, 'config', 'rubocop.yml')
|
18
|
+
app_config = File.join(DevTools.app_root, '.rubocop.yml')
|
19
|
+
|
20
|
+
config = File.exist?(app_config) ? app_config : loc_config
|
21
|
+
cmd = "bundle exec rubocop -c #{config} #{PolishGeeks::DevTools.app_root}"
|
22
|
+
|
23
|
+
@output = Shell.new.execute(cmd)
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Boolean] true if there were no Rubocop offenses detected
|
27
|
+
def valid?
|
28
|
+
offenses_count == 0
|
29
|
+
end
|
30
|
+
|
31
|
+
# @return [String] default label for this command
|
32
|
+
def label
|
33
|
+
"Rubocop (#{files_count} files, #{offenses_count} offenses)"
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# @return [Integer] number of files inspected
|
39
|
+
def files_count
|
40
|
+
output.scan(FILES_REGEXP).flatten.first.to_i
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [Integer] number of offences found
|
44
|
+
def offenses_count
|
45
|
+
output.scan(OFFENSES_REGEXP).flatten.first.to_i
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module PolishGeeks
|
2
|
+
module DevTools
|
3
|
+
module Command
|
4
|
+
# Command wrapper for RubyCritic statistics
|
5
|
+
# It informs us if RubyCritic stats were generated
|
6
|
+
class Rubycritic < Base
|
7
|
+
self.type = :generator
|
8
|
+
|
9
|
+
# Executes this command
|
10
|
+
# @return [String] command output
|
11
|
+
def execute
|
12
|
+
@output = Shell.new.execute('bundle exec rubycritic ./app ./lib/')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module PolishGeeks
|
2
|
+
module DevTools
|
3
|
+
module Command
|
4
|
+
# Command wrapper for Simplecov statistics
|
5
|
+
# It informs us if Simplecov coverage stats were generated
|
6
|
+
class Simplecov < Base
|
7
|
+
self.type = :validator
|
8
|
+
|
9
|
+
# Regexp used to match code coverage from Simplecov generated output
|
10
|
+
MATCH_REGEXP = /\(\d+.\d+\%\) covered/
|
11
|
+
|
12
|
+
# Executes this command
|
13
|
+
# @return [String] command output
|
14
|
+
# @note Since this command wrapper is using external output
|
15
|
+
# information (from Rspec), it doesn't execute any shell tasks
|
16
|
+
def execute
|
17
|
+
@output = stored_output.rspec
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Boolean] true if Simplecov coverage was generated
|
21
|
+
def valid?
|
22
|
+
output[MATCH_REGEXP].length > 0
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [String] default label for this command
|
26
|
+
def label
|
27
|
+
"Simplecov #{output[MATCH_REGEXP]}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module PolishGeeks
|
2
|
+
module DevTools
|
3
|
+
module Command
|
4
|
+
# Checks if tasks files (rake and capistrano) have proper extensions
|
5
|
+
class TasksFilesNames < Base
|
6
|
+
self.type = :validator
|
7
|
+
|
8
|
+
attr_reader :counter
|
9
|
+
|
10
|
+
# Capistrano tasks check rules
|
11
|
+
CAP = OpenStruct.new(
|
12
|
+
dirs: %w(
|
13
|
+
lib/capistrano
|
14
|
+
),
|
15
|
+
regexp: /.*\.cap$/
|
16
|
+
)
|
17
|
+
|
18
|
+
# Rake tasks check rules
|
19
|
+
RAKE = OpenStruct.new(
|
20
|
+
dirs: %w(
|
21
|
+
lib/tasks
|
22
|
+
),
|
23
|
+
regexp: /.*\.rake$/
|
24
|
+
)
|
25
|
+
|
26
|
+
# Executes this command
|
27
|
+
# @return [Array<String>] command output array with list of spec files
|
28
|
+
# that dont have a proper name, or an empty array if everything is ok
|
29
|
+
def execute
|
30
|
+
@output = []
|
31
|
+
@counter = 0
|
32
|
+
|
33
|
+
cap_files = files(CAP)
|
34
|
+
@counter += cap_files.count
|
35
|
+
|
36
|
+
cap_files.delete_if { |file| file =~ CAP.regexp }
|
37
|
+
@output += cap_files
|
38
|
+
|
39
|
+
rake_files = files(RAKE)
|
40
|
+
@counter += rake_files.count
|
41
|
+
|
42
|
+
rake_files.delete_if { |file| file =~ RAKE.regexp }
|
43
|
+
@output += rake_files
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [Boolean] true if all files have proper names and extensions
|
47
|
+
def valid?
|
48
|
+
output.empty?
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [String] default label for this command
|
52
|
+
def label
|
53
|
+
"Tasks files names: #{counter} files checked"
|
54
|
+
end
|
55
|
+
|
56
|
+
# @return [String] message that should be printed when some files have
|
57
|
+
# invalid extensions/names
|
58
|
+
def error_message
|
59
|
+
"Following files have invalid extensions: \n #{output.join("\n")}\n"
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# @param type [OpenStruct] openstruct with a dirs and regexp methods
|
65
|
+
# @return [Array<String>] Array with all the files of appropriate type
|
66
|
+
def files(type)
|
67
|
+
files = type.dirs.map { |dir| Dir["#{DevTools.app_root}/#{dir}/**/*"] }
|
68
|
+
files.flatten!
|
69
|
+
files.delete_if { |file| File.directory?(file) }
|
70
|
+
|
71
|
+
files
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|