File Coverage

bin/ncustom
Criterion Covered Total %
statement 155 157 98.7
branch 25 50 50.0
condition n/a
subroutine 8 8 100.0
pod n/a
total 188 215 87.4


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             # ///////////////////////////////////////////////////////////////////
4             #<< PP: POD Start <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
5             # \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
6              
7             =head1 NAME
8              
9             ncustom - command line interface to NCustom
10              
11             =head1 SYNOPSIS
12              
13             ncustom [{-i|--initialise}]
14              
15             [{-n|--ncustom} ncustom_filename/url ]
16              
17             [{-u|--undo} transaction_dirname ]
18              
19             [{-b|--blat}]
20              
21             [{-c|--config} name=value ]
22              
23              
24             Options:
25             --initialise purges the transaction archive
26              
27             --undo undoes the transactions specified
28              
29             --ncustom fetch and execute the ncustom scripts specified
30              
31             --blat blat personal configuration with global configuration
32              
33             --config edit settings in personal configuration file
34              
35 1         44  
36              
37             =head1 ABSTRACT
38              
39             A command line interface to the NCustom module.
40             Currently invocation of only the simplest NCustom methods is supported, namely initialising the transaction archive, undoing transactions, and executing new NCustom scripts.
41              
42             =head1 DESCRIPTION
43              
44             =head1 OPTIONS
45              
46             =over 8
47              
48             =cut
49              
50             # ///////////////////////////////////////////////////////////////////
51             #<< CC: Code <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
52             # \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
53             #====================================================================
54             # Inline testing
55             # setup only
56              
57             =begin testing
58              
59 1     1   2 use Carp;
  1         313  
  1         25639  
60 1     1   2 use File::Compare ;
  1         102  
  1         878  
61 1     1   1175 use File::Copy ;
  1         54  
  1         999  
62 1     1   7683 use File::Path ;
  1         116  
  1         11  
63 1     1   2 use File::Spec ;
  1         76  
  1         5  
64 1     1   2 use vars qw($ncustom $output $input);
  1         27  
  1         5  
65              
66             # test setup
67 0         0 $output = File::Spec->rel2abs("./t/embedded-bin-ncustom.o");
68 0         0 $input = File::Spec->rel2abs("./t/embedded-bin-ncustom.i");
69 1 50       58 ok( -d $input)
70             || diag("TEST: requires the data input directory be present");
71              
72 1 50       20 -d $input || die; # as if we have that wrong we could clobber allsorts
73 1         41 rmtree $output;
74 1         1109 mkpath $output;
75 1         2158 $ENV{HOME} = $output ; # lets be non-intrusive
76              
77             #system("ncustom") && $ncustom = "ncustom";
78 1 50       246 if(-f "./bin/ncustom"){$ncustom = "./bin/ncustom" }
  1         9  
79 1 50       19 ok($ncustom ne "")
80             || diag("TEST: must be able to find ncustom program");
81              
82              
83             sub test_reset {
84             #Test::Inline doesnt execute test blocks in order
85             #it does all basic tests first (seemingly in declaration order),
86             #then examples tests (seemingly in declaration order).
87             #hmmm.. test_rest can erase "why test failed" data
88 1     5   1 rmtree $output;
89 1         4743 mkpath $output;
90 5         72282 system("cp -r $input/subject/* $output");
91             }
92              
93             sub output {
94 5 50   7   1761 $_STDOUT_ && diag($_STDOUT_);
95 5 50       53021 $_STDERR_ && diag($_STDERR_);
96             }
97              
98 1         2 output();
99              
100             =end testing
101 1         7  
102 1         578 =cut
103              
104             #====================================================================
105              
106 1         1 use 5.008;
  1         2  
