On Mon, 17 Sep 2001, Stas Bekman wrote:
> Doug MacEachern wrote:
>
> > On Mon, 17 Sep 2001, Stas Bekman wrote:
> >
> >
> >>I was wondering whether it'd be better to use File::Path::mkpath in
> >>genfile and gendir so the test writers won't have to call this sub many
> >>times if they need to create a dir foo/bar/baz or a file
> >>foo/bar/baz/test.conf, when foo doesn't exist. Of course in this case
> >>the cleanup code should use File::Path::rmtree. If you think it's cool,
> >>I'll send a patch.
> >>
> >
> > +1 for s/mkdir/mkpath/ in both gendir and t_mkdir. however, the cleanup
> > code intentionally does not use rmtree. it carefully removes generated
> > files first (created via genfile), then only removes the generated
> > directories if they are empty. i don't think rmtree provides that
> > functionality.
> > also, switching to gendir to use mkpath will require you to add each
> > subdirectory created to $self->{clean}->{dirs}
>
>
> Yes, I'm aware of that. And that's exactly what I've planned to do.
> It'll be somewhat slower than mkpath, but not slower than the current
> code, and will take away from the test writer the mess of doing all this
> work.
The following patch does:
- adds a private _makepath, which takes care of creating paths and
maintaining the cleanup list of dirs that it has created
- clean()'s dir section is corrected to make sure that the sub-dirs are
attempted to be deleted first.
- use better API naming s/warn/warn_type/. it's not clear what 'warn' is.
- starts the documentation of the module and documents genwarning,
genfile, gendir, writefile
If you agree with me that _makepath should be made private as in my patch,
I also suggest that genwarning() is made private too. I don't see a reason
why any of these two should be exposed outside.
Hmm, doesn't it make sense at all for Apache-Test to have a concept of
private subs, or am I barking on the wrong tree? I'm just trying to make
it easier to change the functionality later, and it'll be much easier if
we protect some of our subs making them private.
Anyway, here is the patch.
Index: Apache-Test/lib/Apache/TestConfig.pm
===================================================================
RCS file: /home/cvs/httpd-test/perl-framework/Apache-Test/lib/Apache/TestConfig.pm,v
retrieving revision 1.60
diff -u -r1.60 TestConfig.pm
--- Apache-Test/lib/Apache/TestConfig.pm 2001/09/15 19:14:16 1.60
+++ Apache-Test/lib/Apache/TestConfig.pm 2001/09/17 05:14:35
@@ -10,6 +10,8 @@
use File::Copy ();
use File::Find qw(finddepth);
+use File::Basename qw(dirname);
+use File::Path ();
use File::Spec::Functions qw(catfile abs2rel splitdir
catdir file_name_is_absolute);
use Cwd qw(fastcwd);
@@ -536,14 +538,18 @@
}
sub genfile {
- my($self, $file, $warn) = @_;
+ my($self, $file, $warn_type) = @_;
+ # create the parent dir if it doesn't exist yet
+ my $dir = dirname $file;
+ $self->_makepath($dir);
+
my $name = abs2rel $file, $self->{vars}->{t_dir};
$self->trace("generating $name");
open my $fh, '>', $file or die "open $file: $!";
- if (my $msg = $self->genwarning($warn)) {
+ if (my $msg = $self->genwarning($warn_type)) {
print $fh $msg, "\n";
}
@@ -554,14 +560,18 @@
# gen + write file
sub writefile {
- my($self, $file, $content, $warn) = @_;
+ my($self, $file, $content, $warn_type) = @_;
+
+ # create the parent dir if it doesn't exist yet
+ my $dir = dirname $file;
+ $self->_makepath($dir);
my $name = abs2rel $file, $self->{vars}->{t_dir};
$self->trace("generating $name");
open my $fh, '>', $file or die "open $file: $!";
- if (my $msg = $self->genwarning($warn)) {
+ if (my $msg = $self->genwarning($warn_type)) {
print $fh $msg, "\n";
}
@@ -588,9 +598,24 @@
sub gendir {
my($self, $dir) = @_;
+ $self->_makepath($dir);
+}
+
+# returns a list of dirs successfully created
+sub _makepath {
+ my($self, $path) = @_;
+
+ return if !defined($path) || -e $path;
+ my $full_path = $path;
+
+ # remember which dirs were created and should be cleaned up
+ while (1) {
+ $self->{clean}->{dirs}->{$path} = 1;
+ $path = dirname $path;
+ last if -e $path;
+ }
- mkdir $dir, 0755 unless -d $dir;
- $self->{clean}->{dirs}->{$dir} = 1;
+ return File::Path::mkpath($full_path, 0, 0755);
}
sub open_cmd {
@@ -617,11 +642,13 @@
unlink $_;
}
else {
- #print "unlink $_: $!\n";
+ $self->trace("unlink $_: $!");
}
}
- for (keys %{ $self->{clean}->{dirs} }) {
+ # if /foo comes before /foo/bar, /foo will never be removed
+ # hence ensure that sub-dirs are always treated before a parent dir
+ for (reverse sort keys %{ $self->{clean}->{dirs} }) {
if (-d $_) {
opendir(my $dh, $_);
my $notempty = grep { ! /^\.{1,2}$/ } readdir $dh;
@@ -994,6 +1021,105 @@
}
1;
+
+=head1 NAME
+
+Apache::TestConfig -- Test Configuration setup module
+
+=head1 SYNOPSIS
+
+ use Apache::TestConfig;
+
+ my $cfg = Apache::TestConfig->new(%args)
+ my $fh = $cfg->genfile($file, $warn_type);
+ $cfg->writefile($file, $content, $warn_type);
+ $cfg->gendir($dir);
+ ...
+
+=head1 DESCRIPTION
+
+C<Apache::TestConfig> is used in creating the C<Apache::Test>
+configuration files.
+
+=head1 FUNCTIONS
+
+=over
+
+=item genwarning()
+
+ my $warn = $cfg->genwarning($warn_type)
+
+genwarning() returns a string warning that the file is autogenerated,
+plus a perl trace of calls to this this function. This function is
+useful for navigating through autogenerated files.
+
+The returned warnings are enclosed into a suitable for Perl or C
+comment style, if the C<$warn_type> variable:
+
+ 1 => # Perl warning
+ 2 => /* # C warning */
+
+If C<$warn_type> is FALSE, no warning string will be returned.
+
+=item genfile()
+
+ my $fh = $cfg->genfile($file, $warn_type);
+
+genfile() creates a new file C<$file> for writing and returns a file
+handle.
+
+If C<$warn_type> is true a warning header, which states that the file
+was autogenerated and the trace of calls that generated this file,
+will be automatically added to the top of the created file. For valid
+C<$warn_type> values see genwarning().
+
+If parent directories of C<$file> don't exist they will be
+automagically created.
+
+The file C<$file> and any created parent directories (if found empty)
+will be automatically removed on cleanup.
+
+=item writefile()
+
+ $cfg->writefile($file, $content, $warn_type);
+
+writefile() creates a new file C<$file> with the content of
+C<$content>.
+
+If C<$warn_type> is true a warning header, which states that the file
+was autogenerated and the trace of calls that generated this file,
+will be automatically added to the top of the created file. For valid
+C<$warn_type> values see genwarning().
+
+If parent directories of C<$file> don't exist they will be
+automagically created.
+
+The file C<$file> and any created parent directories (if found empty)
+will be automatically removed on cleanup.
+
+=item gendir()
+
+ $cfg->gendir($dir);
+
+gendir() creates a new directory C<$dir>.
+
+If parent directories of C<$dir> don't exist they will be
+automagically created.
+
+The directory C<$dir> and any created parent directories will be
+automatically removed on cleanup if found empty.
+
+=back
+
+=head1 AUTHOR
+
+=head1 SEE ALSO
+
+perl(1), Apache::Test(3)
+
+=cut
+
+
__DATA__
ServerRoot "@ServerRoot@"
DocumentRoot "@DocumentRoot@"
_____________________________________________________________________
Stas Bekman JAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide http://perl.apache.org/guide
mailto:[EMAIL PROTECTED] http://apachetoday.com http://eXtropia.com/
http://singlesheaven.com http://perl.apache.org http://perlmonth.com/
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]