Add several command-line options to invoke the schema validator

This commit is contained in:
Celtic Minstrel 2018-11-03 15:42:02 -04:00
parent 52c4dc0e3d
commit 8ef0c1734d
5 changed files with 85 additions and 7 deletions

View File

@ -369,6 +369,10 @@ makes the
.B package
package available to lua scripts, so that they can load arbitrary packages. Do not do this with untrusted scripts! This action gives lua the same permissions as the wesnoth executable.
.TP
.BI --use-schema \ path
sets the WML schema for use with
.BR --validate .
.TP
.BI --userconfig-dir \ name
sets the user configuration directory to
.I name
@ -400,6 +404,18 @@ uses
.I username
when connecting to a server, ignoring other preferences.
.TP
.BI --validate \ path
validates a file against the WML schema.
.TP
.BI --validate-addon \ addon_id
validates the WML of the given addon as you play.
.TP
.B --validate-core
validates the core WML as you play.
.TP
.B --validate-schema \ path
validates a file as a WML schema.
.TP
.B --validcache
assumes that the cache is valid. (dangerous)
.TP

View File

@ -141,6 +141,7 @@ commandline_options::commandline_options (const std::vector<std::string>& args)
args_(args.begin() + 1 , args.end()),
args0_(*args.begin()),
all_(),
validate_core(false),
visible_(),
hidden_()
{
@ -267,7 +268,11 @@ commandline_options::commandline_options (const std::vector<std::string>& args)
("log-strict", po::value<std::string>(), "sets the strict level of the logger. any messages sent to log domains of this level or more severe will cause the unit test to fail regardless of the victory result.")
("noreplaycheck", "don't try to validate replay of unit test.")
("mp-test", "load the test mp scenarios.")
("validate", "validate the core WML against the schema")
("use-schema,S", "specify a schema to validate WML against (defaults to the core schema)")
("validate,V", "validate a specified WML file against a schema")
("validate-addon", "validate the specified addon's WML against the schema")
("validate-core", "validate the core WML against the schema")
("validate-schema", "validate a specified WML schema")
;
po::options_description preprocessor_opts("Preprocessor mode options");
@ -484,7 +489,15 @@ commandline_options::commandline_options (const std::vector<std::string>& args)
if (vm.count("validcache"))
validcache = true;
if (vm.count("validate"))
validate_wml = true;
validate_wml = vm["validate"].as<std::string>();
if (vm.count("validate-core"))
validate_core = true;
if (vm.count("validate-addon"))
validate_addon = vm["validate-addon"].as<std::string>();
if (vm.count("validate-schema"))
validate_schema = vm["validate-schema"].as<std::string>();
if (vm.count("use-schema"))
validate_with = vm["use-schema"].as<std::string>();;
if (vm.count("version"))
version = true;
if (vm.count("windowed"))

View File

@ -207,8 +207,16 @@ public:
boost::optional<std::string> userdata_dir;
/// True if --validcache was given on the command line. Makes Wesnoth assume the cache is valid.
bool validcache;
/// True if --validate was given on the command line. Makes Wesnoth validate the core WML.
bool validate_wml;
/// True if --validate-core was given on the command line. Makes Wesnoth validate the core WML.
bool validate_core;
/// Non-empty if --validate-addon was given on the command line. Makes Wesnoth validate an addon's WML.
boost::optional<std::string> validate_addon;
/// Non-empty if --validate-schema was given on the command line. Makes Wesnoth validate a WML schema.
boost::optional<std::string> validate_schema;
/// Non-empty if --validate was given on the command line. Makes Wesnoth validate a WML file against a schema.
boost::optional<std::string> validate_wml;
/// Non-empty if --use-schema was given on the command line. Specifies the schema for use with --validate.
boost::optional<std::string> validate_with;
/// True if --version was given on the command line. Prints version and exits.
bool version;
/// True if --report was given on the command line. Prints a bug report-style info dump and exits.

View File

@ -262,7 +262,7 @@ void game_config_manager::load_game_config(FORCE_RELOAD_CONFIG force_reload,
// Load the selected core
std::unique_ptr<schema_validation::schema_validator> validator;
if(cmdline_opts_.validate_wml) {
if(cmdline_opts_.validate_core) {
validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location("schema/game_config.cfg")));
validator->set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway
}
@ -432,9 +432,14 @@ void game_config_manager::load_addons_cfg()
version_info addon_version(metadata["version"]);
try {
std::unique_ptr<schema_validation::schema_validator> validator;
if( cmdline_opts_.validate_addon && *cmdline_opts_.validate_addon == addon_id) {
validator.reset(new schema_validation::schema_validator(filesystem::get_wml_location("schema/game_config.cfg")));
validator->set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway
}
// Load this addon from the cache to a config.
config umc_cfg;
cache_.get_config(main_cfg, umc_cfg);
cache_.get_config(main_cfg, umc_cfg, validator.get());
static const std::set<std::string> tags_with_addon_id {
"era",

View File

@ -46,7 +46,7 @@
#include "serialization/parser.hpp" // for read
#include "serialization/preprocessor.hpp" // for preproc_define, etc
#include "serialization/unicode_cast.hpp"
#include "serialization/validator.hpp" // for strict_validation_enabled
#include "serialization/schema_validator.hpp" // for strict_validation_enabled and schema_validator
#include "sound.hpp" // for commit_music_changes, etc
#include "statistics.hpp" // for fresh_stats
#include "utils/functional.hpp"
@ -333,6 +333,24 @@ static void handle_preprocess_command(const commandline_options& cmdline_opts)
std::cerr << "preprocessing finished. Took " << SDL_GetTicks() - startTime << " ticks.\n";
}
static int handle_validate_command(const std::string& file, abstract_validator& validator, const std::vector<std::string>& defines) {
preproc_map defines_map;
for(const std::string& define : defines) {
if(define.empty()) {
std::cerr << "empty define supplied\n";
continue;
}
LOG_PREPROC << "adding define: " << define << '\n';
defines_map.emplace(define, preproc_define(define));
}
filesystem::scoped_istream stream = preprocess_file(file, &defines_map);
config result;
read(result, *stream, &validator);
// TODO: Return 1 if any errors found.
return 0;
}
/** Process commandline-arguments */
static int process_command_args(const commandline_options& cmdline_opts)
{
@ -478,6 +496,12 @@ static int process_command_args(const commandline_options& cmdline_opts)
std::cout << "\n========= BUILD INFORMATION =========\n\n" << game_config::full_build_report();
return 0;
}
if(cmdline_opts.validate_schema) {
schema_validation::schema_self_validator validator;
validator.set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway
handle_validate_command(*cmdline_opts.validate_schema, validator, {});
}
// Options changing their behavior dependent on some others should be checked below.
@ -485,6 +509,18 @@ static int process_command_args(const commandline_options& cmdline_opts)
handle_preprocess_command(cmdline_opts);
return 0;
}
if(cmdline_opts.validate_wml) {
std::string schema_path;
if(cmdline_opts.validate_with) {
schema_path = *cmdline_opts.validate_with;
} else {
schema_path = filesystem::get_wml_location("schema/game_config.cfg");
}
schema_validation::schema_validator validator(schema_path);
validator.set_create_exceptions(false); // Don't crash if there's an error, just go ahead anyway
handle_validate_command(*cmdline_opts.validate_wml, validator, boost::get_optional_value_or(cmdline_opts.preprocess_defines, {}));
}
// Not the most intuitive solution, but I wanted to leave current semantics for now
return -1;