Skip to content

Commit

Permalink
Command for automatically generating JSON Schema for .ameba.yml
Browse files Browse the repository at this point in the history
  • Loading branch information
nobodywasishere committed Nov 17, 2024
1 parent e082eeb commit 2c75cbc
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
/lib/
/bin/ameba
/bin/ameba.dwarf
/bin/schema
/bin/schema.dwarf
/.shards/

# Libraries don't need dependency lock
# Dependencies will be locked in application that uses them
/shard.lock

/.vscode
2 changes: 2 additions & 0 deletions shard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ authors:
targets:
ameba:
main: src/cli.cr
schema:
main: src/ameba/cli/schema.cr

scripts:
postinstall: shards build -Dpreview_mt
Expand Down
44 changes: 44 additions & 0 deletions src/ameba/cli/schema.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require "./cmd"

schema = JSON.build(2) do |b|
b.object do
b.field("$schema", "http://json-schema.org/draft-07/schema#")
b.field("title", ".ameba.yml")
b.field("description", "Configuration rules for the Crystal lang ameba linter")
b.field("type", "object")
b.field("additionalProperties", false)

b.string("properties")
b.object do
b.string("Excluded")
b.object do
b.field("type", "array")
b.field("title", "excluded files and paths")
b.field("description", "an array of wildcards (or paths) to exclude from the source list")

b.string("items")
b.object do
b.field("type", "string")
end
end

b.string("Globs")
b.object do
b.field("type", "array")
b.field("title", "globbed files and paths")
b.field("description", "an array of wildcards (or paths) to include to the inspection")

b.string("items")
b.object do
b.field("type", "string")
end
end

Ameba::Rule.rules.each do |rule|
rule.to_json_schema(b)
end
end
end
end

File.write(".ameba.yml.schema.json", schema)
100 changes: 100 additions & 0 deletions src/ameba/config.cr
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,106 @@ class Ameba::Config
@[YAML::Field(key: "Excluded")]
property excluded : Array(String)?
{% end %}

def self.to_json_schema(b : JSON::Builder)
b.string(rule_name)
b.object do
b.field("type", "object")
b.field("title", rule_name)
{% if properties["description".id] %}
b.field("description", {{ properties["description".id][:default] }} + "\nhttps://crystal-ameba.github.io/ameba/Ameba/Rule/#{rule_name}.html")
{% else %}
b.field("description", "https://crystal-ameba.github.io/ameba/Ameba/Rule/#{rule_name}.html")
{% end %}

b.string("properties")
b.object do
{% for prop_name in properties %}
{% prop = properties[prop_name] %}

b.string({{ prop[:key] }})
b.object do
{% if prop[:type] == String %}
b.field("type", "string")
{% elsif prop[:type] == Int32 %}
b.field("type", "number")
{% elsif prop[:type] == Bool %}
b.field("type", "boolean")
{% elsif prop[:type] == Nil %}
b.field("type", "null")
{% elsif prop[:type].stringify == "::Union(String, ::Nil)" %}
b.string("type")
b.array do
b.string("string")
b.string("null")
end
{% elsif prop[:type].stringify == "::Union(Int32, ::Nil)" %}
b.string("type")
b.array do
b.string("number")
b.string("null")
end
{% elsif prop[:type] == Ameba::Severity %}
b.string("enum")
b.array do
b.string("Error")
b.string("Warning")
b.string("Convention")
end
{% else %}
b.field("type", "array")

b.string("items")
b.object do
b.field("type", "string")
end
{% end %}

{% if prop[:default] %}
b.field("default", {{ prop[:default] }})
{% end %}
end
{% end %}

{% unless properties["enabled".id] %}
b.string("Enabled")
b.object do
b.field("type", "boolean")
b.field("default", true)
end
{% end %}

{% unless properties["severity".id] %}
b.string("Severity")
b.object do
b.field("type", "string")
b.string("enum")
b.array do
b.string("Error")
b.string("Warning")
b.string("Convention")
end
end
{% end %}

{% unless properties["excluded".id] %}
b.string("Excluded")
b.object do
b.string("type")
b.array do
b.string("array")
b.string("string")
end

b.string("items")
b.object do
b.field("type", "string")
end
end
{% end %}
end
end
end
end

macro included
Expand Down

0 comments on commit 2c75cbc

Please sign in to comment.