Skip to main content

create-addon

Scaffold a new Dradis addon gem with the correct boilerplate structure. Ask questions to determine the addon type, name, description, and capabilities, then generate all required files in a new directory.

소스 정보

저장소
dradis/dradis-ce
최근 소스 활동
2026년 3월 16일 16:07
감지된 SKILL.md 언어
영어
스타
845
포크
228

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
create-addon
description
Scaffold a new Dradis addon gem with the correct boilerplate structure. Ask questions to determine the addon type, name, description, and capabilities, then generate all required files in a new directory.
You are scaffolding a new Dradis addon. Follow these steps exactly. ## Step 1 — Gather information Ask the user the following questions one group at a time. Keep the tone friendly and jargon-free. Wait for all answers in a group before moving to the next group. **Group 1 — The basics:** Ask these four questions together: 1. **What would you like to call your addon?** This can be a tool name, a product name, or just a short descriptive name. For example: "Custom Importer", "Custom Exporter", "ACME Risk Matrix". It will be used to name the addon directory and files. 2. **Describe what your addon does in one sentence.** For example: "Imports findings from our internal scanning tool into Dradis" or "Displays all project findings in a custom risk matrix table tailored to ACME's scoring methodology." 3. **Your name** — this will appear in the addon's metadata. 4. **Your email address** — also used in the addon's metadata. --- **Group 2 — What should your addon do?** Ask this as a simple choice. Frame it conversationally: > Dradis addons can do one or more of the following things. Which fits what you're building? > > **Option A — Import files** > Your addon will let users upload a file — any kind of file — and Dradis will read it and turn the contents into items in the project (like issues, notes, or evidence). Choose this if you have data in a file that you want to bring into Dradis automatically. > > **Option B — Export / generate reports** > Your addon will take the data already in a Dradis project and produce an output file from it — for example, a custom HTML report, a CSV export, or any other format your team needs. Choose this if you want to generate something *from* Dradis. > > **Option C — Add new pages to Dradis** > Your addon will add its own screens or interfaces inside the Dradis web app — for example, a custom risk matrix table, a team-specific findings view, or a bespoke workflow that only makes sense for your organisation. Choose this if you're building something that needs its own UI. > > **Option D — A combination** > Mix and match any of the above. Just tell us which ones apply. ## Step 2 — Confirm before creating Silently derive the following from the addon name: - `<slug>` — lowercase, hyphenated (e.g. `custom-importer`, `acme-risk-matrix`) - `<module_name>` — CamelCase (e.g. `CustomImporter`, `AcmeRiskMatrix`) - `<plugin_name>` — underscored (e.g. `custom_importer`, `acme_risk_matrix`) Then confirm with the user using only the details they gave you: > Here's what I'll create: > > - **Name:** <addon name they provided> > - **Description:** <description they provided> > - **Type:** <what they chose — Import, Export, Custom pages, or a combination> > - **Location:** `../plugins/dradis-<slug>/` > > Shall I go ahead? ## Step 3 — Generate files Create all files inside `../plugins/dradis-<slug>/` (a sibling directory to `dradis-ce`, under a `plugins/` folder). Generate every file listed below with correct content based on the answers. --- ### Files to generate #### `dradis-<slug>.gemspec` ```ruby $:.push File.expand_path('../lib', __FILE__) require 'dradis/plugins/<slug>/version' version = Dradis::Plugins::<module_name>::VERSION::STRING Gem::Specification.new do |spec| spec.platform = Gem::Platform::RUBY spec.name = 'dradis-<slug>' spec.version = version spec.summary = '<description>' spec.description = '<description>' spec.license = 'GPL-2' spec.authors = ['<author_name>'] spec.email = ['<author_email>'] spec.homepage = 'https://dradis.com' spec.files = `git ls-files`.split($\) spec.executables = spec.files.grep(%r{^bin/}).map { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ['lib'] spec.add_dependency 'dradis-plugins', '~> 4.0' spec.add_development_dependency 'bundler', '~> 2.0' spec.add_development_dependency 'combustion', '~> 1.3' spec.add_development_dependency 'rake' spec.add_development_dependency 'rspec-rails' end ``` #### `Gemfile` ```ruby source 'https://rubygems.org' gemspec ``` #### `Rakefile` ```ruby require 'bundler/gem_tasks' require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) task default: :spec ``` #### `lib/dradis-<slug>.rb` ```ruby require 'dradis-plugins' require 'dradis/plugins/<slug>' ``` #### `lib/dradis/plugins/<slug>.rb` ```ruby module Dradis::Plugins::<module_name> PLUGIN_NAME = :<plugin_name> end require 'dradis/plugins/<slug>/engine' require 'dradis/plugins/<slug>/gem_version' require 'dradis/plugins/<slug>/version' ``` If upload addon, also add: ```ruby require 'dradis/plugins/<slug>/field_processor' require 'dradis/plugins/<slug>/importer' require 'dradis/plugins/<slug>/mapping' ``` #### `lib/dradis/plugins/<slug>/engine.rb` The `provides` line reflects the user's chosen option(s): - Import only: `provides :upload` - Export only: `provides :export` - Custom pages only: `provides :addon` - Any combination: `provides :upload, :export` / `provides :upload, :addon` / etc. ```ruby module Dradis::Plugins::<module_name> class Engine < ::Rails::Engine isolate_namespace Dradis::Plugins::<module_name> include ::Dradis::Plugins::Base description '<description>' provides :<capability> # one or more of: :upload, :export, :addon end end ``` If `provides :addon` or `provides :export` is included, add an initializer block to mount the engine. Use `routes.append` (not `prepend`) so the engine never overrides the main app's routes: ```ruby initializer '<slug>.mount_engine' do Rails.application.routes.append do mount Dradis::Plugins::<module_name>::Engine => '/', as: :<plugin_name> end end ``` #### `lib/dradis/plugins/<slug>/version.rb` ```ruby require_relative 'gem_version' module Dradis module Plugins module <module_name> module VERSION MAJOR = 0 MINOR = 1 TINY = 0 PRE = nil STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.') end end end end ``` #### `lib/dradis/plugins/<slug>/gem_version.rb` ```ruby module Dradis module Plugins module <module_name> def self.gem_version Gem::Version.new VERSION::STRING end end end end ``` #### `lib/dradis/plugins/<slug>/importer.rb` (upload addons only) ```ruby module Dradis::Plugins::<module_name> class Importer < Dradis::Plugins::Upload::Importer # Override the import method to process the uploaded file. # # The `params` hash includes: # params[:file] - path to the uploaded file (a Tempfile or String path) # params[:project] - the current Dradis project # # Use content_service to create nodes, issues, and evidence: # content_service.create_node(label: 'hostname') # content_service.create_note(node: node, text: '#[Title]#\nValue') # content_service.create_issue(text: '#[Title]#\nValue') # content_service.create_evidence(issue: issue, node: node, content: '#[Port]#\n443') # # Use mapping_service to apply field mappings from templates: # mapping_service.apply_mapping(source: :<entity>, data: object) def import(params = {}) file_content = File.read(params[:file]) # TODO: parse file_content and iterate over findings logger.info { 'Done.' } end end end ``` #### `lib/dradis/plugins/<slug>/field_processor.rb` (upload addons only) ```ruby module Dradis::Plugins::<module_name> class FieldProcessor < Dradis::Plugins::Upload::FieldProcessor # Map a Liquid template field name to a value from the source data object. # # `params[:data]` is the object you passed to mapping_service.apply_mapping. # `params[:field]` is the field name from the template (e.g. '<plugin_name>[entity.attribute]'). # # Example: # when '<plugin_name>[finding.title]' then object.title def value(params = {}) _object = params[:data] _field = params[:field] case params[:field] # TODO: add field mappings here # when '<plugin_name>[finding.title]' then object.title end end end end ``` #### `lib/dradis/plugins/<slug>/mapping.rb` (upload addons only) ```ruby module Dradis::Plugins::<module_name> module Mapping # DEFAULT_MAPPING defines the default Liquid templates used when importing. # Keys are entity types (matching your importer), values are field-to-template maps. # Template variables use the syntax: {{ <plugin_name>[entity.attribute] }} DEFAULT_MAPPING = { issue: { 'Title' => '{{ <plugin_name>[issue.title] }}', 'Description' => '{{ <plugin_name>[issue.description] }}' }, evidence: { 'Output' => '{{ <plugin_name>[evidence.output] }}' } }.freeze SOURCE_FIELDS = { issue: %w[ issue.title issue.description ], evidence: %w[ evidence.output ] }.freeze end end ``` Adjust entity names and fields based on the user's answers about their data model. #### `templates/` (upload addons only) Create both sample files. Use the Dradis `#[FieldName]#` syntax. **`templates/issue.sample`:** ``` #[Title]# {{ <plugin_name>[issue.title] }} #[Description]# {{ <plugin_name>[issue.description] }} ``` **`templates/evidence.sample`:** ``` #[Output]# {{ <plugin_name>[evidence.output] }} ``` #### `spec/spec_helper.rb` ```ruby ENV['RAILS_ENV'] ||= 'test' require 'combustion' Combustion.initialize! :all require 'rspec/rails' RSpec.configure do |config| config.expect_with :rspec do |expectations| expectations.include_chain_clauses_in_custom_matcher_descriptions = true end config.mock_with :rspec do |mocks| mocks.verify_partial_doubles = true end config.shared_context_metadata_behavior = :apply_to_host_groups end ``` #### `spec/dradis/plugins/<slug>/importer_spec.rb` (upload addons only) ```ruby require 'spec_helper' describe Dradis::Plugins::<module_name>::Importer do pending 'add importer specs here' end ``` #### `spec/fixtures/files/.gitkeep` Empty placeholder file so the fixtures directory is tracked. #### `.gitignore` ``` *.gem *.rbc .bundle .config .yardoc Gemfile.lock InstalledFiles _yardoc/ coverage/ doc/ lib/bundler/man/ pkg/ rdoc/ spec/reports/ test/tmp/ test/version_tmp/ tmp/ ``` #### `LICENSE` ``` Copyright (c) <year> <author_name> This software is open source and available under the GNU General Public License version 2 (GPL-2). See https://www.gnu.org/licenses/old-licenses/gpl-2.0.html ``` #### `CHANGELOG.md` ```markdown # Changelog ## [Unreleased] ### Added - Initial release ``` #### `README.md` ```markdown # dradis-<slug> <description> ## Installation Add to your Dradis `Gemfile`: ```ruby gem 'dradis-<slug>' ``` Then run: ``` bundle install ``` ## Usage <!-- TODO: describe how to use this addon -->
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기