vinter 0.6.1 → 0.6.3

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/lib/vinter/cli.rb +209 -26
  3. data/lib/vinter.rb +1 -1
  4. metadata +8 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 18b99e927ea645baaa6bf8290f53625a800c64a36e7bcb681d8096f7591ab862
4
- data.tar.gz: 35660a038fcc98c284731d75fe3644d41ff5a9212dd1ca7930d21d72b9f02764
3
+ metadata.gz: 24da5c73f3d23b6cf4102c37632877a090534aa5343e99b73aab613aa6e5a860
4
+ data.tar.gz: 7250550dedf15c7fe332ab7a048b833ff93c09bbc48433f50b0845aff7448db1
5
5
  SHA512:
6
- metadata.gz: f9ed5e432fcdc6e0a88545e15da0996dda4c31176c88fdcbb46f2ea4228bc4c431fe1e569b3e7420f370ab8147ac290738ac27dd21f1f7bed0a0d2093da5b933
7
- data.tar.gz: be685a411f5592425d122ea8a3080208c1cad58566dc88b7e5850a0e017ae9beebfff1c1a019955a47eb7e54a732ba94e4f2966d52e536404ce35ad1096465f9
6
+ metadata.gz: 26d2eb57e3ee43e442e786e76da8c06729c0f9253deca4ac991582a7595bdfe08580d4d9ac784eefa55d7619392725c5f818612744088fe49a2d87019261f29f
7
+ data.tar.gz: 380639a4f1fff2b3010317d8f1fa392ac6911a5fd3beb827590ce6220320d5c5a77209edce450032751e00030391a35743a6787fc51cb5a21ea1c5f7a70db0db
data/lib/vinter/cli.rb CHANGED
@@ -6,21 +6,125 @@ module Vinter
6
6
 
7
7
  def run(args)
8
8
  if args.empty?
9
- puts "Usage: vinter [file.vim|directory]"
9
+ puts "Usage: vinter [file.vim|directory] [--exclude=dir1,dir2] [--stdio]"
10
10
  return 1
11
11
  end
12
12
 
13
- target_path = args[0]
13
+ # Parse args: first non-option argument is the target path.
14
+ exclude_value = nil
15
+ target_path = nil
16
+ stdio = false
17
+ format_value = nil
14
18
 
15
- unless File.exist?(target_path)
16
- puts "Error: File or directory not found: #{target_path}"
19
+ args.each_with_index do |a, i|
20
+ if a.start_with?("--exclude=")
21
+ exclude_value = a.split("=", 2)[1]
22
+ elsif a == "--exclude"
23
+ exclude_value = args[i + 1]
24
+ elsif a == "--stdio" || a.start_with?("--stdio=")
25
+ stdio = true
26
+ elsif a.start_with?("--format=")
27
+ format_value = a.split("=", 2)[1]
28
+ elsif a == "--format"
29
+ format_value = args[i + 1]
30
+ elsif !a.start_with?('-') && target_path.nil?
31
+ target_path = a
32
+ end
33
+ end
34
+
35
+ if target_path.nil? && !stdio
36
+ puts "Usage: vinter [file.vim|directory] [--exclude=dir1,dir2] [--stdio]"
17
37
  return 1
18
38
  end
19
39
 
