Added removing empty directories from destination repository.
authorStanislaw Klekot <dozzie@jarowit.net>
Mon, 4 Apr 2011 16:32:26 +0000 (18:32 +0200)
committerStanislaw Klekot <dozzie@jarowit.net>
Wed, 6 Apr 2011 12:28:12 +0000 (14:28 +0200)
cronbuilder
lib/Cron/Builder/Repo.pm
lib/Cron/Builder/Repo/git.pm
lib/Cron/Builder/Repo/svn.pm

index 64c4769..bc5452c 100755 (executable)
@@ -191,6 +191,10 @@ if (defined $last_build) {
 my $commit_output;
 
 if ($opts{commit}) {
+  # remove any possible empty directories, regarding versioning system
+  # metadata
+  $dst->remove_empty_dirs;
+
   $commit_output = $dst->commit($current_source, $additional_comment);
 
   if (not defined $commit_output) {
index 452413c..b783d98 100644 (file)
@@ -191,6 +191,21 @@ sub commit {
 
 #-----------------------------------------------------------------------------
 
+=item C<remove_empty_dirs()> I<(virtual)>
+
+Method removes empty directories (where is no user-supplied files) from
+working copy and repository (it does not commit changes, though).
+
+=cut
+
+sub remove_empty_dirs {
+  my ($self) = @_;
+
+  die "This method is not implemented!";
+}
+
+#-----------------------------------------------------------------------------
+
 =item C<revert()> I<(virtual)>
 
 Method reverts any changes made to this working copy that were not committed.
index 27546ad..6fa95c6 100644 (file)
@@ -20,6 +20,7 @@ use URI;
 use Cwd qw{getcwd realpath};
 use Cron::Builder qw{spawn};
 use File::Path qw{rmtree};
+use File::Find;
 
 #-----------------------------------------------------------------------------
 
@@ -324,6 +325,33 @@ sub commit {
 
 #-----------------------------------------------------------------------------
 
+=item C<remove_empty_dirs()> I<(virtual)>
+
+Method removes empty directories (where is no user-supplied files) from
+working copy and repository (it does not commit changes, though).
+
+=cut
+
+sub remove_empty_dirs {
+  my ($self) = @_;
+
+  my %contents;
+  my %toremove;
+  my @toremove;
+
+  find({
+      bydepth => 1,
+      no_chdir => 1,
+      # git repository can be quite big; skip it
+      preprocess => sub { return grep { $_ ne '.git' } @_ },
+      wanted => sub { rmdir if -d },
+    },
+    $self->{workdir},
+  );
+}
+
+#-----------------------------------------------------------------------------
+
 =item C<revert()>
 
 Method reverts any changes made to this working copy that were not committed.
index f53d098..312b583 100644 (file)
@@ -20,6 +20,7 @@ use base qw{Cron::Builder::Repo};
 
 use Cron::Builder qw{spawn};
 use File::Path qw{rmtree};
+use File::Find;
 
 #-----------------------------------------------------------------------------
 
@@ -324,6 +325,63 @@ sub commit {
 
 #-----------------------------------------------------------------------------
 
+=item C<remove_empty_dirs()> I<(virtual)>
+
+Method removes empty directories (where is no user-supplied files) from
+working copy and repository (it does not commit changes, though).
+
+=cut
+
+sub remove_empty_dirs {
+  my ($self) = @_;
+
+  my %contents;
+  my %toremove;
+  my @toremove;
+
+  find({
+      bydepth => 1,
+      no_chdir => 1,
+      preprocess => sub {
+        # make every directory having an array reference (at least empty)
+        $contents{$File::Find::dir} = [];
+        # exclude .svn directories
+        return grep { $_ ne '.svn' } @_;
+      },
+      wanted => sub {
+        # fill in contents array in hashmap
+        push @{ $contents{$File::Find::dir} }, $_;
+      },
+      postprocess => sub {
+        my @kept = @{ $contents{$File::Find::dir} };
+        delete $contents{$File::Find::dir};
+
+        # filter out all directories that are going to be removed (they're
+        # treated as empty, too)
+        @kept = grep { not exists $toremove{$_} } @kept;
+
+        # if directory has no files, mark it as to be removed
+        if (@kept == 0) {
+          $toremove{$File::Find::dir} = 1;
+          push @toremove, $File::Find::dir;
+        }
+      },
+    },
+    $self->{workdir},
+  );
+
+  # in case the repository is (or is going to) empty, filter out working copy
+  # itself from directories to remove
+  @toremove = grep { $_ ne $self->{workdir} } @toremove;
+
+  if (@toremove) {
+    my $message = spawn("svn", "rm", "--quiet", "--force", @toremove);
+    $self->check_or_die("svn rm", $message);
+  }
+}
+
+#-----------------------------------------------------------------------------
+
 =item C<revert()>
 
 Method reverts any changes made to this working copy that were not committed.