docopslab-dev 0.1.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 +7 -0
- data/LICENSE +21 -0
- data/README.adoc +904 -0
- data/assets/config-packs/actionlint/base.yml +13 -0
- data/assets/config-packs/actionlint/project.yml +13 -0
- data/assets/config-packs/htmlproofer/base.yml +27 -0
- data/assets/config-packs/htmlproofer/project.yml +25 -0
- data/assets/config-packs/rubocop/base.yml +130 -0
- data/assets/config-packs/rubocop/project.yml +8 -0
- data/assets/config-packs/shellcheck/base.shellcheckrc +14 -0
- data/assets/config-packs/subtxt/ai-asciidoc-antipatterns.sub.txt +11 -0
- data/assets/config-packs/vale/asciidoc/ExplicitSectionIDs.yml +8 -0
- data/assets/config-packs/vale/asciidoc/ExtraLineBeforeLevel1.yml +7 -0
- data/assets/config-packs/vale/asciidoc/OneSentencePerLine.yml +8 -0
- data/assets/config-packs/vale/asciidoc/PreferSourceBlocks.yml +8 -0
- data/assets/config-packs/vale/asciidoc/ProperAdmonitions.yml +8 -0
- data/assets/config-packs/vale/asciidoc/ProperDLs.yml +7 -0
- data/assets/config-packs/vale/asciidoc/UncleanListStart.yml +8 -0
- data/assets/config-packs/vale/authoring/ButParagraph.yml +8 -0
- data/assets/config-packs/vale/authoring/ExNotEg.yml +8 -0
- data/assets/config-packs/vale/authoring/LiteralTerms.yml +20 -0
- data/assets/config-packs/vale/authoring/Spelling.yml +679 -0
- data/assets/config-packs/vale/base.ini +38 -0
- data/assets/config-packs/vale/config/scripts/ExplicitSectionIDs.tengo +56 -0
- data/assets/config-packs/vale/config/scripts/ExtraLineBeforeLevel1.tengo +121 -0
- data/assets/config-packs/vale/config/scripts/OneSentencePerLine.tengo +53 -0
- data/assets/config-packs/vale/project.ini +5 -0
- data/assets/hooks/pre-commit +63 -0
- data/assets/hooks/pre-push +72 -0
- data/assets/scripts/adoc_section_ids.rb +50 -0
- data/assets/scripts/build-common.sh +193 -0
- data/assets/scripts/build-docker.sh +64 -0
- data/assets/scripts/build.sh +56 -0
- data/assets/scripts/parse_jekyll_asciidoc_logs.rb +467 -0
- data/assets/templates/Gemfile +7 -0
- data/assets/templates/Rakefile +3 -0
- data/assets/templates/gitignore +69 -0
- data/assets/templates/jekyll-asciidoc-fix.prompt.yml +17 -0
- data/assets/templates/spellcheck.prompt.yml +16 -0
- data/docopslab-dev.gemspec +56 -0
- data/docs/agent/AGENTS.md +229 -0
- data/docs/agent/index.md +80 -0
- data/docs/agent/missions/conduct-release.md +224 -0
- data/docs/agent/missions/setup-new-project.md +250 -0
- data/docs/agent/roles/devops-release-engineer.md +152 -0
- data/docs/agent/roles/docops-engineer.md +193 -0
- data/docs/agent/roles/planner-architect.md +74 -0
- data/docs/agent/roles/product-engineer.md +153 -0
- data/docs/agent/roles/product-manager.md +130 -0
- data/docs/agent/roles/project-manager.md +139 -0
- data/docs/agent/roles/qa-testing-engineer.md +115 -0
- data/docs/agent/roles/tech-docs-manager.md +143 -0
- data/docs/agent/roles/tech-writer.md +163 -0
- data/docs/agent/skills/asciidoc.md +609 -0
- data/docs/agent/skills/code-commenting.md +347 -0
- data/docs/agent/skills/fix-broken-links.md +309 -0
- data/docs/agent/skills/fix-jekyll-asciidoc-build-errors.md +23 -0
- data/docs/agent/skills/fix-spelling-issues.md +13 -0
- data/docs/agent/skills/git.md +170 -0
- data/docs/agent/skills/github-issues.md +135 -0
- data/docs/agent/skills/product-release-rollback-and-patching.md +71 -0
- data/docs/agent/skills/rake-cli-dev.md +57 -0
- data/docs/agent/skills/readme-driven-dev.md +13 -0
- data/docs/agent/skills/release-history.md +29 -0
- data/docs/agent/skills/ruby.md +192 -0
- data/docs/agent/skills/schemagraphy-sgyml.md +18 -0
- data/docs/agent/skills/tests-running.md +25 -0
- data/docs/agent/skills/tests-writing.md +45 -0
- data/docs/agent/skills/write-the-docs.md +54 -0
- data/docs/agent/topics/common-project-paths.md +117 -0
- data/docs/agent/topics/dev-tooling-usage.md +202 -0
- data/docs/agent/topics/devops-ci-cd.md +55 -0
- data/docs/agent/topics/product-docs-deployment.md +25 -0
- data/lib/docopslab/dev/auto_fix_asciidoc.rb +46 -0
- data/lib/docopslab/dev/checkers.rb +108 -0
- data/lib/docopslab/dev/config_manager.rb +241 -0
- data/lib/docopslab/dev/file_utils.rb +140 -0
- data/lib/docopslab/dev/git_hooks.rb +140 -0
- data/lib/docopslab/dev/help.rb +121 -0
- data/lib/docopslab/dev/initializer.rb +95 -0
- data/lib/docopslab/dev/linters.rb +451 -0
- data/lib/docopslab/dev/log_parser.rb +31 -0
- data/lib/docopslab/dev/paths.rb +46 -0
- data/lib/docopslab/dev/script_manager.rb +136 -0
- data/lib/docopslab/dev/spell_check.rb +194 -0
- data/lib/docopslab/dev/sync_ops.rb +468 -0
- data/lib/docopslab/dev/tasks.rb +440 -0
- data/lib/docopslab/dev/tool_execution.rb +68 -0
- data/lib/docopslab/dev/version.rb +8 -0
- data/lib/docopslab/dev.rb +392 -0
- data/specs/data/default-manifest.yml +64 -0
- data/specs/data/manifest-schema.yaml +63 -0
- data/specs/data/tasks-def.yml +321 -0
- data/specs/data/tools.yml +60 -0
- metadata +362 -0
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rake/tasklib'
|
|
4
|
+
require 'yaml'
|
|
5
|
+
|
|
6
|
+
module DocOpsLab
|
|
7
|
+
module Dev
|
|
8
|
+
# Rake task definitions for DocOps Lab development tools
|
|
9
|
+
# Task structure defined in specs/data/tasks-def.yml
|
|
10
|
+
class Tasks < Rake::TaskLib
|
|
11
|
+
def initialize
|
|
12
|
+
super
|
|
13
|
+
load_task_definitions
|
|
14
|
+
define_tasks
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
attr_reader :task_defs
|
|
20
|
+
|
|
21
|
+
def load_task_definitions
|
|
22
|
+
tasks_def_path = File.join(__dir__, '../../../specs/data/tasks-def.yml')
|
|
23
|
+
@task_defs = YAML.load_file(tasks_def_path)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Look up task description from tasks-def.yml
|
|
27
|
+
# Path format: 'check:env' looks up labdev.check.env._desc
|
|
28
|
+
def desc_for task_path
|
|
29
|
+
parts = task_path.split(':')
|
|
30
|
+
node = task_defs.dig('labdev', *parts)
|
|
31
|
+
return nil unless node.is_a?(Hash)
|
|
32
|
+
|
|
33
|
+
node['_desc']
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def define_tasks
|
|
37
|
+
namespace :labdev do
|
|
38
|
+
# ============================================================
|
|
39
|
+
# CHECK tasks; Assess local repo and environment
|
|
40
|
+
# ============================================================
|
|
41
|
+
|
|
42
|
+
# Base task; show help for 'check' namespace
|
|
43
|
+
task :check do
|
|
44
|
+
Help.show_task_help('check')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
namespace :check do
|
|
48
|
+
desc desc_for('check:env')
|
|
49
|
+
task :env do
|
|
50
|
+
puts '🩺 DocOps Lab Environment Diagnostics'
|
|
51
|
+
Dev.check_ruby_version
|
|
52
|
+
puts "Gem version: #{VERSION}"
|
|
53
|
+
Dev.check_config_structure
|
|
54
|
+
Dev.check_standard_rake_tasks
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
desc desc_for('check:updates')
|
|
58
|
+
task :updates do
|
|
59
|
+
Dev.check_hook_updates
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
desc desc_for('check:all')
|
|
63
|
+
task :all do
|
|
64
|
+
Rake::Task['labdev:check:env'].invoke
|
|
65
|
+
Rake::Task['labdev:check:updates'].invoke
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# ============================================================
|
|
70
|
+
# INIT tasks; Bootstrap development environment
|
|
71
|
+
# ============================================================
|
|
72
|
+
|
|
73
|
+
desc desc_for('init')
|
|
74
|
+
task :init do
|
|
75
|
+
Help.show_task_help('init')
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
namespace :init do
|
|
79
|
+
desc desc_for('init:all')
|
|
80
|
+
task :all do
|
|
81
|
+
Dev.bootstrap_project
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
desc desc_for('init:docs')
|
|
85
|
+
task :docs do
|
|
86
|
+
if Dev.sync_docs
|
|
87
|
+
puts '✅ Agent docs synced'
|
|
88
|
+
else
|
|
89
|
+
puts '⚠️ Agent docs sync skipped or failed'
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# ============================================================
|
|
95
|
+
# RUN tasks; Execute tools with custom arguments
|
|
96
|
+
# ============================================================
|
|
97
|
+
|
|
98
|
+
namespace :run do
|
|
99
|
+
desc desc_for('run:script')
|
|
100
|
+
task :script, %i[script opts] => [] do |_t, args|
|
|
101
|
+
script = args[:script]
|
|
102
|
+
if script.nil?
|
|
103
|
+
puts '❌ Script name is required.'
|
|
104
|
+
puts 'Usage: bundle exec rake labdev:run:script[script]'
|
|
105
|
+
puts 'Use labdev:show:scripts to see available scripts.'
|
|
106
|
+
return
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Parse opts_string if provided
|
|
110
|
+
extra_args = args[:opts] ? args[:opts].split : []
|
|
111
|
+
Dev.run_script(script, extra_args)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
desc desc_for('run:rubocop')
|
|
115
|
+
task :rubocop, [:opts] => [] do |_t, args|
|
|
116
|
+
opts = args[:opts] || ''
|
|
117
|
+
# Strip quotes that Rake includes when arguments contain spaces
|
|
118
|
+
opts = opts.gsub(/^["']|["']$/, '') if opts.include?(' ')
|
|
119
|
+
success = Dev.run_rubocop(nil, opts)
|
|
120
|
+
exit(1) unless success
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
desc desc_for('run:vale')
|
|
124
|
+
task :vale, [:opts] => [] do |_t, args|
|
|
125
|
+
opts = args[:opts] || ''
|
|
126
|
+
Dev.run_vale(nil, opts)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Removed from 0.1.0 for incongruent options between CLI and API
|
|
130
|
+
# desc desc_for('run:htmlproofer')
|
|
131
|
+
# task :htmlproofer, [:opts] => [] do |_t, args|
|
|
132
|
+
# opts = args[:opts] || ''
|
|
133
|
+
# puts '🔗 Running HTMLProofer...'
|
|
134
|
+
# Dev.run_htmlproofer(opts)
|
|
135
|
+
# end
|
|
136
|
+
|
|
137
|
+
desc desc_for('run:shellcheck')
|
|
138
|
+
task :shellcheck, [:opts] => [] do |_t, args|
|
|
139
|
+
opts = args[:opts] || ''
|
|
140
|
+
Dev.run_shellcheck(nil, opts)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
desc desc_for('run:actionlint')
|
|
144
|
+
task :actionlint, [:opts] => [] do |_t, args|
|
|
145
|
+
opts = args[:opts] || ''
|
|
146
|
+
Dev.run_actionlint(opts)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# ============================================================
|
|
151
|
+
# SYNC tasks; Sync managed files from upstream
|
|
152
|
+
# ============================================================
|
|
153
|
+
|
|
154
|
+
namespace :sync do
|
|
155
|
+
desc desc_for('sync:configs')
|
|
156
|
+
task :configs do
|
|
157
|
+
Dev.sync_config_files
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
desc desc_for('sync:scripts')
|
|
161
|
+
task :scripts do
|
|
162
|
+
Dev.sync_scripts
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
desc desc_for('sync:docs')
|
|
166
|
+
task :docs do
|
|
167
|
+
Dev.sync_docs(force: true)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
namespace :styles do
|
|
171
|
+
desc desc_for('sync:styles:local')
|
|
172
|
+
task :local do
|
|
173
|
+
Dev.sync_vale_styles(local: true)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
desc desc_for('sync:styles:all')
|
|
177
|
+
task :all do
|
|
178
|
+
Dev.sync_vale_styles
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Base task; show help for 'sync:styles' namespace
|
|
183
|
+
task :styles do
|
|
184
|
+
Help.show_task_help('sync:styles')
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
desc desc_for('sync:hooks')
|
|
188
|
+
task :hooks do
|
|
189
|
+
Dev.update_hooks_interactive
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
namespace :vale do
|
|
193
|
+
desc desc_for('sync:vale:local')
|
|
194
|
+
task :local do
|
|
195
|
+
Dev.sync_config_files(:vale)
|
|
196
|
+
Dev.sync_vale_styles(local: true)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
desc desc_for('sync:vale:all')
|
|
200
|
+
task :all do
|
|
201
|
+
Dev.sync_config_files(:vale)
|
|
202
|
+
Dev.sync_vale_styles
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Base task; show help for 'sync:vale' namespace
|
|
207
|
+
task :vale do
|
|
208
|
+
Help.show_task_help('sync:vale')
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
desc desc_for('sync:all')
|
|
212
|
+
task :all do
|
|
213
|
+
Dev.sync_config_files
|
|
214
|
+
Dev.sync_scripts
|
|
215
|
+
Dev.sync_docs
|
|
216
|
+
Dev.install_missing_hooks
|
|
217
|
+
Dev.sync_vale_styles
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
# Base task; show help for 'sync' namespace
|
|
222
|
+
task :sync do
|
|
223
|
+
Help.show_task_help('sync')
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# ============================================================
|
|
227
|
+
# LINT tasks; Run linters
|
|
228
|
+
# ============================================================
|
|
229
|
+
|
|
230
|
+
namespace :lint do
|
|
231
|
+
desc desc_for('lint:ruby')
|
|
232
|
+
task :ruby, %i[path rule opts] => [] do |_t, args|
|
|
233
|
+
path = args[:path]
|
|
234
|
+
rule = args[:rule]
|
|
235
|
+
opts = args[:opts]
|
|
236
|
+
|
|
237
|
+
if path || rule || opts
|
|
238
|
+
# Specific file/rule mode
|
|
239
|
+
cmd_opts = []
|
|
240
|
+
cmd_opts << "--only #{rule}" if rule
|
|
241
|
+
cmd_opts << opts if opts
|
|
242
|
+
target = path || nil
|
|
243
|
+
Dev.run_rubocop(target, cmd_opts.join(' '))
|
|
244
|
+
else
|
|
245
|
+
# Default: run on all Ruby files
|
|
246
|
+
Dev.run_linter_group('Ruby', %w[rubocop])
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
desc desc_for('lint:bash')
|
|
251
|
+
task :bash, %i[path rule opts] => [] do |_t, args|
|
|
252
|
+
path = args[:path]
|
|
253
|
+
opts = args[:opts]
|
|
254
|
+
|
|
255
|
+
if path || opts
|
|
256
|
+
target = path || nil
|
|
257
|
+
Dev.run_shellcheck(target, opts || '')
|
|
258
|
+
else
|
|
259
|
+
Dev.run_linter_group('shell script', %w[shellcheck])
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
desc desc_for('lint:docs')
|
|
264
|
+
task :docs, %i[path rule opts] => [] do |_t, args|
|
|
265
|
+
path = args[:path]
|
|
266
|
+
rule = args[:rule]
|
|
267
|
+
opts = args[:opts]
|
|
268
|
+
|
|
269
|
+
if path || rule || opts
|
|
270
|
+
filter = rule ? ".Name==#{rule}" : nil
|
|
271
|
+
target = path || nil
|
|
272
|
+
Dev.run_vale(target, opts || '', filter: filter)
|
|
273
|
+
else
|
|
274
|
+
Dev.run_linter_group('AsciiDoc', %w[vale])
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
desc desc_for('lint:html')
|
|
279
|
+
task :html do
|
|
280
|
+
Dev.run_linter_group('HTML', %w[htmlproofer])
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
desc desc_for('lint:adoc')
|
|
284
|
+
task :adoc, %i[path rule opts] => [] do |_t, args|
|
|
285
|
+
path = args[:path]
|
|
286
|
+
rule = args[:rule]
|
|
287
|
+
opts = args[:opts]
|
|
288
|
+
|
|
289
|
+
if path || rule || opts
|
|
290
|
+
filter = rule ? ".Name==#{rule}" : nil
|
|
291
|
+
target = path || nil
|
|
292
|
+
Dev.run_vale(target, opts || '', filter: filter, style_override: :adoc)
|
|
293
|
+
else
|
|
294
|
+
Dev.run_vale(style_override: :adoc)
|
|
295
|
+
end
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
# Alias: labdev:lint:asciidoc -> labdev:lint:adoc
|
|
299
|
+
task asciidoc: 'adoc'
|
|
300
|
+
|
|
301
|
+
desc desc_for('lint:text')
|
|
302
|
+
task :text, %i[path rule opts] => [] do |_t, args|
|
|
303
|
+
path = args[:path]
|
|
304
|
+
rule = args[:rule]
|
|
305
|
+
opts = args[:opts]
|
|
306
|
+
|
|
307
|
+
if path || rule || opts
|
|
308
|
+
filter = rule ? ".Name==#{rule}" : nil
|
|
309
|
+
target = path || nil
|
|
310
|
+
Dev.run_vale(target, opts || '', filter: filter, style_override: :text)
|
|
311
|
+
else
|
|
312
|
+
Dev.run_vale(style_override: :text)
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
desc desc_for('lint:workflows')
|
|
317
|
+
task :workflows, %i[path opts] => [] do |_t, args|
|
|
318
|
+
# path = args[:path] # TODO: path not yet supported by run_actionlint
|
|
319
|
+
opts = args[:opts]
|
|
320
|
+
|
|
321
|
+
if opts
|
|
322
|
+
Dev.run_actionlint(opts)
|
|
323
|
+
else
|
|
324
|
+
Dev.run_linter_group('GitHub Actions', %w[actionlint])
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
desc desc_for('lint:spellcheck')
|
|
329
|
+
task :spellcheck, %i[path opts] => [] do |_t, args|
|
|
330
|
+
path = args[:path]
|
|
331
|
+
SpellCheck.generate_spellcheck_report(path)
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
desc desc_for('lint:logs')
|
|
335
|
+
task :logs, %i[type path outdir] => [] do |_t, args|
|
|
336
|
+
log_type = args[:type]
|
|
337
|
+
log_file = args[:path]
|
|
338
|
+
output_dir = args[:outdir]
|
|
339
|
+
|
|
340
|
+
unless log_type && log_file
|
|
341
|
+
puts 'Usage: bundle exec rake labdev:lint:logs[type,path]'
|
|
342
|
+
puts 'Example: bundle exec rake labdev:lint:logs[jekyll-asciidoc,.agent/build.log]'
|
|
343
|
+
puts 'Supported log types: jekyll-asciidoc'
|
|
344
|
+
next
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
case log_type.to_s.downcase
|
|
348
|
+
when 'jekyll-asciidoc', 'jekyll_asciidoc', 'jekyll'
|
|
349
|
+
LogParser.parse_jekyll_asciidoc_log(log_file, output_dir)
|
|
350
|
+
else
|
|
351
|
+
puts "❌ Unknown log type: #{log_type}"
|
|
352
|
+
puts 'Supported types: jekyll-asciidoc'
|
|
353
|
+
false
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
desc desc_for('lint:all')
|
|
358
|
+
task :all do
|
|
359
|
+
Dev.run_all_linters
|
|
360
|
+
end
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
# Base task; show help for 'lint' namespace
|
|
364
|
+
task :lint do
|
|
365
|
+
Help.show_task_help('lint')
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
# ============================================================
|
|
369
|
+
# HEAL tasks; Auto-fix issues
|
|
370
|
+
# ============================================================
|
|
371
|
+
|
|
372
|
+
namespace :heal do
|
|
373
|
+
desc desc_for('heal:ruby')
|
|
374
|
+
task :ruby, [:path] => [] do |_t, args|
|
|
375
|
+
Dev.run_rubocop_auto_fix(path: args[:path])
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
desc desc_for('heal:adoc')
|
|
379
|
+
# Add an optional path argument that defaults to nil
|
|
380
|
+
task :adoc, %i[path] => [] do |_t, args|
|
|
381
|
+
Dev.run_adoc_auto_fix(args[:path])
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
desc desc_for('heal:all')
|
|
385
|
+
task :all do
|
|
386
|
+
# if the user passed an argument, we wan to tell them this task does not accept any arguments and we want to peaec out of this operation rather than running it
|
|
387
|
+
if ARGV.any? { |arg| arg.include?('labdev:heal:all') && arg.include?('[') }
|
|
388
|
+
puts '⚠️ labdev:heal:all does not accept any arguments. Exiting.'
|
|
389
|
+
puts 'Use labdev:heal:ruby[path] or labdev:heal:adoc[path] to auto-fix specific files.'
|
|
390
|
+
return
|
|
391
|
+
end
|
|
392
|
+
Dev.run_auto_fix
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
# Base task; show help for 'heal' namespace
|
|
397
|
+
task :heal do
|
|
398
|
+
Help.show_task_help('heal')
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
# ============================================================
|
|
402
|
+
# SHOW and HELP tasks; Display information
|
|
403
|
+
# ============================================================
|
|
404
|
+
|
|
405
|
+
namespace :show do
|
|
406
|
+
desc desc_for('show:scripts')
|
|
407
|
+
task :scripts do
|
|
408
|
+
Dev.list_script_templates
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
desc desc_for('show:hooks')
|
|
412
|
+
task :hooks do
|
|
413
|
+
Dev.list_hook_templates
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
desc desc_for('show:rule')
|
|
417
|
+
task :rule, %i[tool rule] => [] do |_t, args|
|
|
418
|
+
tool = args[:tool]
|
|
419
|
+
rule = args[:rule]
|
|
420
|
+
|
|
421
|
+
if tool.nil? || rule.nil?
|
|
422
|
+
puts '❌ Tool and rule are required parameters.'
|
|
423
|
+
puts 'Usage: bundle exec rake labdev:show:rule[tool,rule]'
|
|
424
|
+
puts 'Example: bundle exec rake labdev:show:rule[vale,*.Spelling]'
|
|
425
|
+
return
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
Dev.show_lint_rule(tool, rule)
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
desc desc_for('help')
|
|
433
|
+
task :help, [:task_string] => [] do |_t, args|
|
|
434
|
+
Help.show_task_help(args[:task_string])
|
|
435
|
+
end
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'shellwords'
|
|
4
|
+
|
|
5
|
+
module DocOpsLab
|
|
6
|
+
module Dev
|
|
7
|
+
module ToolExecution
|
|
8
|
+
class << self
|
|
9
|
+
def tool_available? tool_name
|
|
10
|
+
system("which #{tool_name} > /dev/null 2>&1")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def docker_available?
|
|
14
|
+
@docker_available ||= system('which docker > /dev/null 2>&1')
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def image_available?
|
|
18
|
+
unless docker_available?
|
|
19
|
+
@image_available = false
|
|
20
|
+
return @image_available
|
|
21
|
+
end
|
|
22
|
+
@image_available ||= system('docker image inspect docopslab/dev > /dev/null 2>&1')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def run_with_fallback tool_name, command, use_docker: false
|
|
26
|
+
# Accept String or Array command; prefer Array for safer execution
|
|
27
|
+
cmd_runner = lambda do |cmd|
|
|
28
|
+
cmd.is_a?(Array) ? system(*cmd) : system(cmd)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# if env var LABDEV_DEBUG=true, print the full command
|
|
32
|
+
if ENV['LABDEV_DEBUG'] == 'true'
|
|
33
|
+
if command.is_a?(Array)
|
|
34
|
+
puts "🐛 [DEBUG] Command to run: #{command.map do |c|
|
|
35
|
+
Shellwords.escape(c)
|
|
36
|
+
end.join(' ')}"
|
|
37
|
+
else
|
|
38
|
+
puts "🐛 [DEBUG] Command to run: #{command}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Run command natively or fall back to Docker
|
|
43
|
+
if use_docker || !tool_available?(tool_name)
|
|
44
|
+
if image_available?
|
|
45
|
+
run_in_docker(command)
|
|
46
|
+
else
|
|
47
|
+
puts "❌ #{tool_name} not available natively and Docker not found"
|
|
48
|
+
puts " Install #{tool_name} or pull Docker image to continue" if docker_available?
|
|
49
|
+
puts " Install #{tool_name} or Docker to continue" unless docker_available?
|
|
50
|
+
false
|
|
51
|
+
end
|
|
52
|
+
else
|
|
53
|
+
cmd_runner.call(command)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def run_in_docker command
|
|
58
|
+
# Run command in docopslab/dev container
|
|
59
|
+
# Handle both String and Array command formats
|
|
60
|
+
cmd_str = command.is_a?(Array) ? command.shelljoin : command
|
|
61
|
+
docker_cmd = "docker run -it --rm -v \"$(pwd):/workspace\" -w /workspace docopslab/dev #{cmd_str}"
|
|
62
|
+
puts "🐳 Running in Docker: #{cmd_str}"
|
|
63
|
+
system(docker_cmd)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|