Class: RubynCode::Skills::Document

Inherits:
Object
  • Object
show all
Defined in:
lib/rubyn_code/skills/document.rb

Constant Summary collapse

FRONTMATTER_PATTERN =
/\A---\s*\n(.+?\n)---\s*\n(.*)\z/m
TAG_RULES =
[
  ['ruby',        /\bruby\b/i],
  ['rails',       /\brails\b/i],
  ['rspec',       /\brspec\b/i],
  ['testing',     /\b(?:test|spec|minitest)\b/i],
  ['patterns',    /\b(?:pattern|design|solid)\b/i],
  ['refactoring', /\brefactor/i]
].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name:, description:, tags:, body:, triggers: [], gems: [], rails: nil) ⇒ Document

rubocop:disable Metrics/ParameterLists – frontmatter-driven, keyword-only is clearer than a metadata hash



12
13
14
15
16
17
18
19
20
# File 'lib/rubyn_code/skills/document.rb', line 12

def initialize(name:, description:, tags:, body:, triggers: [], gems: [], rails: nil) # rubocop:disable Metrics/ParameterLists -- frontmatter-driven, keyword-only is clearer than a metadata hash
  @name = name
  @description = description
  @tags = tags
  @triggers = triggers
  @gems = gems
  @rails = rails
  @body = body
end

Instance Attribute Details

#bodyObject (readonly)

Returns the value of attribute body.



10
11
12
# File 'lib/rubyn_code/skills/document.rb', line 10

def body
  @body
end

#descriptionObject (readonly)

Returns the value of attribute description.



10
11
12
# File 'lib/rubyn_code/skills/document.rb', line 10

def description
  @description
end

#gemsObject (readonly)

Returns the value of attribute gems.



10
11
12
# File 'lib/rubyn_code/skills/document.rb', line 10

def gems
  @gems
end

#nameObject (readonly)

Returns the value of attribute name.



10
11
12
# File 'lib/rubyn_code/skills/document.rb', line 10

def name
  @name
end

#railsObject (readonly)

Returns the value of attribute rails.



10
11
12
# File 'lib/rubyn_code/skills/document.rb', line 10

def rails
  @rails
end

#tagsObject (readonly)

Returns the value of attribute tags.



10
11
12
# File 'lib/rubyn_code/skills/document.rb', line 10

def tags
  @tags
end

#triggersObject (readonly)

Returns the value of attribute triggers.



10
11
12
# File 'lib/rubyn_code/skills/document.rb', line 10

def triggers
  @triggers
end

Class Method Details

.parse(content, filename: nil) ⇒ Object



23
24
25
26
# File 'lib/rubyn_code/skills/document.rb', line 23

def parse(content, filename: nil)
  match = FRONTMATTER_PATTERN.match(content)
  match ? parse_with_frontmatter(match) : parse_without_frontmatter(content, filename)
end

.parse_file(path) ⇒ Object

Raises:



54
55
56
57
58
59
60
# File 'lib/rubyn_code/skills/document.rb', line 54

def parse_file(path)
  raise Error, "Skill file not found: #{path}" unless File.exist?(path)
  raise Error, "Not a file: #{path}" unless File.file?(path)

  content = File.read(path, encoding: 'UTF-8')
  parse(content, filename: path)
end

.parse_with_frontmatter(match) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/rubyn_code/skills/document.rb', line 28

def parse_with_frontmatter(match)
  frontmatter = YAML.safe_load(match[1], permitted_classes: [Symbol]) || {}
  new(
    name: frontmatter['name'].to_s,
    description: frontmatter['description'].to_s,
    tags: Array(frontmatter['tags']),
    triggers: Array(frontmatter['triggers']).map(&:to_s),
    gems: Array(frontmatter['gems']).map(&:to_s),
    rails: frontmatter['rails']&.to_s,
    body: match[2].to_s.strip
  )
end

.parse_without_frontmatter(content, filename) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/rubyn_code/skills/document.rb', line 41

def parse_without_frontmatter(content, filename)
  body = content.to_s.strip
  title = extract_title(body)
  derived_name = filename ? File.basename(filename, '.*').tr('_', '-') : title_to_name(title)

  new(
    name: derived_name,
    description: title,
    tags: derive_tags(derived_name, body),
    body: body
  )
end