abide_dev_utils 0.12.2 → 0.14.0

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: 1e93a77cf4142b06ee4d41863ef2d0b737d21d37306b57082aa316f2731de5e9
4
- data.tar.gz: 9b49e05aa575884d54efed8fd70b5662712845c083a8b59caeccf406a19f5633
3
+ metadata.gz: aa840c23e0e5ab5d978e04b6c3192bd473fa7d3886033be49c20124f33964c8b
4
+ data.tar.gz: 6d8d44b81c393907052d1cd70907b31e8e339ee7519080152ba3f2b5da3cd420
5
5
  SHA512:
6
- metadata.gz: 51316ad752020f3b2297acbdc4bb328c5275d03e499721ee12381aaac5da3a6e77ecb9efeb0ffa4b3b6bb512154dbb4b36bf249f4816944a0110d3ceeb871b2b
7
- data.tar.gz: 40b83d7be09ccb1349650617548276f6f34e266fe2e590e8c1b28b8e9c44f4499c93652abf9e254d77469fec9c98e9394a1ae2f4b2d3f0921827c3ce302dfb7e
6
+ metadata.gz: b18c4a042ae47492d235a3778f3b50a3589940af256cd0407ea38c170766fcaade5d8ead74c9baa47490c407bc9c375703356640e8f1e393a230055ddd099798
7
+ data.tar.gz: c2578428399f77596809838daa1adae12aa76e0f34298c3695bd9058a9da1a6c6e3a4e9120542dad9a6b2eda473581196e40df3467a8ff706332ce52824f2707
@@ -0,0 +1,39 @@
1
+ name: mend_scan
2
+ on:
3
+ workflow_dispatch:
4
+ push:
5
+ branches:
6
+ - main
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - name: checkout repo content
12
+ uses: actions/checkout@v2 # checkout the repository content to github runner.
13
+ with:
14
+ fetch-depth: 1
15
+ - name: setup ruby
16
+ uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: 2.7
19
+ - name: create lock
20
+ run: bundle lock
21
+ # install java
22
+ - uses: actions/setup-java@v3
23
+ with:
24
+ distribution: 'temurin' # See 'Supported distributions' for available options
25
+ java-version: '17'
26
+ # download mend
27
+ - name: download_mend
28
+ run: curl -o wss-unified-agent.jar https://unified-agent.s3.amazonaws.com/wss-unified-agent.jar
29
+ - name: run mend
30
+ run: java -jar wss-unified-agent.jar
31
+ env:
32
+ WS_APIKEY: ${{ secrets.MEND_API_KEY }}
33
+ WS_WSS_URL: https://saas-eu.whitesourcesoftware.com/agent
34
+ WS_USERKEY: ${{ secrets.MEND_TOKEN }}
35
+ WS_PRODUCTNAME: 'content-and-tooling' # I think this apply for our repo
36
+ WS_PROJECTNAME: ${{ github.event.repository.name }}
37
+ WS_FILESYSTEMSCAN: true
38
+ WS_CHECKPOLICIES: true
39
+ WS_FORCEUPDATE: true
data/Gemfile.lock CHANGED
@@ -1,15 +1,16 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- abide_dev_utils (0.12.2)
4
+ abide_dev_utils (0.14.0)
5
5
  amatch (~> 0.4)
6
6
  cmdparse (~> 3.0)
7
- facterdb (>= 1.18)
7
+ facterdb (>= 1.21)
8
8
  google-cloud-storage (~> 1.34)
9
9
  hashdiff (~> 1.0)
10
10
  jira-ruby (~> 2.2)
11
11
  nokogiri (~> 1.13)
12
12
  puppet (>= 6.23)
13
+ puppet-strings (>= 2.7)
13
14
  ruby-progressbar (~> 1.11)
14
15
  selenium-webdriver (~> 4.0.0.beta4)
15
16
 
@@ -17,7 +18,7 @@ GEM
17
18
  remote: https://rubygems.org/
