changeset 9881:9ea261201db5 octave-forge

subpkg_collector: new perl script for admin. Eases creation of a simple package structure from a package with multiple subpackages
author carandraug
date Mon, 26 Mar 2012 18:21:13 +0000
parents 2da3952924f6
children f129b3ea857d
files admin/subpkg_collector.pl
diffstat 1 files changed, 178 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/admin/subpkg_collector.pl	Mon Mar 26 18:21:13 2012 +0000
@@ -0,0 +1,178 @@
+#!/usr/bin/perl
+## Copyright (C) 2012 Carnë Draug <carandraug+dev@gmail.com>
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 3 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, see <http://www.gnu.org/licenses/>.
+
+use 5.010;                      # Use Perl 5.10
+use strict;                     # Enforce some good programming rules
+use warnings;                   # Replacement for the -w flag, but lexically scoped
+use File::Spec;                 # Portably perform operations on file names
+use File::Find;                 # Load functions to traverse a directory tree
+use File::Copy;
+
+## This function takes the path for the root of a package as argument and creates
+## a directory tree ready to be packaged on the current working directory.
+##
+## It expects the following:
+##
+##  -root--->deprecated---> .m files
+##        |
+##        |-> inst-------->subpkg1--->src---------> .cc/.h/Makefile files
+##        |           |            |
+##        |           |            |->deprecated--> .m files
+##        |           |            |
+##        |           |            |->private-----> .m files
+##        |           |            |
+##        |           |            -> .m files
+##        |           |
+##        |           |--->subpkg2--->same structure as subpkg1
+##        |           |--->subpkg3--->same structure as subpkg1
+##        |          ...
+##        |           |--->subpkgn
+##        |
+##        |-> src
+##
+##   * it will mix all Makefile it finds and merge them into a $root/src/Makefile.
+##      This file should then be adjusted by the package mantainer. A Makefile
+##      can already exist at $root/src and the others will be appended. If the
+##      Makefiles are written with this on mind, it can save having to fix it
+##
+##   * if the deprecated/src/private directories are empty at the end, the script
+##      removes them
+##
+##   * it's possible that $root/inst/private directory already exists inside
+##      inst/, as well as some .m files inside inst/ and .cc files inside src/
+
+my $dev   = $ARGV[0];
+my $root  = get_export_dir ($dev);
+
+my @command = ("svn", "export", $dev, $root);
+system(@command) == 0 or die "system @command failed: $?";
+
+find(\&rm_svnignore, $root);   # a little cleaning up
+
+my $inst        = File::Spec->catdir($root, "inst");
+my $deprecated  = File::Spec->catdir($root, "deprecated");
+my $src         = File::Spec->catdir($root, "src");
+my $private     = File::Spec->catdir($inst, "private");
+
+## create them if they don't exist
+-e $_ || mkdir $_ for ($inst, $deprecated, $src, $private);
+
+opendir(my $INST, $inst) or die "Can't opendir $inst: $!";
+while (my $subpkg = readdir($INST)) {
+  next if $subpkg =~ /^\.\.?$/;
+  next if $subpkg =~ /^private$/;
+
+  my $subpkg_path = File::Spec->catdir($inst, $subpkg);
+  opendir(my $SUBPKG, $subpkg_path) or die "Can't opendir $subpkg_path: $!";
+  while (my $file = readdir($SUBPKG)) {
+    next if $file =~ /^\.\.?$/;
+
+    my $old = File::Spec->catdir($inst, $subpkg, $file);
+    my $new;
+    if ($file =~ /^deprecated$/) {
+      $new = File::Spec->catdir($deprecated);
+    } elsif ($file =~ /^private$/) {
+      copy_private ($old, $private);
+      next;
+    } elsif ($file =~ /^src$/) {
+      my @makefile = copy_src ($old, $src);
+      my $makefile = File::Spec->catdir($src, "Makefile");
+      open(my $MAKEFILE, ">>", $makefile) or die "Couldn't open $makefile for reading: $!\n";
+      print {$MAKEFILE} $_ for @makefile;
+      close($MAKEFILE);
+      next;
+    } else {
+      $new = File::Spec->catdir($inst, $file);
+    }
+    move ($old, $new) or warn "Can't move $old to $new: $!";
+  }
+  closedir($SUBPKG);
+  rmdir $subpkg_path or warn "Could not rmdir $subpkg_path: $!";
+}
+closedir($INST);
+
+## if they were not necessary(are still empty, remove them
+rm_if_empty ($_) for ($inst, $deprecated, $src, $private);
+exit;
+
+################################################################################
+## Subroutines from this point on
+
+sub get_export_dir {
+  my @dirs = File::Spec->splitdir($_[0]);
+  pop @dirs if $dirs[-1] eq "";                 # because it will be empty string if given path ended in filesep
+  die "Export path '$dirs[-1]' already exist" if -e $dirs[-1];
+  return $dirs[-1];
+}
+
+sub rm_svnignore {
+  ## $_ is file path relative to pwd (always changing)
+  ## $path is relative to working directory where script started
+  my $path = $File::Find::name;
+  unlink $_ or warn "Could not unlink $path: $!" if $_ =~ m/^\.svnignore$/;
+}
+
+sub copy_private {
+  my ($old_private, $new_private) = @_;
+  opendir(my $PRIVATE, $old_private) or die "Can't opendir $old_private: $!";
+  while (my $file = readdir($PRIVATE)) {
+    next if $file =~ /^\.\.?$/;
+
+    my $old = File::Spec->catdir($old_private, $file);
+    my $new = File::Spec->catdir($new_private, $file);
+    if ($file =~ /^private$/) {
+      copy_private ($old, $new);
+    } else {
+      move ($old, $new) or warn "Can't move $old to $new: $!";
+    }
+  }
+  closedir($PRIVATE);
+  rmdir $old_private or warn "Could not rmdir $old_private: $!";
+}
+
+sub copy_src {
+  my ($old_src, $new_src) = @_;
+  my @makefile;
+  opendir(my $SRC, $old_src) or die "Can't opendir $old_src: $!";
+  while (my $source = readdir($SRC)) {
+    next if $source =~ /^\.\.?$/;
+    if ($source =~ /^Makefile$/) {
+      my $path = File::Spec->catdir($old_src, $source);
+      open(my $MAKEFILE, "<", $path) or die "Couldn't open $path for reading: $!\n";
+      @makefile = <$MAKEFILE>;
+      close($MAKEFILE);
+      unlink $path or warn "Could not unlink $path: $!";
+    } else {
+      my $old = File::Spec->catdir($old_src, $source);
+      my $new = File::Spec->catdir($new_src, $source);
+      move ($old, $new) or warn "Can't move $old to $new: $!";
+    }
+  }
+  closedir($SRC);
+  rmdir $old_src or warn "Could not rmdir $old_src: $!";
+  return @makefile;
+}
+
+sub rm_if_empty {
+  my $counter = 0;
+  opendir(my $DIR, $_[0]) or die "Can't opendir $_[0]: $!";
+  while (my $file = readdir($DIR) && $counter == 0) {
+    next if $file =~ /^\.\.?$/;
+    $counter++;
+  }
+  closedir ($DIR);
+  rmdir $_[0] or warn "Could not rmdir $_[0]: $!" if $counter == 0;
+}