3 use DX::Lib::FS::Observation::PathStatus;
4 use DX::Lib::FS::Action::CreateDirectory;
5 use DX::Lib::FS::Action::CreateFile;
6 use DX::Lib::FS::Action::SetPathMode;
7 use DX::Lib::FS::Observation::FileContent;
8 use DX::Lib::FS::Action::RewriteFile;
14 [ path_status => [ qw(PS) ],
15 [ member_of => 'PS', \'path_status' ] ],
16 [ path => [ qw(PS P) ],
17 [ prop => 'PS', \'path', 'P' ] ],
18 [ info_prop => [ qw(PS N V) ],
19 [ exists => [ qw(PSI) ],
20 [ prop => 'PS', \'info', 'PSI' ],
21 [ prop => 'PSI', 'N', 'V' ] ] ],
22 [ mode => [ qw(PS M) ],
23 [ info_prop => 'PS', \'mode', 'M' ] ],
24 [ exists_path => [ qw(PS) ],
25 [ info_prop => 'PS', \'is_directory', \1 ] ],
26 [ exists_path => [ qw(PS) ],
27 [ info_prop => 'PS', \'is_file', \1 ] ],
28 [ is_directory => [ qw(PS) ],
29 [ info_prop => 'PS', \'is_directory', \1 ] ],
30 [ is_file => [ qw(PS) ],
31 [ info_prop => 'PS', \'is_file', \1 ] ],
32 [ path_status_at => [ 'PS', 'P' ],
33 [ path_status => 'PS' ],
36 [ path_status_at => [ 'PS', 'P' ],
37 [ observe => [ 'P' ], sub {
38 DX::Lib::FS::Observation::PathStatus->new(
42 [ path_status => 'PS' ],
43 [ path => qw(PS P) ] ],
44 [ directory_at => [ qw(PS P) ],
45 [ path_status_at => qw(PS P) ],
46 [ is_directory => 'PS' ] ],
47 [ file_at => [ qw(PS P) ],
48 [ path_status_at => qw(PS P) ],
49 [ is_file => 'PS' ] ],
50 [ is_directory => [ qw(PS) ],
51 [ not => [ exists_path => 'PS' ] ],
52 [ act => [ 'PS' ], sub {
53 DX::Lib::FS::Action::CreateDirectory->new(
57 [ is_file => [ qw(PS) ],
58 [ not => [ exists_path => 'PS' ] ],
59 [ act => [ 'PS' ], sub {
60 DX::Lib::FS::Action::CreateFile->new(
64 [ directory_in => [ qw(DirStatus DirName SubDirStatus) ],
65 [ is_directory => qw(DirStatus) ],
66 [ exists => [ qw(DirPath) ],
67 [ path => qw(DirStatus DirPath) ],
68 [ exists => [ qw(SubDirPath) ],
69 [ catfile => qw(DirPath DirName SubDirPath) ],
70 [ directory_at => qw(SubDirStatus SubDirPath) ] ] ] ],
71 [ file_in => [ qw(DirStatus FileName FileStatus) ],
72 [ is_directory => qw(DirStatus) ],
73 [ exists => [ qw(DirPath) ],
74 [ path => qw(DirStatus DirPath) ],
75 [ exists => [ qw(FilePath) ],
76 [ catfile => qw(DirPath FileName FilePath) ],
77 [ file_at => qw(FileStatus FilePath) ] ] ] ],
78 [ mode => [ qw(PS M) ],
79 [ exists => [ qw(A) ],
80 [ has_action => qw(PS A) ],
81 [ does => 'A', \'DX::Lib::FS::Action::CreateDirectory' ],
82 [ react => [ qw(PS M) ], sub {
83 $_[0]->but(mode => $_[1]);
86 [ mode => [ qw(PS M) ],
87 [ exists => [ qw(A) ],
88 [ has_action => qw(PS A) ],
89 [ does => 'A', \'DX::Lib::FS::Action::CreateFile' ],
90 [ react => [ qw(PS M) ], sub {
91 $_[0]->but(mode => $_[1]);
94 [ mode => [ qw(PS M) ],
95 [ exists_path => qw(PS) ],
96 [ not => [ info_prop => 'PS', \'mode', 'M' ] ],
97 [ act => [ qw(PS M) ], sub {
98 DX::Lib::FS::Action::SetPathMode->new(
99 path_status => $_[0], mode => $_[1]
102 [ file_content => [ qw(FC) ],
103 [ member_of => 'FC', \'file_content' ] ],
104 [ file_content_at => [ qw(FC P) ],
105 [ file_content => 'FC' ],
106 [ path => qw(FC P) ],
108 [ file_content_at => [ qw(FC P) ],
109 [ observe => [ 'P' ], sub {
110 DX::Lib::FS::Observation::FileContent->new(
114 [ file_content => 'FC' ],
115 [ path => qw(FC P) ] ],
116 [ file_data => [ qw(FC D) ], [ prop => 'FC', \'data', 'D' ] ],
117 [ file_content_line => [ qw(FC L) ],
118 [ exists => [ 'Lines' ],
119 [ prop => 'FC' => \'lines' => 'Lines' ],
120 [ member_of => 'L' => 'Lines' ] ] ],
121 [ contains_line => [ qw(PS L) ],
123 [ exists => [ qw(FC P) ],
124 [ path => qw(PS P) ],
125 [ file_content_at => qw(FC P) ],
126 [ file_content_line => qw(FC L) ] ] ],
127 [ file_content_line => [ qw(FC L) ],
129 [ exists => [ 'Lines' ],
130 [ prop => 'FC' => \'lines' => 'Lines' ],
131 [ member_of => 'L' => 'Lines' ] ] ],
133 [ has_action => qw(FC A) ],
134 [ does => 'A' => \'DX::Lib::FS::Action::CreateFile' ] ],
135 [ react => [ qw(FC L) ], sub {
136 $_[0]->but(data => $_[0]->data.$_[1]."\n")
139 [ file_content_line => [ qw(FC L) ],
141 [ exists => [ 'Lines' ],
142 [ prop => 'FC' => \'lines' => 'Lines' ],
143 [ member_of => 'L' => 'Lines' ] ] ],
145 [ has_action => qw(FC A) ],
146 [ does => 'A' => \'DX::Lib::FS::Action::RewriteFile' ] ],
147 [ react => [ qw(FC L) ], sub { $_[0]->but_add($_[1]) } ],
149 [ file_content_line => [ qw(FC L) ],
151 [ exists => [ 'Lines' ],
152 [ prop => 'FC' => \'lines' => 'Lines' ],
153 [ member_of => 'L' => 'Lines' ] ] ],
154 [ act => [ qw(FC L) ], sub {
155 DX::Lib::FS::Action::RewriteFile->new(
157 add_lines => [ $_[1] ]
161 [ not_file_content_line => [ qw(FC L) ],
163 [ exists => [ 'Lines' ],
164 [ prop => 'FC' => \'lines' => 'Lines' ],
165 [ member_of => 'L' => 'Lines' ] ] ] ],
166 [ not_contains_line => [ qw(PS L) ],
168 [ exists => [ qw(FC P) ],
169 [ path => qw(PS P) ],
170 [ file_content_at => qw(FC P) ],
171 [ not_file_content_line => qw(FC L) ] ] ],
172 [ not_file_content_line => [ qw(FC L) ],
173 [ exists => [ 'Lines' ],
174 [ prop => 'FC' => \'lines' => 'Lines' ],
175 [ member_of => 'L' => 'Lines' ] ],
177 [ has_action => qw(FC A) ],
178 [ does => 'A' => \'DX::Lib::FS::Action::RewriteFile' ] ],
179 [ react => [ qw(FC L) ], sub { $_[0]->but_remove($_[1]) } ],
181 [ not_file_content_line => [ qw(FC L) ],
182 [ exists => [ 'Lines' ],
183 [ prop => 'FC' => \'lines' => 'Lines' ],
184 [ member_of => 'L' => 'Lines' ] ],
185 [ act => [ qw(FC L) ], sub {
186 DX::Lib::FS::Action::RewriteFile->new(
188 remove_lines => { $_[1] => 1 }
195 my ($self, $solver) = @_;
196 $solver->facts->{path_status} = DX::SetOver->new(over => 'path');
197 $solver->facts->{file_content} = DX::SetOver->new(over => 'path');
198 $solver->add_predicate(
199 catdir => [ qw(DirPath DirName SubDirPath) ],
200 [ qw(+ + -) ] => sub {
202 value => File::Spec->catdir($_{DirPath}, $_{DirName})
205 [ qw(- - +) ] => sub {
206 my @split = File::Spec->splitdir($_{SubDirPath});
207 my $last = pop @split;
208 my $rest = File::Spec->catdir(@split);
209 +(DirPath => [ value => $rest ], DirName => [ value => $last ])
212 $solver->add_predicate(
213 catfile => [ qw(DirPath FileName FilePath) ],
214 [ qw(+ + -) ] => sub {
215 my ($vol, $dir) = File::Spec->splitpath($_{DirPath}, 1);
216 my $file_path = File::Spec->catpath($vol, $dir, $_{FileName});
217 +(FilePath => [ value => $file_path ])
219 [ qw(- - +) ] => sub {
220 my ($vol, $dir, $file) = File::Spec->splitpath($_{FilePath});
221 my $dir_path = File::Spec->catpath($vol, $dir);
222 +(DirPath => [ value => $dir_path ], FileName => [ value => $file ])
226 does => [ qw(Thing RoleName) ],
227 [ constrain => [ qw(Thing RoleName) ], sub { $_[0]->DOES($_[1]) } ]
229 $solver->add_rule(@$_) for @RULES;