bigfiles 0.1.2 → 0.2.2

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 (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