App-Music-ChordPro/script/cfgboot.pl
#!/usr/bin/perl
# Bootstrapper for ChordPro config.
# Author : Johan Vromans
# Created On : Mon Jun 3 08:14:35 2024
# Last Modified By: Johan Vromans
# Last Modified On: Fri Sep 26 20:45:43 2025
# Update Count : 56
# Status : Unknown, Use with caution!
################ Common stuff ################
use v5.26;
use feature 'signatures';
no warnings 'experimental::signatures';
use FindBin;
use lib "$FindBin::Bin/../lib";
use lib "$FindBin::Bin/../CPAN";
use lib "$FindBin::Bin/../lib/ChordPro/lib";
# Package name.
my $my_package = 'ChordPro';
# Program name and version.
my ($my_name, $my_version) = qw( cfgboot 0.01 );
################ Command line parameters ################
use Getopt::Long 2.13;
# Command line options.
my $output;
my $verbose = 1; # verbose processing
my $debug = 0; # debugging
my $trace = 0; # trace (show process)
my $test = 0; # test mode.
# Process command line options.
app_options();
$trace |= ($debug || $test);
################ The Process ################
use JSON::Relaxed qw();
use JSON::XS qw();
use File::LoadLines;
use Encode qw(decode_utf8);
binmode STDOUT => ':utf8';
binmode STDERR => ':utf8';
my $parser = JSON::Relaxed::Parser->new
( booleans => [ $Types::Serialiser::false, $Types::Serialiser::true ] );
my $file = shift;
my $opts = { split => 0, fail => "soft" };
my $json = loadlines( $file, $opts );
die( "$file: $opts->{error}\n") if $opts->{error};
my $data = $parser->decode($json);
if ( $parser->is_error ) {
warn( "$file: JSON error: ", $parser->err_msg, "\n" );
next;
}
my $writer = JSON::XS->new->canonical->utf8(0)->pretty($test)->convert_blessed;
if ( $output && $output ne "-" ) {
open( my $fd, '>:utf8', $output )
or die("$output: $!\n");
select $fd;
}
print <<'EOD';
#! perl #### THIS IS A GENERATED FILE. DO NO MODIFY
package ChordPro::Config::Data;
use JSON::XS qw();
use JSON::Relaxed::Parser qw();
use feature qw(state);
EOD
print "# Config version.\nour \$VERSION = ", $data->{meta}->{_configversion}, ";\n\n";
print <<'EOD';
sub config {
state $pp = JSON::XS->new->utf8
->boolean_values( $JSON::Boolean::false, $JSON::Boolean::true );
$pp->decode( <<'EndOfJSON' );
EOD
print ( $writer->encode($data), "\n" );
print <<EOD;
EndOfJSON
}
1;
EOD
################ Subroutines ################
sub app_options() {
my $help = 0; # handled locally
my $ident = 0; # handled locally
# Process options, if any.
if ( !GetOptions(
'output=s' => \$output,
'ident' => \$ident,
'verbose+' => \$verbose,
'quiet' => sub { $verbose = 0 },
'trace' => \$trace,
'help|?' => \$help,
'debug' => \$debug
) or $help) {
app_usage(2);
}
app_ident() if $ident;
app_usage(2) unless @ARGV == 1;
}
sub app_ident() {
print STDERR ("This is $my_package [$my_name $my_version]\n");
print STDERR ("JSON::Relaxed version $JSON::Relaxed::VERSION\n");
}
sub app_usage( $exit ) {
app_ident();
print STDERR <<EndOfUsage;
Usage: $0 [options] config.json
--output=XXX optional output file
--ident shows identification
--help shows a brief help message and exits
--verbose provides more verbose information
--quiet runs as silently as possible
EndOfUsage
exit $exit if defined $exit && $exit != 0;
}