diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55606fac..d85fc872 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,7 @@
### Changed
+- **aiken**: Move JSON schema help for `check` under a new dedicated flag `--show-json-schema`. @KtorZ
- **aiken-lang**: Fix pattern-matching on list wildcard sometimes causing compiler crash following the new _decision trees_ approach. @MicroProofs
- **uplc**, **aiken**, **aiken-lang**: Update internal dependencies to pallas-0.31.0. @KtorZ
diff --git a/crates/aiken-project/src/telemetry.rs b/crates/aiken-project/src/telemetry.rs
index 3a8dee75..fb59c5d0 100644
--- a/crates/aiken-project/src/telemetry.rs
+++ b/crates/aiken-project/src/telemetry.rs
@@ -2,7 +2,7 @@ use aiken_lang::{
expr::UntypedExpr,
test_framework::{PropertyTestResult, TestResult, UnitTestResult},
};
-pub use json::Json;
+pub use json::{json_schema, Json};
use std::{
collections::BTreeMap,
fmt::Display,
diff --git a/crates/aiken-project/src/telemetry/json.rs b/crates/aiken-project/src/telemetry/json.rs
index 52aa01fa..45c5fab5 100644
--- a/crates/aiken-project/src/telemetry/json.rs
+++ b/crates/aiken-project/src/telemetry/json.rs
@@ -137,3 +137,137 @@ where
.filter(|t| matches!(t, TestResult::PropertyTestResult { .. }))
.count()
}
+
+pub fn json_schema() -> serde_json::Value {
+ let definitions = json!({
+ "Summary": {
+ "type": "object",
+ "required": ["total", "passed", "failed", "kind"],
+ "properties": {
+ "total": { "type": "integer" },
+ "passed": { "type": "integer" },
+ "failed": { "type": "integer" },
+ "kind": {
+ "type": "object",
+ "required": ["unit", "property"],
+ "properties": {
+ "unit": { "type": "integer" },
+ "property": { "type": "integer" }
+ }
+ }
+ }
+ },
+ "Status": {
+ "type": "string",
+ "enum": [ "pass", "fail" ]
+ },
+ "OnFailure": {
+ "type": "string",
+ "enum": [
+ "fail_immediately",
+ "succeed_immediately",
+ "succeed_eventually"
+ ]
+ }
+ });
+
+ let unit_test = json!({
+ "type": "object",
+ "required": [
+ "kind",
+ "title",
+ "status",
+ "on_failure",
+ "execution_units"
+ ],
+ "properties": {
+ "kind": {
+ "type": "string",
+ "enum": [ "unit" ]
+ },
+ "title": { "type": "string" },
+ "status": { "$ref": "#/properties/definitions/Status" },
+ "on_failure": { "$ref": "#/properties/definitions/OnFailure" },
+ "execution_units": {
+ "type": "object",
+ "properties": {
+ "mem": { "type": "integer" },
+ "cpu": { "type": "integer" }
+ }
+ },
+ "assertion": { "type": "string" },
+ }
+ });
+
+ let property_test = json!({
+ "type": "object",
+ "required": [
+ "kind",
+ "title",
+ "status",
+ "on_failure",
+ "iterations",
+ "counterexample"
+ ],
+ "properties": {
+ "kind": {
+ "type": "string",
+ "enum": [ "property" ]
+ },
+ "title": { "type": "string" },
+ "status": { "$ref": "#/properties/definitions/Status" },
+ "on_failure": { "$ref": "#/properties/definitions/OnFailure" },
+ "iterations": { "type": "integer" },
+ "labels": {
+ "type": "object",
+ "additionalProperties": { "type": "integer" }
+ },
+ "counterexample": {
+ "oneOf": [
+ { "type": "string" },
+ { "type": "null" },
+ {
+ "type": "object",
+ "properties": {
+ "error": { "type": "string" }
+ }
+ }
+ ]
+ }
+ }
+ });
+
+ json!({
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$vocabulary": {
+ "https://json-schema.org/draft/2020-12/vocab/core": true,
+ "https://json-schema.org/draft/2020-12/vocab/applicator": true,
+ "https://json-schema.org/draft/2020-12/vocab/validation": true
+ },
+ "title": "Aiken CLI JSON Schema",
+ "type": "object",
+ "properties": {
+ "command[check]": {
+ "seed": { "type": "integer" },
+ "summary": { "$ref": "#/properties/definitions/Summary" },
+ "modules": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "summary": { "$ref": "#/properties/definitions/Summary" },
+ "test": {
+ "type": "array",
+ "items": {
+ "oneOf": [ unit_test, property_test ]
+ }
+ }
+ }
+ }
+ }
+ },
+ "definitions": definitions
+ }
+ })
+}
diff --git a/crates/aiken/src/cmd/check.rs b/crates/aiken/src/cmd/check.rs
index b145b8ea..ef96c771 100644
--- a/crates/aiken/src/cmd/check.rs
+++ b/crates/aiken/src/cmd/check.rs
@@ -3,7 +3,10 @@ use aiken_lang::{
ast::{TraceLevel, Tracing},
test_framework::PropertyTest,
};
-use aiken_project::watch::{self, watch_project, with_project};
+use aiken_project::{
+ telemetry::json_schema,
+ watch::{self, watch_project, with_project},
+};
use rand::prelude::*;
use std::{
io::{self, IsTerminal},
@@ -19,92 +22,9 @@ Type-check an Aiken project and run any tests found.
Test results are printed as stylized outputs when `stdout` is a TTY-capable terminal. If it
isn't, (e.g. because you are redirecting the output to a file), test results are printed as
-a JSON structured object. Use `--help` to see the whole schema.
+a JSON structured object. Use `--show-json-schema` to see the whole schema.
"#),
- after_long_help = color_print::cstr!(r#"Output JSON schema:
- type: object
- properties:
- seed: &type_integer
- type: integer
- summary:
- type: object
- properties: &type_summary
- total: *type_integer
- passed: *type_integer
- failed: *type_integer
- kind:
- type: object
- properties:
- unit: *type_integer
- property: *type_integer
- modules:
- type: array
- items:
- type: object
- properties:
- name: &type_string
- type: string
- summary: *type_summary
- test:
- type: array
- items:
- oneOf:
- - type: object
- required:
- - kind
- - title
- - status
- - on_failure
- - execution_units
- properties:
- kind
- type: string
- enum: [ "unit" ]
- title: *type_string
- status: &type_status
- type: string
- enum: [ "pass", "fail" ]
- on_failure: &type_on_failure
- type: string
- enum:
- - fail_immediately
- - succeed_immediately
- - succeed_eventually
- execution_units:
- type: object
- properties:
- mem: *type_integer
- cpu: *type_integer
- assertion: *type_string
- - type: object
- required:
- - kind
- - title
- - status
- - on_failure
- - iterations
- - counterexample
- properties:
- kind
- type: string
- enum: [ "property" ]
- title: *type_string
- status: *type_status
- on_failure: *type_on_failure
- iterations: *type_integer
- labels:
- type: object
- additionalProperties: *type_integer
- counterexample:
- oneOf:
- - *type_string
- - type: "null"
- - type: object
- properties:
- error: *type_string
-
-Note:
- You are seeing the extended help. Use `-h` instead of `--help` for a more compact view.
+ after_long_help = color_print::cstr!(r#"You are seeing the extended help. Use `-h` instead of `--help` for a more compact view.
"#
))]
pub struct Args {
@@ -123,6 +43,11 @@ pub struct Args {
#[clap(long)]
debug: bool,
+ /// When enabled, print-out the JSON-schema of the command output when the target isn't an
+ /// ANSI-capable terminal
+ #[clap(long, required = false)]
+ show_json_schema: bool,
+
/// When enabled, re-run the command on file changes instead of exiting
#[clap(long)]
watch: bool,
@@ -185,6 +110,7 @@ pub fn exec(
deny,
skip_tests,
debug,
+ show_json_schema,
match_tests,
exact_match,
watch,
@@ -195,6 +121,11 @@ pub fn exec(
env,
}: Args,
) -> miette::Result<()> {
+ if show_json_schema {
+ println!("{}", serde_json::to_string_pretty(&json_schema()).unwrap());
+ std::process::exit(0);
+ }
+
let mut rng = rand::thread_rng();
let seed = seed.unwrap_or_else(|| rng.gen());