Skip to content

Commit

Permalink
Implement --fix for the lint command
Browse files Browse the repository at this point in the history
Signed-off-by: Juan Cruz Viotti <[email protected]>
  • Loading branch information
jviotti committed May 31, 2024
1 parent df54d65 commit ca947c0
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 17 deletions.
44 changes: 29 additions & 15 deletions src/command_lint.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
#include <sourcemeta/jsontoolkit/jsonschema.h>

#include <cstdlib> // EXIT_SUCCESS
#include <fstream> // std::ofstream
#include <iostream> // std::cerr, std::cout, std::endl

#include "command.h"
#include "utils.h"

// TODO: Implement a --fix flag
auto intelligence::jsonschema::cli::lint(
const std::span<const std::string> &arguments) -> int {
const auto options{parse_options(arguments, {})};
const auto options{parse_options(arguments, {"f", "fix"})};

sourcemeta::jsontoolkit::SchemaTransformBundle bundle;
bundle.add(
Expand All @@ -19,19 +19,33 @@ auto intelligence::jsonschema::cli::lint(
sourcemeta::jsontoolkit::SchemaTransformBundle::Category::AntiPattern);

bool result{true};
for (const auto &entry : for_each_json(options.at(""))) {
const bool subresult = bundle.check(
entry.second, sourcemeta::jsontoolkit::default_schema_walker,
resolver(options),
[&entry](const auto &pointer, const auto &name, const auto &message) {
std::cout << entry.first.string() << "\n";
std::cout << " ";
sourcemeta::jsontoolkit::stringify(pointer, std::cout);
std::cout << " " << message << " (" << name << ")\n";
});

if (!subresult) {
result = false;

if (options.contains("f") || options.contains("fix")) {
for (const auto &entry : for_each_json(options.at(""))) {
log_verbose(options) << "Linting: " << entry.first.string() << "\n";
auto copy = entry.second;
bundle.apply(copy, sourcemeta::jsontoolkit::default_schema_walker,
resolver(options));
std::ofstream output{entry.first};
sourcemeta::jsontoolkit::prettify(
copy, output, sourcemeta::jsontoolkit::schema_format_compare);
output << std::endl;
}
} else {
for (const auto &entry : for_each_json(options.at(""))) {
const bool subresult = bundle.check(
entry.second, sourcemeta::jsontoolkit::default_schema_walker,
resolver(options),
[&entry](const auto &pointer, const auto &name, const auto &message) {
std::cout << entry.first.string() << "\n";
std::cout << " ";
sourcemeta::jsontoolkit::stringify(pointer, std::cout);
std::cout << " " << message << " (" << name << ")\n";
});

if (!subresult) {
result = false;
}
}
}

Expand Down
8 changes: 6 additions & 2 deletions src/utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ auto parse_options(const std::span<const std::string> &arguments,
const std::set<std::string> &flags)
-> std::map<std::string, std::vector<std::string>> {
std::map<std::string, std::vector<std::string>> options;
std::set<std::string> effective_flags{flags};
effective_flags.insert("v");
effective_flags.insert("verbose");

options.insert({"", {}});
std::optional<std::string> current_option;
for (const auto &argument : arguments) {
Expand All @@ -72,7 +76,7 @@ auto parse_options(const std::span<const std::string> &arguments,
assert(!current_option.value().empty());
options.insert({current_option.value(), {}});
assert(options.contains(current_option.value()));
if (flags.contains(current_option.value())) {
if (effective_flags.contains(current_option.value())) {
current_option = std::nullopt;
}

Expand All @@ -83,7 +87,7 @@ auto parse_options(const std::span<const std::string> &arguments,
assert(current_option.value().size() == 1);
options.insert({current_option.value(), {}});
assert(options.contains(current_option.value()));
if (flags.contains(current_option.value())) {
if (effective_flags.contains(current_option.value())) {
current_option = std::nullopt;
}

Expand Down
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ add_jsonschema_test_unix(test_single_fail)
add_jsonschema_test_unix(test_single_unsupported)
add_jsonschema_test_unix(lint_pass)
add_jsonschema_test_unix(lint_fail)
add_jsonschema_test_unix(lint_fix)
28 changes: 28 additions & 0 deletions test/lint_fix.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/sh

set -o errexit
set -o nounset

TMP="$(mktemp -d)"
# shellcheck disable=SC2317
clean() { rm -rf "$TMP"; }
trap clean EXIT

cat << 'EOF' > "$TMP/schema.json"
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "string",
"enum": [ "foo" ]
}
EOF

"$1" lint "$TMP/schema.json" --fix

cat << 'EOF' > "$TMP/expected.json"
{
"$schema": "http://json-schema.org/draft-04/schema#",
"const": "foo"
}
EOF

diff "$TMP/schema.json" "$TMP/expected.json"

0 comments on commit ca947c0

Please sign in to comment.