40
+ unless stdio
41
+ unless File.exist?(target_path)
42
+ puts "Error: File or directory not found: #{target_path}"
43
+ return 1
44
+ end
45
+ end
46
+
47
+ excludes = Array(exclude_value).flat_map { |v| v.to_s.split(',') }.map(&:strip).reject(&:empty?)
48
+
49
+ # normalize format value
50
+ format_value = format_value.to_s.downcase if format_value
51
+
52
+ # Handle STDIN input mode
53
+ if stdio
54
+ content = STDIN.read
55
+
56
+ if content.nil? || content.empty?
57
+ puts "No input received on stdin"
58
+ return 0
59
+ end
60
+
61
+ issues = @linter.lint(content)
62
+ total_issues = issues.length
63
+
64
+ if format_value == 'json'
65
+ require 'json'
66
+
67
+ files = [
68
+ {
69
+ path: 'stdin',
70
+ offenses: issues.map do |issue|
71
+ {
72
+ severity: (issue[:type] == :error ? 'fatal' : (issue[:type] == :warning ? 'warning' : 'convention')),
73
+ message: issue[:message],
74
+ cop_name: issue[:rule],
75
+ corrected: false,
76
+ correctable: false,
77
+ location: {
78
+ start_line: issue[:line] || 1,
79
+ start_column: issue[:column] || 1,
80
+ last_line: issue[:line] || 1,
81
+ last_column: issue[:column] || 1,
82
+ length: 0,
83
+ line: issue[:line] || 1,
84
+ column: issue[:column] || 1
85
+ }
86
+ }
87
+ end
88
+ }
89
+ ]
90
+
91
+ metadata = {
92
+ 'rubocop_version' => defined?(Vinter::VERSION) ? Vinter::VERSION : nil,
93
+ 'ruby_engine' => defined?(RUBY_ENGINE) ? RUBY_ENGINE : RUBY_PLATFORM,
94
+ 'ruby_version' => RUBY_VERSION,
95
+ 'ruby_patchlevel' => RUBY_PATCHLEVEL.to_s,
96
+ 'ruby_platform' => RUBY_PLATFORM
97
+ }
98
+
99
+ summary = {
100
+ 'offense_count' => total_issues,
101
+ 'target_file_count' => files.length,
102
+ 'inspected_file_count' => files.length
103
+ }
104
+
105
+ output = { metadata: metadata, files: files, summary: summary }
106
+ options = {
107
+ indent: '',
108
+ space: '',
109
+ space_before: '',
110
+ object_nl: '',
111
+ array_nl: ''
112
+ }
113
+ puts JSON.pretty_generate(output, options)
114
+
115
+ return total_issues > 0 ? 1 : 0
116
+ end
117
+ end
118
+
20
119
  vim_files = if File.directory?(target_path)
21
- find_vim_files(target_path)
120
+ find_vim_files(target_path, excludes)
22
121
  else
23
- [target_path]
122
+ # Check if single file is inside an excluded directory
123
+ if excluded_file?(target_path, excludes, File.dirname(target_path))
124
+ []
125
+ else
126
+ [target_path]
127
+ end
24
128
  end
25
129
 
26
130
  if vim_files.empty?
@@ -30,46 +134,125 @@ module Vinter
30
134
 
31
135
  total_issues = 0
32
136
  error_count = 0
137
+ json_files = []
33
138
 
34
139
  vim_files.each do |file_path|
35
140
  content = File.read(file_path)
36
141
  issues = @linter.lint(content)
37
142
  total_issues += issues.length
38
143
 
39
- if issues.empty?
40
- puts "No issues found in #{file_path}" if vim_files.length == 1
144
+ if format_value == 'json'
145
+ json_files << {
146
+ path: file_path,
147
+ offenses: issues.map do |issue|
148
+ {
149
+ severity: (issue[:type] == :error ? 'fatal' : (issue[:type] == :warning ? 'warning' : 'convention')),
150
+ message: issue[:message],
151
+ cop_name: issue[:rule],
152
+ corrected: false,
153
+ correctable: false,
154
+ location: {
155
+ start_line: issue[:line] || 1,
156
+ start_column: issue[:column] || 1,
157
+ last_line: issue[:line] || 1,
158
+ last_column: issue[:column] || 1,
159
+ length: 0,
160
+ line: issue[:line] || 1,
161
+ column: issue[:column] || 1
162
+ }
163
+ }
164
+ end
165
+ }
41
166
  else
42
- puts "Found #{issues.length} issues in #{file_path}:" if vim_files.length > 1
167
+ if issues.empty?
168
+ puts "No issues found in #{file_path}" if vim_files.length == 1
169
+ else
170
+ puts "Found #{issues.length} issues in #{file_path}:" if vim_files.length > 1
43
171
 
44
- issues.each do |issue|
45
- type_str = case issue[:type]
46
- when :error then "ERROR"
47
- when :warning then "WARNING"
48
- when :rule then "RULE(#{issue[:rule]})"
49
- else "UNKNOWN"
50
- end
172
+ issues.each do |issue|
173
+ type_str = case issue[:type]
174
+ when :error then "ERROR"
175
+ when :warning then "WARNING"
176
+ when :rule then "RULE(#{issue[:rule]})"
177
+ else "UNKNOWN"
178
+ end
51
179
 
52
- line = issue[:line] || 1
53
- column = issue[:column] || 1
180
+ line = issue[:line] || 1
181
+ column = issue[:column] || 1
54
182
 
55
- puts "#{file_path}:#{line}:#{column}: #{type_str}: #{issue[:message]}"
56
- end
183
+ puts "#{file_path}:#{line}:#{column}: #{type_str}: #{issue[:message]}"
184
+ end
57
185
 
58
- error_count += 1 if issues.any? { |i| i[:type] == :error }
186
+ error_count += 1 if issues.any? { |i| i[:type] == :error }
187
+ end
59
188
  end