18
19
  specs:
19
20
  CFPropertyList (2.3.6)
20
- activesupport (7.0.3)
21
+ activesupport (7.0.4.1)
21
22
  concurrent-ruby (~> 1.0, >= 1.0.2)
22
23
  i18n (>= 1.6, < 2)
23
24
  minitest (>= 5.1)
@@ -60,10 +61,10 @@ GEM
60
61
  diff-lcs (1.5.0)
61
62
  digest-crc (0.6.4)
62
63
  rake (>= 12.0.0, < 14.0.0)
63
- facter (4.2.11)
64
+ facter (4.2.14)
64
65
  hocon (~> 1.3)
65
66
  thor (>= 1.0.1, < 2.0)
66
- facterdb (1.19.0)
67
+ facterdb (1.21.0)
67
68
  facter (< 5.0.0)
68
69
  jgrep
69
70
  faraday (2.3.0)
@@ -84,7 +85,7 @@ GEM
84
85
  octokit (~> 4.6)
85
86
  rainbow (>= 2.2.1)
86
87
  rake (>= 10.0)
87
- google-apis-core (0.7.0)
88
+ google-apis-core (0.10.0)
88
89
  addressable (~> 2.5, >= 2.5.1)
89
90
  googleauth (>= 0.16.2, < 2.a)
90
91
  httpclient (>= 2.8.1, < 3.a)
@@ -93,25 +94,25 @@ GEM
93
94
  retriable (>= 2.0, < 4.a)
94
95
  rexml
95
96
  webrick
96
- google-apis-iamcredentials_v1 (0.13.0)
97
- google-apis-core (>= 0.7, < 2.a)
98
- google-apis-storage_v1 (0.17.0)
99
- google-apis-core (>= 0.7, < 2.a)
97
+ google-apis-iamcredentials_v1 (0.16.0)
98
+ google-apis-core (>= 0.9.1, < 2.a)
99
+ google-apis-storage_v1 (0.19.0)
100
+ google-apis-core (>= 0.9.0, < 2.a)
100
101
  google-cloud-core (1.6.0)
101
102
  google-cloud-env (~> 1.0)
102
103
  google-cloud-errors (~> 1.0)
103
104
  google-cloud-env (1.6.0)
104
105
  faraday (>= 0.17.3, < 3.0)
105
- google-cloud-errors (1.2.0)
106
- google-cloud-storage (1.38.0)
106
+ google-cloud-errors (1.3.0)
107
+ google-cloud-storage (1.44.0)
107
108
  addressable (~> 2.8)
108
109
  digest-crc (~> 0.4)
109
110
  google-apis-iamcredentials_v1 (~> 0.1)
110
- google-apis-storage_v1 (~> 0.17.0)
111
+ google-apis-storage_v1 (~> 0.19.0)
111
112
  google-cloud-core (~> 1.6)
112
113
  googleauth (>= 0.16.2, < 2.a)
113
114
  mini_mime (~> 1.0)
114
- googleauth (1.2.0)
115
+ googleauth (1.3.0)
115
116
  faraday (>= 0.17.3, < 3.a)
116
117
  jwt (>= 1.4, < 3.0)
117
118
  memoist (~> 0.16)
@@ -119,31 +120,34 @@ GEM
119
120
  os (>= 0.9, < 2.0)
120
121
  signet (>= 0.16, < 2.a)
121
122
  hashdiff (1.0.1)
122
- hiera (3.10.0)
123
+ hashie (5.0.0)
124
+ hiera (3.11.0)
123
125
  hocon (1.3.1)
124
126
  httpclient (2.8.3)
125
- i18n (1.10.0)
127
+ i18n (1.12.0)
126
128
  concurrent-ruby (~> 1.0)
127
129
  jgrep (1.5.4)
128
- jira-ruby (2.2.0)
130
+ jira-ruby (2.3.0)
129
131
  activesupport
