Initial commit
authorMarius Gavrilescu <marius@ieval.ro>
Sun, 28 Dec 2014 21:42:31 +0000 (23:42 +0200)
committerMarius Gavrilescu <marius@ieval.ro>
Sun, 28 Dec 2014 21:42:31 +0000 (23:42 +0200)
24 files changed:
Changes [new file with mode: 0644]
MANIFEST [new file with mode: 0644]
Makefile.PL [new file with mode: 0644]
README [new file with mode: 0644]
lib/Zeal.pm [new file with mode: 0644]
lib/Zeal/Docset.pm [new file with mode: 0644]
lib/Zeal/Document.pm [new file with mode: 0644]
t/Zeal.t [new file with mode: 0644]
t/ds/a.docset/Contents/Info.plist [new file with mode: 0644]
t/ds/a.docset/Contents/Resources/Documents/about.html [new file with mode: 0644]
t/ds/a.docset/Contents/Resources/Documents/array.html [new file with mode: 0644]
t/ds/a.docset/Contents/Resources/docSet.dsidx [new file with mode: 0644]
t/ds/b.docset/Contents/Info.plist [new file with mode: 0644]
t/ds/b.docset/Contents/Resources/Documents/building.html [new file with mode: 0644]
t/ds/b.docset/Contents/Resources/Documents/builtin.html [new file with mode: 0644]
t/ds/b.docset/Contents/Resources/docSet.dsidx [new file with mode: 0644]
t/ds/c.docset/Contents/Info.plist [new file with mode: 0644]
t/ds/c.docset/Contents/Resources/Documents/category.html [new file with mode: 0644]
t/ds/c.docset/Contents/Resources/Documents/class.html [new file with mode: 0644]
t/ds/c.docset/Contents/Resources/docSet.dsidx [new file with mode: 0644]
t/ds/dummy-file [new file with mode: 0644]
t/mkindex.pl [new file with mode: 0644]
t/perlcritic.t [new file with mode: 0644]
t/perlcriticrc [new file with mode: 0644]

diff --git a/Changes b/Changes
new file mode 100644 (file)
index 0000000..3ba71c6
--- /dev/null
+++ b/Changes
@@ -0,0 +1,4 @@
+Revision history for Perl extension Zeal.
+
+0.000_001 2014-12-28T23:42+02:00
+ - Initial release
diff --git a/MANIFEST b/MANIFEST
new file mode 100644 (file)
index 0000000..c930f3e
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,24 @@
+Changes
+lib/Zeal.pm
+lib/Zeal/Docset.pm
+lib/Zeal/Document.pm
+Makefile.PL
+MANIFEST
+README
+t/ds/a.docset/Contents/Info.plist
+t/ds/a.docset/Contents/Resources/docSet.dsidx
+t/ds/a.docset/Contents/Resources/Documents/about.html
+t/ds/a.docset/Contents/Resources/Documents/array.html
+t/ds/b.docset/Contents/Info.plist
+t/ds/b.docset/Contents/Resources/docSet.dsidx
+t/ds/b.docset/Contents/Resources/Documents/building.html
+t/ds/b.docset/Contents/Resources/Documents/builtin.html
+t/ds/c.docset/Contents/Info.plist
+t/ds/c.docset/Contents/Resources/docSet.dsidx
+t/ds/c.docset/Contents/Resources/Documents/category.html
+t/ds/c.docset/Contents/Resources/Documents/class.html
+t/ds/dummy-file
+t/mkindex.pl
+t/perlcritic.t
+t/perlcriticrc
+t/Zeal.t
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644 (file)
index 0000000..815a53c
--- /dev/null
@@ -0,0 +1,24 @@
+use 5.014000;
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+       NAME              => 'Zeal',
+       VERSION_FROM      => 'lib/Zeal.pm',
+       ABSTRACT_FROM     => 'lib/Zeal.pm',
+       AUTHOR            => 'Marius Gavrilescu <marius@ieval.ro>',
+       MIN_PERL_VERSION  => '5.14.0',
+       LICENSE           => 'perl',
+       SIGN              => 1,
+       PREREQ_PM         => {
+               qw/DBI                    0
+                  DBD::SQLite            0
+                  File::Slurp            0
+                  Mac::PropertyList::SAX 0/,
+       },
+       META_ADD         => {
+               dynamic_config => 0,
+               resources      => {
+                       repository   => 'http://git.ieval.ro/?p=zeal.git',
+               },
+       }
+);
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..7cdf798
--- /dev/null
+++ b/README
@@ -0,0 +1,36 @@
+Zeal version 0.000_001
+======================
+
+Dash is an offline API documentation browser. Zeal.pm is a module for
+reading and querying Dash documentation sets.
+
+For more information see the POD and the Dash website:
+http://kapeli.com/dash
+
+INSTALLATION
+
+To install this module type the following:
+
+   perl Makefile.PL
+   make
+   make test
+   make install
+
+DEPENDENCIES
+
+This module requires these other modules and libraries:
+
+* DBI
+* DBD::SQLite
+* File::Slurp
+* Mac::PropertyList::SAX
+
+COPYRIGHT AND LICENCE
+
+Copyright (C) 2014 by Marius Gavrilescu
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.20.1 or,
+at your option, any later version of Perl 5 you may have available.
+
+
diff --git a/lib/Zeal.pm b/lib/Zeal.pm
new file mode 100644 (file)
index 0000000..93d193c
--- /dev/null
@@ -0,0 +1,134 @@
+package Zeal;
+
+use 5.014000;
+use strict;
+use warnings;
+use re '/s';
+
+our $VERSION = '0.000_001';
+
+use File::Spec::Functions qw/catfile/;
+
+use Zeal::Docset;
+use Zeal::Document;
+
+sub new {
+       my ($class, $path) = @_;
+       $path //= $ENV{ZEAL_PATH};
+       my $self = bless {sets => {}}, $class;
+       if ($path) {
+               $self->add($_) for split /:/, $path;
+       }
+       $self
+}
+
+sub add {
+       my ($self, $path) = @_;
+       return unless -d $path;
+       if ($path =~ /[.]docset$/) {
+               my $ds = Zeal::Docset->new($path);
+               $self->{sets}{$ds->family} //= [];
+               push @{$self->{sets}{$ds->family}}, $ds;
+       } else {
+               my $dir;
+               opendir $dir, $path;
+               my @entries = grep { !/^[.]{1,2}$/ } readdir $dir;
+               closedir $dir;
+               $self->add(catfile $path, $_) for @entries
+       }
+}
+
+sub sets {
+       my ($self, $family) = @_;
+       return map { @$_ } values %{$self->{sets}} unless $family;
+       @{$self->{sets}{$family}}
+}
+
+sub query {
+       my ($self, $query, $family) = @_;
+       ($family, $query) = split /:/, $query, 2 if !$family && $query =~ /:/;
+       my @res = map { $_->query($query) } $self->sets($family);
+       wantarray ? @res : $res[0]
+}
+
+1;
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+Zeal - Read and query Dash/Zeal docsets
+
+=head1 SYNOPSIS
+
+  use Zeal;
+  my $zeal = Zeal->new("/home/mgv/docsets/:/home/mgv/something.docset");
+  # Add another docset
+  $zeal->add('/home/mgv/somethingelse.docset');
+  # Add a directory containing docsets
+  $zeal->add('/home/mgv/moredocsets/');
+  # Documentation for 'length' in all docsets
+  my $doc = $zeal->query('length');
+  # Documentation for all Test:: perl modules
+  my @docs = $zeal->query('Test::%', 'perl');
+  # Alternative syntax
+  @docs = $zeal->query('perl:Test::%);
+
+=head1 DESCRIPTION
+
+Dash is an offline API documentation browser. Zeal.pm is a module for
+reading and querying Dash documentation sets.
+
+This module queries multiple docsets. If you only have one docset, you
+should use the L<Zeal::Docset> module directly.
+
+Available methods:
+
+=over
+
+=item Zeal->B<new>([I<$path>])
+
+Create a new Zeal object. I<$path> is an optional colon delimited
+string for initializing the object. Each of its components is
+recursively scanned for docsets (and can also be a docset itself). If
+<$path> is not provided, the value of I<$ENV{ZEAL_PATH>> (if defined)
+is used instead.
+
+=item $zeal->B<add>(I<$path>)
+
+Recursively scan a path for docsets, adding them to this object.
+
+=item $zeal->B<sets>([I<$family>])
+
+Return a list of docsets (L<Zeal::Docset> objects) in the given
+family, or in all families if I<$family> is not provided.
+
+=item $zeal->B<query>(I<"$family:$query">)
+
+=item $zeal->B<query>(I<$query>, [I<$family>])
+
+Return a list of documents (L<Zeal::Document> objects) matching a
+query, optionally restricted to a family. In scalar context only one
+such document is returned. I<$query> is a SQL LIKE condition.
+
+=back
+
+=head1 SEE ALSO
+
+L<http://kapeli.com/dash>, L<http://zealdocs.org>
+
+=head1 AUTHOR
+
+Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2014 by Marius Gavrilescu
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.20.1 or,
+at your option, any later version of Perl 5 you may have available.
+
+
+=cut
diff --git a/lib/Zeal/Docset.pm b/lib/Zeal/Docset.pm
new file mode 100644 (file)
index 0000000..d280a50
--- /dev/null
@@ -0,0 +1,172 @@
+package Zeal::Docset;
+
+use 5.014000;
+use strict;
+use warnings;
+
+our $VERSION = '0.000_001';
+
+use parent qw/Class::Accessor::Fast/;
+__PACKAGE__->mk_ro_accessors(qw/path plist dbh name id family/);
+
+use Carp qw/carp/;
+use Cwd qw/realpath/;
+use File::Spec::Functions qw/catfile catdir rel2abs/;
+use HTTP::Tiny;
+
+use DBI;
+use File::Slurp qw/read_file/;
+use Mac::PropertyList::SAX qw/parse_plist_file/;
+
+use Zeal::Document;
+
+sub new {
+       my ($class, $path) = @_;
+       $path = realpath $path;
+       my $plpath  = catfile $path, 'Contents', 'Info.plist';
+       my $dbpath = catfile $path, 'Contents', 'Resources', 'docSet.dsidx';
+       my $plist = parse_plist_file($plpath)->as_perl;
+       carp 'This is not a Dash docset' unless $plist->{isDashDocset};
+
+       bless {
+               path   => $path,
+               plist  => $plist,
+               dbh    => DBI->connect("dbi:SQLite:dbname=$dbpath", '', ''),
+               name   => $plist->{CFBundleName},
+               id     => $plist->{CFBundleIdentifier},
+               family => $plist->{DocSetPlatformFamily},
+       }, $class
+}
+
+sub _blessdocs {
+       my ($self, $docsref) = @_;
+       map { Zeal::Document->new(+{%$_, docset => $self}) } @$docsref;
+}
+
+sub fetch {
+       my ($self, $path) = @_;
+       return HTTP::Tiny->new->get($path) if $path =~ /^http:/s;
+       my $docroot = catdir $self->path, 'Contents', 'Resources', 'Documents';
+       $path = rel2abs $path, $docroot;
+       scalar read_file $path
+}
+
+sub query {
+       my ($self, $cond) = @_;
+       my $query = 'SELECT * FROM searchIndex WHERE name LIKE ?';
+       my $res = $self->dbh->selectall_arrayref($query, {Slice => {}}, $cond);
+       my @results = $self->_blessdocs($res);
+       wantarray ? @results : $results[0]
+}
+
+sub get {
+       my ($self, $cond) = @_;
+       $self->query($cond)->fetch
+}
+
+sub list {
+       my ($self) = @_;
+       my $query = 'SELECT * FROM searchIndex';
+       my $res = $self->dbh->selectall_arrayref($query, {Slice => {}});
+       $self->_blessdocs($res)
+}
+
+1;
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+Zeal::Docset - Class representing a Dash/Zeal docset
+
+=head1 SYNOPSIS
+
+  use Zeal::Docset;
+
+=head1 DESCRIPTION
+
+Dash is an offline API documentation browser. Zeal::Docset is a class
+representing a Dash/Zeal docset.
+
+Available methods:
+
+=over
+
+=item Zeal::Docset->B<new>(I<$path>)
+
+Create a Zeal::Docset object from a given docset. I<$path> should be
+the path to a F<something.docset> directory.
+
+=item $ds->B<path>
+
+The path to the docset folder.
+
+=item $ds->B<plist>
+
+A hashref with the contents of Info.plist.
+
+=item $ds->B<dbh>
+
+A DBI database handle to the docSet.dsidx index.
+
+=item $ds->B<name>
+
+The name of this docset. Equivalent to
+C<< $ds->plist->{CFBundleName} >>
+
+=item $ds->B<id>
+
+The identifier of this docset. Equivalent to
+C<< $ds->plist->{CFBundleIdentifier} >>
+
+=item $ds->B<family>
+
+The family this docset belongs to. Dash uses this as the keyword for
+restricting searches to a particular family of docsets. Equivalent to
+C<< $ds->plist->{DocSetPlatformFamily} >>
+
+=item $ds->B<fetch>(I<$path>)
+
+Internal method for fetching the HTML content of a document. I<$path>
+is either the path to the document relative to C<< $ds->B<path> >> or
+a HTTP URL.
+
+=item $ds->B<query>(I<$cond>)
+
+In list context, return all documents (L<Zeal::Document> instances)
+matching I<$cond>. In scalar context, return one such document.
+I<$cond> is a SQL LIKE condition.
+
+=item $ds->B<get>(I<$cond>)
+
+The HTML content of one document that matches I<$cond>.
+I<$cond> is a SQL LIKE condition.
+
+This method is shorthand for C<< $ds->query(I<$cond>)->fetch >>.
+
+=item $ds->B<list>
+
+The list of all documents (L<Zeal::Document> instances) in this
+docset.
+
+=back
+
+=head1 SEE ALSO
+
+L<Zeal>, L<http://kapeli.com/dash>, L<http://zealdocs.org>
+
+=head1 AUTHOR
+
+Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2014 by Marius Gavrilescu
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.20.1 or,
+at your option, any later version of Perl 5 you may have available.
+
+
+=cut
diff --git a/lib/Zeal/Document.pm b/lib/Zeal/Document.pm
new file mode 100644 (file)
index 0000000..f80bad8
--- /dev/null
@@ -0,0 +1,82 @@
+package Zeal::Document;
+
+use 5.014000;
+use strict;
+use warnings;
+
+our $VERSION = '0.000_001';
+
+use parent qw/Class::Accessor::Fast/;
+__PACKAGE__->mk_accessors(qw/id name type path docset/);
+
+sub fetch {
+       my ($self) = @_;
+       $self->docset->fetch($self->path)
+}
+
+1;
+__END__
+
+=encoding utf-8
+
+=head1 NAME
+
+Zeal::Document - Class representing a Dash/Zeal document
+
+=head1 SYNOPSIS
+
+  use Zeal::Document;
+
+=head1 DESCRIPTION
+
+Dash is an offline API documentation browser. Zeal::Document is a class
+representing a Dash/Zeal document.
+
+Available methods:
+
+=over
+
+=item $doc->B<id>
+
+The ID of this document. Not typically interesting.
+
+=item $doc->B<name>
+
+The name of this document.
+
+=item $doc->B<type>
+
+The type of this document. The list of types is available on
+the Dash website: L<http://kapeli.com/docsets#supportedentrytypes>
+
+=item $doc->B<path>
+
+The path of this document, relative to
+F<docset_root/Contents/Resources/Documents/>. This can also be a HTTP
+URL.
+
+=item $doc->B<fetch>
+
+The HTML content of this document, retrieved from the file system or
+via HTTP::Tiny.
+
+=back
+
+=head1 SEE ALSO
+
+L<Zeal>, L<http://kapeli.com/dash>, L<http://zealdocs.org>
+
+=head1 AUTHOR
+
+Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2014 by Marius Gavrilescu
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself, either Perl version 5.20.1 or,
+at your option, any later version of Perl 5 you may have available.
+
+
+=cut
diff --git a/t/Zeal.t b/t/Zeal.t
new file mode 100644 (file)
index 0000000..5bbf7a5
--- /dev/null
+++ b/t/Zeal.t
@@ -0,0 +1,48 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+use Test::More tests => 18;
+BEGIN { use_ok('Zeal') };
+
+note 'Working with t/ds/b.docset';
+my $ds = Zeal::Docset->new('t/ds/b.docset');
+is $ds->name, 'B', 'docset name is B';
+is $ds->id, 'b', 'docset id is b';
+is $ds->family, 'consonants', 'docset family is consonants';
+
+my @results = $ds->query('buil%');
+is @results, 2, 'query(buil%) returns two results';
+my $doc = $ds->query('building');
+is $doc->name, 'building', 'document name is building';
+is $doc->type, 'Word', 'document type is Word';
+like $doc->fetch, qr/^Dummy/, 'document HTML starts with "Dummy"';
+
+@results = sort {$a->name cmp $b->name} $ds->list;
+is @results, 2, 'docset contains two documents';
+is $results[0]->name, 'building', 'first result is "building"';
+
+note 'Working with all docsets in t/ds/';
+my $zeal = Zeal->new('t/ds/');
+my @sets = $zeal->sets;
+is @sets, 3, '3 docsets loaded';
+@results = $zeal->query('buil%');
+is @results, 2, '2 documents begin with "buil"';
+@results = $zeal->query('%t%');
+is @results, 3, '3 documents contain letter t';
+@results = $zeal->query('consonants:%t%');
+is @results, 2, '2 documents from the consonants family contain letter t';
+@results = $zeal->query('%t%', 'vowels');
+is @results, 1, '1 document from the vowels family contain letter t';
+
+note 'Working with t/ds/a.docset via Zeal and ->add';
+$zeal = Zeal->new;
+$zeal->add('t/ds/a.docset');
+@sets = $zeal->sets;
+is @sets, 1, '1 docset loaded';
+like $sets[0]->get('abou%'), qr/word/, 'HTML for abou% contains the word "word"';
+
+note 'Working with t/ds/a.docset via ZEAL_PATH';
+$ENV{ZEAL_PATH} = 't/ds/a.docset';
+$zeal = Zeal->new;
+is $zeal->query('about')->name, 'about';
diff --git a/t/ds/a.docset/Contents/Info.plist b/t/ds/a.docset/Contents/Info.plist
new file mode 100644 (file)
index 0000000..2969f68
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plist version="1.0">
+<dict>
+<key>CFBundleIdentifier</key>
+<string>a</string>
+<key>CFBundleName</key>
+<string>A</string>
+<key>DocSetPlatformFamily</key>
+<string>vowels</string>
+<key>isDashDocset</key><true/></dict>
+</plist>
+
diff --git a/t/ds/a.docset/Contents/Resources/Documents/about.html b/t/ds/a.docset/Contents/Resources/Documents/about.html
new file mode 100644 (file)
index 0000000..19d19ee
--- /dev/null
@@ -0,0 +1 @@
+About is a word beginning with the letter a.
diff --git a/t/ds/a.docset/Contents/Resources/Documents/array.html b/t/ds/a.docset/Contents/Resources/Documents/array.html
new file mode 100644 (file)
index 0000000..309ed29
--- /dev/null
@@ -0,0 +1 @@
+Array is a word beginning with the letter a
diff --git a/t/ds/a.docset/Contents/Resources/docSet.dsidx b/t/ds/a.docset/Contents/Resources/docSet.dsidx
new file mode 100644 (file)
index 0000000..6f0cf0f
Binary files /dev/null and b/t/ds/a.docset/Contents/Resources/docSet.dsidx differ
diff --git a/t/ds/b.docset/Contents/Info.plist b/t/ds/b.docset/Contents/Info.plist
new file mode 100644 (file)
index 0000000..783d7e9
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plist version="1.0">
+<dict>
+<key>CFBundleIdentifier</key>
+<string>b</string>
+<key>CFBundleName</key>
+<string>B</string>
+<key>DocSetPlatformFamily</key>
+<string>consonants</string>
+<key>isDashDocset</key><true/></dict>
+</plist>
+
diff --git a/t/ds/b.docset/Contents/Resources/Documents/building.html b/t/ds/b.docset/Contents/Resources/Documents/building.html
new file mode 100644 (file)
index 0000000..e8df1a8
--- /dev/null
@@ -0,0 +1 @@
+Dummy text
diff --git a/t/ds/b.docset/Contents/Resources/Documents/builtin.html b/t/ds/b.docset/Contents/Resources/Documents/builtin.html
new file mode 100644 (file)
index 0000000..4e2372a
--- /dev/null
@@ -0,0 +1 @@
+Even more dummy text
diff --git a/t/ds/b.docset/Contents/Resources/docSet.dsidx b/t/ds/b.docset/Contents/Resources/docSet.dsidx
new file mode 100644 (file)
index 0000000..267ae67
Binary files /dev/null and b/t/ds/b.docset/Contents/Resources/docSet.dsidx differ
diff --git a/t/ds/c.docset/Contents/Info.plist b/t/ds/c.docset/Contents/Info.plist
new file mode 100644 (file)
index 0000000..301a145
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<plist version="1.0">
+<dict>
+<key>CFBundleIdentifier</key>
+<string>c</string>
+<key>CFBundleName</key>
+<string>C</string>
+<key>DocSetPlatformFamily</key>
+<string>consonants</string>
+<key>isDashDocset</key><true/></dict>
+</plist>
+
diff --git a/t/ds/c.docset/Contents/Resources/Documents/category.html b/t/ds/c.docset/Contents/Resources/Documents/category.html
new file mode 100644 (file)
index 0000000..12537fa
--- /dev/null
@@ -0,0 +1 @@
+Nothing of interest here
diff --git a/t/ds/c.docset/Contents/Resources/Documents/class.html b/t/ds/c.docset/Contents/Resources/Documents/class.html
new file mode 100644 (file)
index 0000000..b5279c2
--- /dev/null
@@ -0,0 +1 @@
+This document intentionally left blank
diff --git a/t/ds/c.docset/Contents/Resources/docSet.dsidx b/t/ds/c.docset/Contents/Resources/docSet.dsidx
new file mode 100644 (file)
index 0000000..71b8505
Binary files /dev/null and b/t/ds/c.docset/Contents/Resources/docSet.dsidx differ
diff --git a/t/ds/dummy-file b/t/ds/dummy-file
new file mode 100644 (file)
index 0000000..6ca8147
--- /dev/null
@@ -0,0 +1 @@
+This is a dummy file
diff --git a/t/mkindex.pl b/t/mkindex.pl
new file mode 100644 (file)
index 0000000..eb11917
--- /dev/null
@@ -0,0 +1,34 @@
+#!/usr/bin/perl
+use v5.14;
+use warnings;
+
+use Cwd qw/getcwd/;
+use File::Find;
+use File::Spec::Functions qw/abs2rel/;
+use Zeal::Docset;
+
+sub mkindex {
+       my ($root) = @_;
+       my $oldwd = getcwd;
+       unlink "$root/Contents/Resources/docSet.dsidx";
+
+       my $ds = Zeal::Docset->new($root);
+       $ds->dbh->do('CREATE TABLE searchIndex(id INTEGER PRIMARY KEY, name TEXT, type TEXT, path TEXT)');
+       $ds->dbh->do('CREATE UNIQUE INDEX anchor on searchIndex (name, type, path)');
+
+       chdir "$root/Contents/Resources/Documents";
+
+       find +{
+               no_chdir => 1,
+               wanted => sub {
+                       return unless -f;
+                       my ($name) = m/(\w+)\.html/;
+                       my $path = abs2rel $_;
+                       say STDERR "Adding document $name at $path";
+                       $ds->dbh->do('INSERT OR IGNORE INTO searchIndex(name, type, path) VALUES (?, \'Word\', ?)', {}, $name, $path);
+               }
+       }, '.';
+       chdir $oldwd;
+}
+
+mkindex $_ for <ds/*>
diff --git a/t/perlcritic.t b/t/perlcritic.t
new file mode 100644 (file)
index 0000000..51bad9d
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/perl
+use v5.14;
+use warnings;
+
+use Test::More;
+
+BEGIN { plan skip_all => '$ENV{RELEASE_TESTING} is false' unless $ENV{RELEASE_TESTING} }
+use Test::Perl::Critic -profile => 't/perlcriticrc';
+
+all_critic_ok
diff --git a/t/perlcriticrc b/t/perlcriticrc
new file mode 100644 (file)
index 0000000..8713835
--- /dev/null
@@ -0,0 +1,31 @@
+severity = 1
+
+[-BuiltinFunctions::ProhibitComplexMappings]
+[-CodeLayout::RequireTidyCode]
+[-ControlStructures::ProhibitPostfixControls]
+[-ControlStructures::ProhibitUnlessBlocks]
+[-Documentation::PodSpelling]
+[-Documentation::RequirePodLinksIncludeText]
+[-InputOutput::RequireBracedFileHandleWithPrint]
+[-References::ProhibitDoubleSigils]
+[-RegularExpressions::ProhibitEnumeratedClasses]
+[-RegularExpressions::RequireLineBoundaryMatching]
+[-Subroutines::RequireFinalReturn]
+[-ValuesAndExpressions::ProhibitConstantPragma]
+[-ValuesAndExpressions::ProhibitEmptyQuotes]
+[-ValuesAndExpressions::ProhibitMagicNumbers]
+[-ValuesAndExpressions::ProhibitNoisyQuotes]
+[-Variables::ProhibitLocalVars]
+[-Variables::ProhibitPackageVars]
+[-Variables::ProhibitPunctuationVars]
+
+[RegularExpressions::RequireExtendedFormatting]
+minimum_regex_length_to_complain_about = 20
+
+[Documentation::RequirePodSections]
+lib_sections = NAME | SYNOPSIS | DESCRIPTION | AUTHOR | COPYRIGHT AND LICENSE
+script_sections = NAME | SYNOPSIS | DESCRIPTION | AUTHOR | COPYRIGHT AND LICENSE
+
+[Subroutines::RequireArgUnpacking]
+short_subroutine_statements = 5
+allow_subscripts = 1
This page took 0.026788 seconds and 4 git commands to generate.