#!/usr/bin/perl use strict; use warnings; use version; use Carp; use Digest; use File::Spec; use File::Spec::Unix; use YAML::Tiny; my $version = qv('0.0.1'); sub say { print @_, "\n"; } my $basedir = '../..'; my $commands = { 'help' => \&help, 'add' => \&add, 'status' => \&status, }; my $help = {}; sub filetype { my ($path) = @_; if ($path =~ /\.(java|g)$/xms) { return 'text/plain'; } else { return 'application/octet-stream'; } } sub sha1sum { my ($filename) = @_; open my $in, '<', $filename or croak "Can't open $filename: $!"; if (filetype($filename) =~ /^text\//xms) { # keep standard line feed conversion } else { if (!binmode $in) { croak "Can't binmode $filename: $!"; } } my $sha1 = Digest->new('SHA-1'); $sha1->addfile($in); my $digest = $sha1->hexdigest; close $in or warn "Can't close $filename: $!"; return $digest; } my $inc_paths = [ $basedir, "$basedir/runtime/Java/src", ]; sub resolve_file { my ($filename) = @_; my $resolved_file; if (-e $filename) { $resolved_file = $filename; } else { my @canidates = grep { -e $_ } map { File::Spec->catfile($_, $filename) } @$inc_paths; $resolved_file = $canidates[0]; } if (defined $resolved_file) { $resolved_file = File::Spec::Unix->canonpath($resolved_file); } return $resolved_file; } $help->{help} = << 'EOH'; help: Describe the usage of this program or its subcommands. Usage: help [SUBCOMMAND...] EOH sub help { my ($cmd) = @_; if (defined $cmd) { print $help->{$cmd}; } else { say << 'EOH'; Usage: port [options] [args] EOH say "Available subcommands:"; foreach my $cmd (keys %$help) { say " $cmd"; } } } $help->{add} = << 'EOH'; add: Adds the file to the list of ported files. Usage: add PATH... EOH sub add { my ($filename) = @_; my $port = YAML::Tiny->read('port.yml'); my $status = $port->[0]->{status}; if (!defined $status) { $status = $port->[0]->{status} = {}; } my $path = resolve_file($filename); if (!defined $path) { croak "File not found: $filename"; } my $digest = sha1sum($path); $status->{$filename} = { 'sha1' => $digest, }; $port->write('port.yml'); } $help->{status} = << 'EOH'; status: Print the status of the ported files. usage: status [PATH...] EOH sub status { my $port = YAML::Tiny->read('port.yml'); my $status = $port->[0]->{status}; while (my ($filename, $fstatus) = each (%$status)) { my $path = resolve_file($filename); my $digest = sha1sum($path); if ($digest ne $fstatus->{sha1}) { say "M $filename"; } } } my ($cmd, @args) = @ARGV; if (defined $cmd) { my $cmd_f = $commands->{$cmd}; if (defined $cmd_f) { $cmd_f->(@args); } else { say "Unknown command: '$cmd'"; say "Type 'port help' for usage."; exit 1; } } else { say "Type 'port help' for usage."; exit 1; } __END__ =head1 NAME port - ANTLR Perl 5 port status =head1 VERSION This documentation refers to port version 0.0.1 =head1 USAGE port help port status =head1 DESCRIPTION The primary language target for ANTLR is Java. The Perl 5 port only follows this primary target language. This brings up the problem to follow the changes made to the primary target, by knowing I has changed and I. This tool keeps a database of file paths and content checksum. Once the port of a file (Java class, grammar, ...) is completed it is added to the database (C). This database can then be queried to check what primary files have changed (C). The revision control software should be helpful to determine the actual changes. =head1 AUTHOR Ronald Blaschke (ron@rblasch.org)