bigfiles 0.1.2 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +134 -0
  3. data/.envrc +2 -0
  4. data/.git-hooks/pre_commit/circle_ci.rb +21 -0
  5. data/.gitattributes +6 -0
  6. data/.gitignore +65 -0
  7. data/.overcommit.yml +55 -0
  8. data/.rubocop.yml +116 -0
  9. data/.rubocop_todo.yml +13 -0
  10. data/.yamllint.yml +8 -0
  11. data/CODE_OF_CONDUCT.md +133 -0
  12. data/DEVELOPMENT.md +30 -0
  13. data/Gemfile +6 -0
  14. data/Gemfile.lock +110 -0
  15. data/LICENSE +21 -0
  16. data/Makefile +73 -0
  17. data/README.md +60 -0
  18. data/Rakefile +3 -30
  19. data/bigfiles.gemspec +44 -30
  20. data/bin/bigfiles +26 -2
  21. data/bin/bump +29 -0
  22. data/bin/overcommit +29 -0
  23. data/bin/rake +29 -0
  24. data/coverage/.last_run.json +6 -0
  25. data/docs/cookiecutter_input.json +13 -0
  26. data/exe/bigfiles +6 -0
  27. data/feature/big_files_cli_spec.rb +49 -0
  28. data/feature/expected/four_files_results.txt +3 -0
  29. data/feature/expected/no_files_results.txt +0 -0
  30. data/feature/expected/swift_and_ruby_files_results.txt +3 -0
  31. data/feature/expected/swift_zorb_and_ruby_files_excluded_results.txt +3 -0
  32. data/feature/expected/swift_zorb_and_ruby_files_results.txt +3 -0
  33. data/feature/expected/three_files_results.txt +3 -0
  34. data/feature/feature_helper.rb +33 -0
  35. data/feature/pronto_big_files_use_spec.rb +54 -0
  36. data/feature/samples/four_files/five_lines.rb +5 -0
  37. data/feature/samples/four_files/four_lines.rb +4 -0
  38. data/feature/samples/four_files/three_lines.rb +3 -0
  39. data/feature/samples/four_files/two_lines.rb +2 -0
  40. data/feature/samples/no_files/.keepme +0 -0
  41. data/feature/samples/swift_and_ruby_files/five_lines.swift +5 -0
  42. data/feature/samples/swift_and_ruby_files/four_lines.rb +4 -0
  43. data/feature/samples/swift_and_ruby_files/three_lines.rb +3 -0
  44. data/feature/samples/swift_zorb_and_ruby_files/five_lines.swift +5 -0
  45. data/feature/samples/swift_zorb_and_ruby_files/four_lines.zorb +4 -0
  46. data/feature/samples/swift_zorb_and_ruby_files/three_lines.rb +3 -0
  47. data/feature/samples/swift_zorb_and_ruby_files_excluded/excluded.rb +9 -0
  48. data/feature/samples/swift_zorb_and_ruby_files_excluded/five_lines.swift +5 -0
  49. data/feature/samples/swift_zorb_and_ruby_files_excluded/four_lines.zorb +4 -0
  50. data/feature/samples/swift_zorb_and_ruby_files_excluded/three_lines.rb +3 -0
  51. data/feature/samples/three_files/five_lines.rb +5 -0
  52. data/feature/samples/three_files/four_lines.rb +4 -0
  53. data/feature/samples/three_files/three_lines.rb +3 -0
  54. data/fix.sh +371 -0
  55. data/lib/bigfiles/config.rb +38 -0
  56. data/lib/bigfiles/file_with_lines.rb +2 -0
  57. data/lib/bigfiles/inspector.rb +35 -0
  58. data/lib/bigfiles/option_parser.rb +54 -0
  59. data/lib/bigfiles/version.rb +3 -1
  60. data/lib/bigfiles.rb +27 -63
  61. data/rakelib/citest.rake +4 -0
  62. data/rakelib/clear_metrics.rake +17 -0
  63. data/rakelib/console.rake +6 -0
  64. data/rakelib/default.rake +4 -0
  65. data/rakelib/feature.rake +10 -0
  66. data/rakelib/gem_tasks.rake +3 -0
  67. data/rakelib/localtest.rake +4 -0
  68. data/rakelib/overcommit.rake +6 -0
  69. data/rakelib/quality.rake +4 -0
  70. data/rakelib/repl.rake +4 -0
  71. data/rakelib/spec.rake +9 -0
  72. data/rakelib/undercover.rake +8 -0
  73. data/requirements_dev.txt +2 -0
  74. metadata +207 -30
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tmpdir'
4
+
5
+ # Example use from https://github.com/apiology/pronto-bigfiles
6
+
7
+ # This spec is here to make sure we don't break backwards
8
+ # compatibility with how this is used elsewhere (i.e., establish a
9
+ # public interface).
10
+
11
+ describe BigFiles do
12
+ let(:bigfiles_config) { ::BigFiles::Config.new }
13
+
14
+ let(:bigfiles_inspector) { ::BigFiles::Inspector.new }
15
+
16
+ let(:bigfiles_results) { bigfiles_inspector.find_and_analyze }
17
+
18
+ let(:under_limit) { bigfiles_config.under_limit?(total_lines) }
19
+
20
+ let(:total_lines) { bigfiles_results.map(&:num_lines).reduce(:+) }
21
+
22
+ let(:sample_filename) { 'file_with_two_lines.rb' }
23
+
24
+ let(:file_with_line) do
25
+ bigfiles_results.find { |f| f.filename == sample_filename }
26
+ end
27
+
28
+ let(:example_files) do
29
+ {
30
+ sample_filename => "\n\n",
31
+ }
32
+ end
33
+
34
+ around do |example|
35
+ Dir.mktmpdir do |dir|
36
+ Dir.chdir(dir) do
37
+ system('git init')
38
+ system('git config user.email "you@example.com"')
39
+ system('git config user.name "Fake User"')
40
+ example_files.each do |filename, contents|
41
+ File.write(filename, contents)
42
+ end
43
+ system('git add .')
44
+ system('git commit -m "First commit"')
45
+ example.run
46
+ end
47
+ end
48
+ end
49
+
50
+ it 'continues to behave like it did' do
51
+ expect(file_with_line).not_to eq(nil)
52
+ expect(under_limit).to be(true)
53
+ end
54
+ end
@@ -0,0 +1,5 @@
1
+ #
2
+ #
3
+ #
4
+ #
5
+ #
@@ -0,0 +1,4 @@
1
+ #
2
+ #
3
+ #
4
+ #
@@ -0,0 +1,3 @@
1
+ #
2
+ #
3
+ #
@@ -0,0 +1,2 @@
1
+ puts 'one'
2
+ puts 'two'
File without changes
@@ -0,0 +1,9 @@
1
+ lkasjf
2
+ alskfj
3
+ alsdkjf
4
+ asldfkj
5
+ asldfkj
6
+ aslfkj
7
+ asdlfkj
8
+ asdlfkj
9
+ asdlfj
@@ -0,0 +1,5 @@
1
+ #
2
+ #
3
+ #
4
+ #
5
+ #
@@ -0,0 +1,4 @@
1
+ #
2
+ #
3
+ #
4
+ #
@@ -0,0 +1,3 @@
1
+ #
2
+ #
3
+ #
data/fix.sh ADDED
@@ -0,0 +1,371 @@
1
+ #!/bin/bash -eu
2
+
3
+ set -o pipefail
4
+
5
+ apt_upgraded=0
6
+
7
+ update_apt() {
8
+ if [ "${apt_upgraded}" = 0 ]
9
+ then
10
+ sudo DEBIAN_FRONTEND=noninteractive apt-get update -y
11
+ apt_upgraded=1
12
+ fi
13
+ }
14
+
15
+ install_rbenv() {
16
+ if [ "$(uname)" == "Darwin" ]
17
+ then
18
+ HOMEBREW_NO_AUTO_UPDATE=1 brew install rbenv || true
19
+ if ! type rbenv 2>/dev/null
20
+ then
21
+ # https://github.com/pyenv/pyenv-installer/blob/master/bin/pyenv-installer
22
+ >&2 cat <<EOF
23
+ WARNING: seems you still have not added 'rbenv' to the load path.
24
+
25
+ # Load rbenv automatically by adding
26
+ # the following to ~/.bashrc:
27
+
28
+ export PATH="$HOME/.rbenv/bin:$PATH"
29
+ eval "$(rbenv init -)"
30
+ EOF
31
+ fi
32
+ else
33
+ git clone https://github.com/rbenv/rbenv.git ~/.rbenv
34
+ fi
35
+ }
36
+
37
+ set_rbenv_env_variables() {
38
+ export PATH="${HOME}/.rbenv/bin:$PATH"
39
+ eval "$(rbenv init -)"
40
+ }
41
+
42
+ install_ruby_build() {
43
+ if [ "$(uname)" == "Darwin" ]
44
+ then
45
+ HOMEBREW_NO_AUTO_UPDATE=1 brew install ruby-build || true
46
+ else
47
+ mkdir -p "$(rbenv root)"/plugins
48
+ git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
49
+ fi
50
+ }
51
+
52
+ ensure_ruby_build() {
53
+ if ! type ruby-build >/dev/null 2>&1 && ! [ -d "${HOME}/.rbenv/plugins/ruby-build" ]
54
+ then
55
+ install_ruby_build
56
+ fi
57
+ }
58
+
59
+ ensure_rbenv() {
60
+ if ! type rbenv >/dev/null 2>&1 && ! [ -f "${HOME}/.rbenv/bin/rbenv" ]
61
+ then
62
+ install_rbenv
63
+ fi
64
+
65
+ set_rbenv_env_variables
66
+
67
+ ensure_ruby_build
68
+ }
69
+
70
+ latest_ruby_version() {
71
+ major_minor=${1}
72
+ rbenv install --list 2>/dev/null | grep "^${major_minor}."
73
+ }
74
+
75
+ ensure_dev_library() {
76
+ header_file_name=${1:?header file name}
77
+ homebrew_package=${2:?homebrew package}
78
+ apt_package=${3:-${homebrew_package}}
79
+ if ! [ -f /usr/include/"${header_file_name}" ] && \
80
+ ! [ -f /usr/include/x86_64-linux-gnu/"${header_file_name}" ] && \
81
+ ! [ -f /usr/local/include/"${header_file_name}" ] && \
82
+ ! [ -f /usr/local/opt/"${homebrew_package}"/include/"${header_file_name}" ]
83
+ then
84
+ install_package "${homebrew_package}" "${apt_package}"
85
+ fi
86
+ }
87
+
88
+ ensure_ruby_build_requirements() {
89
+ ensure_dev_library readline/readline.h readline libreadline-dev
90
+ ensure_dev_library zlib.h zlib zlib1g-dev
91
+ ensure_dev_library openssl/ssl.h openssl libssl-dev
92
+ }
93
+
94
+ # You can find out which feature versions are still supported / have
95
+ # been release here: https://www.ruby-lang.org/en/downloads/
96
+ ensure_ruby_versions() {
97
+ # You can find out which feature versions are still supported / have
98
+ # been release here: https://www.ruby-lang.org/en/downloads/
99
+ ruby_versions="$(latest_ruby_version 2.6)"
100
+
101
+ echo "Latest Ruby versions: ${ruby_versions}"
102
+
103
+ ensure_ruby_build_requirements
104
+
105
+ for ver in $ruby_versions
106
+ do
107
+ # These CFLAGS can be retired once 2.6.7 is no longer needed :
108
+ #
109
+ # https://github.com/rbenv/ruby-build/issues/1747
110
+ # https://github.com/rbenv/ruby-build/issues/1489
111
+ # https://bugs.ruby-lang.org/issues/17777
112
+ if [ "${ver}" == 2.6.7 ]
113
+ then
114
+ CFLAGS="-Wno-error=implicit-function-declaration" rbenv install -s "${ver}"
115
+ else
116
+ rbenv install -s "${ver}"
117
+ fi
118
+ done
119
+ }
120
+
121
+ ensure_bundle() {
122
+ # Not sure why this is needed a second time, but it seems to be?
123
+ #
124
+ # https://app.circleci.com/pipelines/github/apiology/source_finder/21/workflows/88db659f-a4f4-4751-abc0-46f5929d8e58/jobs/107
125
+ set_rbenv_env_variables
126
+ bundle --version >/dev/null 2>&1 || gem install --no-document bundler
127
+ bundler_version=$(bundle --version | cut -d ' ' -f3)
128
+ bundler_version_major=$(cut -d. -f1 <<< "${bundler_version}")
129
+ bundler_version_minor=$(cut -d. -f2 <<< "${bundler_version}")
130
+ bundler_version_patch=$(cut -d. -f3 <<< "${bundler_version}")
131
+ # Version 2.1 of bundler seems to have some issues with nokogiri:
132
+ #
133
+ # https://app.asana.com/0/1107901397356088/1199504270687298
134
+
135
+ # Version 2.2.22 of bundler comes with a fix to ensure the 'bundle
136
+ # update --conservative' flag works as expected - important when
137
+ # doing a 'bundle update' on a about-to-be-published gem after
138
+ # bumping a gem version.
139
+ need_better_bundler=false
140
+ if [ "${bundler_version_major}" -lt 2 ]
141
+ then
142
+ need_better_bundler=true
143
+ elif [ "${bundler_version_major}" -eq 2 ]
144
+ then
145
+ if [ "${bundler_version_minor}" -lt 2 ]
146
+ then
147
+ need_better_bundler=true
148
+ elif [ "${bundler_version_minor}" -eq 2 ]
149
+ then
150
+ if [ "${bundler_version_patch}" -lt 22 ]
151
+ then
152
+ need_better_bundler=true
153
+ fi
154
+ fi
155
+ fi
156
+ if [ "${need_better_bundler}" = true ]
157
+ then
158
+ gem install --no-document bundler
159
+ fi
160
+ make bundle_install
161
+ # https://bundler.io/v2.0/bundle_lock.html#SUPPORTING-OTHER-PLATFORMS
162
+ #
163
+ # "If you want your bundle to support platforms other than the one
164
+ # you're running locally, you can run bundle lock --add-platform
165
+ # PLATFORM to add PLATFORM to the lockfile, force bundler to
166
+ # re-resolve and consider the new platform when picking gems, all
167
+ # without needing to have a machine that matches PLATFORM handy to
168
+ # install those platform-specific gems on.'
169
+ #
170
+ # This affects nokogiri, which will try to reinstall itself in
171
+ # Docker builds where it's already installed if this is not run.
172
+ for platform in x86_64-darwin-20 x86_64-linux
173
+ do
174
+ grep "${platform:?}" Gemfile.lock >/dev/null 2>&1 || bundle lock --add-platform "${platform:?}"
175
+ done
176
+ }
177
+
178
+ set_ruby_local_version() {
179
+ latest_ruby_version="$(cut -d' ' -f1 <<< "${ruby_versions}")"
180
+ echo "${latest_ruby_version}" > .ruby-version
181
+ }
182
+
183
+ latest_python_version() {
184
+ major_minor=${1}
185
+ # https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable
186
+ pyenv install --list | grep "^ ${major_minor}." | grep -v -- -dev | tail -1 | xargs
187
+ }
188
+
189
+ install_pyenv() {
190
+ if [ "$(uname)" == "Darwin" ]
191
+ then
192
+ HOMEBREW_NO_AUTO_UPDATE=1 brew install pyenv || true
193
+ if ! type pyenv 2>/dev/null
194
+ then
195
+ # https://github.com/pyenv/pyenv-installer/blob/master/bin/pyenv-installer
196
+ >&2 cat <<EOF
197
+ WARNING: seems you still have not added 'pyenv' to the load path.
198
+
199
+ # Load pyenv automatically by adding
200
+ # the following to ~/.bashrc:
201
+
202
+ export PYENV_ROOT="${HOME}/.pyenv"
203
+ export PATH="${PYENV_ROOT}/bin:$PATH"
204
+ eval "$(pyenv init --path)"
205
+ eval "$(pyenv virtualenv-init -)"
206
+ EOF
207
+ fi
208
+ else
209
+ curl https://pyenv.run | bash
210
+ fi
211
+ }
212
+
213
+ set_pyenv_env_variables() {
214
+ # looks like pyenv scripts aren't -u clean:
215
+ #
216
+ # https://app.circleci.com/pipelines/github/apiology/cookiecutter-pypackage/15/workflows/10506069-7662-46bd-b915-2992db3f795b/jobs/15
217
+ set +u
218
+ export PYENV_ROOT="${HOME}/.pyenv"
219
+ export PATH="${PYENV_ROOT}/bin:$PATH"
220
+ eval "$(pyenv init --path)"
221
+ eval "$(pyenv virtualenv-init -)"
222
+ set -u
223
+ }
224
+
225
+ ensure_pyenv() {
226
+ if ! type pyenv >/dev/null 2>&1 && ! [ -f "${HOME}/.pyenv/bin/pyenv" ]
227
+ then
228
+ install_pyenv
229
+ fi
230
+
231
+ if ! type pyenv >/dev/null 2>&1
232
+ then
233
+ set_pyenv_env_variables
234
+ fi
235
+ }
236
+
237
+ install_package() {
238
+ homebrew_package=${1:?homebrew package}
239
+ apt_package=${2:-${homebrew_package}}
240
+ if [ "$(uname)" == "Darwin" ]
241
+ then
242
+ HOMEBREW_NO_AUTO_UPDATE=1 brew install "${homebrew_package}"
243
+ elif type apt-get >/dev/null 2>&1
244
+ then
245
+ update_apt
246
+ sudo DEBIAN_FRONTEND=noninteractive apt-get install -y "${apt_package}"
247
+ else
248
+ >&2 echo "Teach me how to install packages on this plaform"
249
+ exit 1
250
+ fi
251
+ }
252
+
253
+ ensure_python_build_requirements() {
254
+ ensure_dev_library zlib.h zlib zlib1g-dev
255
+ ensure_dev_library bzlib.h bzip2 libbz2-dev
256
+ ensure_dev_library openssl/ssl.h openssl libssl-dev
257
+ ensure_dev_library ffi.h libffi libffi-dev
258
+ ensure_dev_library sqlite3.h sqlite3 libsqlite3-dev
259
+ ensure_dev_library lzma.h xz liblzma-dev
260
+ ensure_dev_library readline/readline.h readline libreadline-dev
261
+ }
262
+
263
+ # You can find out which feature versions are still supported / have
264
+ # been release here: https://www.python.org/downloads/
265
+ ensure_python_versions() {
266
+ # You can find out which feature versions are still supported / have
267
+ # been release here: https://www.python.org/downloads/
268
+ python_versions="$(latest_python_version 3.10)"
269
+
270
+ echo "Latest Python versions: ${python_versions}"
271
+
272
+ ensure_python_build_requirements
273
+
274
+ for ver in $python_versions
275
+ do
276
+ if [ "$(uname)" == Darwin ]
277
+ then
278
+ if [ -z "${HOMEBREW_OPENSSL_PREFIX:-}" ]
279
+ then
280
+ HOMEBREW_OPENSSL_PREFIX="$(brew --prefix openssl)"
281
+ fi
282
+ pyenv_install() {
283
+ CFLAGS="-I/usr/local/opt/zlib/include -I/usr/local/opt/bzip2/include -I${HOMEBREW_OPENSSL_PREFIX}/include" LDFLAGS="-L/usr/local/opt/zlib/lib -L/usr/local/opt/bzip2/lib -L${HOMEBREW_OPENSSL_PREFIX}/lib" pyenv install --skip-existing "$@"
284
+ }
285
+
286
+ major_minor="$(cut -d. -f1-2 <<<"${ver}")"
287
+ if [ "${major_minor}" == 3.6 ]
288
+ then
289
+ pyenv_install --patch "${ver}" < <(curl -sSL https://github.com/python/cpython/commit/8ea6353.patch\?full_index=1)
290
+ else
291
+ pyenv_install "${ver}"
292
+ fi
293
+ else
294
+ pyenv install -s "${ver}"
295
+ fi
296
+ done
297
+ }
298
+
299
+ ensure_pyenv_virtualenvs() {
300
+ latest_python_version="$(cut -d' ' -f1 <<< "${python_versions}")"
301
+ virtualenv_name="bigfiles-${latest_python_version}"
302
+ pyenv virtualenv "${latest_python_version}" "${virtualenv_name}" || true
303
+ # You can use this for your global stuff!
304
+ pyenv virtualenv "${latest_python_version}" mylibs || true
305
+ # shellcheck disable=SC2086
306
+ pyenv local "${virtualenv_name}" ${python_versions} mylibs
307
+ }
308
+
309
+ ensure_pip_and_wheel() {
310
+ # Make sure we have a pip with the 20.3 resolver, and after the
311
+ # initial bugfix release
312
+ major_pip_version=$(pip --version | cut -d' ' -f2 | cut -d '.' -f 1)
313
+ if [[ major_pip_version -lt 21 ]]
314
+ then
315
+ pip install 'pip>=20.3.1'
316
+ fi
317
+ # wheel is helpful for being able to cache long package builds
318
+ pip show wheel >/dev/null 2>&1 || pip install wheel
319
+ }
320
+
321
+ ensure_python_requirements() {
322
+ make pip_install
323
+ }
324
+
325
+ ensure_shellcheck() {
326
+ if ! type shellcheck >/dev/null 2>&1
327
+ then
328
+ install_package shellcheck
329
+ fi
330
+ }
331
+
332
+ ensure_overcommit() {
333
+ # don't run if we're in the middle of a cookiecutter child project
334
+ # test, or otherwise don't have a Git repo to install hooks into...
335
+ if [ -d .git ]
336
+ then
337
+ bundle exec overcommit --install
338
+ else
339
+ >&2 echo 'Not in a git repo; not installing git hooks'
340
+ fi
341
+ }
342
+
343
+ ensure_rugged_packages_installed() {
344
+ install_package icu4c libicu-dev # needed by rugged, needed by undercover
345
+ install_package pkg-config # needed by rugged, needed by undercover
346
+ install_package cmake # needed by rugged, needed by undercover
347
+ }
348
+
349
+ ensure_rbenv
350
+
351
+ ensure_ruby_versions
352
+
353
+ set_ruby_local_version
354
+
355
+ ensure_rugged_packages_installed
356
+
357
+ ensure_bundle
358
+
359
+ ensure_pyenv
360
+
361
+ ensure_python_versions
362
+
363
+ ensure_pyenv_virtualenvs
364
+
365
+ ensure_pip_and_wheel
366
+
367
+ ensure_python_requirements
368
+
369
+ ensure_shellcheck
370
+
371
+ ensure_overcommit
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'source_finder/option_parser'
4
+ require 'high_water_mark/threshold'
5
+
6
+ module BigFiles
7
+ # Configuration for bigfiles gem
8
+ class Config
9
+ NUM_FILES_DEFAULT = 3
10
+
11
+ attr_reader :help, :num_files, :glob, :exclude, :minimum_high_water_mark
12
+
13
+ def initialize(source_finder_option_parser: SourceFinder::OptionParser.new,
14
+ num_files: Config::NUM_FILES_DEFAULT,
15
+ quality_threshold:
16
+ ::HighWaterMark::Threshold.new('bigfiles'),
17
+ minimum_high_water_mark: 300,
18
+ help: false,
19
+ glob: source_finder_option_parser.default_source_files_glob,
20
+ exclude: source_finder_option_parser
21
+ .default_source_files_exclude_glob)
22
+ @num_files = num_files
23
+ @help = help
24
+ @glob = glob
25
+ @exclude = exclude
26
+ @quality_threshold = quality_threshold
27
+ @minimum_high_water_mark = minimum_high_water_mark
28
+ end
29
+
30
+ def high_water_mark
31
+ @quality_threshold.threshold || @minimum_high_water_mark
32
+ end
33
+
34
+ def under_limit?(num_lines)
35
+ num_lines <= high_water_mark
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module BigFiles
2
4
  # Encapsulates a file which has a certain number of lines
3
5
  class FileWithLines
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'config'
4
+ require_relative 'file_with_lines'
5
+
6
+ # Simple tool to find the largest source files in your project.
7
+ module BigFiles
8
+ # Investigate a project and generate a report on the n biggest files
9
+ class Inspector
10
+ def initialize(config: Config.new,
11
+ source_file_globber: SourceFinder::SourceFileGlobber.new,
12
+ file_with_lines: FileWithLines,
13
+ io_class: Kernel)
14
+ @config = config
15
+ @source_file_globber = source_file_globber
16
+ @file_with_lines = file_with_lines
17
+ @io_class = io_class
18
+ end
19
+
20
+ def find_and_analyze
21
+ @source_file_globber.source_files_glob = @config.glob
22
+ @source_file_globber.source_files_exclude_glob = @config.exclude
23
+ file_list = @source_file_globber.source_files_arr
24
+ file_list.map do |filename|
25
+ @file_with_lines.new(filename)
26
+ end.sort.reverse[0..(@config.num_files - 1)]
27
+ end
28
+
29
+ def find_analyze_and_report_on_files
30
+ find_and_analyze.each do |file|
31
+ @io_class.puts "#{file.num_lines}: #{file.filename}"
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'config'
4
+
5
+ module BigFiles
6
+ # Parse options passed to bigfiles command
7
+ class OptionParser
8
+ def initialize(source_finder_option_parser:, option_parser_class: ::OptionParser,
9
+ io_class: Kernel,
10
+ exiter: Kernel)
11
+ @option_parser_class = option_parser_class
12
+ @io_class = io_class
13
+ @exiter = exiter
14
+ @source_finder_option_parser = source_finder_option_parser
15
+ end
16
+
17
+ def setup_options(opts)
18
+ options = {}
19
+ opts.banner = 'Usage: bigfiles [options]'
20
+ @source_finder_option_parser.add_options(opts, options)
21
+ add_help_option(opts, options)
22
+ add_num_files_option(opts, options)
23
+ options
24
+ end
25
+
26
+ def add_num_files_option(opts, options)
27
+ opts.on('-n', '--num-files number-here',
28
+ Integer,
29
+ "Top number of files to show--" \
30
+ "default #{Config::NUM_FILES_DEFAULT}") do |n|
31
+ options[:num_files] = n
32
+ end
33
+ end
34
+
35
+ def add_help_option(opts, options)
36
+ opts.on('-h', '--help', 'This message') { |_| options[:help] = true }
37
+ end
38
+
39
+ def parse_options(args)
40
+ options = nil
41
+ @option_parser_class.new do |opts|
42
+ options = setup_options(opts)
43
+ @option_parser = opts
44
+ end.parse!(args)
45
+ Config.new(**options,
46
+ source_finder_option_parser: @source_finder_option_parser)
47
+ end
48
+
49
+ def usage
50
+ @io_class.puts @option_parser
51
+ @exiter.exit(1)
52
+ end
53
+ end
54
+ end
@@ -1,4 +1,6 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Tool to find the largest source files in your project
2
4
  module BigFiles
3
- VERSION = '0.1.2'
5
+ VERSION = '0.2.2'
4
6
  end