summaryrefslogtreecommitdiff
path: root/author
diff options
context:
space:
mode:
Diffstat (limited to 'author')
-rw-r--r--author/docGenerator.pl279
-rwxr-xr-xauthor/extract-inline-tests47
-rwxr-xr-xauthor/find-dupe-test-numbers23
3 files changed, 349 insertions, 0 deletions
diff --git a/author/docGenerator.pl b/author/docGenerator.pl
new file mode 100644
index 0000000..6e3eef0
--- /dev/null
+++ b/author/docGenerator.pl
@@ -0,0 +1,279 @@
+use blib;
+use Moose;
+use Class::Load 0.07 qw(load_class);
+
+my $text = generate_docs();
+print $text;
+
+sub generate_docs {
+ my $dir;
+ my $path = 'lib/Moose/Exception/';
+ my $pod_file;
+
+ opendir( $dir, $path) or die $!;
+
+ my $version = $ARGV[0];
+
+ my $number = 0;
+ my $text = '';
+
+ my $exceptions_to_msg_hashref = get_exceptions_to_messages();
+
+ while( my $file = readdir($dir) )
+ {
+ my %exceptions = %$exceptions_to_msg_hashref;
+
+ my ($exception, $description, $attributes_text, $superclasses, $consumed_roles, $exception_messages);
+ my (@attributes, @roles, @super_classes, @roles_names, @super_class_names);
+ if( !(-d 'lib/Moose/Exception/'.$file) )
+ {
+ $file =~ s/\.pm//i;
+
+ $exception = "Moose::Exception::".$file;
+
+ load_class( $exception );
+ my $metaclass = Class::MOP::class_of( $exception )
+ or die "No metaclass for $exception";
+
+ my @super_classes = sort { $a->name cmp $b->name } $metaclass->superclasses;
+ my @roles = sort { $a->name cmp $b->name } $metaclass->calculate_all_roles;
+ my @attributes = sort { $a->name cmp $b->name } $metaclass->get_all_attributes;
+
+ my $file_handle;
+
+ @roles_names = map {
+ my $name = $_->name;
+ if( $name =~ /\|/ ) {
+ undef;
+ } else {
+ $name;
+ }
+ } @roles;
+
+ $superclasses = place_commas_and_and( @super_classes );
+ $consumed_roles = place_commas_and_and( @roles_names );
+
+ foreach my $attribute ( @attributes )
+ {
+ my $name = $attribute->name;
+ my $traits;
+
+ if( $attribute->has_applied_traits ) {
+ my @traits_array = @{$attribute->applied_traits};
+
+ $traits = "has traits of ";
+ my $traits_str = place_commas_and_and( @traits_array );
+ $traits .= $traits_str;
+ }
+
+ my ( $tc, $type_constraint ) = ( $attribute->type_constraint->name, "isa " );
+ if( $tc =~ /::/ && !(defined $traits) ) {
+ $type_constraint .= "L<".$tc.">";
+ } else {
+ $type_constraint .= $tc;
+ }
+ my $read_or_write = ( $attribute->has_writer ? 'is read-write' : 'is read-only' );
+ my $required = ( $attribute->is_required ? 'is required' : 'is optional' );
+ my $predicate = ( $attribute->has_predicate ? 'has a predicate C<'.$attribute->predicate.'>': undef );
+
+ my $default;
+ if( $attribute->has_default ) {
+ if( $tc eq "Str" ) {
+ $default = 'has a default value "'.$attribute->default.'"';
+ }
+ else {
+ $default = 'has a default value '.$attribute->default;
+ }
+ }
+
+ my $handles_text;
+ if( $attribute->has_handles ) {
+ my %handles = %{$attribute->handles};
+ my @keys = sort keys( %handles );
+ my $first_element_inserted = 1;
+ foreach my $key ( @keys ) {
+ next
+ if( $key =~ /^_/ );
+ my $str_text = sprintf("\n %-25s=> %s", $key, $handles{$key});
+ if( $first_element_inserted == 1 ) {
+ $handles_text = "This attribute has handles as follows:";
+ $first_element_inserted = 0;
+ }
+ $handles_text .= $str_text;
+ }
+ }
+
+ $exception_messages = "=back\n\n=head4 Sample Error Message";
+
+ my $msg_or_msg_ref = $exceptions{$file};
+ if( ref $msg_or_msg_ref eq "ARRAY" ) {
+ $exception_messages .= "s:\n\n";
+ my @array = @$msg_or_msg_ref;
+ foreach( @array ) {
+ $exception_messages .= " $_";
+ }
+ } else {
+ $exception_messages .= ":\n\n";
+ if( $exceptions{$file} ) {
+ $exception_messages .= " ".$exceptions{$file};
+ }
+ }
+
+ $exception_messages .= "\n";
+
+ $attributes_text .= "=item B<< \$exception->$name >>\n\n";
+ if( $attribute->has_documentation ) {
+ $attributes_text .= $attribute->documentation."\n\n";
+ } else {
+ $attributes_text .= "This attribute $read_or_write, $type_constraint".
+ ( defined $predicate ? ", $predicate" : '' ).
+ ( defined $default ? ", $default" : '').
+ " and $required.".
+ ( defined $handles_text && ( $handles_text ne "This attribute has handles as follows:\n" ) ? "\n\n$handles_text" : '' )."\n\n";
+ }
+ }
+ my $role_verb = "consume".( $#roles == 0 ? 's role' : ' roles' );
+
+ $text .= "=head1 Moose::Exception::$file\n\nThis class is a subclass of $superclasses".
+( defined $consumed_roles ? " and $role_verb $consumed_roles.": '.' ).
+"\n\n=over 4\n\n=back\n\n=head2 ATTRIBUTES\n\n=over 4\n\n".
+( defined $attributes_text ? "$attributes_text\n\n" : '' );
+
+ $text = fix_line_length( $text );
+ $text .= $exception_messages;
+ $number++;
+ $text =~ s/\s+$//;
+ $text .= "\n\n";
+ }
+ }
+
+ return $text;
+}
+
+sub fix_line_length {
+ my $doc = shift;
+
+ my @tokens = split /\n/, $doc;
+
+ my $str;
+ foreach( @tokens ) {
+ my $string = shorten_to_eighty($_);
+ $str .= ($string."\n");
+ }
+ return $str."\n";
+}
+
+sub shorten_to_eighty {
+ my ($str) = @_;
+ if( length $str > 80 && length $str != 81 ) {
+ my $s1 = substr($str, 0, 80);
+ my $s2 = substr($str, 80);
+ my $substr1 = substr($s1, length($s1) - 1 );
+ my $substr2 = substr($s2, 0, 1);
+ $s1 =~ s/[\s]+$//g;
+ $s2 =~ s/[\s]+$//g;
+ if( ( $substr1 =~ /[\(\)\[\w:,'"<>\]\$]/ ) && ( $substr2 =~ /[\$'"\(\)\[<>\w:,\]]/ ) ) {
+ if( $s1 =~ s/\s([\(\)\[<:\w+>,"'\]\$]+)$// ) {
+ $s1 =~ s/[\s]+$//g;
+ $s2 = $1.$s2;
+ $s2 =~ s/[\s]+$//g;
+ my $s3 = shorten_to_eighty( $s2 );
+ $s3 =~ s/[\s]+$//g;
+ $s2 =~ s/[\s]+$//g;
+ if( $s2 ne $s3 ) {
+ return "$s1\n$s3";
+ } else {
+ return "$s1\n$s2";
+ }
+ }
+ }
+ return "$s1\n$s2";
+ }
+ else
+ {
+ return $str;
+ }
+}
+
+sub place_commas_and_and {
+ my @array = @_;
+ my ($str, $last_undef);
+
+ for( my $i = 0; $i <= $#array; $i++ ) {
+ my $element = $array[$i];
+ if( !(defined $element ) ) {
+ $last_undef = 1;
+ next;
+ }
+ if ( $i == 0 || ( $last_undef && $i == 1 ) ) {
+ $str .= "L<$element>";
+ } elsif( $i == $#array ) {
+ $str .= " and L<$element>";
+ } else {
+ $str .= ", L<$element>";
+ }
+ $last_undef = 0;
+ }
+ return $str;
+}
+
+sub get_exceptions_to_messages {
+ my $test_dir;
+ my $test_path = 't/exceptions/';
+
+ my %hash;
+
+ opendir( $test_dir, $test_path ) or die $!;
+
+ my $file;
+ while( $file = readdir( $test_dir ) ) {
+ my $file_handle;
+
+ open( $file_handle, "t/exceptions/$file" ) or die $!;
+ my ($message, $exception);
+ while( <$file_handle> ) {
+ if( /like\($/ ) {
+ my $exception_var = <$file_handle>;
+ if( $exception_var =~ /\$exception,$/ ) {
+ $message = <$file_handle>;
+ if( $message =~ q/\$\w+/ || ( $message =~ /\\\(\w+\\\)/) ) {
+ my $garbage = <$file_handle>;
+ $message = <$file_handle>;
+ $message =~ s/^\s+#//;
+ }
+ $message =~ s!^\s*qr(/|\!)(\^)?(\\Q)?!!;
+ $message =~ s!(/|\!),$!!;
+ }
+ } elsif( /isa_ok\($/ ) {
+ my $exception_var = <$file_handle>;
+ if( $exception_var =~ /\$exception(->error)?,$/ ) {
+ $exception = <$file_handle>;
+ if( $exception =~ /Moose::Exception::(\w+)/ ) {
+ $exception = $1;
+ }
+ }
+ }
+
+ if( ( defined $exception ) && ( defined $message ) ) {
+ if( exists $hash{$exception} &&
+ ( ref $hash{$exception} eq "ARRAY" ) ) {
+ my @array = @{$hash{$exception}};
+ push @array, $message;
+ $hash{$exception} = \@array;
+ } elsif( exists $hash{$exception} &&
+ ( $hash{$exception} ne $message ) ) {
+ my $msg = $hash{$exception};
+ my $array_ref = [ $msg, $message ];
+ $hash{$exception} = $array_ref;
+ } else {
+ $hash{$exception} = $message;
+ }
+ $exception = undef;
+ $message = undef;
+ }
+ }
+ close $file_handle;
+ }
+
+ return \%hash;
+}
diff --git a/author/extract-inline-tests b/author/extract-inline-tests
new file mode 100755
index 0000000..aa90787
--- /dev/null
+++ b/author/extract-inline-tests
@@ -0,0 +1,47 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use File::Find::Rule;
+use Getopt::Long;
+use Test::Inline;
+
+use lib 'inc';
+use MyInline;
+
+my $quiet;
+GetOptions( 'quiet' => \$quiet );
+
+my $inline = Test::Inline->new(
+ verbose => !$quiet,
+ ExtractHandler => 'My::Extract',
+ ContentHandler => 'My::Content',
+ OutputHandler => 'My::Output',
+);
+
+for my $pod (
+ File::Find::Rule->file->name(qr/\.pod$/)->in('lib/Moose/Cookbook') ) {
+ $inline->add($pod);
+}
+
+$inline->save;
+
+{
+
+ package My::Output;
+
+ use Path::Tiny;
+
+ sub write {
+ my $class = shift;
+ my $name = shift;
+ my $content = shift;
+
+ $name =~ s/^moose_cookbook_//;
+
+ path( "t/recipes/$name" )->spew( $content );
+
+ return 1;
+ }
+}
diff --git a/author/find-dupe-test-numbers b/author/find-dupe-test-numbers
new file mode 100755
index 0000000..ce975a0
--- /dev/null
+++ b/author/find-dupe-test-numbers
@@ -0,0 +1,23 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use File::Basename qw( basename );
+
+for my $subdir ( glob 't/*' ) {
+ my %files;
+
+ for my $file ( map { basename($_) } glob "$subdir/*.t" ) {
+ my ($number) = $file =~ /^(\d+)/;
+ next unless defined $number;
+
+ push @{ $files{$number} }, $file;
+ }
+
+ for my $number ( grep { @{ $files{$_} } > 1 } keys %files ) {
+ print $subdir, "\n";
+ print ' - ', $_, "\n" for @{ $files{$number} };
+ print "\n";
+ }
+}