Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ set_target_properties(jsonschema_cli PROPERTIES OUTPUT_NAME jsonschema)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::core::error)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::core::io)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::core::uri)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::core::diff)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::core::json)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::core::jsonl)
target_link_libraries(jsonschema_cli PRIVATE sourcemeta::core::gzip)
Expand Down
99 changes: 80 additions & 19 deletions src/command_fmt.cc
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#include <sourcemeta/blaze/format.h>
#include <sourcemeta/blaze/foundation.h>
#include <sourcemeta/core/diff.h>
#include <sourcemeta/core/io.h>
#include <sourcemeta/core/json.h>

#include <iostream> // std::cerr, std::cout
#include <sstream> // std::ostringstream
#include <utility> // std::move
#include <vector> // std::vector
#include <iostream> // std::cerr, std::cout
#include <sstream> // std::ostringstream
#include <string> // std::string
#include <string_view> // std::string_view
#include <utility> // std::move, std::unreachable

#include "command.h"
#include "error.h"
Expand All @@ -15,12 +17,80 @@
#include "resolver.h"
#include "utils.h"

namespace {

auto diff_operation_name(const sourcemeta::core::Diff::Operation::Type type)
-> std::string_view {
switch (type) {
case sourcemeta::core::Diff::Operation::Type::Equal:
return "equal";
case sourcemeta::core::Diff::Operation::Type::Delete:
return "delete";
case sourcemeta::core::Diff::Operation::Type::Insert:
return "insert";
default:
std::unreachable();
}
}

auto to_diff_json(const sourcemeta::core::Diff &difference)
Comment thread
jviotti marked this conversation as resolved.
-> sourcemeta::core::JSON {
auto operations{sourcemeta::core::JSON::make_array()};

for (const auto &operation : difference.operations) {
// An insertion is the only operation that reads the modified input, as
// the lines it introduces are not present in the original one
const auto insertion{operation.type ==
sourcemeta::core::Diff::Operation::Type::Insert};
const auto &tokens{insertion ? difference.modified : difference.original};
const auto start{insertion ? operation.modified_start
: operation.original_start};
const auto end{insertion ? operation.modified_end : operation.original_end};

auto lines{sourcemeta::core::JSON::make_array()};
for (auto index{start}; index < end; ++index) {
lines.push_back(sourcemeta::core::JSON{tokens[index]});
}

auto entry{sourcemeta::core::JSON::make_object()};
entry.assign("type",
sourcemeta::core::JSON{diff_operation_name(operation.type)});
entry.assign("lines", std::move(lines));
operations.push_back(std::move(entry));
}

return operations;
}

auto report_check_failure(const std::string &current,
const std::string &expected, const std::string &label,
const bool output_json,
sourcemeta::core::JSON &errors) -> void {
const auto difference{sourcemeta::core::diff(
current, expected, sourcemeta::core::Diff::Mode::Line,
sourcemeta::core::Diff::Algorithm::Myers)};

if (output_json) {
auto entry{sourcemeta::core::JSON::make_object()};
entry.assign("path", sourcemeta::core::JSON{label});
entry.assign("diff", to_diff_json(difference));
errors.push_back(std::move(entry));
} else {
std::cerr << "fail: " << label << "\n";
sourcemeta::core::stringify(
difference, std::cerr, sourcemeta::core::Diff::Format::Unified,
{.original_label = "current", .modified_label = "expected"});
}
}

} // namespace

