Module: SimpleCov::CLI::Clean
Overview
simplecov clean [--dry-run]: remove the coverage report directory.
--dry-run prints what would be deleted without touching disk.
Constant Summary
Constants included from CommandHelpers
SimpleCov::CLI::CommandHelpers::STATS_ROW_FORMAT
Instance Method Summary collapse
- #announce(stdout, opts, message) ⇒ Object
- #canonical_path(path) ⇒ Object
-
#descendant_of?(path, possible_ancestor) ⇒ Boolean
Canonical paths only carry a trailing separator on a filesystem root, and roots are refused before this check runs.
-
#entry_count(dir) ⇒ Object
FNM_DOTMATCH so the dotfiles rm_rf will actually delete count too.
- #parse(args) ⇒ Object
-
#protected_paths ⇒ Object
The working directory, which a coverage directory must not be or contain.
- #run(args, stdout:, stderr:) ⇒ Object
-
#safe_to_remove?(dir) ⇒ Boolean
A filesystem root is its own dirname, on every platform and every Windows drive.
- #sweep(dir, opts, stdout) ⇒ Object
Methods included from CommandHelpers
build_parser, command_name, common_options, error, error_nil, on_help, one?, parse_common, quiet_option, recorded_contexts, stats_row
Instance Method Details
#announce(stdout, opts, message) ⇒ Object
43 44 45 |
# File 'lib/simplecov/cli/clean.rb', line 43 def announce(stdout, opts, ) stdout.puts("simplecov #{command_name}: #{}") unless opts.fetch(:quiet) end |
#canonical_path(path) ⇒ Object
71 72 73 74 75 |
# File 'lib/simplecov/cli/clean.rb', line 71 def canonical_path(path) REAL_PATHS.realpath(path) rescue SystemCallError File.(path) end |
#descendant_of?(path, possible_ancestor) ⇒ Boolean
Canonical paths only carry a trailing separator on a filesystem root, and roots are refused before this check runs.
67 68 69 |
# File 'lib/simplecov/cli/clean.rb', line 67 def descendant_of?(path, possible_ancestor) path.start_with?("#{possible_ancestor}#{File::SEPARATOR}") end |
#entry_count(dir) ⇒ Object
FNM_DOTMATCH so the dotfiles rm_rf will actually delete count too. The glob still yields the directory's own "." entry, which rm_rf does not remove separately.
39 40 41 |
# File 'lib/simplecov/cli/clean.rb', line 39 def entry_count(dir) Dir.glob("#{dir}/**/*", File::FNM_DOTMATCH).count { |path| !path.end_with?("/.") } end |
#parse(args) ⇒ Object
77 78 79 80 81 82 83 84 |
# File 'lib/simplecov/cli/clean.rb', line 77 def parse(args) opts = {dry_run: false, quiet: false} build_parser do |o| o.on("--dry-run") { opts[:dry_run] = true } quiet_option(o, opts) end.parse(args) opts end |
#protected_paths ⇒ Object
The working directory, which a coverage directory must not be or contain.
The .simplecov project root needs no entry of its own: Dotfile.find
walks up from the working directory, so any target containing that root
contains the working directory too.
61 62 63 |
# File 'lib/simplecov/cli/clean.rb', line 61 def protected_paths [canonical_path(Dir.pwd)] end |
#run(args, stdout:, stderr:) ⇒ Object
17 18 19 20 21 22 23 24 25 |
# File 'lib/simplecov/cli/clean.rb', line 17 def run(args, stdout:, stderr:, **) opts = parse(args) dir = CLI.coverage_dir return error(stderr, "refusing to remove unsafe coverage directory #{dir.inspect}") unless safe_to_remove?(dir) return announce(stdout, opts, "#{dir} doesn't exist; nothing to do") || 0 unless File.directory?(dir) sweep(dir, opts, stdout) 0 end |
#safe_to_remove?(dir) ⇒ Boolean
A filesystem root is its own dirname, on every platform and every Windows drive. The descendant check only protects roots that happen to contain the cwd, which misses other drives, so roots are refused outright.
50 51 52 53 54 55 |
# File 'lib/simplecov/cli/clean.rb', line 50 def safe_to_remove?(dir) target = canonical_path(dir) return false if File.dirname(target).eql?(target) protected_paths.none? { |path| path.eql?(target) || descendant_of?(path, target) } end |
#sweep(dir, opts, stdout) ⇒ Object
27 28 29 30 31 32 33 34 |
# File 'lib/simplecov/cli/clean.rb', line 27 def sweep(dir, opts, stdout) if opts.fetch(:dry_run) announce(stdout, opts, "would remove #{dir} (#{entry_count(dir)} entries)") else FileUtils.rm_rf(dir) announce(stdout, opts, "removed #{dir}") end end |