diff --git a/TODO b/TODO index d9897bd..0711cdd 100644 --- a/TODO +++ b/TODO @@ -1,3 +1,3 @@ - Differentiate multiple similar matches (show path or repository label) - Recognize file idioms such as './file.rb' and matching "./file/" @done -- Custom recipes \ No newline at end of file +- Custom recipes @done \ No newline at end of file diff --git a/bin/qw b/bin/qw index 6747ade..5e21060 100755 --- a/bin/qw +++ b/bin/qw @@ -4,24 +4,17 @@ $:.unshift File.dirname(__FILE__) + '/../lib' # Require it require "qwandry.rb" -recipe_paths = Dir[ - (ENV['HOME']||'')+'/.qwandry/*.rb', # custom recipes - File.dirname(__FILE__)+'/../lib/qwandry/recipes/*.rb', # built in recipes -] +recipes = Qwandry::Recipe.load_recipes opts = OptionParser.new do |opts| opts.banner = "Usage: qwandry [options] name" opts.separator "" - recipe_names = recipe_paths.map{|path| File.basename(path,'.rb')}.uniq - opts.on("-r", "--recipe RECIPE", "Use paths from RECIPE","Recipes:", *recipe_names.map{|k| "* #{k}"}) do |recipe| - if recipe_names.include?(recipe) - @recipe = recipe - else - STDERR.puts "Recipe '#{recipe}' is not available, using default." - end + opts.on("-r", "--recipe RECIPE", "Use paths from RECIPE","Recipes:", *recipes.map{|r| "* #{r.name}: #{r.description}"}) do |recipe| + @recipe_name = recipe end + opts.separator "" opts.on("-e", "--editor EDITOR", "Use EDITOR to open the package") do |editor| @editor = editor end @@ -45,14 +38,21 @@ end @qwandry.editor = @editor if @editor # Load recipe -@recipe ||= 'default' -@recipe_path = recipe_paths.find{|p| File.basename(p,'.rb') == @recipe } -unless @recipe_path - STDERR.puts "Could not find recipe '#{@recipe}'" +@recipe_name ||= ENV['QW_DEFAULT'] || 'default' +@recipe = recipes.find{|r| r.name.downcase == @recipe_name } + +unless @recipe + STDERR.puts "Could not find recipe '#{@recipe_name}'" exit(1) end -# Configure @qwandry -@qwandry.instance_eval(File.read(@recipe_path) ) + +# Configure Qwandry +@recipe.new.configure(@qwandry) + +# Warn if there are no repositories +if @qwandry.repositories.empty? + STDERR.puts "Warning: no repositories were defined in '#{@recipe_path}'" +end name = ARGV.pop packages = @qwandry.find(name) diff --git a/lib/qwandry.rb b/lib/qwandry.rb index 5a6dd47..1d1084c 100644 --- a/lib/qwandry.rb +++ b/lib/qwandry.rb @@ -19,4 +19,5 @@ module Qwandry autoload :FlatRepository, "qwandry/flat_repository" autoload :LibraryRepository, "qwandry/library_repository" autoload :Package, "qwandry/package" + autoload :Recipe, "qwandry/recipe" end \ No newline at end of file diff --git a/lib/qwandry/launcher.rb b/lib/qwandry/launcher.rb index 177713c..9e85e1d 100644 --- a/lib/qwandry/launcher.rb +++ b/lib/qwandry/launcher.rb @@ -16,8 +16,12 @@ module Qwandry # `label` is used to label packages residing in the folder `path`. # The `repository_type` controls the class used to index the `path`. def add(label, path, repository_type=Qwandry::FlatRepository) - label = label.to_s - @repositories[label] << repository_type.new(label, path) + if path.is_a?(Array) + path.each{|p| add label, p, repository_type} + else + label = label.to_s + @repositories[label] << repository_type.new(label, path) + end end # Searches all of the loaded repositories for `name` diff --git a/lib/qwandry/recipe.rb b/lib/qwandry/recipe.rb new file mode 100644 index 0000000..5a09519 --- /dev/null +++ b/lib/qwandry/recipe.rb @@ -0,0 +1,36 @@ +class Qwandry::Recipe + class << self + + def name(v=nil) + if v + @name = v + else + @name || self.to_s + end + end + + def description(v=nil) + if v + @description = v + else + @description || "" + end + end + end + + + # Recipes should implement the `configure` method. + def configure(qw) + + end + + + def self.load_recipes + # Load all required recipes: + Dir[File.dirname(__FILE__) + '/recipes/*.rb'].map do |recipe_path| + require recipe_path + class_name = File.basename(recipe_path,'.rb').split('_').map{|w| w.capitalize}.join + Qwandry.const_get(class_name) + end + end +end \ No newline at end of file diff --git a/lib/qwandry/recipes/default.rb b/lib/qwandry/recipes/default.rb index 2e2012f..e0629ff 100644 --- a/lib/qwandry/recipes/default.rb +++ b/lib/qwandry/recipes/default.rb @@ -3,18 +3,25 @@ # Ensure that rubygems is on the path so we can search it require 'rubygems' -# Get all the paths on ruby's load path: -paths = $: +class Qwandry::Default < Qwandry::Recipe + name "Default" + description "Searches the ruby standard library and ruby gems" + + def configure(qw) + # Get all the paths on ruby's load path: + paths = $: -# Reject binary paths, we only want ruby sources: -paths = paths.reject{|path| path =~ /#{RUBY_PLATFORM}$/} + # Reject binary paths, we only want ruby sources: + paths = paths.reject{|path| path =~ /#{RUBY_PLATFORM}$/} -# Add ruby standard libraries: -paths.grep(/lib\/ruby/).each do |path| - add :ruby, path, Qwandry::LibraryRepository -end + # Add ruby standard libraries: + paths.grep(/lib\/ruby/).each do |path| + qw.add :ruby, path, Qwandry::LibraryRepository + end -# Add gem repositories: -($:).grep(/gems/).map{|p| p[/.+\/gems\//]}.uniq.each do |path| - add :gem, path + # Add gem repositories: + ($:).grep(/gems/).map{|p| p[/.+\/gems\//]}.uniq.each do |path| + qw.add :gem, path + end + end end \ No newline at end of file