[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

adding Ruby module dependencies to rpm



Hi,

The following patch against CVS and the two new files I've attached
(ruby.req and ruby.prov) add support for determining Ruby module
dependencies at build time in the same way that Perl package
dependencies are currently determined.

Indeed, the code used for ruby.req and ruby.prov is adapted from that of
perl.req and perl.prov by Ken Estes. I considered rewriting the new Ruby
versions in Ruby itself, but I reasoned that there was value to not
requiring Ruby to be on the build system.

I've tested the mechanism against several Ruby module RPMs that I've
created and the dependencies seem to get determined pretty
intelligently. Occasionally, the system gets it wrong when a variable
needs to be interpolated as part of a 'require' or 'load', but this is a
rare enough occurrence that it doesn't detract from the usefulness of
the feature.

The new ruby.req and ruby.prov should be added to the rpm/scripts
subdirectory of the CVS tree.

Jeff, is there any chance of this being committed to CVS?

Ian
-- 
Ian Macdonald               | As President I have to go vacuum my coin
ian@caliban.org             | collection! 
                            | 
                            | 
                            | 
Index: ./autodeps/linux.prov
===================================================================
RCS file: /cvs/devel/rpm/autodeps/linux.prov,v
retrieving revision 1.14
diff -u -u -r1.14 linux.prov
--- ./autodeps/linux.prov	8 Apr 2002 19:13:35 -0000	1.14
+++ ./autodeps/linux.prov	12 Jan 2003 10:21:00 -0000
@@ -58,4 +58,9 @@
 [ -x /usr/lib/rpm/tcl.prov -a -n "$tcllist" ] &&
     echo $tcllist | tr '[:blank:]' \\n | /usr/lib/rpm/tcl.prov | sort -u
 
+#
+# --- ruby modules.
+[ -x /usr/lib/rpm/ruby.prov ] &&
+    echo $filelist | tr '[:blank:]' \\n | grep '\.rb$' | /usr/lib/rpm/ruby.prov | sort -u
+
 exit 0
Index: ./autodeps/linux.req
===================================================================
RCS file: /cvs/devel/rpm/autodeps/linux.req,v
retrieving revision 1.33
diff -u -u -r1.33 linux.req
--- ./autodeps/linux.req	14 Nov 2002 12:53:11 -0000	1.33
+++ ./autodeps/linux.req	12 Jan 2003 10:21:00 -0000
@@ -2,7 +2,7 @@
 
 #
 # Auto-generate requirements for executables (both ELF and a.out) and library
-# sonames, script interpreters, and perl modules.
+# sonames, script interpreters, Perl modules and Ruby libraries.
 #
 
 ulimit -c 0
@@ -31,6 +31,7 @@
 perllist=
 pythonlist=
 tcllist=
+rubylist=
 
 #
 # --- Alpha does not mark 64bit dependencies
@@ -77,6 +78,7 @@
     interplist="$interplist $interp"
     case $interp in
     */perl)	perllist="$perllist $f" ;;
+    */ruby)	rubylist="$rubylist $f" ;;
     esac
 done
 [ -n "$interplist" ] && { echo "$interplist" | tr '[:blank:]' \\n | sort -u ; }
@@ -88,6 +90,12 @@
 done
 
 #
+# --- Add Ruby module files to rubylist.
+for f in $filelist; do
+    [ -r $f -a "${f%.rb}" != "${f}" ] && rubylist="$rubylist $f"
+done
+
+#
 # --- Weak symbol versions (from glibc).
 [ -n "$mark64" ] && mark64="(64bit)"
 for f in $liblist $exelist ; do
@@ -130,5 +138,10 @@
 # --- Tcl modules.
 [ -x /usr/lib/rpm/tcl.req -a -n "$tcllist" ] && \
     echo $tcllist | tr '[:blank:]' \\n | /usr/lib/rpm/tcl.req | sort -u
+
+#
+# --- Ruby modules.
+[ -x /usr/lib/rpm/ruby.req -a -n "$rubylist" ] && \
+    echo $rubylist | tr '[:blank:]' \\n | /usr/lib/rpm/ruby.req | sort -u
 
 exit 0
#!/usr/bin/perl

# RPM (and it's source code) is covered under two separate licenses.

# The entire code base may be distributed under the terms of the GNU
# General Public License (GPL), which appears immediately below.
# Alternatively, all of the source code in the lib subdirectory of the
# RPM source code distribution as well as any code derived from that
# code may instead be distributed under the GNU Library General Public
# License (LGPL), at the choice of the distributor. The complete text
# of the LGPL appears at the bottom of this file.

# This alternative is allowed to enable applications to be linked
# against the RPM library (commonly called librpm) without forcing
# such applications to be distributed under the GPL.

# Any questions regarding the licensing of RPM should be addressed to
# Erik Troan <ewt@redhat.com>.

# a simple script to print the proper name for Ruby libraries.

# The filenames to scan are either passed on the command line or if
# that is empty they are passed via stdin.

# If there are lines in the file which match the pattern
#      (m/^\s*VERSION\s*=\s+/)
# then these are taken to be the version numbers of the modules.
# Special care is taken with a few known idioms for specifying version
# numbers of files under rcs/cvs control.

# If there are strings in the file which match the pattern
#     m/^\s*RPM_Provides\s*=\s*["'](.*)['"]/i
# then these are treated as additional names which are provided by the
# file and are printed as well.

# adapted from a script by Ken Estes Mail.com kestes@staff.mail.com
# by Ian Macdonald <ian@caliban.org>

