Class: Ace::Lint::Atoms::TypeDetector
- Inherits:
-
Object
- Object
- Ace::Lint::Atoms::TypeDetector
- Defined in:
- lib/ace/lint/atoms/type_detector.rb
Overview
Pure function to detect file type from extension or content
Constant Summary collapse
- BASENAME_MAP =
{ "Gemfile" => :ruby, "Rakefile" => :ruby }.freeze
- EXTENSION_MAP =
{ ".md" => :markdown, ".markdown" => :markdown, ".yml" => :yaml, ".yaml" => :yaml, ".rb" => :ruby, ".rake" => :ruby, ".gemspec" => :ruby }.freeze
- SKILL_BASENAME_PATTERN =
Patterns for markdown subtype detection SKILL.md or SKILLS.md (case-insensitive)
/\ASKILLS?\.md\z/i- WORKFLOW_SUFFIX =
*.wf.md for workflow files
".wf.md"- AGENT_SUFFIX =
*.ag.md for agent files
".ag.md"
Class Method Summary collapse
-
.detect(file_path, content: nil) ⇒ Symbol
Detect file type from file path and optional content.
- .detect_from_content(content) ⇒ Object
-
.detect_markdown_subtype(file_path, basename) ⇒ Symbol?
Detect markdown subtype based on filename patterns.
-
.has_frontmatter?(content) ⇒ Boolean
Detect if file has frontmatter.
- .markdown_content?(content) ⇒ Boolean
- .yaml_content?(content) ⇒ Boolean
Class Method Details
.detect(file_path, content: nil) ⇒ Symbol
Detect file type from file path and optional content
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/ace/lint/atoms/type_detector.rb', line 37 def self.detect(file_path, content: nil) return :unknown if file_path.nil? || file_path.to_s.empty? # Try basename-based detection for known Ruby entrypoints basename = File.basename(file_path) type = BASENAME_MAP[basename] return type if type # Try extension-based detection ext = File.extname(file_path).downcase type = EXTENSION_MAP[ext] # For markdown files, check for skill/workflow/agent subtypes if type == :markdown subtype = detect_markdown_subtype(file_path, basename) return subtype if subtype return :markdown end return type if type # Try content-based detection if content provided return detect_from_content(content) if content :unknown end |
.detect_from_content(content) ⇒ Object
90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/ace/lint/atoms/type_detector.rb', line 90 def self.detect_from_content(content) return :unknown if content.nil? || content.empty? # Check for markdown indicators if markdown_content?(content) :markdown # Check for YAML indicators elsif yaml_content?(content) :yaml else :unknown end end |
.detect_markdown_subtype(file_path, basename) ⇒ Symbol?
Detect markdown subtype based on filename patterns
68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/ace/lint/atoms/type_detector.rb', line 68 def self.detect_markdown_subtype(file_path, basename) # Check for SKILL.md or SKILLS.md (case-insensitive) return :skill if basename.match?(SKILL_BASENAME_PATTERN) # Check for *.wf.md (workflow files) return :workflow if file_path.downcase.end_with?(WORKFLOW_SUFFIX) # Check for *.ag.md (agent files) return :agent if file_path.downcase.end_with?(AGENT_SUFFIX) nil end |
.has_frontmatter?(content) ⇒ Boolean
Detect if file has frontmatter
84 85 86 87 88 |
# File 'lib/ace/lint/atoms/type_detector.rb', line 84 def self.has_frontmatter?(content) return false if content.nil? || content.empty? content.start_with?("---\n") && content.include?("\n---\n") end |
.markdown_content?(content) ⇒ Boolean
104 105 106 107 108 109 110 111 |
# File 'lib/ace/lint/atoms/type_detector.rb', line 104 def self.markdown_content?(content) # Look for common markdown patterns content.match?(/^\#{1,6}\s+\S/) || # Headers content.match?(/^\*\s+\S/) || # Unordered lists content.match?(/^\d+\.\s+\S/) || # Ordered lists content.match?(/```/) || # Code blocks has_frontmatter?(content) # Frontmatter indicates markdown end |
.yaml_content?(content) ⇒ Boolean
113 114 115 116 117 |
# File 'lib/ace/lint/atoms/type_detector.rb', line 113 def self.yaml_content?(content) # Look for YAML patterns (key: value) content.match?(/^\w+:\s*\S/) || content.match?(/^-\s+\w+:/) # Array of objects end |