ruboclean 0.4.0 → 0.6.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/.github/workflows/ci.yml +1 -1
- data/.rubocop.yml +42 -0
- data/Gemfile.lock +18 -15
- data/README.md +14 -8
- data/lib/ruboclean/{arguments.rb → cli_arguments.rb} +9 -1
- data/lib/ruboclean/grouper.rb +5 -3
- data/lib/ruboclean/logger.rb +19 -0
- data/lib/ruboclean/orderer.rb +7 -7
- data/lib/ruboclean/path_cleanup.rb +79 -0
- data/lib/ruboclean/runner.rb +70 -8
- data/lib/ruboclean/to_yaml_converter.rb +46 -0
- data/lib/ruboclean/version.rb +1 -1
- data/lib/ruboclean.rb +27 -11
- metadata +7 -6
- data/lib/ruboclean/rubocop_configuration.rb +0 -18
- data/lib/ruboclean/rubocop_configuration_path.rb +0 -68
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eed645db36081518d593efb17c64f3c1566a978548a699d10aecf64893ad0f48
|
4
|
+
data.tar.gz: 62c988143427e15fa10e551cedb5965be6a81dd7afbba5ec40ef303ce6e6183c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31f137822127611a4aa5b54df8e7d9222d96937438367ab73a3bdf588e1a854b36a2ba8ce617125ff955948046214ad63037b4ae8a4b5f571f979793c252b2c0
|
7
|
+
data.tar.gz: c939cd53f18fae460f56d76b6ed1c463b229795ac4518ef246ef12b4dd11135067c329276b5d1a9418aebdcf690c8088a4944ff5b338b314be01246dd0acd26e
|
data/.github/workflows/ci.yml
CHANGED
data/.rubocop.yml
CHANGED
@@ -103,12 +103,21 @@ Lint/IdentityComparison:
|
|
103
103
|
Lint/IncompatibleIoSelectWithFiberScheduler:
|
104
104
|
Enabled: true
|
105
105
|
|
106
|
+
Lint/ItWithoutArgumentsInBlock:
|
107
|
+
Enabled: true
|
108
|
+
|
106
109
|
Lint/LambdaWithoutLiteralBlock:
|
107
110
|
Enabled: true
|
108
111
|
|
112
|
+
Lint/LiteralAssignmentInCondition:
|
113
|
+
Enabled: true
|
114
|
+
|
109
115
|
Lint/MissingSuper:
|
110
116
|
Enabled: true
|
111
117
|
|
118
|
+
Lint/MixedCaseRange:
|
119
|
+
Enabled: true
|
120
|
+
|
112
121
|
Lint/MixedRegexpCaptureTypes:
|
113
122
|
Enabled: true
|
114
123
|
|
@@ -133,6 +142,9 @@ Lint/RaiseException:
|
|
133
142
|
Lint/RedundantDirGlobSort:
|
134
143
|
Enabled: true
|
135
144
|
|
145
|
+
Lint/RedundantRegexpQuantifiers:
|
146
|
+
Enabled: true
|
147
|
+
|
136
148
|
Lint/RefinementImportMethods:
|
137
149
|
Enabled: true
|
138
150
|
|
@@ -193,6 +205,9 @@ Minitest/AssertInDelta:
|
|
193
205
|
Minitest/AssertKindOf:
|
194
206
|
Enabled: true
|
195
207
|
|
208
|
+
Minitest/AssertOperator:
|
209
|
+
Enabled: true
|
210
|
+
|
196
211
|
Minitest/AssertOutput:
|
197
212
|
Enabled: true
|
198
213
|
|
@@ -236,15 +251,24 @@ Minitest/MultipleAssertions:
|
|
236
251
|
Enabled: true
|
237
252
|
Max: 5
|
238
253
|
|
254
|
+
Minitest/NonExecutableTestMethod:
|
255
|
+
Enabled: true
|
256
|
+
|
239
257
|
Minitest/NonPublicTestMethod:
|
240
258
|
Enabled: true
|
241
259
|
|
260
|
+
Minitest/RedundantMessageArgument:
|
261
|
+
Enabled: true
|
262
|
+
|
242
263
|
Minitest/RefuteInDelta:
|
243
264
|
Enabled: true
|
244
265
|
|
245
266
|
Minitest/RefuteKindOf:
|
246
267
|
Enabled: true
|
247
268
|
|
269
|
+
Minitest/RefuteOperator:
|
270
|
+
Enabled: true
|
271
|
+
|
248
272
|
Minitest/RefutePathExists:
|
249
273
|
Enabled: true
|
250
274
|
|
@@ -449,6 +473,9 @@ Style/RedundantAssignment:
|
|
449
473
|
Style/RedundantConstantBase:
|
450
474
|
Enabled: true
|
451
475
|
|
476
|
+
Style/RedundantCurrentDirectoryInPath:
|
477
|
+
Enabled: true
|
478
|
+
|
452
479
|
Style/RedundantDoubleSplatHashBraces:
|
453
480
|
Enabled: true
|
454
481
|
|
@@ -473,6 +500,9 @@ Style/RedundantInitialize:
|
|
473
500
|
Style/RedundantLineContinuation:
|
474
501
|
Enabled: true
|
475
502
|
|
503
|
+
Style/RedundantRegexpArgument:
|
504
|
+
Enabled: true
|
505
|
+
|
476
506
|
Style/RedundantRegexpCharacterClass:
|
477
507
|
Enabled: true
|
478
508
|
|
@@ -491,12 +521,18 @@ Style/RedundantSelfAssignmentBranch:
|
|
491
521
|
Style/RedundantStringEscape:
|
492
522
|
Enabled: true
|
493
523
|
|
524
|
+
Style/ReturnNilInPredicateMethodDefinition:
|
525
|
+
Enabled: true
|
526
|
+
|
494
527
|
Style/SelectByRegexp:
|
495
528
|
Enabled: true
|
496
529
|
|
497
530
|
Style/SingleArgumentDig:
|
498
531
|
Enabled: true
|
499
532
|
|
533
|
+
Style/SingleLineDoEndBlock:
|
534
|
+
Enabled: true
|
535
|
+
|
500
536
|
Style/SlicingWithRange:
|
501
537
|
Enabled: true
|
502
538
|
|
@@ -513,8 +549,14 @@ Style/StringLiterals:
|
|
513
549
|
Enabled: true
|
514
550
|
EnforcedStyle: double_quotes
|
515
551
|
|
552
|
+
Style/SuperWithArgsParentheses:
|
553
|
+
Enabled: true
|
554
|
+
|
516
555
|
Style/SwapValues:
|
517
556
|
Enabled: true
|
518
557
|
|
558
|
+
Style/YAMLFileRead:
|
559
|
+
Enabled: true
|
560
|
+
|
519
561
|
Style/YodaExpression:
|
520
562
|
Enabled: true
|
data/Gemfile.lock
CHANGED
@@ -1,38 +1,41 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruboclean (0.
|
4
|
+
ruboclean (0.6.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
9
|
ast (2.4.2)
|
10
10
|
docile (1.4.0)
|
11
|
-
json (2.
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
json (2.7.1)
|
12
|
+
language_server-protocol (3.17.0.3)
|
13
|
+
minitest (5.20.0)
|
14
|
+
parallel (1.24.0)
|
15
|
+
parser (3.2.2.4)
|
15
16
|
ast (~> 2.4.1)
|
16
17
|
racc
|
17
|
-
racc (1.7.
|
18
|
+
racc (1.7.3)
|
18
19
|
rainbow (3.1.1)
|
19
|
-
rake (13.0
|
20
|
-
regexp_parser (2.8.
|
21
|
-
rexml (3.2.
|
22
|
-
rubocop (1.
|
20
|
+
rake (13.1.0)
|
21
|
+
regexp_parser (2.8.3)
|
22
|
+
rexml (3.2.6)
|
23
|
+
rubocop (1.59.0)
|
23
24
|
json (~> 2.3)
|
25
|
+
language_server-protocol (>= 3.17.0)
|
24
26
|
parallel (~> 1.10)
|
25
|
-
parser (>= 3.2.
|
27
|
+
parser (>= 3.2.2.4)
|
26
28
|
rainbow (>= 2.2.2, < 4.0)
|
27
29
|
regexp_parser (>= 1.8, < 3.0)
|
28
30
|
rexml (>= 3.2.5, < 4.0)
|
29
|
-
rubocop-ast (>= 1.
|
31
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
30
32
|
ruby-progressbar (~> 1.7)
|
31
33
|
unicode-display_width (>= 2.4.0, < 3.0)
|
32
|
-
rubocop-ast (1.
|
34
|
+
rubocop-ast (1.30.0)
|
33
35
|
parser (>= 3.2.1.0)
|
34
|
-
rubocop-minitest (0.
|
36
|
+
rubocop-minitest (0.34.2)
|
35
37
|
rubocop (>= 1.39, < 2.0)
|
38
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
36
39
|
rubocop-rake (0.6.0)
|
37
40
|
rubocop (~> 1.0)
|
38
41
|
ruby-progressbar (1.13.0)
|
@@ -41,7 +44,7 @@ GEM
|
|
41
44
|
json (>= 1.8, < 3)
|
42
45
|
simplecov-html (~> 0.10.0)
|
43
46
|
simplecov-html (0.10.2)
|
44
|
-
unicode-display_width (2.
|
47
|
+
unicode-display_width (2.5.0)
|
45
48
|
|
46
49
|
PLATFORMS
|
47
50
|
ruby
|
data/README.md
CHANGED
@@ -28,7 +28,10 @@ Rails:
|
|
28
28
|
|
29
29
|
AllCops:
|
30
30
|
Exclude:
|
31
|
-
-
|
31
|
+
- path/file_exists.rb
|
32
|
+
- path_with_files/**/*
|
33
|
+
- path/file_does_not_exist.rb # This entry will be removed if the file doesn't exist. Skip with --preserve-paths option.
|
34
|
+
- path_without_files/**/* # Will be removed if no files within pattern exist. Skip with --preserve-paths option.
|
32
35
|
|
33
36
|
# Preceding comments will be removed unless the --preserve-comments option is used.
|
34
37
|
require:
|
@@ -45,7 +48,8 @@ require:
|
|
45
48
|
|
46
49
|
AllCops:
|
47
50
|
Exclude:
|
48
|
-
-
|
51
|
+
- path/file_exists.rb
|
52
|
+
- path_with_files/**/*
|
49
53
|
|
50
54
|
Rails:
|
51
55
|
Enabled: true
|
@@ -80,16 +84,18 @@ gem install ruboclean
|
|
80
84
|
## Command synopsis
|
81
85
|
|
82
86
|
```shell
|
83
|
-
ruboclean [path] [--silent] [--preserve-comments]
|
87
|
+
ruboclean [path] [--silent] [--preserve-comments] [--preserve-paths] [--verify]
|
84
88
|
```
|
85
89
|
|
86
90
|
### Parameters
|
87
91
|
|
88
|
-
| Parameter
|
89
|
-
|
90
|
-
| `path`
|
91
|
-
| `--silent`
|
92
|
-
| `--preserve-comments` |
|
92
|
+
| Parameter | Description |
|
93
|
+
|:----------------------|:--------------------------------------------------------------------------------------------------------------------------------------|
|
94
|
+
| `path` | Can be a directory that contains a `.rubocop.yml`, or a path to a `.rubocop.yml` directly. Defaults to the current working directory. |
|
95
|
+
| `--silent` | Suppress any output displayed on the screen when executing the command. |
|
96
|
+
| `--preserve-comments` | Preserves **preceding** comments for each top-level entry in the configuration. Inline comments are **not** preserved. |
|
97
|
+
| `--preserve-paths` | Skips the path cleanup that are applied against `Include:` and `Exclude:` configuration. |
|
98
|
+
| `--verify` | Executes in dry-run mode. Exits with 1 if changes are needed, otherwise 0. |
|
93
99
|
|
94
100
|
### Examples
|
95
101
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Ruboclean
|
4
4
|
# Reads command line arguments and exposes corresponding reader methods
|
5
|
-
class
|
5
|
+
class CliArguments
|
6
6
|
def initialize(command_line_arguments = [])
|
7
7
|
@command_line_arguments = Array(command_line_arguments)
|
8
8
|
end
|
@@ -23,6 +23,14 @@ module Ruboclean
|
|
23
23
|
@preserve_comments ||= find_argument("--preserve-comments")
|
24
24
|
end
|
25
25
|
|
26
|
+
def preserve_paths?
|
27
|
+
@preserve_paths ||= find_argument("--preserve-paths")
|
28
|
+
end
|
29
|
+
|
30
|
+
def verify?
|
31
|
+
@verify ||= find_argument("--verify")
|
32
|
+
end
|
33
|
+
|
26
34
|
private
|
27
35
|
|
28
36
|
attr_reader :command_line_arguments
|
data/lib/ruboclean/grouper.rb
CHANGED
@@ -6,12 +6,12 @@ module Ruboclean
|
|
6
6
|
# - namespaces: every item which does **not** include an "/"
|
7
7
|
# - cops: every item which **includes** an "/"
|
8
8
|
class Grouper
|
9
|
-
def initialize(
|
10
|
-
@
|
9
|
+
def initialize(configuration_hash)
|
10
|
+
@configuration_hash = configuration_hash
|
11
11
|
end
|
12
12
|
|
13
13
|
def group_config
|
14
|
-
|
14
|
+
configuration_hash.each_with_object(empty_groups) do |item, result|
|
15
15
|
key, value = item
|
16
16
|
target_group = find_target_group(key)
|
17
17
|
result[target_group].merge!({ key => value })
|
@@ -20,6 +20,8 @@ module Ruboclean
|
|
20
20
|
|
21
21
|
private
|
22
22
|
|
23
|
+
attr_reader :configuration_hash
|
24
|
+
|
23
25
|
def empty_groups
|
24
26
|
{ base: {}, namespaces: {}, cops: {} }
|
25
27
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ruboclean
|
4
|
+
# Logger for clean management of log levels
|
5
|
+
class Logger
|
6
|
+
def initialize(log_level = :verbose)
|
7
|
+
raise ArgumentError, "Invalid log level" unless %i[verbose none].include?(log_level)
|
8
|
+
|
9
|
+
@log_level = log_level
|
10
|
+
end
|
11
|
+
|
12
|
+
def verbose(message)
|
13
|
+
case @log_level
|
14
|
+
when :verbose
|
15
|
+
print message
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/ruboclean/orderer.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "ruboclean/grouper"
|
4
|
-
|
5
3
|
module Ruboclean
|
6
4
|
# Orders the items within the groups alphabetically
|
7
5
|
class Orderer
|
8
|
-
def initialize(
|
9
|
-
@
|
6
|
+
def initialize(configuration_hash)
|
7
|
+
@configuration_hash = configuration_hash
|
10
8
|
end
|
11
9
|
|
12
10
|
def order
|
@@ -18,12 +16,14 @@ module Ruboclean
|
|
18
16
|
|
19
17
|
private
|
20
18
|
|
21
|
-
|
22
|
-
|
19
|
+
attr_reader :configuration_hash
|
20
|
+
|
21
|
+
def order_by_key(group_items)
|
22
|
+
group_items.sort_by(&:first).to_h
|
23
23
|
end
|
24
24
|
|
25
25
|
def grouped_config
|
26
|
-
Ruboclean::Grouper.new(
|
26
|
+
Ruboclean::Grouper.new(configuration_hash).group_config
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ruboclean
|
4
|
+
# Cleans up any `Include` or `Exclude` paths that don't exist.
|
5
|
+
# The `Include` and `Exclude` paths are relative to the directory
|
6
|
+
# where the `.rubocop.yml` file is located. If a path includes a
|
7
|
+
# regexp, it's assumed to be valid.
|
8
|
+
# If all entries in `Include` or `Exclude` are removed, the entire property is removed.
|
9
|
+
# If a Cop gets entirely truncated due to removing all `Includes` and/or `Exclude`, the Cop itself will be removed.
|
10
|
+
class PathCleanup
|
11
|
+
def initialize(configuration_hash, root_directory)
|
12
|
+
@configuration_hash = configuration_hash
|
13
|
+
@root_directory = root_directory
|
14
|
+
end
|
15
|
+
|
16
|
+
def cleanup
|
17
|
+
configuration_hash.each_with_object({}) do |(top_level_key, top_level_value), hash|
|
18
|
+
result = process_top_level_value(top_level_value)
|
19
|
+
|
20
|
+
next if Array(result).empty? # No configuration keys left in the cop, remove the entire cop
|
21
|
+
|
22
|
+
hash[top_level_key] = result
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
attr_reader :configuration_hash, :root_directory
|
29
|
+
|
30
|
+
# top_level_value could be something like this:
|
31
|
+
#
|
32
|
+
# {
|
33
|
+
# Include: [...],
|
34
|
+
# Exclude: [...],
|
35
|
+
# EnforcedStyle: "..."
|
36
|
+
# }
|
37
|
+
#
|
38
|
+
# We process it further in case of a Hash.
|
39
|
+
def process_top_level_value(top_level_value)
|
40
|
+
return top_level_value unless top_level_value.is_a?(Hash)
|
41
|
+
|
42
|
+
top_level_value.each_with_object({}) do |(cop_property_key, cop_property_value), hash|
|
43
|
+
result = process_cop_property(cop_property_key, cop_property_value)
|
44
|
+
|
45
|
+
next if Array(result).empty? # No entries left, will skip adding the key to the hash
|
46
|
+
|
47
|
+
hash[cop_property_key] = result
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def process_cop_property(cop_property_key, cop_property_value)
|
52
|
+
return cop_property_value unless %w[Include Exclude].include?(cop_property_key.to_s)
|
53
|
+
return cop_property_value unless cop_property_value.respond_to?(:filter_map)
|
54
|
+
|
55
|
+
cop_property_value.find_all do |item|
|
56
|
+
path_exists?(item)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def path_exists?(item)
|
61
|
+
regexp_pattern?(item) ||
|
62
|
+
specific_path_exists?(item) ||
|
63
|
+
any_global_command_pattern?(item)
|
64
|
+
end
|
65
|
+
|
66
|
+
def specific_path_exists?(item)
|
67
|
+
root_directory.join(item).exist?
|
68
|
+
end
|
69
|
+
|
70
|
+
def any_global_command_pattern?(item)
|
71
|
+
root_directory.glob(item).any?
|
72
|
+
end
|
73
|
+
|
74
|
+
# We don't support Regexp, so we just say it exists.
|
75
|
+
def regexp_pattern?(item)
|
76
|
+
item.is_a?(Regexp)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/ruboclean/runner.rb
CHANGED
@@ -1,23 +1,85 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "pathname"
|
4
|
+
require "yaml"
|
5
|
+
|
3
6
|
module Ruboclean
|
4
|
-
#
|
7
|
+
# Entry point for processing
|
5
8
|
class Runner
|
6
|
-
def initialize(
|
7
|
-
@
|
9
|
+
def initialize(args = [])
|
10
|
+
@cli_arguments = CliArguments.new(args)
|
8
11
|
end
|
9
12
|
|
10
13
|
def run!
|
11
|
-
|
12
|
-
|
14
|
+
return if source_file_pathname.empty?
|
15
|
+
|
16
|
+
load_file.then(&method(:order))
|
17
|
+
.then(&method(:cleanup_paths))
|
18
|
+
.then(&method(:convert_to_yaml))
|
19
|
+
.then(&method(:write_file!))
|
20
|
+
.then(&method(:changed?))
|
21
|
+
end
|
22
|
+
|
23
|
+
def changed?(target_yaml)
|
24
|
+
target_yaml != source_yaml
|
25
|
+
end
|
26
|
+
|
27
|
+
def verbose?
|
28
|
+
cli_arguments.verbose?
|
29
|
+
end
|
13
30
|
|
14
|
-
|
31
|
+
def verify?
|
32
|
+
cli_arguments.verify?
|
33
|
+
end
|
15
34
|
|
16
|
-
|
35
|
+
def path
|
36
|
+
cli_arguments.path
|
17
37
|
end
|
18
38
|
|
19
39
|
private
|
20
40
|
|
21
|
-
attr_reader :
|
41
|
+
attr_reader :cli_arguments
|
42
|
+
|
43
|
+
def source_yaml
|
44
|
+
@source_yaml ||= source_file_pathname.read
|
45
|
+
end
|
46
|
+
|
47
|
+
def load_file
|
48
|
+
YAML.safe_load(source_yaml, permitted_classes: [Regexp])
|
49
|
+
end
|
50
|
+
|
51
|
+
def order(configuration_hash)
|
52
|
+
Orderer.new(configuration_hash).order
|
53
|
+
end
|
54
|
+
|
55
|
+
def cleanup_paths(configuration_hash)
|
56
|
+
return configuration_hash if cli_arguments.preserve_paths?
|
57
|
+
|
58
|
+
PathCleanup.new(configuration_hash, source_file_pathname.dirname).cleanup
|
59
|
+
end
|
60
|
+
|
61
|
+
def convert_to_yaml(configuration_hash)
|
62
|
+
ToYamlConverter.new(configuration_hash, cli_arguments.preserve_comments?, source_yaml).to_yaml
|
63
|
+
end
|
64
|
+
|
65
|
+
def write_file!(target_yaml)
|
66
|
+
target_yaml.tap do |content|
|
67
|
+
source_file_pathname.write(content) unless verify?
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def source_file_pathname
|
72
|
+
@source_file_pathname ||= find_source_file_pathname
|
73
|
+
end
|
74
|
+
|
75
|
+
def find_source_file_pathname
|
76
|
+
source_path = Pathname.new(cli_arguments.path)
|
77
|
+
|
78
|
+
source_path = source_path.join(".rubocop.yml") if source_path.directory?
|
79
|
+
|
80
|
+
return source_path if source_path.exist?
|
81
|
+
|
82
|
+
raise ArgumentError, "path does not exist: '#{source_path}'"
|
83
|
+
end
|
22
84
|
end
|
23
85
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Ruboclean
|
4
|
+
# Converts the configuration hash to YAML and applies modifications on it, if requested
|
5
|
+
class ToYamlConverter
|
6
|
+
def initialize(configuration_hash, preserve_comments, source_yaml)
|
7
|
+
@configuration_hash = configuration_hash
|
8
|
+
@preserve_comments = preserve_comments
|
9
|
+
@source_yaml = source_yaml
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_yaml
|
13
|
+
target_yaml = sanitize_yaml(configuration_hash.transform_keys(&:to_s).to_yaml)
|
14
|
+
|
15
|
+
return target_yaml unless preserve_comments?
|
16
|
+
|
17
|
+
preserve_preceding_comments(source_yaml, target_yaml)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :configuration_hash, :preserve_comments, :source_yaml
|
23
|
+
|
24
|
+
def preserve_comments?
|
25
|
+
preserve_comments
|
26
|
+
end
|
27
|
+
|
28
|
+
def sanitize_yaml(data)
|
29
|
+
data.gsub(/^([a-zA-Z]+)/, "\n\\1")
|
30
|
+
end
|
31
|
+
|
32
|
+
def preserve_preceding_comments(source, target)
|
33
|
+
target.dup.tap do |output|
|
34
|
+
source.scan(/(((^ *#.*\n|^\s*\n)+)(?![\s#]).+)/) do |groups|
|
35
|
+
config_keys_with_preceding_lines = groups.first
|
36
|
+
*preceding_lines, config_key = config_keys_with_preceding_lines.split("\n")
|
37
|
+
|
38
|
+
next if preceding_lines.all?(:empty?)
|
39
|
+
next if config_key.gsub(/\s/, "").empty?
|
40
|
+
|
41
|
+
output.sub!(/^#{config_key}$/, config_keys_with_preceding_lines.strip)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/ruboclean/version.rb
CHANGED
data/lib/ruboclean.rb
CHANGED
@@ -1,21 +1,37 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "ruboclean/
|
4
|
-
require "ruboclean/arguments"
|
5
|
-
require "ruboclean/rubocop_configuration"
|
6
|
-
require "ruboclean/rubocop_configuration_path"
|
7
|
-
require "ruboclean/runner"
|
3
|
+
require "ruboclean/cli_arguments"
|
8
4
|
require "ruboclean/orderer"
|
5
|
+
require "ruboclean/logger"
|
6
|
+
require "ruboclean/grouper"
|
7
|
+
require "ruboclean/path_cleanup"
|
8
|
+
require "ruboclean/runner"
|
9
|
+
require "ruboclean/to_yaml_converter"
|
10
|
+
require "ruboclean/version"
|
9
11
|
|
10
12
|
# Ruboclean entry point
|
11
13
|
module Ruboclean
|
12
|
-
|
14
|
+
def self.run_from_cli!(args)
|
15
|
+
runner = Runner.new(args)
|
16
|
+
logger = Ruboclean::Logger.new(runner.verbose? ? :verbose : :none)
|
17
|
+
|
18
|
+
logger.verbose "Using path '#{runner.path}' ... "
|
19
|
+
changed = runner.run!
|
20
|
+
logger.verbose post_execution_message(changed, runner.verify?)
|
21
|
+
|
22
|
+
exit !changed if runner.verify?
|
23
|
+
exit 0
|
24
|
+
end
|
13
25
|
|
14
|
-
def self.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
26
|
+
def self.post_execution_message(changed, verify)
|
27
|
+
if changed
|
28
|
+
if verify
|
29
|
+
"needs clean.\n"
|
30
|
+
else
|
31
|
+
"done.\n"
|
32
|
+
end
|
33
|
+
else
|
34
|
+
"already clean.\n"
|
19
35
|
end
|
20
36
|
end
|
21
37
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruboclean
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- lxxxvi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Cleans and orders settings in .rubocop.yml
|
14
14
|
email:
|
@@ -32,12 +32,13 @@ files:
|
|
32
32
|
- bin/setup
|
33
33
|
- bin/test
|
34
34
|
- lib/ruboclean.rb
|
35
|
-
- lib/ruboclean/
|
35
|
+
- lib/ruboclean/cli_arguments.rb
|
36
36
|
- lib/ruboclean/grouper.rb
|
37
|
+
- lib/ruboclean/logger.rb
|
37
38
|
- lib/ruboclean/orderer.rb
|
38
|
-
- lib/ruboclean/
|
39
|
-
- lib/ruboclean/rubocop_configuration_path.rb
|
39
|
+
- lib/ruboclean/path_cleanup.rb
|
40
40
|
- lib/ruboclean/runner.rb
|
41
|
+
- lib/ruboclean/to_yaml_converter.rb
|
41
42
|
- lib/ruboclean/version.rb
|
42
43
|
- ruboclean.gemspec
|
43
44
|
homepage: https://github.com/lxxxvi/ruboclean
|
@@ -63,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
63
64
|
- !ruby/object:Gem::Version
|
64
65
|
version: '0'
|
65
66
|
requirements: []
|
66
|
-
rubygems_version: 3.
|
67
|
+
rubygems_version: 3.5.3
|
67
68
|
signing_key:
|
68
69
|
specification_version: 4
|
69
70
|
summary: Cleans and orders settings in .rubocop.yml
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Ruboclean
|
4
|
-
# Contains the config_hash representation of the `.rubocop.yml` file
|
5
|
-
class RubocopConfiguration
|
6
|
-
def initialize(config_hash)
|
7
|
-
@config_hash = config_hash
|
8
|
-
end
|
9
|
-
|
10
|
-
def order
|
11
|
-
Ruboclean::Orderer.new(@config_hash).order
|
12
|
-
end
|
13
|
-
|
14
|
-
def nil?
|
15
|
-
@config_hash.nil?
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "pathname"
|
4
|
-
require "yaml"
|
5
|
-
|
6
|
-
module Ruboclean
|
7
|
-
# Interface for reading and writing the `.rubocop.yml` file
|
8
|
-
class RubocopConfigurationPath
|
9
|
-
PERMITTED_CLASSED = [Regexp].freeze
|
10
|
-
|
11
|
-
# Thrown if given path is invalid
|
12
|
-
class InvalidPathError < StandardError
|
13
|
-
def initialize(path)
|
14
|
-
super "path does not exist: '#{path}'"
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def initialize(path)
|
19
|
-
input_path = Pathname.new(path)
|
20
|
-
|
21
|
-
@rubocop_configuration_path = if input_path.directory?
|
22
|
-
input_path.join(".rubocop.yml")
|
23
|
-
else
|
24
|
-
input_path
|
25
|
-
end
|
26
|
-
|
27
|
-
raise InvalidPathError, @rubocop_configuration_path unless @rubocop_configuration_path.exist?
|
28
|
-
end
|
29
|
-
|
30
|
-
def load
|
31
|
-
Ruboclean::RubocopConfiguration.new(load_yaml)
|
32
|
-
end
|
33
|
-
|
34
|
-
def write(rubocop_configuration, preserve_comments: false)
|
35
|
-
output_yaml = sanitize_yaml(rubocop_configuration.to_yaml)
|
36
|
-
output_yaml = preserve_preceding_comments(source_yaml, output_yaml) if preserve_comments
|
37
|
-
@rubocop_configuration_path.write(output_yaml)
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def sanitize_yaml(data)
|
43
|
-
data.gsub(/^([a-zA-Z]+)/, "\n\\1")
|
44
|
-
end
|
45
|
-
|
46
|
-
def load_yaml
|
47
|
-
YAML.safe_load(source_yaml, permitted_classes: PERMITTED_CLASSED)
|
48
|
-
end
|
49
|
-
|
50
|
-
def source_yaml
|
51
|
-
@source_yaml ||= @rubocop_configuration_path.read
|
52
|
-
end
|
53
|
-
|
54
|
-
def preserve_preceding_comments(source, target)
|
55
|
-
target.dup.tap do |output|
|
56
|
-
source.scan(/(((^ *#.*\n|^\s*\n)+)(?![\s#]).+)/) do |groups|
|
57
|
-
config_keys_with_preceding_lines = groups.first
|
58
|
-
*preceding_lines, config_key = config_keys_with_preceding_lines.split("\n")
|
59
|
-
|
60
|
-
next if preceding_lines.all?(:empty?)
|
61
|
-
next if config_key.gsub(/\s/, "").empty?
|
62
|
-
|
63
|
-
output.sub!(/^#{config_key}$/, config_keys_with_preceding_lines.strip)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|