60
189
  end
61
190
 
62
- if vim_files.length > 1
63
- puts "\nProcessed #{vim_files.length} files, found #{total_issues} total issues"
191
+ #if vim_files.length > 1
192
+ #puts "\nProcessed #{vim_files.length} files, found #{total_issues} total issues"
193
+ #end
194
+
195
+ if format_value == 'json'
196
+ require 'json'
197
+
198
+ metadata = {
199
+ 'rubocop_version' => defined?(Vinter::VERSION) ? Vinter::VERSION : nil,
200
+ 'ruby_engine' => defined?(RUBY_ENGINE) ? RUBY_ENGINE : RUBY_PLATFORM,
201
+ 'ruby_version' => RUBY_VERSION,
202
+ 'ruby_patchlevel' => RUBY_PATCHLEVEL.to_s,
203
+ 'ruby_platform' => RUBY_PLATFORM
204
+ }
205
+
206
+ summary = {
207
+ 'offense_count' => total_issues,
208
+ 'target_file_count' => vim_files.length,
209
+ 'inspected_file_count' => vim_files.length
210
+ }
211
+
212
+ output = { metadata: metadata, files: json_files, summary: summary }
213
+ options = {
214
+ indent: '',
215
+ space: '',
216
+ space_before: '',
217
+ object_nl: '',
218
+ array_nl: ''
219
+ }
220
+ puts JSON.pretty_generate(output, options)
221
+
222
+ return total_issues > 0 ? 1 : 0
64
223
  end
65
224
 
66
- return error_count > 0 ? 1 : 0
225
+ return total_issues > 0 ? 1 : 0
67
226
  end
68
227
 
69
228
  private
70
229
 
71
- def find_vim_files(directory)
72
- Dir.glob(File.join(directory, "**", "*.vim")).sort
230
+ def find_vim_files(directory, excludes = [])
231
+ files = Dir.glob(File.join(directory, "**", "*.vim")).sort
232
+
233
+ return files if excludes.empty?
234
+
235
+ # Normalize exclude directories to absolute paths (relative to the target directory)
236
+ normalized = excludes.map { |e| File.expand_path(e, directory) }
237
+
238
+ files.reject do |f|
239
+ normalized.any? do |ex|
240
+ ex_with_slash = ex.end_with?(File::SEPARATOR) ? ex : ex + File::SEPARATOR
241
+ f.start_with?(ex_with_slash) || File.expand_path(f).start_with?(ex_with_slash)
242
+ end
243
+ end
244
+ end
245
+
246
+ def excluded_file?(file_path, excludes, base_dir)
247
+ return false if excludes.empty?
248
+
249
+ normalized = excludes.map { |e| File.expand_path(e, base_dir) }
250
+ file_abs = File.expand_path(file_path)
251
+
252
+ normalized.any? do |ex|
253
+ ex_with_slash = ex.end_with?(File::SEPARATOR) ? ex : ex + File::SEPARATOR
254
+ file_abs.start_with?(ex_with_slash)
255
+ end
73
256
  end
74
257
  end
75
258
  end
data/lib/vinter.rb CHANGED
@@ -5,5 +5,5 @@ require "vinter/cli"
5
5
  require "vinter/ast_printer"
6
6
 
7
7
  module Vinter
8
- VERSION = "0.6.1"
8
+ VERSION = "0.6.3"
9
9
  end
metadata CHANGED
@@ -1,16 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vinter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
4
+ version: 0.6.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Bradbury
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2025-12-01 00:00:00.000000000 Z
11
12
  dependencies: []
12
- description: A linter for the Vim9 script language, helping to identify issues and
13
- enforce best practices
13
+ description: A linter for vim9script
14
14
  email: dan.luckydaisy@gmail.com
15
15
  executables:
16
16
  - vinter
@@ -30,6 +30,7 @@ homepage: https://github.com/DanBradbury/vinter
30
30
  licenses:
31
31
  - MIT
32
32
  metadata: {}
33
+ post_install_message:
33
34
  rdoc_options: []
34
35
  require_paths:
35
36
  - lib
@@ -44,7 +45,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
44
45
  - !ruby/object:Gem::Version
45
46
  version: '0'
46
47
  requirements: []
47
- rubygems_version: 3.6.9
48
+ rubygems_version: 3.5.11
49
+ signing_key:
48
50
  specification_version: 4
49
- summary: A linter for leagacy + Vim9 script
51
+ summary: A vim9script linter
50
52
  test_files: []