#!/usr/bin/perl # Squashes together the parts of the app into the single script. # (Adapted from the script that squashes App::Ack - see https://github.com/beyondgrep/ack3) use warnings; use strict; my $code; for my $arg (@ARGV) { my $filename = $arg; if ($arg =~ /::/) { my $key = "$arg.pm"; $key =~ s{::}{/}g; $filename = $INC{$key} or die "Can't find the file for $arg"; } warn "Reading $filename\n"; open my $fh, '<', $filename or die "Can't open $filename: $!"; my $in_pod = 0; my $in_section = ''; my $ignore_lines = 0; my $empty_lines = 0; while (<$fh>) { if (/#.*:squash-ignore-start:$/) { $in_section = 'ignore'; $ignore_lines = 1; } elsif (/#.*:squash-ignore-end:$/) { $in_section = ''; $ignore_lines = 1; } if ($ignore_lines > 0) { $ignore_lines--; next; } if ($in_section eq 'ignore') { $empty_lines = 0 unless /^$/; $code .= $_; next; } # Remove repeated newlines between paragraphs # (Provided of course we're not in an 'ignore' section) if (/^$/) { ++$empty_lines; if ($empty_lines > 1) { next; } } else { $empty_lines = 0; } if (/#.*:squash-remove-start:$/) { $in_section = 'remove'; next; } elsif (/#.*:squash-remove-end:$/) { $in_section = ''; next; } next if $in_section eq 'remove'; next if /#.*:squash-remove-line:$/; next if /^\s*1;$/; if ($filename =~ /\.pm$/) { # See if we're in module POD blocks if (/^=(\w+)/) { $in_pod = ($1 ne 'cut'); next; } elsif ($in_pod) { next; } next if /^# vi:/; } # Remove Perl::Critic comments. # I'd like to remove all comments, but this is a start s{\s*##.+critic.*}{}; $code .= $_; } # Warn if there were unterminated :squash-*: sections warn "$filename: Unterminated :squash-$in_section-start: section" if $in_section; close $fh; } print $code; exit 0;