130
132
  atlassian-jwt
131
133
  multipart-post
132
134
  oauth (~> 0.5, >= 0.5.0)
133
- jwt (2.4.1)
135
+ jwt (2.7.0)
134
136
  locale (2.1.3)
135
137
  memoist (0.16.2)
136
138
  method_source (1.0.0)
137
139
  mini_mime (1.1.2)
138
- minitest (5.15.0)
139
- mize (0.4.0)
140
+ minitest (5.17.0)
141
+ mize (0.4.1)
140
142
  protocol (~> 2.0)
141
143
  multi_json (1.15.0)
142
- multipart-post (2.2.3)
144
+ multipart-post (2.3.0)
143
145
  nio4r (2.5.8)
144
- nokogiri (1.13.8-x86_64-darwin)
146
+ nokogiri (1.14.1-x86_64-darwin)
145
147
  racc (~> 1.4)
146
- oauth (0.5.10)
148
+ oauth (0.6.2)
149
+ snaky_hash (~> 2.0)
150
+ version_gem (~> 1.1)
147
151
  octokit (4.25.0)
148
152
  faraday (>= 1, < 3)
149
153
  sawyer (~> 0.9)
@@ -164,9 +168,9 @@ GEM
164
168
  coderay (~> 1.1)
165
169
  method_source (~> 1.0)
166
170
  public_suffix (4.0.7)
167
- puppet (7.18.0-universal-darwin)
171
+ puppet (7.22.0-universal-darwin)
168
172
  CFPropertyList (~> 2.2)
169
- concurrent-ruby (~> 1.0)
173
+ concurrent-ruby (~> 1.0, < 1.2.0)
170
174
  deep_merge (~> 1.0)
171
175
  facter (> 2.0.1, < 5)
172
176
  fast_gettext (>= 1.1, < 3)
@@ -178,7 +182,10 @@ GEM
178
182
  semantic_puppet (~> 1.0)
179
183
  puppet-resource_api (1.8.14)
180
184
  hocon (>= 1.0)
181
- racc (1.6.0)
185
+ puppet-strings (2.9.0)
186
+ rgen
187
+ yard (~> 0.9.5)
188
+ racc (1.6.2)
182
189
  rainbow (3.1.1)
183
190
  rake (13.0.6)
184
191
  regexp_parser (2.5.0)
@@ -188,6 +195,7 @@ GEM
188
195
  uber (< 0.2.0)
189
196
  retriable (3.1.2)
190
197
  rexml (3.2.5)
198
+ rgen (0.9.1)
191
199
  rspec (3.11.0)
192
200
  rspec-core (~> 3.11.0)
193
201
  rspec-expectations (~> 3.11.0)
@@ -221,7 +229,7 @@ GEM
221
229
  rubocop (~> 1.19)
222
230
  ruby-progressbar (1.11.0)
223
231
  ruby2_keywords (0.0.5)
224
- ruby_parser (3.19.1)
232
+ ruby_parser (3.19.2)
225
233
  sexp_processor (~> 4.16)
226
234
  rubyzip (2.3.2)
227
235
  sawyer (0.9.2)
@@ -239,18 +247,24 @@ GEM
239
247
  faraday (>= 0.17.5, < 3.a)
240
248
  jwt (>= 1.5, < 3.0)
241
249
  multi_json (~> 1.10)
250
+ snaky_hash (2.0.1)
251
+ hashie
252
+ version_gem (~> 1.1, >= 1.1.1)
242
253
  sync (0.5.0)
243
254
  thor (1.2.1)
244
255
  timers (4.3.3)
245
- tins (1.31.1)
256
+ tins (1.32.1)
246
257
  sync
247
258
  traces (0.4.1)
248
259
  trailblazer-option (0.1.2)
249
- tzinfo (2.0.4)
260
+ tzinfo (2.0.5)
250
261
  concurrent-ruby (~> 1.0)
251
262
  uber (0.1.0)