auto sourcemeta::jsonschema::fmt(const sourcemeta::core::Options &options)
-> void {
validate_http_headers(options);
const bool output_json{options.contains("json")};
bool result{true};
std::vector<std::string> failed_files;
auto errors{sourcemeta::core::JSON::make_array()};
const auto indentation{parse_indentation(options)};

const auto handle_stdin = [&]() {
Expand Down Expand Up @@ -66,11 +136,9 @@ auto sourcemeta::jsonschema::fmt(const sourcemeta::core::Options &options)

if (raw_stdin == expected.str()) {
LOG_VERBOSE(options) << "ok: " << stdin_label << "\n";
} else if (output_json) {
failed_files.push_back(stdin_label);
result = false;
} else {
std::cerr << "fail: " << stdin_label << "\n";
report_check_failure(raw_stdin, expected.str(), stdin_label,
output_json, errors);
result = false;
}
} else {
Expand Down Expand Up @@ -162,11 +230,9 @@ auto sourcemeta::jsonschema::fmt(const sourcemeta::core::Options &options)
if (options.contains("check")) {
if (current == expected.str()) {
LOG_VERBOSE(options) << "ok: " << entry.first << "\n";
} else if (output_json) {
failed_files.push_back(entry.first);
result = false;
} else {
std::cerr << "fail: " << entry.first << "\n";
report_check_failure(current, expected.str(), entry.first,
output_json, errors);
result = false;
}
} else {
Expand Down Expand Up @@ -240,12 +306,7 @@ auto sourcemeta::jsonschema::fmt(const sourcemeta::core::Options &options)
output_json_object.assign("valid", sourcemeta::core::JSON{result});

if (!result) {
auto errors_array{sourcemeta::core::JSON::make_array()};
for (auto &file_path : failed_files) {
errors_array.push_back(sourcemeta::core::JSON{std::move(file_path)});
}

output_json_object.assign("errors", sourcemeta::core::JSON{errors_array});
output_json_object.assign("errors", std::move(errors));
}

sourcemeta::core::prettify(output_json_object, std::cout, indentation);
Expand Down
22 changes: 22 additions & 0 deletions test/format/fail_check_many.clitest
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,29 @@ REPLACE $CWD WITH '[CWD]' IN result.txt

WRITE expected.txt UNTIL EOF
2> fail: [CWD]/schemas/1.json
2> --- current
2> +++ expected
2> @@ -1,6 +1,6 @@
2> {
2> - "type": "string",
2> "$schema": "http://json-schema.org/draft-04/schema#",
2> "title": "Test",
2> - "description": "Test schema"
2> + "description": "Test schema",
2> + "type": "string"
2> }
2> fail: [CWD]/schemas/2.json
2> --- current
2> +++ expected
2> @@ -1,6 +1,6 @@
2> {
2> - "type": "string",
2> "$schema": "http://json-schema.org/draft-04/schema#",
2> "title": "Test",
2> - "description": "Test schema"
2> + "description": "Test schema",
2> + "type": "string"
2> }
2>
2> Run the `fmt` command without `--check/-c` to fix the formatting
EOF
Expand Down
78 changes: 73 additions & 5 deletions test/format/fail_check_many_json.clitest
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ WRITE schemas/1.json UNTIL EOF
"type": "string",
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Test",
"description": "Test schema"
"description": "Test schema for formatting"
}
EOF

Expand All @@ -12,15 +12,15 @@ WRITE schemas/2.json UNTIL EOF
"type": "string",
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Test",
"description": "Test schema"
"description": "Test schema for formatting"
}
EOF

WRITE schemas/3.json UNTIL EOF
{
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Test",
"description": "Test schema"
"description": "Test schema for formatting"
}
EOF

Expand All @@ -33,8 +33,76 @@ WRITE expected.txt UNTIL EOF
1> {
1> "valid": false,
1> "errors": [
1> "[CWD]/schemas/1.json",
1> "[CWD]/schemas/2.json"
1> {
1> "path": "[CWD]/schemas/1.json",
1> "diff": [
1> {
1> "type": "equal",
1> "lines": [ "{" ]
1> },
1> {
1> "type": "delete",
1> "lines": [ " \"type\": \"string\"," ]
1> },
1> {
1> "type": "equal",
1> "lines": [
1> " \"$schema\": \"http://json-schema.org/draft-04/schema#\",",
1> " \"title\": \"Test\","
1> ]
1> },
1> {
1> "type": "delete",
1> "lines": [ " \"description\": \"Test schema for formatting\"" ]
1> },
1> {
1> "type": "insert",
1> "lines": [
1> " \"description\": \"Test schema for formatting\",",
1> " \"type\": \"string\""
1> ]
1> },
1> {
1> "type": "equal",
1> "lines": [ "}" ]
1> }
1> ]
1> },
1> {
1> "path": "[CWD]/schemas/2.json",
1> "diff": [
1> {
1> "type": "equal",
1> "lines": [ "{" ]
1> },
1> {
1> "type": "delete",
1> "lines": [ " \"type\": \"string\"," ]
1> },
1> {
1> "type": "equal",
1> "lines": [
1> " \"$schema\": \"http://json-schema.org/draft-04/schema#\",",
1> " \"title\": \"Test\","
1> ]
1> },
1> {
1> "type": "delete",
1> "lines": [ " \"description\": \"Test schema for formatting\"" ]
1> },
1> {
1> "type": "insert",
1> "lines": [
1> " \"description\": \"Test schema for formatting\",",
1> " \"type\": \"string\""
1> ]
1> },
1> {
1> "type": "equal",
1> "lines": [ "}" ]
1> }
1> ]
1> }
1> ]
1> }
EOF
Expand Down
11 changes: 11 additions & 0 deletions test/format/fail_check_single.clitest
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ REPLACE $CWD WITH '[CWD]' IN result.txt

WRITE expected.txt UNTIL EOF
2> fail: [CWD]/schema.json
2> --- current
2> +++ expected
2> @@ -1,6 +1,6 @@
2> {
2> - "type": "string",
2> "$schema": "http://json-schema.org/draft-04/schema#",
2> "title": "Test",
2> - "description": "Test schema"
2> + "description": "Test schema",
2> + "type": "string"
2> }
2>
2> Run the `fmt` command without `--check/-c` to fix the formatting
EOF
Expand Down
13 changes: 13 additions & 0 deletions test/format/fail_check_single_indentation.clitest
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ REPLACE $CWD WITH '[CWD]' IN result.txt

WRITE expected.txt UNTIL EOF
2> fail: [CWD]/schema.json
2> --- current
2> +++ expected
2> @@ -1,6 +1,6 @@
2> {
2> - "$schema": "http://json-schema.org/draft-04/schema#",
2> - "title": "Test",
2> - "description": "Test schema",
2> - "type": 1
2> + "$schema": "http://json-schema.org/draft-04/schema#",
2> + "title": "Test",
2> + "description": "Test schema",
2> + "type": 1
2> }
2>
2> Run the `fmt` command without `--check/-c` to fix the formatting
EOF
Expand Down
38 changes: 36 additions & 2 deletions test/format/fail_check_single_json.clitest
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ WRITE this/is/a/very/very/very/very/very/very/long/path/schema.json UNTIL EOF
"type": "string",
"$schema": "http://json-schema.org/draft-04/schema#",
"title": "Test",
"description": "Test schema"
"description": "Test schema for formatting"
}
EOF

Expand All @@ -16,7 +16,41 @@ WRITE expected.txt UNTIL EOF
1> {
1> "valid": false,
1> "errors": [
1> "[CWD]/this/is/a/very/very/very/very/very/very/long/path/schema.json"
1> {
1> "path": "[CWD]/this/is/a/very/very/very/very/very/very/long/path/schema.json",
1> "diff": [
1> {
1> "type": "equal",
1> "lines": [ "{" ]
1> },
1> {
1> "type": "delete",
1> "lines": [ " \"type\": \"string\"," ]
1> },
1> {
1> "type": "equal",
1> "lines": [
1> " \"$schema\": \"http://json-schema.org/draft-04/schema#\",",
1> " \"title\": \"Test\","
1> ]
1> },
1> {
1> "type": "delete",
1> "lines": [ " \"description\": \"Test schema for formatting\"" ]
1> },
1> {
1> "type": "insert",
1> "lines": [
1> " \"description\": \"Test schema for formatting\",",
1> " \"type\": \"string\""
1> ]
1> },
1> {
1> "type": "equal",
1> "lines": [ "}" ]
1> }
1> ]
1> }
1> ]
1> }
EOF
Expand Down
Loading
Loading