if ("@ARGV") {
  foreach (@ARGV) {
    process_file($_);
  }
} else {

  # notice we are passed a list of filenames NOT as common in unix the
  # contents of the file.

  foreach (<>) {
    process_file($_);
  }
}


foreach $module (sort keys %require) {
  if (length($require{$module}) == 0) {
    print "ruby($module)\n";
  } else {

    # I am not using rpm3.0 so I do not want spaces arround my
    # operators. Also I will need to change the processing of the
    # RPM_* variable when I upgrade.

    print "ruby($module) = $require{$module}\n";
  }
}

exit 0;



sub process_file {

  my ($file) = @_;
  chomp $file;
  
  open(FILE, "<$file") || return;

  my ($package, $version) = ();

  while (<FILE>) {
    
    # skip the documentation

    next if m/^=begin/ .. m/^=end/;

    # skip the data section
    if (m/^__(DATA|END)__$/) {
      last;
    }

    # not everyone puts the package name of the file as the first
    # package name so we report all namespaces as if they were
    # provided packages (really ugly).

    if (m/^\s*module\s+([_:a-zA-Z0-9]+)\s*;?/) {
      $package=$1;
      undef $version;
      $require{$package}=undef;
    }

    # after we found the package name take the first assignment to
    # VERSION as the version number.

    if ( 
	($package) && 
	(m/^\s*VERSION\s*=\s+/)
       ) {

      # first see if the version string contains the string
      # '$Revision' this often causes bizarre strings and is the most
      # common method of non static numbering.

      if (m/(\$Revision: (\d+[.0-9]+))/) {
	$version= $2; 
      } elsif (m/[\'\"]?(\d+[.0-9]+)[\'\"]?/) {
	
	# look for a static number hard coded in the script
	
	$version= $1; 
      }
      $require{$package}=$version;
    }
    
    # Each keyword can appear multiple times.  Don't
    #  bother with datastructures to store these strings,
    #  if we need to print it print it now.
	
    if ( m/^\s*RPM_Provides\s*=\s*["'](.*)['"]/i) {
      foreach $_ (split(/\s+/, $1)) {
	print "$_\n";
      }
    }

  }

  close(FILE) ||
    die("$0: Could not close file: '$file' : $!\n");

  return ;
}
#!/usr/bin/perl

# RPM (and it's source code) is covered under two separate licenses. 

# The entire code base may be distributed under the terms of the GNU
# General Public License (GPL), which appears immediately below.
# Alternatively, all of the source code in the lib subdirectory of the
# RPM source code distribution as well as any code derived from that
# code may instead be distributed under the GNU Library General Public
# License (LGPL), at the choice of the distributor. The complete text
# of the LGPL appears at the bottom of this file.

# This alternatively is allowed to enable applications to be linked
# against the RPM library (commonly called librpm) without forcing
# such applications to be distributed under the GPL.

# Any questions regarding the licensing of RPM should be addressed to
# Erik Troan <ewt@redhat.com>.

# a simple makedepends like script for Ruby.
 
# The filenames to scan are either passed on the command line or if
# that is empty they are passed via stdin.

# If there are strings in the file which match the pattern
#     m/^\s*RPM_Requires\s*=\s*["'](.*)['"]/i
# then these are treated as additional names which are required by the
# file and are printed as well.

# adapted from a script by Ken Estes Mail.com kestes@staff.mail.com
# by Ian Macdonald <ian@caliban.org>

if ("@ARGV") {
  foreach (@ARGV) {
    process_file($_);
  }
} else {
  
  # notice we are passed a list of filenames NOT as common in unix the
  # contents of the file.
  
  foreach (<>) {
    process_file($_);
  }
}


foreach $module (sort keys %require) {
  if (length($require{$module}) == 0) {
    print "ruby($module)\n";
  } else {

    # I am not using rpm3.0 so I do not want spaces arround my
    # operators. Also I will need to change the processing of the
    # RPM_* variable when I upgrade.

    print "ruby($module) >= $require{$module}\n";
  }
}

exit 0;



sub process_file {
  
  my ($file) = @_;
  chomp $file;
  
  open(FILE, "<$file") || return;
  
  while (<FILE>) {
    
    # skip the documentation

    if ( (m/^=begin/) .. (m/^=end/) ) {
      next;
    }
    
    # skip the data section
    if (m/^__(DATA|END)__$/) {
      last;
    }

    # Each keyword can appear multiple times.  Don't
    #  bother with datastructures to store these strings,
    #  if we need to print it print it now.
    
    if ( m/^\s*RPM_Requires\s*=\s*["'](.*)['"]/i) {
      foreach $_ (split(/\s+/, $1)) {
	print "$_\n";
      }
    }

    if ( 
	(m/^(\s*)         # we hope the inclusion starts the line
	 (require|load)\s+
	 # quotes around name are always legal
	 [\'\"]?([^\;\ \'\"\t]*)[\'\"]?[\t\ ]?
	 /x)
       ) {
      my ($whitespace, $statement, $module) = ($1, $2, $3);

      # we only consider require statements that are flush against
      # the left edge. any other require statements give too many
      # false positives, as they are usually inside of an if statement
      # as a fallback module or a rarely used option

      ($whitespace ne "" && $statement =~ /require|load/) && next;

      # starts with /, which means its an absolute path to a file
      if ($module =~ m(^/)) {
        print "$module\n";
        next;
      }

      # if the module ends with .rb strip it to leave only basename.
      $module =~ s/\.rb$//;

      $require{$module}=$version;
      $line{$module}=$_;
    }
    
  }

  close(FILE) ||
    die("$0: Could not close file: '$file' : $!\n");
  
  return ; 
}

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index] []