no_comments 0.1.4 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f4d0bbabf8d2083a22cb850026add69671c3af79b1d0cb75a0a891e5187aea4
4
- data.tar.gz: a8a312eea4658d6da9ac64007d9da4ea94efc642fc0381406e4fbc82b0b84726
3
+ metadata.gz: 71ade70ce6b697e2f4f4244766a9b7914c04b628eb9c87ba4f4273b8c4cbb846
4
+ data.tar.gz: 9ed3453c9e8c9fe097e6b5506ada7917adcd54e10ec7bfd0e2297508612eff12
5
5
  SHA512:
6
- metadata.gz: aa15e36876ee00b72f23b2043eb661a736df5de5876b14e5e587cb04c99e7af9858d8f030520efac7af0ff8939901571a12f67f72182f87e6e94ae9abc1eb779
7
- data.tar.gz: a3aa64ab64f4c7ba06da376b7fe16e027d363b8a22626b5b23e7a5c6d99051939dd23039751ac14ed3f27258abdcf7c5869516c5fdcfc772c0f81c67e1d23478
6
+ metadata.gz: 6768a1bafedf5cf9abb143c5a08cca1bd534122d888fde625ebb124fb1591b6f6fce9c8585463ab2f27692a322c85c1f119d454b4f4847c03428545174a8b0a9
7
+ data.tar.gz: c3f05e89997be0923516daf3599a080b222d19c1cbca23e5b52553e282fcdfe7246e7cbbc1e2b4fa543181765b23dc36f35ee307337c2d29fd9ca39b72e3a55f
data/.rubocop.yml CHANGED
@@ -16,6 +16,12 @@ Metrics/BlockLength:
16
16
  Exclude:
17
17
  - 'spec/no_comments/**/*'
18
18
 
19
+ Metrics/ClassLength:
20
+ Max: 150
21
+
22
+ Metrics/MethodLength:
23
+ Max: 20
24
+
19
25
  Style/Documentation:
20
26
  Enabled: false
21
27
 
data/README.md CHANGED
@@ -1,23 +1,52 @@
1
- # no_comments
1
+ # NoComments
2
+ NoComments is a Ruby gem designed to clean up `.rb` files by removing unnecessary comments, leaving your code clean and ready for deployment.
2
3
 
3
- `no_comments` is a simple Ruby gem that removes comments from `.rb` files. It can handle single-line comments and inline comments, leaving your code clean and readable.
4
+ ## What This Gem Does
5
+ It removes:
4
6
 
