class Dependency

Constants

DIRSEP
SEP

Attributes

graph[R]

Public Instance Methods

execute() click to toggle source
# File examples/rdep-rgl.rb, line 280
def execute
  @has_dep      = false
  @warnfiles    = []
  @newdirs      = []
  @inpath       = []
  @cantfind     = []
  @suffixes     = [""] + %w[ .rb .o .so .dll ]
  @rdirs        = []
  @global_found = []
  @graph        = RGL::DirectedAdjacencyGraph.new

  # No parameters? Usage message

  if not ARGV[0]
    puts "Usage: ruby rdep.rb sourcefile [searchroot]"
    exit 0
  end

  # Does sourcefile exist?

  if !test ?e, ARGV[0]
    puts "#{ARGV[0]} does not exist."
    exit 1
  end

  # Is sourcefile a "real" file?

  if !test ?f, ARGV[0]
    puts "#{ARGV[0]} is not a regular file."
    exit 2
  end

  # Be sure to search under the dir where the
  # program lives...

  @proghome = File.dirname(File.expand_path(ARGV[0]))
  if @proghome != File.expand_path(".")
    $: << @proghome
  end

  # Get list of dirs in $:

  @search_path = $:
  @search_path.collect! { |x| x[-1] == SEP ? x : x + SEP }

  # All real work happens here -- big recursive find

  find_files(ARGV[0])

  @warnfiles.uniq!
  @cantfind.uniq!
  @newdirs.uniq!
  @inpath.map! { |x| File.expand_path(x) }
  @inpath.uniq!

  #
  # Now, what are all the results? Report to user.
  #

  if @inpath[0]
    print_list("Found in search path:", @inpath)
    if !@cantfind.empty? && @warnfiles.empty?
      puts "This will probably be sufficient.\n"
    end
  end

  # Did we use any dirs under the "home"?

  homedirs = @inpath.find_all { |x| x =~ Regexp.new("^"+@proghome) }
  if homedirs[0] # not empty
    homedirs.map! { |x| File.dirname(x) }.uniq!
    puts "Consider adding these directories to RUBYPATH:\n\n"
    homedirs.each { |x| puts "  #{x}" }
    puts
    if @warnfiles[0] and homedirs == [] # There are unparseable statements.
      puts "This will probably NOT be sufficient. See below.\n\n"
    end
  end

  # What's our opinion?

  if @cantfind[0] # There are unknown files.
    puts "This will probably NOT be sufficient. See below.\n\n"
  elsif @warnfiles[0] and homedirs == [] # There are unparseable statements.
    puts "Files may still be missing. See below.\n\n"
  else # We think everything is OK.
    puts "This will probably be sufficient."
  end

  # Report unknown files
  print_list("Not located anywhere:", @cantfind)

  # Print warning about load/require strings we couldn't understand
  print_list("Warning: Unparseable usages of 'load' or 'require' in:",
             @warnfiles)
end
find_files(source) click to toggle source

#find_files - The heart of the program. Search for files using $:

# File examples/rdep-rgl.rb, line 187
def find_files(source)
  # loadable - This file or some variant can be found in one of the
  #            directories in $:
  loadable = false

  files = [] # Save a list of load/require files.
  found = [] # Save a list of files found (.rb only for now)

  # Open the file, strip embedded docs, and look for load/require statements.

  begin
    File.open(source).doc_skip { |line| files << scan(line) }
  rescue => err
    puts "Problem processing file #{source}: #{err}"
    caller.each { |x| puts "  #{x}" }
    exit 3
  end

  # If no dependencies, don't bother searching!
  if !@has_dep
    puts "No dependencies found."
    exit 0
  end

  files.compact!
  catch(:skip) do
    for file in files

      if file == "" # Warning
        @warnfiles << source
        next
      end

      throw :skip if (@inpath.include? file) || (@cantfind.include? file)

      if file =~ /\.rb$/ # Don't add suffix to *.rb
        suffixes = [""] # Hmm... .rbw?? Probably not needed.
      else
        suffixes = @suffixes # Use any suffix (extension)
      end

      # Look through search path (@search_path)

      for dir in @search_path

        for suf in suffixes
          filename = dir + file + suf
          loadable = test ?e, filename
          break if loadable
        end

        if loadable
          @inpath << filename # Files we found in RUBYLIB
                              # Add to 'found' if it's a source file (so we can recurse)
          found << filename if filename =~ /\.rb$/
          break
        end

      end

      @cantfind << file if !loadable
    end
  end

  found.uniq!
  found.compact!

  @graph.add_vertex(source)

  list = found
  found.each { |x|
    @graph.add_edge(source, x)
    list += find_files(x)
  }

  list
end
print_list(header, list) click to toggle source

#print_list - Print a header message followed by a list of files

or directories.
scan(line) click to toggle source

scan - Scans a line and returns the filename from a load or require

statement. Returns null string if there was a parsing problem.
Returns nil if this is not a load or require.
# File examples/rdep-rgl.rb, line 162
def scan(line)
  line.strip!
  if line =~ /^load/ or line =~ /^auto/ or line =~ /^require/
    @has_dep = true # At least one dependency found.
                    # Kludge!!
    junk = %w[ require load autoload ( ) , ] + [""]
    temp = line.split(/[ \t\(\),]/) - junk
    if temp[2] and temp[2][0].chr =~ /[#;]/ # Comments, semi...
      temp = temp[0..1]
    end
    if temp[-1] =~ /\#\{/ # #{} means trouble
      str = ""
    else
      str = unquote(temp[-1]) # May return nil.
    end
    str
  else
    nil
  end
end
unquote(str) click to toggle source

unquote - Find the value of a string. Called from scan.

# File examples/rdep-rgl.rb, line 146
def unquote(str)
  # Still more kludgy code.
  return nil if str == nil
  if [?', ?"].include? str[0] # ' Unconfuse gvim
    str = str[1..-2]
  else
    ""
  end
end