Module: Rails::Hyperdrive::CanonicalSkillRender
- Defined in:
- lib/rails/hyperdrive/canonical_skill_render.rb
Overview
Renders each SKILL.md.erb template in a companion gem repo to the static SKILL.md it pairs with, using the canonical fail-open binding. Companion-repo dev tooling: problems raise.
Defined Under Namespace
Constant Summary collapse
- Error =
GemspecLocator::Error
- PUBLIC_SKILLS_DIR =
"skills".freeze
Class Method Summary collapse
-
.public_erb_templates(gemspec: nil, dir: Dir.pwd, roots: nil) ⇒ Object
A *.md.erb reachable through a public skills root is copied verbatim by generic skills.sh consumers.
- .render_all(gemspec: nil, dir: Dir.pwd, roots: nil) ⇒ Object
-
.resolve_roots(gemspec: nil, dir: Dir.pwd) ⇒ Object
Resolved once per task so a check does not load the gemspec twice.
- .stale(gemspec: nil, dir: Dir.pwd, roots: nil) ⇒ Object
- .write(gemspec: nil, dir: Dir.pwd, roots: nil) ⇒ Object
Class Method Details
.public_erb_templates(gemspec: nil, dir: Dir.pwd, roots: nil) ⇒ Object
A *.md.erb reachable through a public skills root is copied verbatim by generic skills.sh consumers.
101 102 103 104 105 106 107 108 109 110 |
# File 'lib/rails/hyperdrive/canonical_skill_render.rb', line 101 def public_erb_templates(gemspec: nil, dir: Dir.pwd, roots: nil) roots ||= resolve_roots(gemspec: gemspec, dir: dir) templates_root = File.(roots.templates_root) [roots.public_skills_root, roots.skills_root] .uniq { |r| File.(r) } .flat_map { |root| Dir.glob(File.join(root, "**", "*.md.erb")) } .reject { |path| File.(path).start_with?("#{templates_root}/") } .uniq.sort end |
.render_all(gemspec: nil, dir: Dir.pwd, roots: nil) ⇒ Object
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/rails/hyperdrive/canonical_skill_render.rb', line 63 def render_all(gemspec: nil, dir: Dir.pwd, roots: nil) roots ||= resolve_roots(gemspec: gemspec, dir: dir) templates_root = roots.templates_root Dir.glob(File.join(templates_root, "**", "SKILL.md.erb")).sort.flat_map do |template| rel = File.dirname(template).delete_prefix(templates_root).delete_prefix("/") dest_dir = File.join(roots.skills_root, rel) # A SKILL.md written beside the SKILL.md.erb would take precedence # over it at discovery time, silently demoting the skill to its # static face. if File.(dest_dir) == File.(File.dirname(template)) raise Error, "#{template}: content dir equals template dir; set " \ "skills_dir: in hyperdrive.yml to a separate root" end body = render_template(template) validate_output!(body, template) [Rendered.new(template: template, dest: File.join(dest_dir, "SKILL.md"), body: body)] + support_renders(File.dirname(template), dest_dir) end end |
.resolve_roots(gemspec: nil, dir: Dir.pwd) ⇒ Object
Resolved once per task so a check does not load the gemspec twice.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/rails/hyperdrive/canonical_skill_render.rb', line 28 def resolve_roots(gemspec: nil, dir: Dir.pwd) spec, gem_root = GemspecLocator.load_spec(gemspec, dir) path = File.join(gem_root, GemManifest.manifest_relpath(spec)) # Rendering with default roots over a manifest the installer cannot # read would mask the bug this surface exists to catch. manifest, failure = GemManifest.read_root(path) raise Error, "#{path}: #{failure}" if failure Roots.new( skills_root: File.join(gem_root, manifest_dir(manifest, "skills_dir", path) || PUBLIC_SKILLS_DIR), templates_root: File.join(gem_root, manifest_dir(manifest, "skill_templates_dir", path) || File.join("lib", spec.name, "hyperdrive", "skills")), public_skills_root: File.join(gem_root, PUBLIC_SKILLS_DIR) ) end |
.stale(gemspec: nil, dir: Dir.pwd, roots: nil) ⇒ Object
57 58 59 60 61 |
# File 'lib/rails/hyperdrive/canonical_skill_render.rb', line 57 def stale(gemspec: nil, dir: Dir.pwd, roots: nil) render_all(gemspec: gemspec, dir: dir, roots: roots).reject do |r| File.file?(r.dest) && File.read(r.dest) == r.body end end |
.write(gemspec: nil, dir: Dir.pwd, roots: nil) ⇒ Object
50 51 52 53 54 55 |
# File 'lib/rails/hyperdrive/canonical_skill_render.rb', line 50 def write(gemspec: nil, dir: Dir.pwd, roots: nil) render_all(gemspec: gemspec, dir: dir, roots: roots).each do |r| FileUtils.mkdir_p(File.dirname(r.dest)) File.write(r.dest, r.body) end end |