107 1         1 use strict qw(vars);
108             use warnings;
109             use Getopt::Long;
110             use Pod::Usage;
111              
112             # get opts
113             my ($initialise, @ncustom, @undo, $blat, %config );
114             my $rc = GetOptions (
115             "initialise" => \$initialise,
116             "ncustom=s" => \@ncustom,
117             "undo=s" => \@undo,
118             "blat" => \$blat,
119             "config=s" => \%config);
120             unless($rc){pod2usage(2) }
121              
122             # handle opts
123             my $run = 0 ;
124             my $ok = 1;
125             if($initialise ){ initialise() or $ok = 0; $run = 1; }
126             if($#ncustom >= 0){ ncustom() or $ok = 0; $run = 1; }
127             if($#undo >= 0){ undo() or $ok = 0; $run = 1; }
128             if($blat ){ blat() or $ok = 0; $run = 1; }
129             if(%config ){ config() or $ok = 0; $run = 1; }
130              
131             # finished
132             unless($run){pod2usage(2)}
133             exit (! $ok); #perl 1 == TRUE, shell 0 == TRUE
134              
135             #====================================================================
136             # general
137              
138             =begin testing
139              
140 1         2 test_reset();
141 1         1 my ($rc, $o);
142 1         4 $rc = system("$ncustom -junk > /dev/null 2>&1");
143 1 50       18 ok($rc != 0)
144             || diag("TEST: returns error for invalid arguments");
145 1         233753 $o = `$ncustom 2>&1 `;
146 1 50       73 like( $o, qr/Usage:/m)
147             || diag("TEST: displays useage for invalid arguments");
148 1         212123 $rc = system("$ncustom > /dev/null 2>&1");
149 1 50       320 ok($rc != 0)
150             || diag("TEST: returns error for no arguments");
151 1         160885 $o = `$ncustom 2>&1 `;
152 1 50       60 like( $o, qr/Usage:/m)
153             || diag("TEST: displays useage for no arguments");
154              
155 1         224172 output();
156              
157             =end testing
158 1         71  
159 1         841 =cut
160              
161             #====================================================================
162             # initialise
163 1         2  
  1         5  
164 1         6 =item B<-i, --initialise>
165              
166             Initialises (purges) the transaction archive. The transactions will no longer be able to be undone.
167              
168              
169             =begin testing
170              
171 1         3 test_reset();
172              
173 1 50       4 ok(! -d "$output/.ncustom/save/all")
174             || diag("TEST: require void setup, ie no ~/.ncustom...");
175              
176 1         10 my ($rc);
177 1         181 $rc = system("$ncustom -i");
178 1 50       841 ok($rc == 0)
179             || diag("TEST: returns success for void initialisation");
180              
181             # NB: we just called $ncustom, which used NCustom, so ~/.ncustom now exists
182 1 50       252698 ok(-d "$output/.ncustom/save/all")
183             || diag("TEST: require ~/.ncustom...");
184 1         63 system("mkdir -p $output/.ncustom/save/dummydir");
185 1         1784 system("echo content > $output/.ncustom/save/dummydir/dummyfile");
186 1 50       9958 ok(-f "$output/.ncustom/save/dummydir/dummyfile")
187             || diag("TEST: require dummy transaction");
188 1         5195 $rc = system("$ncustom -i");
189 1 50       108 ok($rc == 0)
190             || diag("TEST: returns success for initialisation");
191 1 50       232043 ok(! -f "$output/.ncustom/save/dummydir/dummyfile")
192             || diag("TEST: purges transactions");
193 1         72 output();
194              
195             =end testing
196 1         1124  
197 1         618 =cut
198              
199             #====================================================================
200             sub initialise {
201 1         2 require NCustom;
  1         3  
202 1         7 return NCustom::initialise();
203             }
204              
205             #====================================================================
206             # undo
207              
208             =item B<-u,--undo>
209              
210             =begin example
211              
212 1         3 test_reset();
213 1         1 my $eg ;
214              
215             =end example
216              
217             =for example begin
218              
219 1         4 $eg = <<' end_eg';
220            
221             grep -c incomplete ~/file1 >> ~/log
222              
223             ncustom -n test5.ncus ;
224             grep -c incomplete ~/file1 >> ~/log
225              
226             ncustom -n test6.ncus ;
227             grep -c incomplete ~/file1 >> ~/log
228              
229             ncustom -u test6.ncus ;
230             grep -c incomplete ~/file1 >> ~/log
231            
232             cat ~/log # 7,3,1,3
233              
234             end_eg
235              
236             =for example end
237              
238             Undo is followed by one or more transaction names, transaction names are sub-directoy names within the transaction archive directory.
239             There is a sub-directoy "all" that contains the entire journal of transactions since the last initialise.
240             Transaction names are created when using the NCusom module in NCustom scripts.
241             They are generaly named after the basename of the NCustom script, and generaly the is a one to one relationship, but the NCustom script may override these behaviours.
242              
243             =for example_testing
244 1         34 copy("$input/file1", "$output");
245 1         20 copy("$input/test5.ncus", "$output");
246 1         64 copy("$input/test6.ncus", "$output");
247 1         994 chmod 750, "$output/test5.ncus", "$output/test6.ncus";
248             #
249 1         392 $eg =~ s/ncustom/$ncustom/g ; # or insert ncustom in path ?
250 1         497 system("$eg");
251             #
252 1         20 open(LOG, "< $output/log");
253 1         1024206 my @lines = ;
254 1         99 close(LOG);
255 1         57 my @expected_lines = ("7\n", "3\n", "1\n", "3\n");
256             #
257 1 50       14 eq_array( \@lines, \@expected_lines )
258             || diag("TEST: undoes transactions");
259             #
260 1         13 output();
261              
262 1         36 =cut
263 1         432  
264             #====================================================================
265             sub undo {
266 1         3 my $dirs = join("\n", @undo);
267 1         6 require NCustom;
268             return NCustom::undo_files($dirs);
269 1         6 }
270 1         1  
271 1         4 #====================================================================
272             # ncustom
273              
274             =item B<-n,--ncustom>
275              
276             =begin example
277              
278 1         2 test_reset();
279 1         2 my $eg ;
280              
281             =end example
282              
283             =for example begin
284              
285 1         5 $eg = <<' end_eg';
286            
287             # default_dir contains test2.ncus
288             # default_url contains test3.ncus
289            
290             ncustom -n ~/dir20/test1.ncus -n test2.ncus ;
291             ncustom -n test3.ncus -n http://install/install/NCustom/test4.ncus ;
292            
293             end_eg
294              
295             =for example end
296              
297             Ncustom is followed by one or more filenames, either local filenames or URLs.
298             The filenames are assumed to be NCustom scripts, are fetched, and executed.
299             If the filename is not an NCustom script, then transactions will not be journalled, and will not be able to be undone.
300             An unqualified NCustom script name will be searched for in the loaction(s) specified in NCustom::Config.
301             Settings in NCustom::Config may be overridden using ~/.ncustom/NCustom/MyConfig.pm.
302              
303             =for example_testing
304 1         31 mkpath "$output/dir20";
305 1         18 copy("$input/test1.ncus", "$output/dir20");
306 1         757 copy("$input/test2.ncus", "$output");
307 1         5 chmod 0750, "$output/dir20/test1.ncus", "$output/test2.ncus";
  1         45  
308             #now tell me again, how we are getting test3.ncus to url ?
309             #should make tests conditional on config - but hey test config test chicken egg
310 1         113 #
  1         22  
311 1         408 $eg =~ s/ncustom/$ncustom/g ; # or insert ncustom in path ?
  1         1092  
312 1         466 system("$eg");
313             #
314 1         19 open(STUBSLOG, "< $output/stubs.log");
315 1         507352 my @stubslog = ;
316 1         182 close(STUBSLOG);
317             #
318 1 50       89 ok( grep( /ncustom test1.ncus/, @stubslog) > 0 )
319             || diag("TEST: fetches and executes file from given dir");
320 1 50       18 ok( grep( /ncustom test2.ncus/, @stubslog) > 0 )
321             || diag("TEST: fetches and executes file from default dir");
322 1 50       72 ok( grep( /ncustom test3.ncus/, @stubslog) > 0 )
323             || diag("TEST: fetches and executes file from default url");
324 1 50       1040 ok( grep( /ncustom test4.ncus/, @stubslog) > 0 )
325             || diag("TEST: fetches and executes file from given url");
326             #
327 1         714 output();
328              
329 1         1068 =cut
330 1         734  
331             #====================================================================
332             sub ncustom {
333 1         2 my $files = join("\n", @ncustom);
334 1         7 require NCustom;
335             return NCustom::ncustom($files);
336 1         5 }
337 1         2  
338 1         2 #====================================================================
339             # blat
340              
341             =item B<-b, --blat>
342              
343             Blat overwrites the personal configuration profile with the global conf iguration profile. The personal configuration profile is "~/.ncustom/NCustom/MyConfig.pm".
344              
345              
346             =begin testing
347              
348 1         3 my $rc = system("$ncustom -b");
349 1 50       2 ok($rc == 0)
350             || diag("TEST: returns success for void initialisation");
351 1 50       214509 is(compare("$output/.ncustom/NCustom/MyConfig.pm", "$input/Global.pm"), 0)
352             || diag("TEST: MyConfig.pm replaced by Config.pm");
353 1         65 output();
354              
355             =end testing
356 1         1003  
357 1         403 =cut
358              
359              
360 1         5 #====================================================================
361 1         5 sub blat {
362 1         5 require NCustom;
363             return NCustom::blat_myconfig();
364             }
365              
366             #====================================================================
367             # config
368              
369             =item B<-c,--config>
370              
371             =begin example
372              
373 1         2 test_reset();
374 1         4 my $eg2 ;
375              
376             =end example
377              
378 1         2 =for example begin
379              
380 1         31 $eg2 = <<' end_eg';
381 1         256  
  1         23  
382 1         526 # modify existing values
383             ncustom -c src_fqdn=\"install.baneharbinger.com\" ;
384             ncustom -c test_url1=\"install.baneharbinger.com/index.html\" ;
385              
386             # add new values
387             ncustom -c my_number=5 -c my_text=\"blah\" ;
388              
389             # add new complex (eg hash) values
390             ncustom -c my_hosts='{ mew => "192.168.0.10", pikachu => "192.168.0.20" }' ;
391              
392             end_eg
393              
394             =for example end
395              
396             Config is followed by name vaule pairs. If there is a corresponding name in the personal configuration file, then its vaule shall be updated. If there is no corresponding name then the name value shall be added to the end of the file. If there is no file it shall be created. The personal configuration file is "~/.ncustom/NCustom/MyConfig.pm".
397              
398             If some configuration vlaues are defined in terms of other configuration values, then the order may be important.
399              
400             The current implementation is simplistic and erroneous in all but the simplest cases (eg the pre-existing name value assignment is only a one liner).
401              
402             =for example_testing
403             #
404 1         6 $eg2 =~ s/ncustom/$ncustom/g ; # or insert ncustom in path ?
  1         57  
405 1         32 system("$eg2");
406             #
407 1         114 my @lines ;
  1         12  
  1         57  
408 1         454 open(MYCFG, "< $output/.ncustom/NCustom/MyConfig.pm");
  1         1041710  
409 1         27 @lines = ;
410 1         139 close(MYCFG);
411 1 50       112 ok( grep( /src_fqdn.*"install.baneharbinger.com"/, @lines) > 0 )
412             || diag("TEST: can edit(add) src_fqdn");
413 1 50       20 ok( grep( /test_url1.*"install.baneharbinger.com\/index.html"/, @lines) > 0 )
414             || diag("TEST: can edit(add) test_url1");
415             #
416 1         74 output();
417              
418 1         1327 =cut
419 1         292  
420             #====================================================================
421             sub config {
422 1         2 require NCustom;
423 1         8 return NCustom::config_edit(%config);
424             }
425              
426             #====================================================================
427              
428             # ///////////////////////////////////////////////////////////////////
429             #<< PP: POD end <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
430             # \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
431              
432             =back
433              
434             =head1 SEE ALSO
435              
436             NCustom
437             NCustom::Config
438             ncustom
439              
440             http://baneharbinger.com/NCustom
441              
442             =head1 AUTHOR
443              
444             Bane Harbinger, Ebane@baneharbinger.comE
445              
446             =head1 COPYRIGHT AND LICENSE
447              
448             Copyright 2003 by Bane Harbinger
449              
450             This library is free software; you can redistribute it and/or modify
451             it under the same terms as Perl itself.
452              
453             =cut
454