immosquare-cleaner 0.1.116 → 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 +4 -4
- data/bin/immosquare-cleaner +16 -4
- data/lib/immosquare-cleaner/directory_cleaner.rb +147 -0
- data/lib/immosquare-cleaner/processors/base.rb +13 -5
- data/lib/immosquare-cleaner/processors/prettier.rb +18 -0
- data/lib/immosquare-cleaner/processors/rust.rb +80 -0
- data/lib/immosquare-cleaner/processors/toml.rb +37 -0
- data/lib/immosquare-cleaner/version.rb +1 -1
- data/lib/immosquare-cleaner.rb +16 -4
- data/linters/erb-lint-4.0.7.yml +27 -0
- data/linters/erb-lint.yml +9 -0
- data/linters/eslint.config.mjs +4 -0
- data/linters/js-erb-lint-4.0.7.yml +26 -0
- data/linters/rubocop-4.0.7.yml +219 -0
- data/package.json +6 -6
- metadata +8 -4
- data/lib/immosquare-cleaner/railtie.rb +0 -9
- data/lib/tasks/immosquare_cleaner.rake +0 -76
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fe48e81e3af7200a3967f640a3f3a34f7632a32d71323b2829841516ad5f8cb8
|
|
4
|
+
data.tar.gz: 571422d60f872ce01a3e3896260b4fee7d0e2282f16978fe7cfd18e2530a1a23
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9f9ec67de3055d93376abc0df67abcc4368e661a4f46a0bd702c9d679407407119364f3b4a68817e39b8ec8ae888ae3365eeb3e692b453317396e21abd0ab875
|
|
7
|
+
data.tar.gz: e32bd136ee29441e48f17af89cac59741e11e931b7d335da8a8ccf8be3914deb4f4c558b75a99f85c108c66f18189ad23f3bca93cd7bfa354a25679f1af3a084
|
data/bin/immosquare-cleaner
CHANGED
|
@@ -27,7 +27,7 @@ options = {}
|
|
|
27
27
|
## optparse is a standard library of ruby, it's used to parse command line
|
|
28
28
|
##============================================================##
|
|
29
29
|
OptionParser.new do |parser|
|
|
30
|
-
parser.banner = "Usage: immosquare-cleaner [options] file"
|
|
30
|
+
parser.banner = "Usage: immosquare-cleaner [options] file|directory"
|
|
31
31
|
parser.on("-p", "--prevent-concurrent-write", "Prevent concurrent write") do
|
|
32
32
|
options[:prevent_concurrent_write] = true
|
|
33
33
|
end
|
|
@@ -42,7 +42,7 @@ end.parse!
|
|
|
42
42
|
##============================================================##
|
|
43
43
|
file_path = ARGV[0]
|
|
44
44
|
if !file_path
|
|
45
|
-
puts("Error: Please provide a file path.")
|
|
45
|
+
puts("Error: Please provide a file or directory path.")
|
|
46
46
|
exit(1)
|
|
47
47
|
end
|
|
48
48
|
|
|
@@ -54,6 +54,11 @@ if !File.exist?(file_path)
|
|
|
54
54
|
exit(1)
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
if File.directory?(file_path) && options[:prevent_concurrent_write]
|
|
58
|
+
puts("Error: --prevent-concurrent-write only applies to a single file.")
|
|
59
|
+
exit(1)
|
|
60
|
+
end
|
|
61
|
+
|
|
57
62
|
##============================================================##
|
|
58
63
|
## Check if node_modules exists, if not we launch bun install
|
|
59
64
|
##============================================================##
|
|
@@ -73,7 +78,14 @@ end
|
|
|
73
78
|
## We can now call the clean method, passing the file absolute path and options
|
|
74
79
|
##============================================================##
|
|
75
80
|
file_path = File.expand_path(file_path)
|
|
76
|
-
if
|
|
81
|
+
if File.directory?(file_path)
|
|
82
|
+
##============================================================##
|
|
83
|
+
## Run from the cleaned directory: the project's
|
|
84
|
+
## config/initializers/immosquare-cleaner.rb (exclude_files) is
|
|
85
|
+
## looked up from the working directory
|
|
86
|
+
##============================================================##
|
|
87
|
+
Dir.chdir(file_path) { ImmosquareCleaner.clean_directory(file_path) }
|
|
88
|
+
elsif options[:prevent_concurrent_write]
|
|
77
89
|
##============================================================##
|
|
78
90
|
## concurrent write detection
|
|
79
91
|
## wait 2s for the ide to do a pre-processing, then 3 cases :
|
|
@@ -86,7 +98,7 @@ if options[:prevent_concurrent_write]
|
|
|
86
98
|
temp_path = "/tmp/#{file_path}"
|
|
87
99
|
FileUtils.mkdir_p(File.dirname(temp_path))
|
|
88
100
|
FileUtils.copy(file_path, temp_path)
|
|
89
|
-
ImmosquareCleaner.clean(temp_path)
|
|
101
|
+
ImmosquareCleaner.clean(temp_path, file_path)
|
|
90
102
|
if Digest::MD5.file(file_path) != before
|
|
91
103
|
puts("Original file has changed, giving up cleaning.")
|
|
92
104
|
elsif Digest::MD5.file(temp_path) == before
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
require "parallel"
|
|
2
|
+
require "etc"
|
|
3
|
+
require "open3"
|
|
4
|
+
|
|
5
|
+
module ImmosquareCleaner
|
|
6
|
+
##============================================================##
|
|
7
|
+
## Cleans every source file of a repository in one run, whatever
|
|
8
|
+
## its stack (Rails app, gem, Rust/Tauri app, JS package...).
|
|
9
|
+
##
|
|
10
|
+
## Files come from `git ls-files` (tracked + untracked, minus
|
|
11
|
+
## .gitignore), so each stack's build output (target/, dist/,
|
|
12
|
+
## app/assets/builds...) is skipped by the repository's own
|
|
13
|
+
## rules. Outside a git repository, every file under the root
|
|
14
|
+
## is listed and EXCLUDED_DIRS does the filtering.
|
|
15
|
+
##
|
|
16
|
+
## Only files with a dedicated processor or a Prettier-supported
|
|
17
|
+
## extension are cleaned: the Prettier fallback of the
|
|
18
|
+
## single-file clean would otherwise run on LICENSE, .env...
|
|
19
|
+
##
|
|
20
|
+
## Parallelized via threads (linters shell out, so the GVL is
|
|
21
|
+
## released). Override with: CLEANER_THREADS=N
|
|
22
|
+
##============================================================##
|
|
23
|
+
class DirectoryCleaner
|
|
24
|
+
|
|
25
|
+
##============================================================##
|
|
26
|
+
## EXCLUDED_DIRS : folder names skipped at any depth
|
|
27
|
+
## EXCLUDED_PATHS : paths relative to the root — generated or
|
|
28
|
+
## vendored content that repositories commit
|
|
29
|
+
## (db/schema.rb, Tauri schemas...) and test
|
|
30
|
+
## fixtures that must stay as written
|
|
31
|
+
##============================================================##
|
|
32
|
+
EXCLUDED_DIRS = [
|
|
33
|
+
".git",
|
|
34
|
+
"build",
|
|
35
|
+
"coverage",
|
|
36
|
+
"dist",
|
|
37
|
+
"log",
|
|
38
|
+
"node_modules",
|
|
39
|
+
"target",
|
|
40
|
+
"tmp",
|
|
41
|
+
"vendor"
|
|
42
|
+
].freeze
|
|
43
|
+
EXCLUDED_PATHS = [
|
|
44
|
+
"app/assets/builds",
|
|
45
|
+
"app/assets/fonts",
|
|
46
|
+
"app/assets/images",
|
|
47
|
+
"db",
|
|
48
|
+
"public",
|
|
49
|
+
"src-tauri/gen",
|
|
50
|
+
"src-tauri/permissions/autogenerated",
|
|
51
|
+
"test"
|
|
52
|
+
].freeze
|
|
53
|
+
EXCLUDED_FILES = [
|
|
54
|
+
"npm-shrinkwrap.json",
|
|
55
|
+
"package-lock.json",
|
|
56
|
+
"pnpm-lock.yaml"
|
|
57
|
+
].freeze
|
|
58
|
+
EXCLUDED_SUFFIXES = [
|
|
59
|
+
".min.css",
|
|
60
|
+
".min.js"
|
|
61
|
+
].freeze
|
|
62
|
+
|
|
63
|
+
def self.run(root)
|
|
64
|
+
new(root).run
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
attr_reader :root
|
|
68
|
+
|
|
69
|
+
def initialize(root)
|
|
70
|
+
@root = File.expand_path(root)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def run
|
|
74
|
+
paths = file_paths
|
|
75
|
+
total = paths.size
|
|
76
|
+
mutex = Mutex.new
|
|
77
|
+
index = 0
|
|
78
|
+
threads = ENV["CLEANER_THREADS"]&.to_i || [Etc.nprocessors, 8].min
|
|
79
|
+
started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
80
|
+
|
|
81
|
+
puts("Cleaning #{total} files in #{root} with #{threads} threads...")
|
|
82
|
+
|
|
83
|
+
Parallel.each(paths, :in_threads => threads) do |file_path|
|
|
84
|
+
i = mutex.synchronize { index += 1 }
|
|
85
|
+
puts("#{i}/#{total} - #{file_path}")
|
|
86
|
+
ImmosquareCleaner.clean(file_path)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - started
|
|
90
|
+
mins = (elapsed / 60).to_i
|
|
91
|
+
secs = (elapsed % 60).round(1)
|
|
92
|
+
puts("Done in #{mins}m #{secs}s (#{total} files, #{threads} threads)")
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def file_paths
|
|
96
|
+
listed_files(root).sort
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
private
|
|
100
|
+
|
|
101
|
+
##============================================================##
|
|
102
|
+
## Paths are relative to `dir`, so EXCLUDED_PATHS applies from
|
|
103
|
+
## each repository's own root. git lists a nested repository
|
|
104
|
+
## (`gem/`) or a submodule as a single directory entry without
|
|
105
|
+
## descending into it: it is walked with its own git listing,
|
|
106
|
+
## otherwise a parent folder of repositories cleans nothing
|
|
107
|
+
##============================================================##
|
|
108
|
+
def listed_files(dir)
|
|
109
|
+
relative_paths(dir).flat_map do |entry|
|
|
110
|
+
path = entry.delete_suffix("/")
|
|
111
|
+
absolute_path = File.join(dir, path)
|
|
112
|
+
directory = File.directory?(absolute_path)
|
|
113
|
+
next [] if File.symlink?(absolute_path) || excluded?(path, directory)
|
|
114
|
+
next listed_files(absolute_path) if directory
|
|
115
|
+
|
|
116
|
+
File.file?(absolute_path) && ImmosquareCleaner.supported?(absolute_path) ? [absolute_path] : []
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
##============================================================##
|
|
121
|
+
## --cached lists deleted-but-uncommitted files as well:
|
|
122
|
+
## File.file? filters them out afterwards. The glob fallback
|
|
123
|
+
## keeps files only, a listed directory being walked again
|
|
124
|
+
##============================================================##
|
|
125
|
+
def relative_paths(dir)
|
|
126
|
+
output, status = git_ls_files(dir)
|
|
127
|
+
return output.split("\0").uniq if status&.success?
|
|
128
|
+
|
|
129
|
+
Dir.glob("**/*", :base => dir).reject {|path| File.directory?(File.join(dir, path)) }
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def git_ls_files(dir)
|
|
133
|
+
Open3.capture2("git", "-C", dir, "ls-files", "-z", "--cached", "--others", "--exclude-standard", :err => File::NULL)
|
|
134
|
+
rescue Errno::ENOENT
|
|
135
|
+
nil
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def excluded?(path, directory)
|
|
139
|
+
segments = path.split("/")
|
|
140
|
+
folders = directory ? segments : segments[0..-2]
|
|
141
|
+
return true if folders.intersect?(EXCLUDED_DIRS) || "#{path}/".start_with?(*EXCLUDED_PATHS.map {|excluded| "#{excluded}/" })
|
|
142
|
+
|
|
143
|
+
!directory && (EXCLUDED_FILES.include?(segments.last) || segments.last.end_with?(*EXCLUDED_SUFFIXES))
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
end
|
|
147
|
+
end
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
module ImmosquareCleaner
|
|
2
2
|
module Processors
|
|
3
3
|
class Base
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
|
|
5
|
+
def self.run(file_path, origin_path = nil)
|
|
6
|
+
new(file_path, origin_path).run
|
|
6
7
|
end
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
##============================================================##
|
|
10
|
+
## origin_path : location of the file in its project, used to
|
|
11
|
+
## look up project config (Cargo.toml...). Differs
|
|
12
|
+
## from file_path when a /tmp copy is cleaned (-p)
|
|
13
|
+
##============================================================##
|
|
14
|
+
attr_reader :file_path, :origin_path
|
|
9
15
|
|
|
10
|
-
def initialize(file_path)
|
|
11
|
-
@file_path
|
|
16
|
+
def initialize(file_path, origin_path = nil)
|
|
17
|
+
@file_path = file_path
|
|
18
|
+
@origin_path = origin_path || file_path
|
|
12
19
|
end
|
|
13
20
|
|
|
14
21
|
def run
|
|
@@ -31,6 +38,7 @@ module ImmosquareCleaner
|
|
|
31
38
|
def normalize_last_line(path = file_path)
|
|
32
39
|
File.normalize_last_line(path)
|
|
33
40
|
end
|
|
41
|
+
|
|
34
42
|
end
|
|
35
43
|
end
|
|
36
44
|
end
|
|
@@ -10,6 +10,24 @@ module ImmosquareCleaner
|
|
|
10
10
|
##============================================================##
|
|
11
11
|
class Prettier < Base
|
|
12
12
|
|
|
13
|
+
##============================================================##
|
|
14
|
+
## Extensions Prettier formats out of the box. Used by the
|
|
15
|
+
## directory clean to decide which fallback files to send;
|
|
16
|
+
## a single-file clean still falls back for any extension
|
|
17
|
+
##============================================================##
|
|
18
|
+
EXTENSIONS = [
|
|
19
|
+
".css",
|
|
20
|
+
".graphql",
|
|
21
|
+
".gql",
|
|
22
|
+
".handlebars",
|
|
23
|
+
".hbs",
|
|
24
|
+
".less",
|
|
25
|
+
".scss",
|
|
26
|
+
".vue",
|
|
27
|
+
".yaml",
|
|
28
|
+
".yml"
|
|
29
|
+
].freeze
|
|
30
|
+
|
|
13
31
|
def run
|
|
14
32
|
##============================================================##
|
|
15
33
|
## Prettier flags:
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require "open3"
|
|
2
|
+
|
|
3
|
+
module ImmosquareCleaner
|
|
4
|
+
module Processors
|
|
5
|
+
class Rust < Base
|
|
6
|
+
|
|
7
|
+
DEFAULT_EDITION = "2024".freeze
|
|
8
|
+
EDITION_REGEX = /^\s*edition\s*=\s*["'](\d{4})["']/
|
|
9
|
+
CONFIG_FILES = [".rustfmt.toml", "rustfmt.toml"].freeze
|
|
10
|
+
GLOBAL_CONFIG_DIRS = [
|
|
11
|
+
Dir.home,
|
|
12
|
+
File.join(ENV.fetch("XDG_CONFIG_HOME", File.join(Dir.home, ".config")), "rustfmt"),
|
|
13
|
+
File.join(Dir.home, "Library", "Application Support", "rustfmt")
|
|
14
|
+
].freeze
|
|
15
|
+
|
|
16
|
+
def self.match?(file_path)
|
|
17
|
+
file_path.end_with?(".rs")
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def run
|
|
21
|
+
if !system("which rustfmt > /dev/null 2>&1")
|
|
22
|
+
warn("ERROR: rustfmt is not installed. Please install it with: rustup component add rustfmt")
|
|
23
|
+
return
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
##============================================================##
|
|
27
|
+
## The file goes through stdin: given a path, rustfmt also
|
|
28
|
+
## rewrites every child module declared with `mod foo;`
|
|
29
|
+
## (skip_children is nightly only). In stdin mode rustfmt
|
|
30
|
+
## looks for its config from the cwd, so it is passed
|
|
31
|
+
## explicitly.
|
|
32
|
+
## --edition : standalone rustfmt parses as edition 2015
|
|
33
|
+
## and rejects `async fn` & co
|
|
34
|
+
## --config-path : the project or global rustfmt.toml
|
|
35
|
+
## --config : immosquare default (2-space indent), only
|
|
36
|
+
## when no rustfmt.toml exists — it would
|
|
37
|
+
## override the file's values
|
|
38
|
+
##============================================================##
|
|
39
|
+
config = rustfmt_config
|
|
40
|
+
cmd = ["rustfmt", "--edition", edition, "--emit", "stdout"]
|
|
41
|
+
cmd += config ? ["--config-path", config] : ["--config", "tab_spaces=2"]
|
|
42
|
+
output, status = Open3.capture2(*cmd, :stdin_data => File.read(file_path), :chdir => ImmosquareCleaner.gem_root)
|
|
43
|
+
File.write(file_path, output) if status.success?
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
##============================================================##
|
|
49
|
+
## A workspace member usually declares `edition.workspace = true`
|
|
50
|
+
## (not matched by EDITION_REGEX): the lookup keeps going up to
|
|
51
|
+
## the workspace root, which declares it in [workspace.package]
|
|
52
|
+
##============================================================##
|
|
53
|
+
def edition
|
|
54
|
+
ancestor_dirs.each do |dir|
|
|
55
|
+
cargo_toml = File.join(dir, "Cargo.toml")
|
|
56
|
+
next if !File.file?(cargo_toml)
|
|
57
|
+
|
|
58
|
+
found = File.read(cargo_toml)[EDITION_REGEX, 1]
|
|
59
|
+
return found if found
|
|
60
|
+
end
|
|
61
|
+
DEFAULT_EDITION
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
##============================================================##
|
|
65
|
+
## Same lookup order as rustfmt: closest directory first, then
|
|
66
|
+
## the user's global config
|
|
67
|
+
##============================================================##
|
|
68
|
+
def rustfmt_config
|
|
69
|
+
(ancestor_dirs + GLOBAL_CONFIG_DIRS).product(CONFIG_FILES).map {|dir, name| File.join(dir, name) }.find {|path| File.file?(path) }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def ancestor_dirs
|
|
73
|
+
dirs = [File.dirname(File.expand_path(origin_path))]
|
|
74
|
+
dirs << File.dirname(dirs.last) while File.dirname(dirs.last) != dirs.last
|
|
75
|
+
dirs
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require "shellwords"
|
|
2
|
+
|
|
3
|
+
module ImmosquareCleaner
|
|
4
|
+
module Processors
|
|
5
|
+
class Toml < Base
|
|
6
|
+
|
|
7
|
+
def self.match?(file_path)
|
|
8
|
+
file_path.end_with?(".toml")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def run
|
|
12
|
+
if !system("which taplo > /dev/null 2>&1")
|
|
13
|
+
warn("ERROR: taplo is not installed. Please install it with: brew install taplo")
|
|
14
|
+
return
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
##============================================================##
|
|
18
|
+
## RUST_LOG=warn : taplo logs its file discovery at INFO level
|
|
19
|
+
## on every run; syntax errors stay visible
|
|
20
|
+
## taplo flags:
|
|
21
|
+
## --no-auto-config : taplo looks for .taplo.toml in the
|
|
22
|
+
## working directory, which is the gem
|
|
23
|
+
## root here, not the edited project
|
|
24
|
+
## -o align_entries=true : align the `=` of consecutive keys
|
|
25
|
+
## like the other immosquare linters
|
|
26
|
+
## -o indent_string=" " : 2-space indent for nested arrays
|
|
27
|
+
## -o column_width=10000 : never wrap, same as prettier.yml
|
|
28
|
+
## -o array_auto_collapse=false : keep multi-line arrays as
|
|
29
|
+
## written (workspace members...)
|
|
30
|
+
##============================================================##
|
|
31
|
+
options = ["align_entries=true", "indent_string= ", "column_width=10000", "array_auto_collapse=false"].map {|option| "-o #{Shellwords.escape(option)}" }.join(" ")
|
|
32
|
+
launch_cmds(["RUST_LOG=warn taplo fmt --no-auto-config --colors never #{options} #{Shellwords.escape(file_path)}"])
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/immosquare-cleaner.rb
CHANGED
|
@@ -6,7 +6,7 @@ require "immosquare-extensions"
|
|
|
6
6
|
require "fileutils"
|
|
7
7
|
require_relative "immosquare-cleaner/configuration"
|
|
8
8
|
require_relative "immosquare-cleaner/markdown"
|
|
9
|
-
require_relative "immosquare-cleaner/
|
|
9
|
+
require_relative "immosquare-cleaner/directory_cleaner"
|
|
10
10
|
|
|
11
11
|
##============================================================##
|
|
12
12
|
## Processors
|
|
@@ -18,6 +18,8 @@ require_relative "immosquare-cleaner/processors/javascript"
|
|
|
18
18
|
require_relative "immosquare-cleaner/processors/json"
|
|
19
19
|
require_relative "immosquare-cleaner/processors/markdown"
|
|
20
20
|
require_relative "immosquare-cleaner/processors/shell"
|
|
21
|
+
require_relative "immosquare-cleaner/processors/rust"
|
|
22
|
+
require_relative "immosquare-cleaner/processors/toml"
|
|
21
23
|
require_relative "immosquare-cleaner/processors/yaml"
|
|
22
24
|
require_relative "immosquare-cleaner/processors/prettier"
|
|
23
25
|
|
|
@@ -61,7 +63,7 @@ module ImmosquareCleaner
|
|
|
61
63
|
yield(configuration)
|
|
62
64
|
end
|
|
63
65
|
|
|
64
|
-
def clean(file_path)
|
|
66
|
+
def clean(file_path, origin_path = nil)
|
|
65
67
|
##============================================================##
|
|
66
68
|
## Ensure linter configurations are ready
|
|
67
69
|
##============================================================##
|
|
@@ -75,13 +77,21 @@ module ImmosquareCleaner
|
|
|
75
77
|
|
|
76
78
|
begin
|
|
77
79
|
processor = processor_for(file_path)
|
|
78
|
-
processor.run(file_path)
|
|
80
|
+
processor.run(file_path, origin_path)
|
|
79
81
|
rescue StandardError => e
|
|
80
82
|
warn("Error cleaning #{file_path}: #{e.message}")
|
|
81
83
|
warn(e.backtrace&.join("\n") || "(no backtrace)")
|
|
82
84
|
end
|
|
83
85
|
end
|
|
84
86
|
|
|
87
|
+
def clean_directory(root)
|
|
88
|
+
DirectoryCleaner.run(root)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def supported?(file_path)
|
|
92
|
+
PROCESSORS.any? {|processor| processor.match?(file_path) } || file_path.end_with?(*Processors::Prettier::EXTENSIONS)
|
|
93
|
+
end
|
|
94
|
+
|
|
85
95
|
def gem_root
|
|
86
96
|
File.expand_path("..", __dir__)
|
|
87
97
|
end
|
|
@@ -110,7 +120,9 @@ module ImmosquareCleaner
|
|
|
110
120
|
Processors::Javascript,
|
|
111
121
|
Processors::Json,
|
|
112
122
|
Processors::Markdown,
|
|
113
|
-
Processors::Shell
|
|
123
|
+
Processors::Shell,
|
|
124
|
+
Processors::Rust,
|
|
125
|
+
Processors::Toml
|
|
114
126
|
].freeze
|
|
115
127
|
|
|
116
128
|
def processor_for(file_path)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
EnableDefaultLinters: true
|
|
3
|
+
linters:
|
|
4
|
+
NoJavascriptTagHelper:
|
|
5
|
+
enabled: false
|
|
6
|
+
SpaceInHtmlTag:
|
|
7
|
+
enabled: false
|
|
8
|
+
AllowedScriptType:
|
|
9
|
+
enabled: true
|
|
10
|
+
allowed_types:
|
|
11
|
+
- text/javascript
|
|
12
|
+
- module
|
|
13
|
+
CustomSingleLineIfModifier:
|
|
14
|
+
enabled: true
|
|
15
|
+
CustomHtmlToContentTag:
|
|
16
|
+
enabled: true
|
|
17
|
+
CustomAlignConsecutiveCalls:
|
|
18
|
+
enabled: true
|
|
19
|
+
methods:
|
|
20
|
+
- link_to
|
|
21
|
+
Rubocop:
|
|
22
|
+
enabled: true
|
|
23
|
+
rubocop_config:
|
|
24
|
+
inherit_from:
|
|
25
|
+
- linters/rubocop-4.0.7.yml
|
|
26
|
+
Layout/TrailingWhitespace:
|
|
27
|
+
Enabled: false
|
data/linters/erb-lint.yml
CHANGED
|
@@ -4,6 +4,15 @@ linters:
|
|
|
4
4
|
enabled: false
|
|
5
5
|
SpaceInHtmlTag:
|
|
6
6
|
enabled: false
|
|
7
|
+
##============================================================##
|
|
8
|
+
## "module" is the standard type of ES module scripts (Vite,
|
|
9
|
+
## importmap) — erb_lint only allows text/javascript by default
|
|
10
|
+
##============================================================##
|
|
11
|
+
AllowedScriptType:
|
|
12
|
+
enabled: true
|
|
13
|
+
allowed_types:
|
|
14
|
+
- text/javascript
|
|
15
|
+
- module
|
|
7
16
|
CustomSingleLineIfModifier:
|
|
8
17
|
enabled: true
|
|
9
18
|
CustomHtmlToContentTag:
|
data/linters/eslint.config.mjs
CHANGED
|
@@ -176,7 +176,11 @@ export default [
|
|
|
176
176
|
|
|
177
177
|
//============================================================//
|
|
178
178
|
// TypeScript specific rules
|
|
179
|
+
// The core rule reports parameter names of function types
|
|
180
|
+
// (`onOpen: (path: string) => void`) as unused variables;
|
|
181
|
+
// the TypeScript-aware version replaces it
|
|
179
182
|
//============================================================//
|
|
183
|
+
"no-unused-vars": "off",
|
|
180
184
|
"@typescript-eslint/no-unused-vars": [2],
|
|
181
185
|
"@typescript-eslint/explicit-function-return-type": "off",
|
|
182
186
|
"@typescript-eslint/no-explicit-any": "warn",
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
EnableDefaultLinters: true
|
|
3
|
+
linters:
|
|
4
|
+
NoJavascriptTagHelper:
|
|
5
|
+
enabled: false
|
|
6
|
+
SpaceInHtmlTag:
|
|
7
|
+
enabled: false
|
|
8
|
+
SelfClosingTag:
|
|
9
|
+
enabled: false
|
|
10
|
+
RequireInputAutocomplete:
|
|
11
|
+
enabled: false
|
|
12
|
+
DeprecatedClassesInline:
|
|
13
|
+
enabled: false
|
|
14
|
+
HardCodedString:
|
|
15
|
+
enabled: false
|
|
16
|
+
CustomHtmlToContentTag:
|
|
17
|
+
enabled: false
|
|
18
|
+
CustomSingleLineIfModifier:
|
|
19
|
+
enabled: true
|
|
20
|
+
Rubocop:
|
|
21
|
+
enabled: true
|
|
22
|
+
rubocop_config:
|
|
23
|
+
inherit_from:
|
|
24
|
+
- linters/rubocop-4.0.7.yml
|
|
25
|
+
Layout/TrailingWhitespace:
|
|
26
|
+
Enabled: false
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
---
|
|
2
|
+
require:
|
|
3
|
+
- rubocop/cop/style/method_call_with_args_parentheses_override
|
|
4
|
+
- rubocop/cop/custom_cops/style/comment_normalization
|
|
5
|
+
- rubocop/cop/custom_cops/style/font_awesome_normalization
|
|
6
|
+
- rubocop/cop/custom_cops/style/align_assignments
|
|
7
|
+
- rubocop/cop/custom_cops/style/inline_multiline_calls
|
|
8
|
+
- rubocop/cop/custom_cops/style/kwarg_priority_order
|
|
9
|
+
AllCops:
|
|
10
|
+
NewCops: enable
|
|
11
|
+
EnabledByDefault: false
|
|
12
|
+
UseCache: true
|
|
13
|
+
SuggestExtensions: false
|
|
14
|
+
ActiveSupportExtensionsEnabled: true
|
|
15
|
+
TargetRubyVersion: 4.0.7
|
|
16
|
+
ParserEngine: parser_prism
|
|
17
|
+
Metrics:
|
|
18
|
+
Enabled: false
|
|
19
|
+
Lint/UselessAssignment:
|
|
20
|
+
Enabled: false
|
|
21
|
+
Lint/RescueException:
|
|
22
|
+
Enabled: false
|
|
23
|
+
Lint/UnusedMethodArgument:
|
|
24
|
+
Enabled: false
|
|
25
|
+
Lint/UselessOr:
|
|
26
|
+
Enabled: false
|
|
27
|
+
Lint/InterpolationCheck:
|
|
28
|
+
AutoCorrect: false
|
|
29
|
+
Naming/VariableNumber:
|
|
30
|
+
Enabled: false
|
|
31
|
+
Naming/FileName:
|
|
32
|
+
Enabled: false
|
|
33
|
+
Naming/MethodParameterName:
|
|
34
|
+
MinNameLength: 1
|
|
35
|
+
Layout/LeadingEmptyLines:
|
|
36
|
+
Enabled: false
|
|
37
|
+
Layout/InitialIndentation:
|
|
38
|
+
Enabled: false
|
|
39
|
+
Layout/TrailingEmptyLines:
|
|
40
|
+
Enabled: false
|
|
41
|
+
Layout/ExtraSpacing:
|
|
42
|
+
Enabled: false
|
|
43
|
+
Layout/LineLength:
|
|
44
|
+
Enabled: false
|
|
45
|
+
Layout/TrailingWhitespace:
|
|
46
|
+
Enabled: true
|
|
47
|
+
Layout/EmptyLines:
|
|
48
|
+
Enabled: false
|
|
49
|
+
Layout/LeadingCommentSpace:
|
|
50
|
+
Enabled: false
|
|
51
|
+
Layout/SpaceInsideBlockBraces:
|
|
52
|
+
SpaceBeforeBlockParameters: false
|
|
53
|
+
Layout/EmptyLinesAroundClassBody:
|
|
54
|
+
EnforcedStyle: empty_lines
|
|
55
|
+
Layout/FirstHashElementIndentation:
|
|
56
|
+
EnforcedStyle: consistent
|
|
57
|
+
Layout/ArgumentAlignment:
|
|
58
|
+
EnforcedStyle: with_fixed_indentation
|
|
59
|
+
Layout/HashAlignment:
|
|
60
|
+
EnforcedHashRocketStyle: table
|
|
61
|
+
Layout/MultilineAssignmentLayout:
|
|
62
|
+
EnforcedStyle: same_line
|
|
63
|
+
Layout/SpaceInsideHashLiteralBraces:
|
|
64
|
+
EnforcedStyle: no_space
|
|
65
|
+
Layout/MultilineMethodCallIndentation:
|
|
66
|
+
EnforcedStyle: indented
|
|
67
|
+
Style/CombinableLoops:
|
|
68
|
+
Enabled: false
|
|
69
|
+
Style/SingleArgumentDig:
|
|
70
|
+
Enabled: false
|
|
71
|
+
Style/RedundantBegin:
|
|
72
|
+
Enabled: false
|
|
73
|
+
Style/MultilineTernaryOperator:
|
|
74
|
+
Enabled: false
|
|
75
|
+
Style/NestedTernaryOperator:
|
|
76
|
+
Enabled: false
|
|
77
|
+
Style/MultilineIfModifier:
|
|
78
|
+
Enabled: false
|
|
79
|
+
Style/FrozenStringLiteralComment:
|
|
80
|
+
Enabled: false
|
|
81
|
+
Style/Next:
|
|
82
|
+
Enabled: false
|
|
83
|
+
Style/Documentation:
|
|
84
|
+
Enabled: false
|
|
85
|
+
Style/IfUnlessModifierOfIfUnless:
|
|
86
|
+
Enabled: false
|
|
87
|
+
Style/NegatedIf:
|
|
88
|
+
Enabled: false
|
|
89
|
+
Style/FormatStringToken:
|
|
90
|
+
EnforcedStyle: template
|
|
91
|
+
Style/NumericPredicate:
|
|
92
|
+
EnforcedStyle: comparison
|
|
93
|
+
Style/StringLiterals:
|
|
94
|
+
EnforcedStyle: double_quotes
|
|
95
|
+
Style/StringLiteralsInInterpolation:
|
|
96
|
+
EnforcedStyle: double_quotes
|
|
97
|
+
Style/HashSyntax:
|
|
98
|
+
EnforcedStyle: hash_rockets
|
|
99
|
+
Style/WordArray:
|
|
100
|
+
EnforcedStyle: brackets
|
|
101
|
+
Style/SymbolArray:
|
|
102
|
+
EnforcedStyle: brackets
|
|
103
|
+
Style/RescueModifier:
|
|
104
|
+
Enabled: false
|
|
105
|
+
Style/ArrayIntersect:
|
|
106
|
+
Enabled: false
|
|
107
|
+
Style/NestedParenthesizedCalls:
|
|
108
|
+
Enabled: false
|
|
109
|
+
Style/MethodCallWithArgsParentheses:
|
|
110
|
+
Enabled: true
|
|
111
|
+
EnforcedStyle: require_parentheses
|
|
112
|
+
IgnoreMacros: false
|
|
113
|
+
AllowedMethods:
|
|
114
|
+
- require
|
|
115
|
+
- require_relative
|
|
116
|
+
- include
|
|
117
|
+
- extend
|
|
118
|
+
- prepend
|
|
119
|
+
- raise
|
|
120
|
+
- fail
|
|
121
|
+
- yield
|
|
122
|
+
- attr_accessor
|
|
123
|
+
- attr_reader
|
|
124
|
+
- attr_writer
|
|
125
|
+
- run
|
|
126
|
+
- exec
|
|
127
|
+
- load
|
|
128
|
+
- gem
|
|
129
|
+
- group
|
|
130
|
+
- source
|
|
131
|
+
- ruby
|
|
132
|
+
- install_plugin
|
|
133
|
+
- desc
|
|
134
|
+
- task
|
|
135
|
+
- namespace
|
|
136
|
+
- before_action
|
|
137
|
+
- after_action
|
|
138
|
+
- around_action
|
|
139
|
+
- skip_before_action
|
|
140
|
+
- prepend_before_action
|
|
141
|
+
- append_before_action
|
|
142
|
+
- helper_method
|
|
143
|
+
- layout
|
|
144
|
+
- rescue_from
|
|
145
|
+
- belongs_to
|
|
146
|
+
- has_many
|
|
147
|
+
- has_one
|
|
148
|
+
- has_and_belongs_to_many
|
|
149
|
+
- validates
|
|
150
|
+
- validate
|
|
151
|
+
- validates_presence_of
|
|
152
|
+
- validates_uniqueness_of
|
|
153
|
+
- validates_length_of
|
|
154
|
+
- validates_format_of
|
|
155
|
+
- validates_numericality_of
|
|
156
|
+
- validates_inclusion_of
|
|
157
|
+
- validates_exclusion_of
|
|
158
|
+
- validates_confirmation_of
|
|
159
|
+
- validates_acceptance_of
|
|
160
|
+
- validates_absence_of
|
|
161
|
+
- validates_associated
|
|
162
|
+
- validates_each
|
|
163
|
+
- validates_with
|
|
164
|
+
- after_initialize
|
|
165
|
+
- after_find
|
|
166
|
+
- before_validation
|
|
167
|
+
- after_validation
|
|
168
|
+
- before_save
|
|
169
|
+
- after_save
|
|
170
|
+
- around_save
|
|
171
|
+
- before_create
|
|
172
|
+
- after_create
|
|
173
|
+
- around_create
|
|
174
|
+
- before_update
|
|
175
|
+
- after_update
|
|
176
|
+
- around_update
|
|
177
|
+
- before_destroy
|
|
178
|
+
- after_destroy
|
|
179
|
+
- around_destroy
|
|
180
|
+
- after_touch
|
|
181
|
+
- after_commit
|
|
182
|
+
- after_rollback
|
|
183
|
+
- delegate
|
|
184
|
+
- enum
|
|
185
|
+
- get
|
|
186
|
+
- post
|
|
187
|
+
- put
|
|
188
|
+
- patch
|
|
189
|
+
- delete
|
|
190
|
+
- options
|
|
191
|
+
- head
|
|
192
|
+
- match
|
|
193
|
+
- root
|
|
194
|
+
- rake
|
|
195
|
+
- every
|
|
196
|
+
- command
|
|
197
|
+
- set
|
|
198
|
+
- append
|
|
199
|
+
- server
|
|
200
|
+
- after
|
|
201
|
+
CustomCops/Style/CommentNormalization:
|
|
202
|
+
Enabled: true
|
|
203
|
+
CustomCops/Style/FontAwesomeNormalization:
|
|
204
|
+
Enabled: true
|
|
205
|
+
CustomCops/Style/AlignAssignments:
|
|
206
|
+
Enabled: false
|
|
207
|
+
CustomCops/Style/InlineMultilineCalls:
|
|
208
|
+
Enabled: true
|
|
209
|
+
Methods:
|
|
210
|
+
- link_to
|
|
211
|
+
CustomCops/Style/KwargPriorityOrder:
|
|
212
|
+
Enabled: true
|
|
213
|
+
Methods:
|
|
214
|
+
- link_to
|
|
215
|
+
PriorityKeys:
|
|
216
|
+
- remote
|
|
217
|
+
- method
|
|
218
|
+
Gemspec/RequireMFA:
|
|
219
|
+
Enabled: false
|
data/package.json
CHANGED
|
@@ -7,19 +7,19 @@
|
|
|
7
7
|
],
|
|
8
8
|
"private": true,
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@babel/parser": "^8.0.
|
|
10
|
+
"@babel/parser": "^8.0.5",
|
|
11
11
|
"@eslint/js": "^10.0.1",
|
|
12
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
13
|
-
"@typescript-eslint/parser": "^8.
|
|
12
|
+
"@typescript-eslint/eslint-plugin": "^8.71.0",
|
|
13
|
+
"@typescript-eslint/parser": "^8.71.0",
|
|
14
14
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
15
|
-
"eslint": "^10.
|
|
15
|
+
"eslint": "^10.11.0",
|
|
16
16
|
"eslint-plugin-align-assignments": "^1.1.2",
|
|
17
17
|
"eslint-plugin-align-import": "^1.0.0",
|
|
18
18
|
"eslint-plugin-erb": "^2.1.1",
|
|
19
19
|
"eslint-plugin-prefer-arrow": "^1.2.3",
|
|
20
|
-
"eslint-plugin-sonarjs": "^4.2.
|
|
20
|
+
"eslint-plugin-sonarjs": "^4.2.2",
|
|
21
21
|
"eslint-plugin-unused-imports": "^4.4.1",
|
|
22
|
-
"prettier": "^3.9.
|
|
22
|
+
"prettier": "^3.9.9",
|
|
23
23
|
"typescript": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz"
|
|
24
24
|
}
|
|
25
25
|
}
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: immosquare-cleaner
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- immosquare
|
|
@@ -163,6 +163,7 @@ files:
|
|
|
163
163
|
- bin/immosquare-cleaner
|
|
164
164
|
- lib/immosquare-cleaner.rb
|
|
165
165
|
- lib/immosquare-cleaner/configuration.rb
|
|
166
|
+
- lib/immosquare-cleaner/directory_cleaner.rb
|
|
166
167
|
- lib/immosquare-cleaner/markdown.rb
|
|
167
168
|
- lib/immosquare-cleaner/processors/base.rb
|
|
168
169
|
- lib/immosquare-cleaner/processors/erb.rb
|
|
@@ -171,12 +172,13 @@ files:
|
|
|
171
172
|
- lib/immosquare-cleaner/processors/markdown.rb
|
|
172
173
|
- lib/immosquare-cleaner/processors/prettier.rb
|
|
173
174
|
- lib/immosquare-cleaner/processors/ruby.rb
|
|
175
|
+
- lib/immosquare-cleaner/processors/rust.rb
|
|
174
176
|
- lib/immosquare-cleaner/processors/shell.rb
|
|
177
|
+
- lib/immosquare-cleaner/processors/toml.rb
|
|
175
178
|
- lib/immosquare-cleaner/processors/yaml.rb
|
|
176
|
-
- lib/immosquare-cleaner/railtie.rb
|
|
177
179
|
- lib/immosquare-cleaner/version.rb
|
|
178
|
-
- lib/tasks/immosquare_cleaner.rake
|
|
179
180
|
- linters/erb-lint-4.0.6.yml
|
|
181
|
+
- linters/erb-lint-4.0.7.yml
|
|
180
182
|
- linters/erb-lint.yml
|
|
181
183
|
- linters/erb_lint/custom_align_consecutive_calls.rb
|
|
182
184
|
- linters/erb_lint/custom_html_to_content_tag.rb
|
|
@@ -184,10 +186,12 @@ files:
|
|
|
184
186
|
- linters/eslint-plugins/eslint10-compat.mjs
|
|
185
187
|
- linters/eslint.config.mjs
|
|
186
188
|
- linters/js-erb-lint-4.0.6.yml
|
|
189
|
+
- linters/js-erb-lint-4.0.7.yml
|
|
187
190
|
- linters/js-erb-lint.yml
|
|
188
191
|
- linters/normalize-comments.mjs
|
|
189
192
|
- linters/prettier.yml
|
|
190
193
|
- linters/rubocop-4.0.6.yml
|
|
194
|
+
- linters/rubocop-4.0.7.yml
|
|
191
195
|
- linters/rubocop.yml
|
|
192
196
|
- linters/rubocop/cop/custom_cops/style/align_assignments.rb
|
|
193
197
|
- linters/rubocop/cop/custom_cops/style/comment_normalization.rb
|
|
@@ -215,7 +219,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
215
219
|
- !ruby/object:Gem::Version
|
|
216
220
|
version: '0'
|
|
217
221
|
requirements: []
|
|
218
|
-
rubygems_version: 4.0.
|
|
222
|
+
rubygems_version: 4.0.22
|
|
219
223
|
specification_version: 4
|
|
220
224
|
summary: A gem to lint and organize files in a Rails application.
|
|
221
225
|
test_files: []
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
require "parallel"
|
|
2
|
-
require "etc"
|
|
3
|
-
|
|
4
|
-
namespace :immosquare_cleaner do
|
|
5
|
-
##============================================================##
|
|
6
|
-
## Runs immosquare-cleaner across every file of a Rails app to
|
|
7
|
-
## format/lint in bulk, dispatching by extension:
|
|
8
|
-
## RuboCop (.rb), erb_lint + htmlbeautifier (.html.erb),
|
|
9
|
-
## ESLint (.js/.ts/.jsx/.tsx), ImmosquareYaml (locales/*.yml),
|
|
10
|
-
## shfmt (.sh), Prettier (everything else).
|
|
11
|
-
##
|
|
12
|
-
## Useful to normalize a codebase in one shot (onboarding,
|
|
13
|
-
## cleaner version upgrade, large refactor) rather than
|
|
14
|
-
## relying on the per-file Edit/Write hook.
|
|
15
|
-
##
|
|
16
|
-
## Skips generated/non-source folders (asset builds,
|
|
17
|
-
## node_modules, vendor, tmp, log, public, db, test, coverage)
|
|
18
|
-
## and binary/lock files (.lock, .png, .csv, etc.).
|
|
19
|
-
##
|
|
20
|
-
## Parallelized via threads (linters shell out, so the GVL is
|
|
21
|
-
## released). Override with: CLEANER_THREADS=N rake ...
|
|
22
|
-
##============================================================##
|
|
23
|
-
desc "clean files in rails app"
|
|
24
|
-
task :clean_app => :environment do
|
|
25
|
-
paths_to_exclude = [
|
|
26
|
-
"app/assets/builds",
|
|
27
|
-
"app/assets/fonts",
|
|
28
|
-
"app/assets/images",
|
|
29
|
-
"coverage",
|
|
30
|
-
"log",
|
|
31
|
-
"node_modules",
|
|
32
|
-
"public",
|
|
33
|
-
"test",
|
|
34
|
-
"tmp",
|
|
35
|
-
"vendor",
|
|
36
|
-
"db"
|
|
37
|
-
]
|
|
38
|
-
extensions_to_exclude = [
|
|
39
|
-
".lock",
|
|
40
|
-
".lockb",
|
|
41
|
-
".otf",
|
|
42
|
-
".ttf",
|
|
43
|
-
".png",
|
|
44
|
-
".jpg",
|
|
45
|
-
".jpeg",
|
|
46
|
-
".gif",
|
|
47
|
-
".svg",
|
|
48
|
-
".ico",
|
|
49
|
-
".webp",
|
|
50
|
-
".csv"
|
|
51
|
-
]
|
|
52
|
-
|
|
53
|
-
file_paths = Dir.glob("#{Rails.root}/**/*").reject do |file_path|
|
|
54
|
-
File.directory?(file_path) || file_path.gsub("#{Rails.root}/", "").start_with?(*paths_to_exclude) || file_path.end_with?(*extensions_to_exclude)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
total = file_paths.size
|
|
58
|
-
mutex = Mutex.new
|
|
59
|
-
index = 0
|
|
60
|
-
threads = ENV["CLEANER_THREADS"]&.to_i || [Etc.nprocessors, 8].min
|
|
61
|
-
started = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
62
|
-
|
|
63
|
-
puts("Cleaning #{total} files with #{threads} threads...")
|
|
64
|
-
|
|
65
|
-
Parallel.each(file_paths, :in_threads => threads) do |file_path|
|
|
66
|
-
i = mutex.synchronize { index += 1 }
|
|
67
|
-
puts("#{i}/#{total} - #{file_path}")
|
|
68
|
-
ImmosquareCleaner.clean(file_path)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - started
|
|
72
|
-
mins = (elapsed / 60).to_i
|
|
73
|
-
secs = (elapsed % 60).round(1)
|
|
74
|
-
puts("Done in #{mins}m #{secs}s (#{total} files, #{threads} threads)")
|
|
75
|
-
end
|
|
76
|
-
end
|