puppet-lint-param_comment-check 0.1.5 → 0.1.6

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: 637cfc1953d7f93cd5a8d160e90d7abeaf93efd0a1eafbf651dca61259fb6668
4
- data.tar.gz: 7d74686774590de42d926b2e1a952330a1613e2b3724a8aac531d5003d3916a8
3
+ metadata.gz: eb2381705a17c0af4eed37f55cd09a89fcaa0c14125c23437f3c664eb16cec37
4
+ data.tar.gz: 742a469983e7ccc5dd7c1779a313f9dbd16ed97a6f45d16f39c5c25d2038a510
5
5
  SHA512:
6
- metadata.gz: d67851be5623ec31c85ff025c13420e8535915d7f9df8d6e8c153df4e7f51c3874253a5dcdf87b30ccab4841a31501f91ab98989d40e30717ede4317dd55da18
7
- data.tar.gz: f47b461b2b56d68e9792be6c8da580f4f4222960364ef165d72fe867007e0a2335adcffe5898b978c386141c0b374c10228f9a7257971fbd11374b765666f2f5
6
+ metadata.gz: cbe23d30e66a7bff997c0a757ea1ad22739284547ac0d4bcbb64a7a622f5b2b296399141fe2559fe0717c2b40563d72be50b526a41dbf179da855cfcb57c64ec
7
+ data.tar.gz: 85bf5c06abbaa3d3bfe4f57e0ba78f51622a439a3aa2c6c48df970419831e0d103fa838a3af80886e84548e968436a61a064cc72bff4dba932ef67f55d659db4
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../puppet-lint-param_comment-check/param_workflow'
4
3
  require_relative '../../puppet-lint-param_comment-check/param_comments'
4
+ require_relative '../../puppet-lint-param_comment-check/param'
5
5
 
6
6
  # The empty data of a parameter
