#! /usr/bin/perl
# PODNAME: benchmarkanything-schema
# ABSTRACT: BenchmarkAnything schema cmdline tool
use 5.008;
use strict;
use warnings;
use App::Rad;
######################################################################
#
# App::Rad interface
#
######################################################################
App::Rad->run();
sub setup
{
my $c = shift;
$c->unregister_command("help");
$c->register_commands("help", "validate");
}
sub help
{
my ($c) = @_;
return qq{benchmarkanything-schema [-i|--intype] <FILENAME>
-i
--intype - input format
[json(default), yaml, dumper, xml, tap, ini]
};
}
sub validate :Help(validate if data conforms to BenchmarkAnything json schema)
{
my ($c) = @_;
_getopt($c);
my $file = $c->argv->[0] || '-';
exit (_validate($c, _read_in( $c, $file )) ? 0 : 1);
}
sub default { validate(@_) }
######################################################################
#
# Implementation
#
######################################################################
sub _read_in
{
my ($c, $file) = @_;
my $opt = $c->options;
my $intype = $opt->{intype} || 'json';
my $data;
my $filecontent;
{
local $/;
if ($file eq '-') {
$filecontent = <STDIN>;
}
else
{
open (my $FH, "<", $file) or die "benchmarkanything-schema: cannot open input file $file.\n";
$filecontent = <$FH>;
close $FH;
}
}
if (not defined $filecontent or $filecontent !~ /[^\s\t\r\n]/ms) {
die "benchmarkanything-schema: no meaningful input to read.\n";
}
if ($intype eq "yaml") {
require YAML::Any;
$data = [YAML::Any::Load($filecontent)];
}
elsif ($intype eq "json") {
require JSON;
$data = JSON::decode_json($filecontent);
}
elsif ($intype eq "xml")
{
require XML::Simple;
my $xs = new XML::Simple;
$data = $xs->XMLin($filecontent, KeepRoot => 1);
}
elsif ($intype eq "ini") {
require Config::INI::Serializer;
my $ini = Config::INI::Serializer->new;
$data = $ini->deserialize($filecontent);
}
elsif ($intype eq "cfggeneral") {
require Config::General;
my %data = Config::General->new(-String => $filecontent,
-InterPolateVars => 1,
)->getall;
$data = \%data;
}
elsif ($intype eq "dumper") {
eval '$data = my '.$filecontent;
}
elsif ($intype eq "tap") {
require TAP::DOM;
require TAP::Parser;
$data = new TAP::DOM( tap => $filecontent, $TAP::Parser::VERSION > 3.22 ? (version => 13) : () );
}
else
{
die "benchmarkanything-schema: unrecognized input format: $intype.\n";
}
return $data;
}
sub _validate
{
my ($c, $data) = @_;
if (not $data) {
die "benchmarkanything-schema: no input data to validate.\n";
}
require BenchmarkAnything::Schema;
return BenchmarkAnything::Schema::valid_json_schema($data);
}
sub _getopt
{
my ($c) = @_;
$c->getopt( "intype|i=s",
)
or help() and return undef;
}
__END__
=pod
=encoding UTF-8
=head1 NAME
benchmarkanything-schema - BenchmarkAnything schema cmdline tool
=head1 SYNOPSIS
Validate data against BenchmarkAnything schema, see http://benchmarkanything.org/
Default data format (in and out) is JSON, other formats can be
specified.
$ benchmarkanything-schema validate data.json
Use it as filter:
$ benchmarkanything-schema validate < data.json
$ cat data.json | benchmarkanything-schema validate
Input is YAML:
$ benchmarkanything-schema validate -i yaml data.yaml
=head2 Input formats
The following B<input formats> are allowed, with their according
modules used to convert the input into a data structure:
yaml - YAML::Any (default)
json - JSON
xml - XML::Simple
ini - Config::INI::Serializer
dumper - Data::Dumper (including the leading $VAR1 variable assignment)
tap - TAP::DOM
=head1 SEE ALSO
For more information about the BenchmarkAnything schema, see
L<http://www.benchmarkanything.org/|http://www.benchmarkanything.org/>.
=head1 AUTHOR
Steffen Schwigon <ss5@renormalist.net>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2016 by Steffen Schwigon.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut