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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3bb81cf1641c678335ba6485d0457824ad4f2efd9bec1ad6a3e7973a83617e7
4
- data.tar.gz: b66e76e63984cd595a981fae0a84eb82d4bd47a64092b1373878223da757889b
3
+ metadata.gz: fe48e81e3af7200a3967f640a3f3a34f7632a32d71323b2829841516ad5f8cb8
4
+ data.tar.gz: 571422d60f872ce01a3e3896260b4fee7d0e2282f16978fe7cfd18e2530a1a23
5
5
  SHA512:
6
- metadata.gz: d00cc397871e5131c6cdb3edc8ef9ed40422677c98b9903ce1a2844273f28993c6c679ba8032ed27edfa06b2387d48794fdf5b1dfecc67729336c2a36d29ef82
7
- data.tar.gz: 4e5097e2d7b6db8a2d94ef4e45d6513a065c4d2e7da8be077e2ec2acc3f3588d9a39df20e27162bd3d5e84a49f71c5cf551d638ddc3ba102a02ec5dc8644b231
6
+ metadata.gz: 9f9ec67de3055d93376abc0df67abcc4368e661a4f46a0bd702c9d679407407119364f3b4a68817e39b8ec8ae888ae3365eeb3e692b453317396e21abd0ab875
7
+ data.tar.gz: e32bd136ee29441e48f17af89cac59741e11e931b7d335da8a8ccf8be3914deb4f4c558b75a99f85c108c66f18189ad23f3bca93cd7bfa354a25679f1af3a084
@@ -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 options[:prevent_concurrent_write]
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
- def self.run(file_path)
5
- new(file_path).run
4
+
5
+ def self.run(file_path, origin_path = nil)
6
+ new(file_path, origin_path).run
6
7
  end
7
8
 
8
- attr_reader :file_path
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 = 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
@@ -1,3 +1,3 @@
1
1
  module ImmosquareCleaner
2
- VERSION = "0.1.116".freeze
2
+ VERSION = "1.0.0".freeze
3
3
  end
@@ -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/railtie" if defined?(Rails)
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:
@@ -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.4",
10
+ "@babel/parser": "^8.0.5",
11
11
  "@eslint/js": "^10.0.1",
12
- "@typescript-eslint/eslint-plugin": "^8.67.0",
13
- "@typescript-eslint/parser": "^8.67.0",
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.8.1",
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.0",
20
+ "eslint-plugin-sonarjs": "^4.2.2",
21
21
  "eslint-plugin-unused-imports": "^4.4.1",
22
- "prettier": "^3.9.6",
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.1.116
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.18
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,9 +0,0 @@
1
- module ImmosquareCleaner
2
- class Railtie < Rails::Railtie
3
-
4
- rake_tasks do
5
- load("tasks/immosquare_cleaner.rake")
6
- end
7
-
8
- end
9
- end
@@ -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