7
7
  EMPTY_PARAM = {
@@ -28,44 +28,13 @@ def get_comments(tokens, token_start)
28
28
  comments.reject { |comment| comment.type == :NEWLINE }.reverse
29
29
  end
30
30
 
31
- # Analyze a parameter token
32
- #
33
- # @param token The token to analyze
34
- # @param current_param the data object for the currently analyzed parameter
35
- def analyze_param_token(token, current_param)
36
- # noinspection RubyCaseWithoutElseBlockInspection
37
- case token.type
38
- when :VARIABLE
39
- current_param[:name] = token.value
40
- when :CLASSREF, :TYPE
41
- current_param[:type] = token.value
42
- when :EQUALS
43
- current_param[:has_default] = true
44
- current_param[:default] = token.next_token.value
45
- end
46
- current_param
47
- end
48
-
49
31
  # Analyze the parameters of a class or a defined type
50
32
  #
51
33
  # @param param_tokens The parameter tokens to analyze
52
- def analyze_params(param_tokens) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
53
- params = []
54
- current_param = EMPTY_PARAM.dup
55
- brackets = 0
56
- param_tokens.reject { |token| %i[WHITESPACE NEWLINE INDENT].include? token.type }.each do |token|
57
- brackets += 1 if %i[LBRACK LBRACE].include? token.type
58
- brackets -= 1 if %i[RBRACK RBRACE].include? token.type
59
- next unless brackets.zero?
60
-
61
- current_param = analyze_param_token(token, current_param) unless token.type == :COMMA
62
- if token.type == :COMMA
63
- params.append(current_param)
64
- current_param = EMPTY_PARAM.dup
65
- end
66
- end
67
- params.append(current_param) unless current_param[:name] == ''
68
- params
34
+ def analyze_params(param_tokens)
35
+ param_workflow = Param.new
36
+ param_workflow.process(param_tokens)
37
+ param_workflow.params
69
38
  end
70
39
 
71
40
  # Find, which parameters in the long list are missing in the short list and return their names
@@ -143,10 +112,14 @@ PuppetLint.new_check(:param_comment) do # rubocop:disable Metrics/BlockLength
143
112
  end
144
113
 
145
114
  # Check class or defined type indexes
146
- def check_indexes(indexes)
115
+ def check_indexes(indexes) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
147
116
  indexes.each do |index|
148
117
  comments = get_comments(tokens, index[:start])
149
- params = analyze_params(index[:param_tokens])
118
+ begin
119
+ params = analyze_params(index[:param_tokens])
120
+ rescue InvalidTokenForState, InvalidDefaultForOptional => e
121
+ return warn(e.message, e.token.line, e.token.column)
122
+ end
150
123
  return false unless check_comments(comments)
151
124
  return false unless check_parameters_count(params)
152
125
 
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'param_workflow'
4
+
5
+ PARAM_TYPE_ENUM = {
6
+ mandatory: 1,
7
+ with_default: 2,
8
+ optional: 3
9
+ }.freeze
10
+
11
+ # The empty data of a parameter
12
+ EMPTY_PARAM = {
13
+ name: '',
14
+ type: '',
15
+ default: [],
16
+ param_type: PARAM_TYPE_ENUM[:mandatory]
17
+ }.freeze
18
+
19
+ # Comment received in an invalid state
20
+ class InvalidTokenForState < StandardError
21
+ def initialize(token, state)
22
+ @token = token
23
+ @state = state
24
+ super "Can not process the token '#{@token.value.strip}' in the state #{@state}"
25
+ end
26
+
27
+ attr_reader :token
28
+ end
29
+
30
+ # An optional parameter does not have "undef" as the default
31
+ class InvalidDefaultForOptional < StandardError
32
+ def initialize(token, default_value)
33
+ @token = token
34
+ super "Invalid value '#{default_value}' for an parameter of type Optional. undef is required"
35
+ end
36
+
37
+ attr_reader :token
38
+ end
39
+
40
+ # A helper to analyze parameter comments using the ParamWorkflow fsm
41
+ class Param
42
+ def initialize
43
+ @workflow = ParamWorkflow.new(self)
44
+
45
+ reset
46
+ end
47
+
48
+ def reset
49
+ @params = []
50
+ @in_default = false
51
+ @default_tokens = []
52
+ @in_type = false
53
+ @type_tokens = []
54
+ @current_param = EMPTY_PARAM.dup
55
+ @current_token = nil
56
+ @workflow.restore!(:start)
57
+ end
58
+
59
+ # Walk through every parameter and transition the workflow fsm accordingly
60
+ #
61
+ # @param tokens A list of parameter tokens
62
+ def process(tokens) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/PerceivedComplexity
63
+ reset
64
+ brackets = 0
65
+ tokens.reject { |token| %i[NEWLINE INDENT].include? token.type }.each do |token| # rubocop:disable Metrics/BlockLength
66
+ @current_token = token
67
+ case token.type
68
+ when :TYPE
69
+ @workflow.got_type unless @in_type
70
+ @in_type = true
71
+ @type_tokens.append(token)
72
+ when :VARIABLE
73
+ @workflow.got_name(token, @type_tokens) unless @in_default
74
+ @in_type = false unless @in_default
75
+ @type_tokens = [] unless @in_default
76
+ @default_tokens.append(token) if @in_default
77
+ when :EQUALS
78
+ @in_default = true
79
+ when :COMMA
80
+ @workflow.got_end(@default_tokens) unless @in_type || brackets.positive?
81
+ @default_tokens = [] unless @in_type && brackets.positive?
82
+ @in_default = false unless @in_type && brackets.positive?
83
+ @type_tokens.append(token) if @in_type
84
+ when :LBRACE, :LBRACK
85
+ brackets += 1
86
+ @type_tokens.append(token) if @in_type
87
+ @default_tokens.append(token) if @in_default
88
+ when :RBRACE, :RBRACK
89
+ brackets -= 1
90
+ @type_tokens.append(token) if @in_type
91
+ @default_tokens.append(token) if @in_default
92
+ else
93
+ @type_tokens.append(token) if @in_type
94
+ @default_tokens.append(token) if @in_default
95
+ end
96
+ end
97
+ @workflow.got_end(@default_tokens) unless @workflow.current == :start
98
+ end
99
+
100
+ def got_name_trigger(_, token, type_tokens)
101
+ @current_param[:type] = type_tokens.map(&:value).join('')
102
+ if !@type_tokens.empty? && @type_tokens[0].value == 'OPTIONAL'
103
+ @current_param[:param_type] = PARAM_TYPE_ENUM[:optional]
104
+ end
105
+ @current_param[:name] = token.value
106
+ end
107
+
108
+ def got_end_trigger(_, default_tokens) # rubocop:disable Metrics/AbcSize,Metrics/CyclomaticComplexity
109
+ raise InvalidDefaultForOptional if @current_param[:param_type] == PARAM_TYPE_ENUM[:optional] &&
110
+ !default_tokens.empty? &&
111
+ default_tokens[0].value != 'undef'
112
+
113
+ @current_param[:default] = @default_tokens.map(&:value).join('') unless @default_tokens.empty?
114
+ @current_param[:param_type] = PARAM_TYPE_ENUM[:with_default] unless
115
+ @current_param[:param_type] == PARAM_TYPE_ENUM[:optional] || default_tokens.empty?
116
+ @params.append(@current_param)
117
+ @current_param = EMPTY_PARAM.dup
118
+ @in_default, @in_type = false
119
+ end
120
+
121
+ # Called when an invalid state transition would happen
122
+ def invalid_state
123
+ raise InvalidTokenForState.new(@current_token, @workflow.current)
124
+ end
125
+
126
+ # The list of analyzed parameters in the comments
127
+ attr_reader :params
128
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'param_comments_workflow'
4
+
3
5
  # The empty data of a parameter
4
6
  EMPTY_PARAM_COMMENT = {
5
7
  name: '',
@@ -56,7 +58,7 @@ end
56
58
  # A helper to analyze parameter comments using the ParamWorkflow fsm
57
59
  class ParamComments
58
60
  def initialize
59
- @workflow = ParamWorkflow.new(self)
61
+ @workflow = ParamCommentsWorkflow.new(self)
60
62
 
61
63
  reset
62
64
  end
@@ -73,7 +75,7 @@ class ParamComments
73
75
  # Walk through every comment and transition the workflow fsm accordingly
74
76
  #
75
77
  # @param comments A list of Comment tokens appearing before the class/defined type header
76
- def process(comments) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
78
+ def process(comments) # rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity,Metrics/AbcSize
77
79
  reset
78
80
  @current_comment = PuppetLint::Lexer::Token.new(:COMMENT, '', 1, 1)
79
81
  comments.each do |comment|
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'finite_machine'
4
+
5
+ # A finite state machine working through the expected parameter comments
6
+ class ParamCommentsWorkflow < FiniteMachine::Definition
7
+ initial :start
8
+
9
+ event :got_header, from: :start, to: :awaiting_description
10
+ event :got_header, from: :awaiting_header, to: :awaiting_description
11
+ event :got_description, from: :awaiting_description, to: :awaiting_separator
12
+ event :got_separator, from: :awaiting_separator, to: :awaiting_header
13
+
14
+ # for multi-line descriptions
15
+ event :got_description, from: :awaiting_separator, to: :awaiting_separator
16
+
17
+ # handling options
18
+ event :got_option_header, from: :awaiting_separator, to: :awaiting_option_description
19
+ event :got_option_description, from: :awaiting_option_description, to: :awaiting_separator
20
+
21
+ # for separators inside descriptions
22
+ event :got_description, from: :awaiting_header, to: :awaiting_separator
23
+ event :got_option_description, from: :awaiting_separator, to: :awaiting_separator
24
+
25
+ on_before(:got_header) { |event, comment| target.got_header_trigger(event, comment) }
26
+ on_before(:got_description) { |event, comment| target.got_description_trigger(event, comment) }
27
+ on_before(:got_option_description) { |event, comment| target.got_description_trigger(event, comment) }
28
+ on_before(:got_option_header) { |event, comment| target.got_option_header_trigger(event, comment) }
29
+
30
+ handle FiniteMachine::InvalidStateError, with: -> { target.invalid_state }
31
+ end
@@ -2,30 +2,22 @@
2
2
 
3
3
  require 'finite_machine'
4
4
 
5
- # A finite state machine working through the expected parameter comments
5
+ # A finite state machine working through the expected parameter tokens
6
6
  class ParamWorkflow < FiniteMachine::Definition
7
7
  initial :start
8
8
 
9
- event :got_header, from: :start, to: :awaiting_description
10
- event :got_header, from: :awaiting_header, to: :awaiting_description
11
- event :got_description, from: :awaiting_description, to: :awaiting_separator
12
- event :got_separator, from: :awaiting_separator, to: :awaiting_header
9
+ event :got_type, from: :start, to: :awaiting_name
10
+ event :got_name, from: :awaiting_name, to: :awaiting_default
13
11
 
14
- # for multi-line descriptions
15
- event :got_description, from: :awaiting_separator, to: :awaiting_separator
12
+ # For mandatory parameters
13
+ event :got_end, from: :awaiting_name, to: :start
14
+ event :got_end, from: :awaiting_default, to: :start
16
15
 
17
- # handling options
18
- event :got_option_header, from: :awaiting_separator, to: :awaiting_option_description
19
- event :got_option_description, from: :awaiting_option_description, to: :awaiting_separator
16
+ # For typeless parameters
17
+ event :got_name, from: :start, to: :awaiting_default
20
18
 
21
- # for separators inside descriptions
22
- event :got_description, from: :awaiting_header, to: :awaiting_separator
23
- event :got_option_description, from: :awaiting_separator, to: :awaiting_separator
24
-
25
- on_before(:got_header) { |event, comment| target.got_header_trigger(event, comment) }
26
- on_before(:got_description) { |event, comment| target.got_description_trigger(event, comment) }
27
- on_before(:got_option_description) { |event, comment| target.got_description_trigger(event, comment) }
28
- on_before(:got_option_header) { |event, comment| target.got_option_header_trigger(event, comment) }
19
+ on_before(:got_name) { |event, token, type_tokens| target.got_name_trigger(event, token, type_tokens) }
20
+ on_before(:got_end) { |event, default_tokens| target.got_end_trigger(event, default_tokens) }
29
21
 
30
22
  handle FiniteMachine::InvalidStateError, with: -> { target.invalid_state }
31
23
  end
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'spec_helper'
3
+ require_relative '../../spec_helper'
4
4
 
5
+ # rubocop:disable Metrics/BlockLength
5
6
  describe 'param_comment' do
6
7
  context 'valid code' do
7
8
  let(:code) do
@@ -255,9 +256,11 @@ describe 'param_comment' do
255
256
  end
256
257
 
257
258
  it 'should create a warning' do
258
- expect(problems).to contain_warning('Can not process the comment \'@param withdefault\' in the state awaiting_separator')
259
- .on_line(3)
260
- .in_column(1)
259
+ expect(problems).to contain_warning(
260
+ 'Can not process the comment \'@param withdefault\' in the state awaiting_separator'
261
+ )
262
+ .on_line(3)
263
+ .in_column(1)
261
264
  end
262
265
  end
263
266
 
@@ -276,9 +279,11 @@ describe 'param_comment' do
276
279
  end
277
280
 
278
281
  it 'should create a warning' do
279
- expect(problems).to contain_warning('Invalid param or hash option header: @param mandatory A mandatory parameter')
280
- .on_line(1)
281
- .in_column(1)
282
+ expect(problems).to contain_warning(
283
+ 'Invalid param or hash option header: @param mandatory A mandatory parameter'
284
+ )
285
+ .on_line(1)
286
+ .in_column(1)
282
287
  end
283
288
  end
284
289
 
@@ -321,9 +326,11 @@ describe 'param_comment' do
321
326
  end
322
327
 
323
328
  it 'should create a warning' do
324
- expect(problems).to contain_warning('Option references wrong hash @option mandatry [Boolean] :some_option')
325
- .on_line(3)
326
- .in_column(1)
329
+ expect(problems).to contain_warning(
330
+ 'Option references wrong hash @option mandatry [Boolean] :some_option'
331
+ )
332
+ .on_line(3)
333
+ .in_column(1)
327
334
  end
328
335
  end
329
336
 
@@ -347,10 +354,10 @@ describe 'param_comment' do
347
354
 
348
355
  it 'should create a warning' do
349
356
  expect(problems).to contain_warning(
350
- 'Can not process the comment \'@option mandatory [Boolean] :some_option\' in the state awaiting_header'
351
- )
352
- .on_line(4)
353
- .in_column(1)
357
+ 'Can not process the comment \'@option mandatory [Boolean] :some_option\' in the state awaiting_header'
358
+ )
359
+ .on_line(4)
360
+ .in_column(1)
354
361
  end
355
362
  end
356
363
 
@@ -372,10 +379,10 @@ describe 'param_comment' do
372
379
 
373
380
  it 'should create a warning' do
374
381
  expect(problems).to contain_warning(
375
- 'Invalid param or hash option header: @option mandatory [Boolean] :some_option An option'
376
- )
377
- .on_line(3)
378
- .in_column(1)
382
+ 'Invalid param or hash option header: @option mandatory [Boolean] :some_option An option'
383
+ )
384
+ .on_line(3)
385
+ .in_column(1)
379
386
  end
380
387
  end
381
388
 
@@ -401,10 +408,10 @@ describe 'param_comment' do
401
408
 
402
409
  it 'should create a warning' do
403
410
  expect(problems).to contain_warning(
404
- 'Can not process the comment \'@param second\' in the state awaiting_separator'
405
- )
406
- .on_line(5)
407
- .in_column(1)
411
+ 'Can not process the comment \'@param second\' in the state awaiting_separator'
412
+ )
413
+ .on_line(5)
414
+ .in_column(1)
408
415
  end
409
416
  end
410
417
 
@@ -426,3 +433,4 @@ describe 'param_comment' do
426
433
  end
427
434
  end
428
435
  end
436
+ # rubocop:enable Metrics/BlockLength
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet-lint-param_comment-check
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dennis Ploeger
@@ -131,7 +131,9 @@ extra_rdoc_files: []
131
131
  files:
132
132
  - LICENSE
133
133
  - README.md
134
+ - lib/puppet-lint-param_comment-check/param.rb
134
135
  - lib/puppet-lint-param_comment-check/param_comments.rb
136
+ - lib/puppet-lint-param_comment-check/param_comments_workflow.rb
135
137
  - lib/puppet-lint-param_comment-check/param_workflow.rb
136
138
  - lib/puppet-lint/plugins/check_param_comment.rb
137
139
  - spec/puppet-lint/plugins/check_param_comment_spec.rb