1 #!/usr/bin/perl 2 3 use strict; 4 use warnings; 5 6 use version; 7 use Carp; 8 use Digest; 9 use File::Spec; 10 use File::Spec::Unix; 11 use YAML::Tiny; 12 13 my $version = qv('0.0.1'); 14 15 sub say { 16 print @_, "\n"; 17 } 18 19 my $basedir = '../..'; 20 21 my $commands = { 22 'help' => \&help, 23 'add' => \&add, 24 'status' => \&status, 25 }; 26 27 my $help = {}; 28 29 sub filetype { 30 my ($path) = @_; 31 32 if ($path =~ /\.(java|g)$/xms) { 33 return 'text/plain'; 34 } 35 else { 36 return 'application/octet-stream'; 37 } 38 } 39 40 sub sha1sum { 41 my ($filename) = @_; 42 43 open my $in, '<', $filename or croak "Can't open $filename: $!"; 44 if (filetype($filename) =~ /^text\//xms) { 45 # keep standard line feed conversion 46 } else { 47 if (!binmode $in) { 48 croak "Can't binmode $filename: $!"; 49 } 50 } 51 my $sha1 = Digest->new('SHA-1'); 52 $sha1->addfile($in); 53 my $digest = $sha1->hexdigest; 54 close $in or warn "Can't close $filename: $!"; 55 return $digest; 56 } 57 58 my $inc_paths = [ 59 $basedir, 60 "$basedir/runtime/Java/src", 61 ]; 62 63 sub resolve_file { 64 my ($filename) = @_; 65 66 my $resolved_file; 67 if (-e $filename) { 68 $resolved_file = $filename; 69 } 70 else { 71 my @canidates 72 = grep { -e $_ } 73 map { File::Spec->catfile($_, $filename) } 74 @$inc_paths; 75 $resolved_file = $canidates[0]; 76 } 77 78 if (defined $resolved_file) { 79 $resolved_file = File::Spec::Unix->canonpath($resolved_file); 80 } 81 82 return $resolved_file; 83 } 84 85 $help->{help} = << 'EOH'; 86 help: Describe the usage of this program or its subcommands. 87 Usage: help [SUBCOMMAND...] 88 EOH 89 90 sub help { 91 my ($cmd) = @_; 92 93 if (defined $cmd) { 94 print $help->{$cmd}; 95 } 96 else { 97 say << 'EOH'; 98 Usage: port <subcommand> [options] [args] 99 EOH 100 say "Available subcommands:"; 101 foreach my $cmd (keys %$help) { 102 say " $cmd"; 103 } 104 } 105 106 } 107 108 $help->{add} = << 'EOH'; 109 add: Adds the file to the list of ported files. 110 Usage: add PATH... 111 EOH 112 113 sub add { 114 my ($filename) = @_; 115 116 my $port = YAML::Tiny->read('port.yml'); 117 my $status = $port->[0]->{status}; 118 if (!defined $status) { 119 $status = $port->[0]->{status} = {}; 120 } 121 122 my $path = resolve_file($filename); 123 if (!defined $path) { 124 croak "File not found: $filename"; 125 } 126 my $digest = sha1sum($path); 127 $status->{$filename} = { 128 'sha1' => $digest, 129 }; 130 $port->write('port.yml'); 131 } 132 133 $help->{status} = << 'EOH'; 134 status: Print the status of the ported files. 135 usage: status [PATH...] 136 EOH 137 138 sub status { 139 my $port = YAML::Tiny->read('port.yml'); 140 141 my $status = $port->[0]->{status}; 142 143 while (my ($filename, $fstatus) = each (%$status)) { 144 my $path = resolve_file($filename); 145 146 my $digest = sha1sum($path); 147 148 if ($digest ne $fstatus->{sha1}) { 149 say "M $filename"; 150 } 151 } 152 } 153 154 my ($cmd, @args) = @ARGV; 155 156 if (defined $cmd) { 157 my $cmd_f = $commands->{$cmd}; 158 if (defined $cmd_f) { 159 $cmd_f->(@args); 160 } 161 else { 162 say "Unknown command: '$cmd'"; 163 say "Type 'port help' for usage."; 164 exit 1; 165 } 166 } 167 else { 168 say "Type 'port help' for usage."; 169 exit 1; 170 } 171 172 __END__ 173 174 =head1 NAME 175 176 port - ANTLR Perl 5 port status 177 178 =head1 VERSION 179 180 This documentation refers to port version 0.0.1 181 182 =head1 USAGE 183 184 port help 185 186 port status 187 188 =head1 DESCRIPTION 189 190 The primary language target for ANTLR is Java. The Perl 5 port only follows 191 this primary target language. This brings up the problem to follow the 192 changes made to the primary target, by knowing I<what> has changed and I<how>. 193 194 This tool keeps a database of file paths and content checksum. Once the port 195 of a file (Java class, grammar, ...) is completed it is added to the 196 database (C<port add>). This database can then be queried to check what 197 primary files have changed (C<port status>). The revision control software 198 should be helpful to determine the actual changes. 199 200 =head1 AUTHOR 201 202 Ronald Blaschke (ron@rblasch.org) 203 204