Skip to content

Commit 60ee980

Browse files
authored
Ruby support - tested (#122)
* plugin update with ruby support * python implementation for ruby
1 parent 880ccf1 commit 60ee980

File tree

2 files changed

+90
-4
lines changed

2 files changed

+90
-4
lines changed

src/metis/plugins/plugins.yaml

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@ general_prompts:
1414
FILE: {file_path}
1515
security_review_report: |-
1616
3. How to Report
17-
- Return a JSON object with a single key "reviews" mapping to a list of identified security issues.
17+
- List all identified security issues in a JSON array.
1818
- Each element must strictly follow this structure:
1919
[[REVIEW_SCHEMA_FIELDS]]
20-
- If no identified security issues are found, return: {\"reviews\": []}
21-
- If no CWE identified, does not guess a number.
22-
- Ensure the json is valid, without any additional commentary or text outside the json structure.
20+
- IMPORTANT: If no identified security issues are found, return: {\"reviews\": []}
2321
2422
plugins:
2523
c:
@@ -216,6 +214,49 @@ plugins:
216214
1. FILE - A source code file
217215
2. RELEVANT_CONTEXT - information about what these changes do.
218216
217+
Your tasks are:
218+
1. Security Review Scope
219+
- Review the security implications of the FILE.
220+
If it is empty, ignore it.
221+
ruby:
222+
supported_extensions: [".rb"]
223+
splitting:
224+
chunk_lines: 40
225+
chunk_lines_overlap: 15
226+
max_chars: 1500
227+
prompts:
228+
security_review: |-
229+
You are a thorough security engineer specializing in Ruby.
230+
Always tie your identified issues directly to the evidence in FILE_CHANGES, RELEVANT_CONTEXT,
231+
and ORIGINAL_FILE. Do not introduce new security conclusions that are not supported
232+
by the specific changes or context provided.
233+
You will be given:
234+
1. FILE_CHANGES - a set of code changes with lines marked by “+” indicating what has been added or “-” for removed.
235+
2. RELEVANT_CONTEXT - information about what these changes do.
236+
3. ORIGINAL_FILE - The original file before being modified. Use this to understand how changes affect the code. (this may be empty).
237+
238+
Your tasks are:
239+
1. Security Review Scope
240+
- Review the security implications of the FILE_CHANGES, focusing on lines marked with “+.” or “-” but take into account how they interact with the whole file.
241+
If it is empty, ignore it.
242+
security_review_checks: |-
243+
2. What to Check
244+
- Look for potential security issues such as:
245+
- OWASP Top 10 vulnerabilities
246+
- Hardcoded secrets
247+
- Insecure use of libraries
248+
- Do not report on issues that do not affect security.
249+
validation_review: "Validate the following Ruby review for security concerns."
250+
snippet_security_summary: "Summarize the security implications of these Ruby code changes."
251+
attempt_fix: "Based on the issues detected in the Ruby code changes, propose a fix patch. Issues: {issues} Patch: {patch}"
252+
security_review_file: |-
253+
You are a thorough security engineer specializing in Ruby.
254+
Always tie your identified issues directly to the evidence in FILE and RELEVANT_CONTEXT.
255+
Do not introduce new security conclusions that are not supported by the specific changes or context provided.
256+
You will be given:
257+
1. FILE - A source code file
258+
2. RELEVANT_CONTEXT - information about what these changes do.
259+
219260
Your tasks are:
220261
1. Security Review Scope
221262
- Review the security implications of the FILE.

src/metis/plugins/ruby_plugin.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# SPDX-FileCopyrightText: Copyright 2025 Arm Limited and/or its affiliates <[email protected]>
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
from llama_index.core.node_parser import CodeSplitter
5+
6+
from metis.plugins.base import BaseLanguagePlugin
7+
8+
9+
class RubyPlugin(BaseLanguagePlugin):
10+
def __init__(self, plugin_config):
11+
self.plugin_config = plugin_config
12+
13+
def get_name(self):
14+
return "ruby"
15+
16+
def can_handle(self, extension):
17+
supported = self.get_supported_extensions()
18+
return extension.lower() in supported
19+
20+
def get_supported_extensions(self):
21+
return (
22+
self.plugin_config.get("plugins", {})
23+
.get(self.get_name(), {})
24+
.get("supported_extensions", [".rb"])
25+
)
26+
27+
def get_splitter(self):
28+
splitting_cfg = (
29+
self.plugin_config.get("plugins", {})
30+
.get(self.get_name(), {})
31+
.get("splitting", {})
32+
)
33+
return CodeSplitter(
34+
language=self.get_name(),
35+
chunk_lines=splitting_cfg["chunk_lines"],
36+
chunk_lines_overlap=splitting_cfg["chunk_lines_overlap"],
37+
max_chars=splitting_cfg["max_chars"],
38+
)
39+
40+
def get_prompts(self):
41+
return (
42+
self.plugin_config.get("plugins", {})
43+
.get(self.get_name(), {})
44+
.get("prompts", {})
45+
)

0 commit comments

Comments
 (0)