252
263
  unicode-display_width (2.1.0)
264
+ version_gem (1.1.1)
253
265
  webrick (1.7.0)
266
+ yard (0.9.28)
267
+ webrick (~> 1.7.0)
254
268
 
255
269
  PLATFORMS
256
270
  x86_64-darwin-19
@@ -35,13 +35,14 @@ Gem::Specification.new do |spec|
35
35
  spec.add_dependency 'nokogiri', '~> 1.13'
36
36
  spec.add_dependency 'cmdparse', '~> 3.0'
37
37
  spec.add_dependency 'puppet', '>= 6.23'
38
+ spec.add_dependency 'puppet-strings', '>= 2.7'
38
39
  spec.add_dependency 'jira-ruby', '~> 2.2'
39
40
  spec.add_dependency 'ruby-progressbar', '~> 1.11'
40
41
  spec.add_dependency 'selenium-webdriver', '~> 4.0.0.beta4'
41
42
  spec.add_dependency 'google-cloud-storage', '~> 1.34'
42
43
  spec.add_dependency 'hashdiff', '~> 1.0'
43
44
  spec.add_dependency 'amatch', '~> 0.4'
44
- spec.add_dependency 'facterdb', '>= 1.18'
45
+ spec.add_dependency 'facterdb', '>= 1.21'
45
46
 
46
47
  # Dev dependencies
47
48
  spec.add_development_dependency 'bundler'
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'set'
4
- require 'abide_dev_utils/dot_number_comparable'
5
- require 'abide_dev_utils/errors'
6
- require 'abide_dev_utils/ppt'
7
- require 'abide_dev_utils/cem/mapping/mapper'
4
+ require_relative '../dot_number_comparable'
5
+ require_relative '../errors'
6
+ require_relative '../ppt'
7
+ require_relative 'mapping/mapper'
8
8
 
9
9
  module AbideDevUtils
10
10
  module CEM
@@ -317,7 +317,8 @@ module AbideDevUtils
317
317
  def initialize(osname, major_version, hiera_conf, module_name, framework: 'cis')
318
318
  @osname = osname
319
319
  @major_version = major_version
320
- @os_facts = AbideDevUtils::Ppt::FacterUtils.recursive_facts_for_os(@osname, @major_version)
320
+ @os_facts = AbideDevUtils::Ppt::FacterUtils::FactSets.new.find_by_fact_value_tuples(['os.name', @osname],
321
+ ['os.release.major', @major_version])
321
322
  @osfamily = @os_facts['os']['family']
322
323
  @hiera_conf = hiera_conf
323
324
  @module_name = module_name
@@ -484,6 +485,8 @@ module AbideDevUtils
484
485
  raise AbideDevUtils::Errors::ResourceDataNotFoundError, facts if rdata_files.nil? || rdata_files.empty?
485
486
 
486
487
  YAML.load_file(rdata_files[0].path)
488
+ rescue StandardError => e
489
+ require 'pry'; binding.pry
487
490
  end
488
491
  end
489
492
  end
@@ -15,14 +15,12 @@ module AbideDevUtils
15
15
  # the various compliance frameworks expect to be enforced.
16
16
  module CoverageReport
17
17
  def self.generate(format_func: :to_h, opts: {})
18
- opts = AbideDevUtils::CEM::CoverageReport::ReportOptions.new(opts)
18
+ opts = ReportOptions.new(opts)
19
19
  pupmod = AbideDevUtils::Ppt::PuppetModule.new
20
20
  benchmarks = AbideDevUtils::CEM::Benchmark.benchmarks_from_puppet_module(pupmod,
21
- ignore_all_errors: opts.ignore_all_errors)
21
+ ignore_all_errors: opts.ignore_all_errors)
22
22
  benchmarks.map do |b|
