blob: 350a0cbb6b076b95795c7f3bcdc6d38eff57cf72 [file] [log] [blame]
#!/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 <subcommand> [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<what> has changed and I<how>.
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<port add>). This database can then be queried to check what
primary files have changed (C<port status>). The revision control software
should be helpful to determine the actual changes.
=head1 AUTHOR
Ronald Blaschke (ron@rblasch.org)