# # Copyright (c) 2006-2012 Hal Brodigan (postmodern.mod3 at gmail.com) # # This file is part of Ronin. # # Ronin 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. # # Ronin 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 Ronin. If not, see . # require 'set' module Ronin # # The {Installation} module provides methods which help reflect on the # installation of Ronin on the system. # module Installation # The loaded gemspecs of all installed ronin libraries @gems = {} @paths = Set[] # # Finds the installed Ronin libraries via RubyGems. # # @return [Hash{String => Gem::Specification}] # The names and gem-specs of the installed Ronin libraries. # # @since 1.0.0 # # @api semipublic # def Installation.gems load! if @gems.empty? return @gems end # # The paths of the installed Ronin libraries. # # @return [Set] # The paths of the Ronin libraries. # # @since 1.0.1 # # @api semipublic # def Installation.paths load! if @paths.empty? return @paths end # # The names of the additional Ronin libraries installed on the system. # # @return [Array] # The library names. # # @since 1.0.0 # # @api semipublic # def Installation.libraries gems.keys end # # Enumerates over all files within a given directory found in any # of the installed Ronin libraries. # # @param [String] pattern # The glob pattern to search for. # # @yield [file] # The given block will be passed each file found within the directory. # # @yieldparam [String] file # The sub-path to the file found within the directory. # # @return [Enumerator] # Returns an Enumerator if no block is given. # # @since 1.0.0 # # @api semipublic # def Installation.each_file(pattern) return enum_for(:each_file,pattern) unless block_given? # query the installed gems paths.each do |gem_path| slice_index = gem_path.length + 1 Dir.glob(File.join(gem_path,pattern)) do |path| yield path[slice_index..-1] end end return nil end # # Enumerates over every file in a directory. # # @param [String] directory # The directory to search within. # # @param [String, Symbol] ext # The optional file extension to search for. # # @yield [name] # The given block will be passed each matching file-name. # # @yieldparam [String] name # The basename of the matching path within the directory. # # @return [Enumerator] # If no block is given, an Enumerator will be returned. # # @since 1.0.0 # # @api semipublic # def Installation.each_file_in(directory,ext=nil) return enum_for(:each_file_in,directory,ext) unless block_given? pattern = File.join(directory,'**','*') pattern << ".#{ext}" if ext slice_index = directory.length + 1 each_file(pattern) do |path| yield path[slice_index..-1] end end protected # # Finds the installed Ronin gems. # # @return [true] # All Ronin libraries were successfully found. # # @since 1.0.1 # # @api private # def Installation.load_gems! register_gem = lambda { |gem| @gems[gem.name] = gem @paths << gem.full_gem_path } ronin_gem = Gem.loaded_specs['ronin'] # add the main ronin gem register_gem[ronin_gem] # add any dependent gems ronin_gem.dependent_gems.each do |gems| register_gem[gems[0]] end return true end # # Loads the gemspecs of Ronin libraries from the `$LOAD_PATH`. # # @return [true] # All Ronin gemspecs were successfully found. # # @since 1.0.0 # # @api private # def Installation.load_gemspecs! $LOAD_PATH.each do |lib_dir| root_dir = File.expand_path(File.join(lib_dir,'..')) gemspec_path = Dir[File.join(root_dir,'ronin*.gemspec')][0] if gemspec_path # switch into the gem directory, before loading the gemspec gem = Dir.chdir(root_dir) do Gem::Specification.load(gemspec_path) end # do not add duplicate ronin gems unless @gems.has_key?(gem.name) @gems[gem.name] = gem @paths << root_dir end end end return true end # # Finds the installed Ronin libraries. # # @return [true] # All Ronin libraries were successfully found. # # @since 1.0.1 # # @api private # def Installation.load! if Gem.loaded_specs.has_key?('ronin') load_gems! else load_gemspecs! end end end end