23
- AbideDevUtils::CEM::CoverageReport::BenchmarkReport.new(b)
24
- .send(report_type, **{ profile: profile, level: level })
25
- .send(format_func)
23
+ BenchmarkReport.new(b, opts).run.send(format_func)
26
24
  end
27
25
  end
28
26
 
@@ -306,11 +304,15 @@ module AbideDevUtils
306
304
 
307
305
  # Creates ReportOutput objects based on the given Benchmark
308
306
  class BenchmarkReport
309
- def initialize(benchmark, opts = AbideDevUtils::CEM::CoverageReport::ReportOptions.new)
307
+ def initialize(benchmark, opts = ReportOptions.new)
310
308
  @benchmark = benchmark
311
309
  @opts = opts
312
310
  end
313
311
 
312
+ def run
313
+ send(@opts.report_type)
314
+ end
315
+
314
316
  def controls_in_resource_data
315
317
  @controls_in_resource_data ||= find_controls_in_resource_data
316
318
  end
@@ -322,7 +324,7 @@ module AbideDevUtils
322
324
  def basic_coverage(level: @opts.level, profile: @opts.profile)
323
325
  map_type = @benchmark.map_type(controls_in_resource_data[0])
324
326
  rules_in_map = @benchmark.rules_in_map(map_type, level: level, profile: profile)
325
- AbideDevUtils::CEM::CoverageReport::ReportOutput.new(@benchmark, controls_in_resource_data, rules_in_map)
327
+ ReportOutput.new(@benchmark, controls_in_resource_data, rules_in_map)
326
328
  end
327
329
 
328
330
  # def correlated_coverage(level: @opts.level, profile: @opts.profile)
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'json'
4
+ require 'puppet-strings'
5
+ require 'puppet-strings/yard'
4
6
  require 'shellwords'
5
7
  require 'timeout'
6
8
  require 'yaml'
@@ -31,7 +33,7 @@ module AbideDevUtils
31
33
  case data.fetch(:format, 'markdown')
32
34
  when 'markdown'
33
35
  file = data[:out_file] || 'REFERENCE.md'
34
- MarkdownGenerator.new(benchmarks, pupmod.name, file: file).generate(doc_title)
36
+ MarkdownGenerator.new(benchmarks, pupmod.name, file: file, opts: data).generate(doc_title)
35
37
  else
36
38
  raise "Format #{data[:format]} is unsupported! Only `markdown` format supported"
37
39
  end
@@ -61,31 +63,35 @@ module AbideDevUtils
61
63
  class MarkdownGenerator
62
64
  SPECIAL_CONTROL_IDS = %w[dependent cem_options cem_protected].freeze
63
65
 
64
- def initialize(benchmarks, module_name, file: 'REFERENCE.md')
66
+ def initialize(benchmarks, module_name, file: 'REFERENCE.md', opts: {})
65
67
  @benchmarks = benchmarks
66
68
  @module_name = module_name
67
69
  @file = file
70
+ @opts = opts
68
71
  @md = AbideDevUtils::Markdown.new(@file)
69
72
  end
70
73
 
71
74
  def generate(doc_title = 'Reference')
75
+ @strings = Strings.new(opts: @opts)
72
76
  md.add_title(doc_title)
73
77
  benchmarks.each do |benchmark|
74
- progress_bar = AbideDevUtils::Output.progress(title: "Generating Markdown for #{benchmark.title_key}",
75
- total: benchmark.controls.length)
78
+ unless @opts[:quiet]
79
+ progress_bar = AbideDevUtils::Output.progress(title: "Generating Markdown for #{benchmark.title_key}",
80
+ total: benchmark.controls.length)
81
+ end
76
82
  md.add_h1(benchmark.title_key)
77
83
  benchmark.controls.each do |control|
78
84
  next if SPECIAL_CONTROL_IDS.include? control.id
79
85
  next if benchmark.framework == 'stig' && control.id_map_type != 'vulnid'
80
86
 
