abide_dev_utils 0.12.2 → 0.14.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 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