7 package My::PathStatus;
11 has path => (is => 'ro', required => 1);
12 has info => (is => 'ro', required => 1);
14 package My::PathStatusInfo;
18 has is_directory => (is => 'ro', default => 0);
19 has is_file => (is => 'ro', default => 0);
20 has mode => (is => 'ro', required => 1);
23 @INC{qw(My/PathStatus.pm My/PathStatusInfo.pm)} = (__FILE__,__FILE__);
26 '.ssh' => My::PathStatus->new(
28 info => My::PathStatusInfo->new(is_directory => 1, mode => '0755')
30 '.ssh/authorized_keys' => My::PathStatus->new(
31 path => '.ssh/authorized_keys',
32 info => My::PathStatusInfo->new(is_file => 1, mode => '0644')
38 my $solver = DX::Solver->new(
39 facts => { path_status => DX::SetOver->new(
41 values => \%path_status,
46 [ path_status => [ qw(PS) ],
47 [ member_of => 'PS', [ value => 'path_status' ] ] ],
48 [ path => [ qw(PS P) ],
49 [ constrain => [ qw(PS P) ], sub { $_[0]->path eq $_[1] } ] ],
50 [ mode => [ qw(PS M) ],
51 [ constrain => [ qw(PS M) ],
52 sub { $_[0]->info and $_[0]->info->mode eq $_[1] } ] ],
53 [ is_directory => [ qw(PS) ],
54 [ constrain => [ qw(PS) ],
55 sub { $_[0]->info and $_[0]->info->is_directory } ] ],
56 [ is_file => [ qw(PS) ],
57 [ constrain => [ qw(PS) ],
58 sub { $_[0]->info and $_[0]->info->is_file } ] ],
61 $solver->add_rule(@$_) for @rules;
63 %path_status = %protos;
66 join ' ', map $_->{PS}{path}, $solver->query(
67 [ qw(PS) ], [ path_status => 'PS'], @_
71 is(paths_for(), '.ssh .ssh/authorized_keys');
73 is(paths_for([ is_directory => 'PS' ]), '.ssh');
75 is(paths_for([ is_file => 'PS' ]), '.ssh/authorized_keys');
77 is(paths_for([ mode => 'PS', [ value => '0755' ] ]), '.ssh');