spreen-clean 0.1.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/LICENSE.txt +21 -0
- data/README.md +114 -0
- data/exe/file-clean +6 -0
- data/lib/spreen-clean.rb +6 -0
- data/lib/spreen_clean/application.rb +118 -0
- data/lib/spreen_clean/cli.rb +111 -0
- data/lib/spreen_clean/version.rb +6 -0
- data/lib/spreen_clean.rb +12 -0
- data/sig/generated/spreen-clean.rbs +2 -0
- data/sig/generated/spreen_clean/application.rbs +74 -0
- data/sig/generated/spreen_clean/cli.rbs +57 -0
- data/sig/generated/spreen_clean/version.rbs +5 -0
- data/sig/generated/spreen_clean.rbs +7 -0
- data/sig/generated/test/application_test.rbs +31 -0
- data/sig/generated/test/cli_test.rbs +41 -0
- metadata +62 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 8e66f0b99e7c90e702fa7fbcb8dc08d095d4eb1205ebdf7611242c5511bf6397
|
|
4
|
+
data.tar.gz: 74b300c46a20ba4c124a371fc808de72d0208089f5106d999578ec1d2ebceaff
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 70301df0f5f2d0576e4bcbb21dc80cd53c2e4170a4d2ff8fde8bc3206f97191f10f0ec5023ca2dc39a7204bd93bd3a0092ba3d5fb6f09d304a9a05c9d2f2b2cc
|
|
7
|
+
data.tar.gz: 772a05fbb7f89c600777a2a7f96c590956eb03b271d799313f947c4fb4a44846a77872e4ac06874183434f10d06cb50e1c35e49aa66268d0caf9d9f70baa9ca3
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 - present @hayat01sh1da
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
## 1. Environment
|
|
2
|
+
|
|
3
|
+
- Ruby 4.0.6
|
|
4
|
+
- Gemfile 4.0.16
|
|
5
|
+
- Bundler 4.0.16
|
|
6
|
+
|
|
7
|
+
## 2. Installation
|
|
8
|
+
|
|
9
|
+
```command
|
|
10
|
+
$ gem install spreen-clean
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
For development, install the dependencies via Gemfile and Bundler:
|
|
14
|
+
|
|
15
|
+
```command
|
|
16
|
+
$ bundle install
|
|
17
|
+
$ bundle lock --add-checksums
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## 3. Execution
|
|
21
|
+
|
|
22
|
+
```command
|
|
23
|
+
$ file-clean '*.log' --dirname ./tmp
|
|
24
|
+
Target dirname is /home/hayat01sh1da/workspace/tmp
|
|
25
|
+
========== [DRY RUN] Total File Count to Clean: 2 ==========
|
|
26
|
+
========== [DRY RUN] Start Cleaning *.log ==========
|
|
27
|
+
========== [DRY RUN] Cleaning ./tmp/app.log ==========
|
|
28
|
+
========== [DRY RUN] Cleaning ./tmp/jobs/worker.log ==========
|
|
29
|
+
========== [DRY RUN] Cleaned *.log ==========
|
|
30
|
+
========== [DRY RUN] Total Cleaned File Count: 2 ==========
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The dry run above is the default. Once the list looks right, execute the deletion with `--mode e` (this cannot be undone):
|
|
34
|
+
|
|
35
|
+
```command
|
|
36
|
+
$ file-clean '*.log' --dirname ./tmp --mode e
|
|
37
|
+
Target dirname is /home/hayat01sh1da/workspace/tmp
|
|
38
|
+
========== [EXECUTION] Total File Count to Clean: 2 ==========
|
|
39
|
+
========== [EXECUTION] Start Cleaning *.log ==========
|
|
40
|
+
========== [EXECUTION] Cleaning ./tmp/app.log ==========
|
|
41
|
+
========== [EXECUTION] Cleaning ./tmp/jobs/worker.log ==========
|
|
42
|
+
========== [EXECUTION] Cleaned *.log ==========
|
|
43
|
+
========== [EXECUTION] Total Cleaned File Count: 2 ==========
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
With no arguments, `file-clean` dry-runs every file under the current directory (`PATTERN` defaults to `*`, `--dirname` to `.`).
|
|
47
|
+
|
|
48
|
+
Two guardrails back the dry-run default: a dirname resolving to a filesystem root (`/`, `C:\`, ...) is refused before anything is scanned, and when the execution mode matches more than 100 files the CLI asks for an explicit `y` first — pass `--yes` to skip the prompt in scripts:
|
|
49
|
+
|
|
50
|
+
```command
|
|
51
|
+
$ file-clean '*.log' --dirname ./tmp --mode e
|
|
52
|
+
About to delete 101 files (more than 100). Type `y` to proceed: n
|
|
53
|
+
Aborted the execution mode without deleting anything.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
As a library:
|
|
57
|
+
|
|
58
|
+
```ruby
|
|
59
|
+
require 'spreen_clean' # or require 'spreen-clean'
|
|
60
|
+
|
|
61
|
+
SpreenClean::Application.run(dirname: './tmp', pattern: '*.log') # dry run
|
|
62
|
+
SpreenClean::Application.run(dirname: './tmp', pattern: '*.log', mode: 'e') # execute
|
|
63
|
+
|
|
64
|
+
# The progress log goes to stdout by default; pass any IO to capture it.
|
|
65
|
+
require 'stringio'
|
|
66
|
+
io = StringIO.new
|
|
67
|
+
SpreenClean::Application.run(dirname: './tmp', pattern: '*.log', io:)
|
|
68
|
+
io.string # => "Target dirname is ...\n========== [DRY RUN] ..."
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## 4. Unit Test
|
|
72
|
+
|
|
73
|
+
```command
|
|
74
|
+
$ rake
|
|
75
|
+
Run options: --seed 4809
|
|
76
|
+
|
|
77
|
+
# Running:
|
|
78
|
+
|
|
79
|
+
..................
|
|
80
|
+
|
|
81
|
+
Finished in 13.872874s, 1.2975 runs/s, 4.1088 assertions/s.
|
|
82
|
+
|
|
83
|
+
18 runs, 57 assertions, 0 failures, 0 errors, 0 skips
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 5. Static Code Analysis
|
|
87
|
+
|
|
88
|
+
```command
|
|
89
|
+
$ bundle exec rubocop
|
|
90
|
+
Inspecting 12 files
|
|
91
|
+
............
|
|
92
|
+
|
|
93
|
+
12 files inspected, no offenses detected
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## 6. Type Checks
|
|
97
|
+
|
|
98
|
+
```command
|
|
99
|
+
$ bundle exec rbs-inline --output sig/generated/ .
|
|
100
|
+
🎉 Generated 7 RBS files under sig/generated
|
|
101
|
+
$ bundle exec steep check
|
|
102
|
+
# Type checking files:
|
|
103
|
+
|
|
104
|
+
..............
|
|
105
|
+
|
|
106
|
+
No type error detected. 🫖
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## 7. Build
|
|
110
|
+
|
|
111
|
+
```command
|
|
112
|
+
$ gem build spreen-clean.gemspec
|
|
113
|
+
$ gem install ./spreen-clean-0.1.0.gem
|
|
114
|
+
```
|
data/exe/file-clean
ADDED
data/lib/spreen-clean.rb
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
module SpreenClean
|
|
7
|
+
# Deletes files in a directory tree matching a glob pattern, with a dry-run
|
|
8
|
+
# mode that prints what would be removed without touching the filesystem.
|
|
9
|
+
class Application
|
|
10
|
+
class InvalidModeError < StandardError; end
|
|
11
|
+
class RootDirnameError < StandardError; end
|
|
12
|
+
|
|
13
|
+
# @rbs dirname: String
|
|
14
|
+
# @rbs pattern: String
|
|
15
|
+
# @rbs mode: String
|
|
16
|
+
# @rbs io: IO
|
|
17
|
+
# @rbs return: void
|
|
18
|
+
def self.run(dirname: '.', pattern: '*', mode: 'd', io: $stdout)
|
|
19
|
+
instance = new(dirname:, pattern:, mode:, io:)
|
|
20
|
+
instance.validate_mode!
|
|
21
|
+
instance.validate_dirname!
|
|
22
|
+
instance.run
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @rbs dirname: String
|
|
26
|
+
# @rbs pattern: String
|
|
27
|
+
# @rbs mode: String
|
|
28
|
+
# @rbs io: IO
|
|
29
|
+
# @rbs return: void
|
|
30
|
+
def initialize(dirname: '.', pattern: '*', mode: 'd', io: $stdout)
|
|
31
|
+
@dirname = dirname
|
|
32
|
+
@pattern = pattern
|
|
33
|
+
@mode = mode
|
|
34
|
+
@io = io
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# @rbs return: void
|
|
38
|
+
def validate_mode!
|
|
39
|
+
case mode
|
|
40
|
+
when 'd', 'e'
|
|
41
|
+
nil
|
|
42
|
+
else
|
|
43
|
+
raise InvalidModeError, "#{mode} is invalid mode. Provide either `d`(default) or `e`."
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Refuses filesystem roots (`/`, `C:/`, ...) so a stray `file-clean` can
|
|
48
|
+
# never sweep an entire drive.
|
|
49
|
+
# @rbs return: void
|
|
50
|
+
def validate_dirname!
|
|
51
|
+
return unless File.dirname(absolute_dirname) == absolute_dirname
|
|
52
|
+
|
|
53
|
+
raise RootDirnameError, "#{absolute_dirname} is a filesystem root. Provide a narrower dirname."
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Matched lazily so validation can refuse a dirname before any globbing happens.
|
|
57
|
+
# @rbs return: Array[String]
|
|
58
|
+
def files
|
|
59
|
+
@files ||= Dir.glob(File.join(dirname, '**', pattern))
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# @rbs return: void
|
|
63
|
+
def run
|
|
64
|
+
output "Target dirname is #{absolute_dirname}"
|
|
65
|
+
return announce_empty if files.empty?
|
|
66
|
+
|
|
67
|
+
announce_start
|
|
68
|
+
clean_files
|
|
69
|
+
announce_finish
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
attr_reader :dirname #: String
|
|
75
|
+
attr_reader :pattern #: String
|
|
76
|
+
attr_reader :mode #: String
|
|
77
|
+
attr_reader :io #: IO
|
|
78
|
+
|
|
79
|
+
# @rbs return: String
|
|
80
|
+
def absolute_dirname
|
|
81
|
+
@absolute_dirname ||= File.absolute_path(dirname)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @rbs return: void
|
|
85
|
+
def announce_empty
|
|
86
|
+
output "========== [#{exec_mode}] No #{pattern} Remains =========="
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# @rbs return: void
|
|
90
|
+
def announce_start
|
|
91
|
+
output "========== [#{exec_mode}] Total File Count to Clean: #{files.length} =========="
|
|
92
|
+
output "========== [#{exec_mode}] Start Cleaning #{pattern} =========="
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# @rbs return: void
|
|
96
|
+
def clean_files
|
|
97
|
+
files.each { |file| output "========== [#{exec_mode}] Cleaning #{file} ==========" }
|
|
98
|
+
FileUtils.rm_rf(files) if mode == 'e'
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# @rbs return: void
|
|
102
|
+
def announce_finish
|
|
103
|
+
output "========== [#{exec_mode}] Cleaned #{pattern} =========="
|
|
104
|
+
output "========== [#{exec_mode}] Total Cleaned File Count: #{files.length} =========="
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# @rbs return: String
|
|
108
|
+
def exec_mode
|
|
109
|
+
@exec_mode ||= mode == 'e' ? 'EXECUTION' : 'DRY RUN'
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# @rbs message: String
|
|
113
|
+
# @rbs return: void
|
|
114
|
+
def output(message)
|
|
115
|
+
io.puts message
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
4
|
+
require 'optparse'
|
|
5
|
+
require_relative 'version'
|
|
6
|
+
require_relative 'application'
|
|
7
|
+
|
|
8
|
+
module SpreenClean
|
|
9
|
+
# Command line interface behind the `file-clean` executable:
|
|
10
|
+
# `file-clean [PATTERN] [--dirname DIR] [--mode d|e] [--yes]`.
|
|
11
|
+
class CLI
|
|
12
|
+
MODES = %w[d e].freeze #: Array[String]
|
|
13
|
+
# The execution mode asks for confirmation above this many matches.
|
|
14
|
+
BULK_DELETE_THRESHOLD = 100 #: Integer
|
|
15
|
+
|
|
16
|
+
# @rbs argv: Array[String]
|
|
17
|
+
# @rbs return: Integer
|
|
18
|
+
def self.start(argv = ARGV)
|
|
19
|
+
new(argv).run
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# @rbs argv: Array[String]
|
|
23
|
+
# @rbs return: void
|
|
24
|
+
def initialize(argv)
|
|
25
|
+
@argv = argv.dup
|
|
26
|
+
@dirname = '.'
|
|
27
|
+
@mode = 'd'
|
|
28
|
+
@skip_confirmation = false
|
|
29
|
+
@action = :clean_files
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# @rbs return: Integer
|
|
33
|
+
def run
|
|
34
|
+
parser.parse!(argv)
|
|
35
|
+
__send__(action)
|
|
36
|
+
rescue Application::InvalidModeError, Application::RootDirnameError, OptionParser::ParseError => e
|
|
37
|
+
warn e.message
|
|
38
|
+
1
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
attr_reader :argv #: Array[String]
|
|
44
|
+
attr_reader :dirname #: String
|
|
45
|
+
attr_reader :mode #: String
|
|
46
|
+
attr_reader :skip_confirmation #: bool
|
|
47
|
+
attr_reader :action #: Symbol
|
|
48
|
+
|
|
49
|
+
# @rbs return: Integer
|
|
50
|
+
def clean_files
|
|
51
|
+
application = Application.new(dirname:, pattern:, mode:)
|
|
52
|
+
application.validate_mode!
|
|
53
|
+
application.validate_dirname!
|
|
54
|
+
unless confirmed?(application)
|
|
55
|
+
warn 'Aborted the execution mode without deleting anything.'
|
|
56
|
+
return 1
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
application.run
|
|
60
|
+
0
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Guards the execution mode against oversized sweeps: above
|
|
64
|
+
# BULK_DELETE_THRESHOLD matches it asks for an explicit `y`, unless
|
|
65
|
+
# `--yes` was given for scripted use.
|
|
66
|
+
# @rbs application: Application
|
|
67
|
+
# @rbs return: bool
|
|
68
|
+
def confirmed?(application)
|
|
69
|
+
return true unless mode == 'e'
|
|
70
|
+
return true if skip_confirmation
|
|
71
|
+
|
|
72
|
+
count = application.files.length
|
|
73
|
+
return true if count <= BULK_DELETE_THRESHOLD
|
|
74
|
+
|
|
75
|
+
print "About to delete #{count} files (more than #{BULK_DELETE_THRESHOLD}). Type `y` to proceed: "
|
|
76
|
+
answer = $stdin.gets
|
|
77
|
+
return false if answer.nil?
|
|
78
|
+
|
|
79
|
+
%w[y yes].include?(answer.strip.downcase)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# @rbs return: Integer
|
|
83
|
+
def print_version
|
|
84
|
+
puts VERSION
|
|
85
|
+
0
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# @rbs return: Integer
|
|
89
|
+
def print_help
|
|
90
|
+
puts parser
|
|
91
|
+
0
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# @rbs return: String
|
|
95
|
+
def pattern
|
|
96
|
+
argv.shift || '*'
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# @rbs return: OptionParser
|
|
100
|
+
def parser
|
|
101
|
+
@parser ||= OptionParser.new('Usage: file-clean [PATTERN] [options]') do |opt|
|
|
102
|
+
opt.on('--dirname DIR', 'Directory tree to clean (default: .)') { |value| @dirname = value }
|
|
103
|
+
opt.on('--mode MODE', MODES,
|
|
104
|
+
"Operation mode (#{MODES.join(' or ')}; d = dry run, e = execute, default: d)") { |value| @mode = value }
|
|
105
|
+
opt.on('--yes', 'Skip the bulk-delete confirmation in the execution mode') { @skip_confirmation = true }
|
|
106
|
+
opt.on('--version', 'Print the version') { @action = :print_version }
|
|
107
|
+
opt.on('-h', '--help', 'Print this help') { @action = :print_help }
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
data/lib/spreen_clean.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
4
|
+
require_relative 'spreen_clean/version'
|
|
5
|
+
require_relative 'spreen_clean/application'
|
|
6
|
+
require_relative 'spreen_clean/cli'
|
|
7
|
+
|
|
8
|
+
# Spreens your workspace clean — the falcon's stoop, then the preen: deletes
|
|
9
|
+
# files in a directory tree matching a glob pattern, defaulting to a dry run
|
|
10
|
+
# that prints what would be removed before anything is touched.
|
|
11
|
+
module SpreenClean
|
|
12
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Generated from lib/spreen_clean/application.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module SpreenClean
|
|
4
|
+
# Deletes files in a directory tree matching a glob pattern, with a dry-run
|
|
5
|
+
# mode that prints what would be removed without touching the filesystem.
|
|
6
|
+
class Application
|
|
7
|
+
class InvalidModeError < StandardError
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class RootDirnameError < StandardError
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @rbs dirname: String
|
|
14
|
+
# @rbs pattern: String
|
|
15
|
+
# @rbs mode: String
|
|
16
|
+
# @rbs io: IO
|
|
17
|
+
# @rbs return: void
|
|
18
|
+
def self.run: (?dirname: String, ?pattern: String, ?mode: String, ?io: IO) -> void
|
|
19
|
+
|
|
20
|
+
# @rbs dirname: String
|
|
21
|
+
# @rbs pattern: String
|
|
22
|
+
# @rbs mode: String
|
|
23
|
+
# @rbs io: IO
|
|
24
|
+
# @rbs return: void
|
|
25
|
+
def initialize: (?dirname: String, ?pattern: String, ?mode: String, ?io: IO) -> void
|
|
26
|
+
|
|
27
|
+
# @rbs return: void
|
|
28
|
+
def validate_mode!: () -> void
|
|
29
|
+
|
|
30
|
+
# Refuses filesystem roots (`/`, `C:/`, ...) so a stray `file-clean` can
|
|
31
|
+
# never sweep an entire drive.
|
|
32
|
+
# @rbs return: void
|
|
33
|
+
def validate_dirname!: () -> void
|
|
34
|
+
|
|
35
|
+
# Matched lazily so validation can refuse a dirname before any globbing happens.
|
|
36
|
+
# @rbs return: Array[String]
|
|
37
|
+
def files: () -> Array[String]
|
|
38
|
+
|
|
39
|
+
# @rbs return: void
|
|
40
|
+
def run: () -> void
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
attr_reader dirname: String
|
|
45
|
+
|
|
46
|
+
attr_reader pattern: String
|
|
47
|
+
|
|
48
|
+
attr_reader mode: String
|
|
49
|
+
|
|
50
|
+
attr_reader io: IO
|
|
51
|
+
|
|
52
|
+
# @rbs return: String
|
|
53
|
+
def absolute_dirname: () -> String
|
|
54
|
+
|
|
55
|
+
# @rbs return: void
|
|
56
|
+
def announce_empty: () -> void
|
|
57
|
+
|
|
58
|
+
# @rbs return: void
|
|
59
|
+
def announce_start: () -> void
|
|
60
|
+
|
|
61
|
+
# @rbs return: void
|
|
62
|
+
def clean_files: () -> void
|
|
63
|
+
|
|
64
|
+
# @rbs return: void
|
|
65
|
+
def announce_finish: () -> void
|
|
66
|
+
|
|
67
|
+
# @rbs return: String
|
|
68
|
+
def exec_mode: () -> String
|
|
69
|
+
|
|
70
|
+
# @rbs message: String
|
|
71
|
+
# @rbs return: void
|
|
72
|
+
def output: (String message) -> void
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Generated from lib/spreen_clean/cli.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
module SpreenClean
|
|
4
|
+
# Command line interface behind the `file-clean` executable:
|
|
5
|
+
# `file-clean [PATTERN] [--dirname DIR] [--mode d|e] [--yes]`.
|
|
6
|
+
class CLI
|
|
7
|
+
MODES: Array[String]
|
|
8
|
+
|
|
9
|
+
# The execution mode asks for confirmation above this many matches.
|
|
10
|
+
BULK_DELETE_THRESHOLD: Integer
|
|
11
|
+
|
|
12
|
+
# @rbs argv: Array[String]
|
|
13
|
+
# @rbs return: Integer
|
|
14
|
+
def self.start: (?Array[String] argv) -> Integer
|
|
15
|
+
|
|
16
|
+
# @rbs argv: Array[String]
|
|
17
|
+
# @rbs return: void
|
|
18
|
+
def initialize: (Array[String] argv) -> void
|
|
19
|
+
|
|
20
|
+
# @rbs return: Integer
|
|
21
|
+
def run: () -> Integer
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
attr_reader argv: Array[String]
|
|
26
|
+
|
|
27
|
+
attr_reader dirname: String
|
|
28
|
+
|
|
29
|
+
attr_reader mode: String
|
|
30
|
+
|
|
31
|
+
attr_reader skip_confirmation: bool
|
|
32
|
+
|
|
33
|
+
attr_reader action: Symbol
|
|
34
|
+
|
|
35
|
+
# @rbs return: Integer
|
|
36
|
+
def clean_files: () -> Integer
|
|
37
|
+
|
|
38
|
+
# Guards the execution mode against oversized sweeps: above
|
|
39
|
+
# BULK_DELETE_THRESHOLD matches it asks for an explicit `y`, unless
|
|
40
|
+
# `--yes` was given for scripted use.
|
|
41
|
+
# @rbs application: Application
|
|
42
|
+
# @rbs return: bool
|
|
43
|
+
def confirmed?: (Application application) -> bool
|
|
44
|
+
|
|
45
|
+
# @rbs return: Integer
|
|
46
|
+
def print_version: () -> Integer
|
|
47
|
+
|
|
48
|
+
# @rbs return: Integer
|
|
49
|
+
def print_help: () -> Integer
|
|
50
|
+
|
|
51
|
+
# @rbs return: String
|
|
52
|
+
def pattern: () -> String
|
|
53
|
+
|
|
54
|
+
# @rbs return: OptionParser
|
|
55
|
+
def parser: () -> OptionParser
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Generated from lib/spreen_clean.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
# Spreens your workspace clean — the falcon's stoop, then the preen: deletes
|
|
4
|
+
# files in a directory tree matching a glob pattern, defaulting to a dry run
|
|
5
|
+
# that prints what would be removed before anything is touched.
|
|
6
|
+
module SpreenClean
|
|
7
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Generated from test/application_test.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class ApplicationTest < Minitest::Test
|
|
4
|
+
def setup: () -> untyped
|
|
5
|
+
|
|
6
|
+
def teardown: () -> untyped
|
|
7
|
+
|
|
8
|
+
def test_invalid_mode: () -> untyped
|
|
9
|
+
|
|
10
|
+
def test_run_in_dry_run_mode_with_default_mode: () -> untyped
|
|
11
|
+
|
|
12
|
+
def test_run_in_dry_run_mode_with_explicit_d_mode: () -> untyped
|
|
13
|
+
|
|
14
|
+
def test_run_in_exec_mode: () -> untyped
|
|
15
|
+
|
|
16
|
+
def test_run_announces_the_dry_run_progress: () -> untyped
|
|
17
|
+
|
|
18
|
+
def test_run_announces_the_execution_progress: () -> untyped
|
|
19
|
+
|
|
20
|
+
def test_run_announces_empty_when_nothing_matches: () -> untyped
|
|
21
|
+
|
|
22
|
+
def test_run_refuses_a_filesystem_root: () -> untyped
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
attr_reader dirname: untyped
|
|
27
|
+
|
|
28
|
+
attr_reader pattern: untyped
|
|
29
|
+
|
|
30
|
+
attr_reader io: untyped
|
|
31
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Generated from test/cli_test.rb with RBS::Inline
|
|
2
|
+
|
|
3
|
+
class CLITest < Minitest::Test
|
|
4
|
+
def setup: () -> untyped
|
|
5
|
+
|
|
6
|
+
def teardown: () -> untyped
|
|
7
|
+
|
|
8
|
+
def test_dry_run_by_default: () -> untyped
|
|
9
|
+
|
|
10
|
+
def test_execution_mode: () -> untyped
|
|
11
|
+
|
|
12
|
+
def test_default_pattern_matches_everything: () -> untyped
|
|
13
|
+
|
|
14
|
+
def test_invalid_mode: () -> untyped
|
|
15
|
+
|
|
16
|
+
def test_root_dirname_refused: () -> untyped
|
|
17
|
+
|
|
18
|
+
def test_bulk_execution_aborts_when_declined: () -> untyped
|
|
19
|
+
|
|
20
|
+
def test_bulk_execution_proceeds_when_confirmed: () -> untyped
|
|
21
|
+
|
|
22
|
+
def test_bulk_execution_skips_confirmation_with_yes_flag: () -> untyped
|
|
23
|
+
|
|
24
|
+
def test_version: () -> untyped
|
|
25
|
+
|
|
26
|
+
def test_help: () -> untyped
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
attr_reader dirname: untyped
|
|
31
|
+
|
|
32
|
+
attr_reader pattern: untyped
|
|
33
|
+
|
|
34
|
+
# Tops the fixture up beyond BULK_DELETE_THRESHOLD (101 files in total).
|
|
35
|
+
def make_bulk_files: () -> untyped
|
|
36
|
+
|
|
37
|
+
# @rbs input: String
|
|
38
|
+
# @rbs &block: () -> [String, String]
|
|
39
|
+
# @rbs return: [String, String]
|
|
40
|
+
def with_stdin: (String input) { () -> [ String, String ] } -> [ String, String ]
|
|
41
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: spreen-clean
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- hayat01sh1da
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: Spreen — the falcon's stoop, then the preen. Deletes files in a directory
|
|
13
|
+
tree matching a glob pattern via the file-clean CLI, defaulting to a dry-run mode
|
|
14
|
+
that prints every file that would be removed; pass `--mode e` to actually delete
|
|
15
|
+
them.
|
|
16
|
+
executables:
|
|
17
|
+
- file-clean
|
|
18
|
+
extensions: []
|
|
19
|
+
extra_rdoc_files: []
|
|
20
|
+
files:
|
|
21
|
+
- LICENSE.txt
|
|
22
|
+
- README.md
|
|
23
|
+
- exe/file-clean
|
|
24
|
+
- lib/spreen-clean.rb
|
|
25
|
+
- lib/spreen_clean.rb
|
|
26
|
+
- lib/spreen_clean/application.rb
|
|
27
|
+
- lib/spreen_clean/cli.rb
|
|
28
|
+
- lib/spreen_clean/version.rb
|
|
29
|
+
- sig/generated/spreen-clean.rbs
|
|
30
|
+
- sig/generated/spreen_clean.rbs
|
|
31
|
+
- sig/generated/spreen_clean/application.rbs
|
|
32
|
+
- sig/generated/spreen_clean/cli.rbs
|
|
33
|
+
- sig/generated/spreen_clean/version.rbs
|
|
34
|
+
- sig/generated/test/application_test.rbs
|
|
35
|
+
- sig/generated/test/cli_test.rbs
|
|
36
|
+
homepage: https://github.com/hayat01sh1da/spreen-clean
|
|
37
|
+
licenses:
|
|
38
|
+
- MIT
|
|
39
|
+
metadata:
|
|
40
|
+
homepage_uri: https://github.com/hayat01sh1da/spreen-clean
|
|
41
|
+
source_code_uri: https://github.com/hayat01sh1da/spreen-clean
|
|
42
|
+
changelog_uri: https://github.com/hayat01sh1da/spreen-clean/blob/master/CHANGELOG.md
|
|
43
|
+
bug_tracker_uri: https://github.com/hayat01sh1da/spreen-clean/issues
|
|
44
|
+
rubygems_mfa_required: 'true'
|
|
45
|
+
rdoc_options: []
|
|
46
|
+
require_paths:
|
|
47
|
+
- lib
|
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
49
|
+
requirements:
|
|
50
|
+
- - ">="
|
|
51
|
+
- !ruby/object:Gem::Version
|
|
52
|
+
version: '3.4'
|
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
54
|
+
requirements:
|
|
55
|
+
- - ">="
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: '0'
|
|
58
|
+
requirements: []
|
|
59
|
+
rubygems_version: 4.0.16
|
|
60
|
+
specification_version: 4
|
|
61
|
+
summary: 'Spreen your workspace: delete files matching a glob pattern, dry run first.'
|
|
62
|
+
test_files: []
|