#! /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