81
- control_md = ControlMarkdown.new(control, @md, @module_name, benchmark.framework)
87
+ control_md = ControlMarkdown.new(control, @md, @strings, @module_name, benchmark.framework, opts: @opts)
82
88
  control_md.generate!
83
- progress_bar.increment
89
+ progress_bar.increment unless @opts[:quiet]
84
90
  rescue StandardError => e
85
91
  raise "Failed to generate markdown for control #{control.id}. Original message: #{e.message}"
86
92
  end
87
93
  end
88
- AbideDevUtils::Output.simple("Saving markdown to #{@file}")
94
+ AbideDevUtils::Output.simple("Saving markdown to #{@file}") unless @opts[:quiet]
89
95
  md.to_file
90
96
  end
91
97
 
@@ -96,13 +102,152 @@ module AbideDevUtils
96
102
 
97
103
  class ConfigExampleError < StandardError; end
98
104
 
105
+ # Puppet Strings reference object
106
+ class Strings
107
+ REGISTRY_TYPES = %i[
108
+ root
109
+ module
110
+ class
111
+ puppet_class
112
+ puppet_data_type
113
+ puppet_data_type_alias
114
+ puppet_defined_type
115
+ puppet_type
116
+ puppet_provider
117
+ puppet_function
118
+ puppet_task
119
+ puppet_plan
120
+ ].freeze
121
+
122
+ attr_reader :search_patterns
123
+
124
+ def initialize(search_patterns: nil, opts: {})
125
+ @search_patterns = search_patterns || PuppetStrings::DEFAULT_SEARCH_PATTERNS
126
+ @debug = opts[:debug]
127
+ @quiet = opts[:quiet]
128
+ PuppetStrings::Yard.setup!
129
+ YARD::CLI::Yardoc.run(*yard_args(@search_patterns, debug: @debug, quiet: @quiet))
130
+ end
131
+
132
+ def debug?
133
+ !!@debug
134
+ end
135
+
136
+ def quiet?
137
+ !!@quiet
138
+ end
139
+
140
+ def registry
141
+ @registry ||= YARD::Registry.all(*REGISTRY_TYPES)
142
+ end
143
+
144
+ def find_resource(resource_name)
145
+ to_h.each do |_, resources|
146
+ res = resources.find { |r| r[:name] == resource_name.to_sym }
147
+ return res if res
148
+ end
149
+ end
150
+
151
+ def puppet_classes
152
+ @puppet_classes ||= hashes_for_reg_type(:puppet_class)
153
+ end
154
+
155
+ def data_types
156
+ @data_types ||= hashes_for_reg_type(:puppet_data_types)
157
+ end
158
+
159
+ def data_type_aliases
160
+ @data_type_aliases ||= hashes_for_reg_type(:puppet_data_type_alias)
161
+ end
162
+
163
+ def defined_types
164
+ @defined_types ||= hashes_for_reg_type(:puppet_defined_type)
165
+ end
166
+
167
+ def resource_types
168
+ @resource_types ||= hashes_for_reg_type(:puppet_type)
169
+ end
170
+
171
+ def providers
172
+ @providers ||= hashes_for_reg_type(:puppet_provider)
173
+ end
174
+
175
+ def puppet_functions
176
+ @puppet_functions ||= hashes_for_reg_type(:puppet_function)
177
+ end
178
+
179
+ def puppet_tasks
180
+ @puppet_tasks ||= hashes_for_reg_type(:puppet_task)
181
+ end
182
+
183
+ def puppet_plans
184
+ @puppet_plans ||= hashes_for_reg_type(:puppet_plan)
185
+ end
186
+
187
+ def to_h
188
+ {
189
+ puppet_classes: puppet_classes,
190
+ data_types: data_types,
191
+ data_type_aliases: data_type_aliases,
192
+ defined_types: defined_types,
193
+ resource_types: resource_types,
194
+ providers: providers,
195
+ puppet_functions: puppet_functions,
196
+ puppet_tasks: puppet_tasks,
197
+ puppet_plans: puppet_plans,
198
+ }
199
+ end
200
+
201
+ private
202
+
203
+ def hashes_for_reg_type(reg_type)
204
+ all_to_h(registry.select { |i| i.type == reg_type })
205
+ end
206
+
207
+ def all_to_h(objects)
208
+ objects.sort_by(&:name).map(&:to_hash)
209
+ end
210
+
211
+ def yard_args(patterns, debug: false, quiet: false)
212
+ args = ['doc', '--no-progress', '-n']
213
+ args << '--debug' if debug && !quiet
214
+ args << '--backtrace' if debug && !quiet
215
+ args << '-q' if quiet
216
+ args << '--no-stats' if quiet
217
+ args += patterns
218
+ args
219
+ end
220
+ end
221
+
222
+ # Generates markdown for Puppet classes based on Puppet Strings JSON
223
+ # class PuppetClassMarkdown
224
+ # def initialize(puppet_classes, md, opts: {})
225
+ # @puppet_classes = puppet_classes
226
+ # @md = md
227
+ # @opts = opts
228
+ # end
229
+
230
+ # def generate!
231
+ # @puppet_classes.each do |puppet_class|
232
+ # @md.add_h2(puppet_class['name'])
233
+ # @md.add_paragraph("File(Line): `#{puppet_class['file']}(#{puppet_class['line']})`")
234
+
235
+ # private
236
+
237
+ # def doc_string_builder(puppet_class)
238
+ # return if puppet_class['docstring'].nil? || puppet_class['docstring'].empty?
239
+ # end
240
+
241
+ # Generates markdown for a control
99
242
  class ControlMarkdown