5
- ---
7
+ - Single-line comments (e.g., # This is a comment)
8
+ - Block comments (e.g., =begin ... =end)
9
+ - Inline comments (e.g., puts 'Hello' # This is a comment)
10
+
11
+ It preserves:
12
+
13
+ - Shebangs (e.g., #!/usr/bin/env ruby)
14
+ - Magic comments (e.g., # frozen_string_literal: true)
15
+ - Tool-defined comments (e.g., # rubocop:disable all)
6
16
 
7
17
  ## Table of Contents
18
+ 1. [When to Use This Gem](#When-to-Use-This-Gem)
19
+ 2. [When Not to Use This Gem](#When-Not-to-Use-This-Gem)
20
+ 3. [Installation](#Installation)
21
+ 4. [Usage](#Usage)
22
+ - [Audit Mode](#Audit-Mode)
23
+ - [CLI](#CLI)
24
+ 5. [Testing](#Testing)
25
+ 6. [Contributing](#Contributing)
26
+ 7. [License](#License)
27
+ 8. [TODO](#TODO)
8
28
 
9
- 1. [Installation](#installation)
10
- 2. [Usage](#usage)
11
- 3. [Testing](#testing)
12
- 4. [Contribution](#contribution)
13
- 5. [License](#license)
14
- 6. [TODO](#todo)
29
+ ## When to Use This Gem
15
30
 
16
- ---
31
+ NoComments is particularly useful in the following scenarios:
32
+
33
+ - **Auto-Generated or Boilerplate Code:** Helps clean up scaffolding or boilerplate comments, commonly generated in frameworks like Rails.
34
+ - **Codebases with Overused Comments:** Removes redundant comments that restate obvious code.
35
+ - **Continuous Integration/Code Review Workflows:** Automates comment cleanup during CI/CD processes.
36
+ - **Educational Projects:** Streamlines code by removing teaching-related comments after the learning phase.
37
+ - **Maintaining Open Source Projects:** Ensures consistency by removing unnecessary comments in contributions.
38
+
39
+ ## When Not to Use This Gem
40
+
41
+ While the gem is powerful, it may not be suitable in these scenarios:
42
+
43
+ - **Code with Valuable Documentation Comments:** Avoid using the gem if your code relies on comments for explaining complex logic or business rules.
44
+ - **Codebases Requiring Compliance:** In regulated industries, where specific comments are required for audits or documentation purposes.
45
+ - **Highly Dynamic Environments:** In fast-changing projects, comments might provide crucial context for recent changes or decisions.
17
46
 
18
47
  ## Installation
19
48
 
20
- To install `no_comments`, add it to your Gemfile:
49
+ To install no_comments, add it to your Gemfile:
21
50
 
22
51
  ```ruby
23
52
  gem 'no_comments'
@@ -27,95 +56,109 @@ Then execute:
27
56
  ```bash
28
57
  bundle install
29
58
  ```
30
- Or install it yourself using the following command:
59
+
60
+ Or install directly:
31
61
 
32
62
  ```bash
33
63
  gem install no_comments
34
64
  ```
35
65
 
36
-
37
66
  ## Usage
38
- To clean up comments from a .rb file or directory, use the `NoComments::Remover.clean` method. This will remove all single-line comments and inline comments from the file or directory.
67
+
68
+ ### Cleaning Files or Directories
69
+ To clean up comments from a `.rb` file or an entire directory, use the `NoComments::Remover.clean` method:
39
70
 
40
71
  ```ruby
41
72
  require 'no_comments'
42
73
 
74
+ # Clean a single file
43
75
  NoComments::Remover.clean('path/to/your_file.rb')
44
- NoComments::Remover.clean('path/to/your_directory')
45
76
 
77
+ # Clean all `.rb` files in a directory
78
+ NoComments::Remover.clean('path/to/your_directory')
46
79
  ```
47
80
  ### Audit Mode
48
-
49
- To use the audit mode, pass the `audit: true` flag to the `clean` method. This will output the file paths and lines containing comments without modifying the files.
50
-
51
- #### Example
81
+ Audit mode allows you to preview the comments that would be removed without modifying the files. Use the `audit: true` flag with the `clean` method:
52
82
 
53
83
  ```ruby
54
84
  NoComments::Remover.clean('example.rb', audit: true)
55
85
  ```
56
- #### Output
57
-
86
+ #### Example Output:
87
+ `example.rb`:
88
+ ```ruby
89
+ # This is a comment
90
+ def hello
91
+ puts 'Hello' # Another comment
92
+ end
93
+ ```
94
+ Output:
58
95
  ```bash
59
96
  File: example.rb
60
97
  Line 1: # This is a comment
61
98
  Line 3: # Another comment
62
99
  ```
63
100
 
64
- ### Command-Line Interface (CLI)
65
-
66
- You can use `no_comments` directly from the command line to clean or audit `.rb` files.
67
-
68
- #### Clean Comments
69
-
70
- To remove comments from a file, use:
101
+ ### CLI
102
+ `NoComments` provides a Command Line Interface (CLI) for easy comment cleanup. The CLI supports the following options:
71
103
 
104
+ #### Clean Comments:
72
105
  ```bash
73
106
  no_comments -p path/to/file.rb
74
107
  no_comments -p path/to/directory
75
108
  ```
76
- #### Audit mode
77
-
78
- To run `no_comments` in audit mode without modifying files, use the `--audit` flag:
79
-
109
+ #### Audit Mode:
80
110
  ```bash
81
111
  no_comments -p path/to/file.rb --audit
82
112
  no_comments -p path/to/directory --audit
83
113
  ```
84
114
 
85
115
  ## Testing
86
- `no_comments` uses RSpec for testing. To run the tests, first make sure all dependencies are installed:
87
116
 
117
+ This gem uses RSpec for testing. To run tests:
118
+
119
+ 1. Install dependencies:
88
120
  ```bash
89
121
  bundle install
90
122
  ```
91
- Then, run the tests with:
92
-
123
+ 2. Run the test suite::
93
124
  ```bash
94
125
  bundle exec rspec
95
126
  ```
96
- All tests are located in the spec directory and cover the main functionality of the gem, ensuring it properly removes comments from Ruby files.
97
127
 
98
- ## Contribution
128
+ Tests are located in the spec directory and ensure that the gem behaves as expected, removing comments appropriately while preserving essential ones.
99
129
 
100
- Bug reports and pull requests are welcome on GitHub at https://github.com/justi/no_comments.
130
+ ## Contributing
131
+ We welcome contributions! To contribute:
101
132
 
102
- To contribute:
103
-
104
- Fork the repository.
105
- Create a new branch (git checkout -b feature-branch).
106
- Make your changes.
107
- Commit your changes (git commit -m 'Add new feature').
108
- Push to the branch (git push origin feature-branch).
109
- Open a pull request.
133
+ 1. Fork the repository.
134
+ 2. Create a new branch for your feature or fix:
135
+ ```bash
136
+ git checkout -b feature-branch
137
+ ```
138
+ 3. Make your changes.
139
+ 4. Commit your changes with a descriptive message:
140
+ ```bash
141
+ git commit -m 'Add new feature'
142
+ ```
143
+ 5. Push your branch:
144
+ ```bash
145
+ git push origin feature-branch
146
+ ```
147
+ 6. Open a pull request on GitHub.
110
148
 
111
- Please ensure that your code follows the existing style and that all tests pass.
149
+ Please ensure your code follows the existing style and that all tests pass before submitting.
112
150
 
113
151
  ## License
114
- The gem is available as open source under the terms of the MIT License.
115
-
152
+ This gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
116
153
 
117
154
  ## TODO
118
- - Add support multi-line comments (`=begin`...`=end`)
119
- - Add support to magic comments (e.g. `# frozen_string_literal: true`) https://docs.ruby-lang.org/en/3.2/syntax/comments_rdoc.html - thanks [Chris](https://github.com/khasinski)!
120
- - Option to keep documentation comments (e.g. `# @param`) https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Style/Documentation
121
- - Option to clean all files in a directory except for a specified file
155
+ Planned features for future updates:
156
+ - **Option to Keep Documentation Comments:**
157
+ - Preserve comments like # @param or # @return for tools like YARD.
158
+ Reference: [RuboCop documentation cop](https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Style/Documentation).
159
+ - **Selective Cleaning:**
160
+ - Allow users to clean all files in a directory except for specified ones.
161
+
162
+ ---
163
+ ## Why Use NoComments?
164
+ NoComments is the perfect tool for keeping your codebase clean and focused, whether you're starting fresh or maintaining an existing project. By automating comment cleanup, you can focus on what matters: writing great code.
data/exe/no_comments CHANGED
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "optparse"
5
- require "no_comments"
5
+ require "no_comments/remover"
6
6
 
7
7
  options = {}
8
8
  OptionParser.new do |opts|
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # lib/no_comments/comment_detector.rb
4
+
5
+ module NoComments
6
+ module CommentDetector
7
+ MAGIC_COMMENT_REGEX = /\A#.*\b(?:frozen_string_literal|encoding|coding|warn_indent|fileencoding)\b.*\z/
8
+ TOOL_COMMENT_REGEX = /\A#\s*(?:rubocop|reek|simplecov|coveralls|pry|byebug|noinspection|sorbet|type)\b/
9
+
10
+ def magic_comment?(stripped_line)
11
+ stripped_line.match?(MAGIC_COMMENT_REGEX)
12
+ end
13
+
14
+ def tool_comment?(stripped_line)
15
+ stripped_line.match?(TOOL_COMMENT_REGEX)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ # lib/no_comments/content_processor.rb
4
+
5
+ require "no_comments/version"
6
+ require "no_comments/comment_detector"
7
+ require "no_comments/line_parser"
8
+
9
+ module NoComments
10
+ class ContentProcessor
11
+ include CommentDetector
12
+ include LineParser
13
+
14
+ def initialize
15
+ @comments = []
16
+ @result_lines = []
17
+ @in_multiline_comment = false
18
+ @in_heredoc = false
19
+ @heredoc_delimiter = nil
20
+ @line_number = 0
21
+ @code_started = false
22
+ end
23
+
24
+ def process(content)
25
+ lines = content.lines
26
+
27
+ lines.each do |line|
28
+ @line_number += 1
29
+ stripped_line = line.strip
30
+ process_line(line, stripped_line)
31
+ end
32
+
33
+ cleaned_content = @result_lines.join("\n")
34
+ cleaned_content += "\n" unless cleaned_content.empty?
35
+ [cleaned_content, @comments]
36
+ end
37
+
38
+ def process_line(line, stripped_line)
39
+ if @in_multiline_comment
40
+ handle_multiline_comment(stripped_line)
41
+ elsif @in_heredoc
42
+ handle_heredoc(line, stripped_line)
43
+ elsif !@code_started
44
+ handle_initial_lines(line, stripped_line)
45
+ else
46
+ handle_regular_line(line, stripped_line)
47
+ end
48
+ end
49
+
50
+ def handle_initial_lines(line, stripped_line)
51
+ if stripped_line.empty? || stripped_line.start_with?("#!") || magic_comment?(stripped_line)
52
+ # Preserve blank lines, shebang lines, and magic comments
53
+ @result_lines << line.rstrip
54
+ elsif stripped_line.start_with?("#")
55
+ if tool_comment?(stripped_line)
56
+ # Preserve tool-specific comments
57
+ @result_lines << line.rstrip
58
+ else
59
+ # Regular comment at the top, remove it
60
+ @comments << [@line_number, stripped_line]
61
+ end
62
+ else
63
+ # First code line encountered
64
+ @code_started = true
65
+ handle_regular_line(line, stripped_line)
66
+ end
67
+ end
68
+
69
+ def handle_multiline_comment(stripped_line)
70
+ @comments << [@line_number, stripped_line]
71
+ @in_multiline_comment = false if stripped_line == "=end"
72
+ end
73
+
74
+ def handle_heredoc(line, stripped_line)
75
+ @result_lines << line.rstrip
76
+ @in_heredoc, @heredoc_delimiter = update_heredoc_state(
77
+ stripped_line, @heredoc_delimiter
78
+ )
79
+ end
80
+
81
+ def handle_regular_line(line, stripped_line)
82
+ if stripped_line == "=begin"
83
+ start_multiline_comment(stripped_line)
84
+ elsif (heredoc_start = detect_heredoc_start(line))
85
+ start_heredoc(line, heredoc_start)
86
+ elsif stripped_line.start_with?("#") && tool_comment?(stripped_line)
87
+ # Preserve tool-specific comments anywhere in the code
88
+ @result_lines << line.rstrip
89
+ else
90
+ process_code_line(line)
91
+ end
92
+ end
93
+
94
+ def start_multiline_comment(stripped_line)
95
+ @in_multiline_comment = true
96
+ @comments << [@line_number, stripped_line]
97
+ end
98
+
99
+ def start_heredoc(line, heredoc_start)
100
+ @in_heredoc = true
101
+ @heredoc_delimiter = heredoc_start
102
+ @result_lines << line.rstrip
103
+ end
104
+
105
+ def process_code_line(line)
106
+ code_part, comment_part = split_line(line)
107
+ if comment_part && tool_comment?(comment_part.strip)
108
+ # Preserve tool-specific inline comments
109
+ @result_lines << ("#{code_part.rstrip} #{comment_part.strip}")
110
+ else
111
+ @comments << [@line_number, comment_part.strip] if comment_part
112
+ return if code_part.strip.empty?
113
+
114
+ @result_lines << code_part.rstrip
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ # lib/no_comments/line_parser.rb
4
+
5
+ module NoComments
6
+ module LineParser
7
+ # rubocop:disable Metrics/MethodLength
8
+ # rubocop:disable Metrics/AbcSize
9
+ # rubocop:disable Metrics/CyclomaticComplexity
10
+ # rubocop:disable Metrics/PerceivedComplexity
11
+ # rubocop:disable Metrics/BlockNesting
12
+ #
13
+ def split_line(line)
14
+ in_single_quote = false
15
+ in_double_quote = false
16
+ in_regex = false
17
+ escape = false
18
+ index = 0
19
+
20
+ while index < line.length
21
+ char = line[index]
22
+
23
+ if escape
24
+ escape = false
25
+ else
26
+ case char
27
+ when "\\"
28
+ escape = true
29
+ when "'"
30
+ in_single_quote = !in_single_quote unless in_double_quote || in_regex
31
+ when '"'
32
+ in_double_quote = !in_double_quote unless in_single_quote || in_regex
33
+ when "/"
34
+ if in_regex
35
+ in_regex = false
36
+ elsif !in_single_quote && !in_double_quote &&
37
+ preceding_char_is_operator?(line, index)
38
+ in_regex = true
39
+ end
40
+ when "#"
41
+ result = handle_comment_character(line, index, in_single_quote, in_double_quote, in_regex)
42
+ return result if result
43
+ end
44
+ end
45
+ index += 1
46
+ end
47
+ [line, nil]
48
+ end
49
+ # rubocop:enable Metrics/MethodLength
50
+ # rubocop:enable Metrics/AbcSize
51
+ # rubocop:enable Metrics/CyclomaticComplexity
52
+ # rubocop:enable Metrics/PerceivedComplexity
53
+ # rubocop:enable Metrics/BlockNesting
54
+
55
+ def handle_comment_character(line, index, in_single_quote, in_double_quote, in_regex)
56
+ unless in_single_quote || in_double_quote || in_regex
57
+ code_part = line[0...index]
58
+ comment_part = line[index..]
59
+ return [code_part, comment_part]
60
+ end
61
+ nil
62
+ end
63
+
64
+ def update_heredoc_state(stripped_line, heredoc_delimiter)
65
+ if stripped_line == heredoc_delimiter
66
+ [false, nil]
67
+ else
68
+ [true, heredoc_delimiter]
69
+ end
70
+ end
71
+
72
+ def detect_heredoc_start(line)
73
+ if (match = line.match(/<<[-~]?(["'`]?)(\w+)\1/))
74
+ match[2]
75
+ end
76
+ end
77
+
78
+ def preceding_char_is_operator?(line, index)
79
+ idx = index - 1
80
+ idx -= 1 while idx >= 0 && line[idx] =~ /\s/
81
+
82
+ return true if idx.negative? # Beginning of line or after whitespace
83
+
84
+ # Handle special case where preceding character is part of a multi-character operator
85
+ return true if line[idx - 1..idx] == "::"
86
+
87
+ prev_char = line[idx]
88
+
89
+ # List of operator characters
90
+ operator_chars = %w[\[ = + - * / % | & ! < > ^ ~ ( , ? : ; {]
91
+
92
+ # Return true if preceding character is an operator
93
+ operator_chars.include?(prev_char)
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ # lib/no_comments/remover.rb
4
+
5
+ require "no_comments/version"
6
+ require "no_comments/content_processor"
7
+
8
+ module NoComments
9
+ class Remover
10
+ def self.clean(file_path, audit: false)
11
+ if File.directory?(file_path)
12
+ Dir.glob("#{file_path}/**/*.rb").each do |file|
13
+ process_file(file, audit: audit)
14
+ end
15
+ else
16
+ process_file(file_path, audit: audit)
17
+ end
18
+ end
19
+
20
+ def self.process_file(file_path, audit: false)
21
+ validate_file_extension(file_path)
22
+ content = File.read(file_path)
23
+
24
+ processor = ContentProcessor.new
25
+ cleaned_content, comments = processor.process(content)
26
+
27
+ if audit
28
+ print_audit(file_path, comments)
29
+ else
30
+ File.write(file_path, cleaned_content)
31
+ end
32
+ end
33
+
34
+ def self.validate_file_extension(file_path)
35
+ raise "Only Ruby files are supported" unless file_path.end_with?(".rb")
36
+ end
37
+
38
+ def self.print_audit(file_path, comments)
39
+ return if comments.empty?
40
+
41
+ puts "File: #{file_path}"
42
+ comments.each do |line_number, comment_text|
43
+ puts " Line #{line_number}: #{comment_text}"
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module NoComments
4
- VERSION = "0.1.4"
4
+ VERSION = "0.1.6"
5
5
  end
data/lib/no_comments.rb CHANGED
@@ -1,76 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "no_comments/version"
4
- require "ripper"
3
+ require "no_comments/content_processor"
4
+ require "no_comments/remover"
5
5
 
6
6
  module NoComments
7
- class Remover
8
- def self.clean(file_path, audit: false)
9
- if File.directory?(file_path)
10
- Dir.glob("#{file_path}/**/*.rb").each do |file|
11
- process_file(file, audit: audit)
12
- end
13
- else
14
- process_file(file_path, audit: audit)
15
- end
16
- end
17
-
18
- def self.process_file(file_path, audit: false)
19
- validate_file_extension(file_path)
20
- file_content = File.read(file_path)
21
-
22
- if audit
23
- audit_comments(file_path, file_content)
24
- else
25
- content_cleaned = remove_comments(file_content)
26
- File.write(file_path, content_cleaned)
27
- end
28
- end
29
-
30
- def self.validate_file_extension(file_path)
31
- raise "Only Ruby files are supported" unless file_path.end_with?(".rb")
32
- end
33
-
34
- def self.audit_comments(file_path, content)
35
- comments = extract_comments(content)
36
- puts "File: #{file_path}" unless comments.empty?
37
-
38
- comments.each do |(pos, _, tok, _)|
39
- line, = pos
40
- puts " Line #{line}: #{tok.strip}"
41
- end
42
- end
43
-
44
- def self.remove_comments(content)
45
- comments = extract_comments(content)
46
- content = process_comments(content, comments)
47
- remove_empty_lines(content)
48
- end
49
-
50
- def self.extract_comments(content)
51
- Ripper.lex(content).select { |_pos, type, _tok, _| type == :on_comment }
52
- end
53
-
54
- def self.process_comments(content, comments)
55
- comments.sort_by { |(pos, _, _, _)| [pos[0], pos[1]] }.reverse.each do |(pos, _, _, _)|
56
- line, col = pos
57
- lines = content.lines
58
- lines[line - 1] = process_comment_line(lines[line - 1], col)
59
- content = lines.join
60
- end
61
- content
62
- end
63
-
64
- def self.process_comment_line(line, col)
65
- if line[col..].strip.start_with?("#")
66
- "#{line[0...col].rstrip}\n"
67
- else
68
- "\n"
69
- end
70
- end
71
-
72
- def self.remove_empty_lines(content)
73
- content.gsub(/^\s*$\n/, "")
74
- end
75
- end
76
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: no_comments
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justyna
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-16 00:00:00.000000000 Z
11
+ date: 2024-11-17 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -25,6 +25,10 @@ files:
25
25
  - Rakefile
26
26
  - exe/no_comments
27
27
  - lib/no_comments.rb
28
+ - lib/no_comments/comment_detector.rb
29
+ - lib/no_comments/content_processor.rb
30
+ - lib/no_comments/line_parser.rb
31
+ - lib/no_comments/remover.rb
28
32
  - lib/no_comments/version.rb
29
33
  - sig/no_comments.rbs
30
34
  homepage: