Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add .cache-ignore file support #12

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions .travis.yml
Expand Up @@ -4,8 +4,8 @@ services:
- docker

install:
- docker pull jjmerelo/test-perl6
- docker pull jjmerelo/raku-test
- docker images

script:
- docker run -t -v $TRAVIS_BUILD_DIR:/test jjmerelo/test-perl6
- docker run -t -v $TRAVIS_BUILD_DIR:/test jjmerelo/raku-test
6 changes: 6 additions & 0 deletions README.md
Expand Up @@ -118,6 +118,12 @@ $cache.freeze;
- Old
A source name that is in the cache but no longer reflects an existing source.

- **.cache-ignore**: You can create a file named `.cache-ignore` containing Perl 6 regular expressions. Pod6 filenames in `$source` matching at least one of the provided regexes, will be ignored.

Example:
~~~
*podignored*.pod6
~~~
## LICENSE

You can use and distribute this module under the terms of the The Artistic License 2.0. See the LICENSE file included in this distribution for complete details.
Expand Down
38 changes: 34 additions & 4 deletions lib/Pod/To/Cached.pm6
Expand Up @@ -6,6 +6,7 @@ use CompUnit::PrecompilationRepository::Document;

constant @extensions = <pod pod6 p6 pm pm6>;

constant IGNORE_FILE = ".cache-ignore";
constant INDEX = 'file-index.json';
enum Status is export <Current Valid Failed New Old>; # New is internally used, but not stored in DB

Expand Down Expand Up @@ -65,7 +66,7 @@ submethod TWEAK {
mkdir IO::Path.new( $!path );
self.save-index;
}
my $precomp-store = CompUnit::PrecompilationStore::File.new(prefix => $!path.IO );
my $precomp-store = CompUnit::PrecompilationStore::File.new(prefix => ($!path~"/.precomp").IO );
$!precomp = CompUnit::PrecompilationRepository::Document.new(store => $precomp-store);
# get handles for all Valid / Current files

Expand Down Expand Up @@ -158,7 +159,13 @@ method compile( $source-name, $key, $path, $status is copy ) {
}
$!lock.protect( {
$!precomp.precompile($path.IO, $key, :force );
$handle = $!precomp.load($key)[0];
$handle = $!precomp.try-load(
CompUnit::PrecompilationDependency::File.new(
:src($path),
:id(CompUnit::PrecompilationId.new-from-string($path)),
:spec(CompUnit::DependencySpecification.new(:short-name($path))),
),
);
})
}
with $handle {
Expand Down Expand Up @@ -194,11 +201,23 @@ method save-index {
}
} ).hash );
%h<source> = $!source unless $!frozen;
("$!path/"~INDEX).IO.spurt: to-json(%h);
"$!path".IO.add(INDEX).IO.spurt: to-json(%h);
}

method filter-pods(:@pods) {
if (IGNORE_FILE.IO.e) {
my @regexs = IGNORE_FILE.IO.slurp.split("\n", :skip-empty);
my @filtered = @pods;
for @regexs -> $regex { @filtered .= grep({not /<{$regex}>/}); }
return @filtered;
}
return @pods;
}

method get-pods {
die 'No pods accessible for a frozen cache' if $!frozen; # should never get here
die X::Documentable::TitleNotFound.new(:reason("No pods accessible for a frozen cache"))
if $!frozen; # should never get here

return @!pods if @!pods;
#| Recursively finds all pod files
@!pods = my sub recurse ($dir) {
Expand All @@ -207,6 +226,8 @@ method get-pods {
take slip sort recurse $_ if .d;
}
}($!source); # is the first definition of $dir

@!pods = self.filter-pods(:@!pods);
}

method pod( Str $source-name ) is export {
Expand Down Expand Up @@ -270,6 +291,15 @@ sub rm-cache( $path ) is export {
}
}

# specific exceptions

class X::Pod::To::Cached::FrozenCache is Exception {
has $.reason;
method message() {
"[FROZEN CACHE] $.reason"
}
}

=begin pod

=TITLE Pod::To::Cached
Expand Down
2 changes: 2 additions & 0 deletions t/007-load-precompile.t
Expand Up @@ -29,3 +29,5 @@ rmtree(cache-name);
Perl6 is quite awesome.

=end pod

done-testing;
4 changes: 3 additions & 1 deletion t/010-cached.t
Expand Up @@ -120,4 +120,6 @@ rmtree REP ;

#--MARKER-- Test 8
throws-like { $cache .= new(:source( DOC ), :path( REP )) },
Exception, :message(/'is not a directory'/), 'Detects absence of source directory';
Exception, :message(/'is not a directory'/), 'Detects absence of source directory';

done-testing;
2 changes: 2 additions & 0 deletions t/020-source.t
Expand Up @@ -238,3 +238,5 @@ is-deeply $cache.hash-files(<Valid Old>), %( 'a-pod-file' => 'Valid', 'pod-file-

=end pod
POD-CONTENT

done-testing;
2 changes: 2 additions & 0 deletions t/040-pod-extraction.t
Expand Up @@ -68,3 +68,5 @@ throws-like { $cache.update-cache }, Exception, :message(/ 'Cannot update frozen

#--MARKER-- Test 11
throws-like {$cache.pod('xxxyyyzz') }, Exception, :message(/ 'Source name 「xxxyyyzz」 not in cache'/), 'Cannot get POD for invalid source name';

done-testing;
2 changes: 1 addition & 1 deletion t/050-multiple-instance.t
Expand Up @@ -28,4 +28,4 @@ for ^COUNT {
ok (REP ~ $_ ).IO.d
}

done-testing;
done-testing;
76 changes: 76 additions & 0 deletions t/060-cache-ignore.t
@@ -0,0 +1,76 @@
use lib 'lib';
use Test;
use Pod::To::Cached;
use File::Directory::Tree;

plan *;

constant REP = 't/tmp/ref-ignore';
constant DOC = 't/tmp/doc-ignore';
constant IGNORE_FILE = ".cache-ignore";

mkdir DOC.IO;

my Pod::To::Cached $cache;
diag 'Test .cache-ignore file';

DOC.IO.add('test1.pod6').spurt(q:to/CONTENT/);
=begin pod
=end pod
CONTENT

DOC.IO.add('test2.pod6').spurt(q:to/CONTENT/);
=begin pod
=end pod
CONTENT

#--MARKER-- Test 1
$cache .= new( :source( DOC ), :path( REP ), :!verbose);
ok path-list-cmp($cache,
("t/tmp/doc-ignore/test1.pod6".IO,
"t/tmp/doc-ignore/test2.pod6".IO)),
IGNORE_FILE ~ " does not exist";

#--MARKER-- Test 2
IGNORE_FILE.IO.spurt("");
$cache .= new( :source( DOC ), :path( REP ), :!verbose);
ok path-list-cmp($cache,
("t/tmp/doc-ignore/test1.pod6".IO,
"t/tmp/doc-ignore/test2.pod6".IO)),
IGNORE_FILE ~ " is empty";
unlink IGNORE_FILE;

#--MARKER-- Test 3
IGNORE_FILE.IO.spurt("test2");
$cache .= new( :source( DOC ), :path( REP ), :!verbose);
ok path-list-cmp($cache,
("t/tmp/doc-ignore/test1.pod6".IO,)),
IGNORE_FILE ~ " with simple regex";


unlink IGNORE_FILE;

sub path-list-cmp($cache, @expected --> Bool ) {
my @got = $cache.get-pods.sort.map({.IO});

for @got Z @expected -> $file {
return False unless path-cmp($file[0],$file[1]);
}

True;
}

sub path-cmp ($a, $b --> Bool ) {
if ($*DISTRO.is-win) {
return IO::Spec::Win32.canonpath(:parent, $a).fc eq IO::Spec::Win32.canonpath(:parent, $b).fc;
}

if (!$*DISTRO.is-win) {
return $a eq $b;
}
}

rmtree REP;
rmtree DOC;

done-testing;