100
- def initialize(control, md, module_name, framework, formatter: nil)
243
+ def initialize(control, md, strings, module_name, framework, formatter: nil, opts: {})
101
244
  @control = control
102
245
  @md = md
246
+ @strings = strings
103
247
  @module_name = module_name
104
248
  @framework = framework
105
249
  @formatter = formatter.nil? ? TypeExprValueFormatter : formatter
250
+ @opts = opts
106
251
  @control_data = {}
107
252
  end
108
253
 
@@ -156,6 +301,27 @@ module AbideDevUtils
156
301
  " - #{@md.italic('Default:')} #{@md.code(@control_data[ctrl_param[:name]][:default])}"
157
302
  end
158
303
 
304
+ def param_description(ctrl_param)
305
+ res = if @control.resource.type == 'class'
306
+ @strings.find_resource(@control.resource.title)
307
+ else
308
+ @strings.find_resource(@control.resource.type)
309
+ end
310
+ return unless res&.key?(:docstring) && res[:docstring].key?(:tags)
311
+ return if res[:docstring][:tags].empty? || res[:docstring][:tags].none? { |x| x[:tag_name] == 'param' }
312
+
313
+ param_tag = res[:docstring][:tags].find { |x| x[:tag_name] == 'param' && x[:name] == ctrl_param[:name] }
314
+ if param_tag.nil? || param_tag[:text].nil? || param_tag[:text].chomp.empty?
315
+ if @opts[:strict]
316
+ raise "No description found for parameter #{ctrl_param[:name]} in resource #{@control.resource.title}"
317
+ end
318
+
319
+ return
320
+ end
321
+
322
+ " - #{param_tag[:text]}"
323
+ end
324
+
159
325
  def control_params_builder
160
326
  return unless control_has_valid_params?
161
327
 
@@ -164,6 +330,8 @@ module AbideDevUtils
164
330
  collection.each do |hsh|
165
331
  rparam = resource_param(hsh)
166
332
  str_array = [@md.code(hsh[:name]), param_type_expr(hsh, rparam), param_default_value(hsh, rparam)]
333
+ desc = param_description(hsh)
334
+ str_array << desc if desc
167
335
  @md.add_ul(str_array.compact.join, indent: 1)
168
336
  end
169
337
  end