More concise file pattern matching.

This commit is contained in:
Adam Sanderson 2010-11-19 09:20:37 -08:00
parent 57157b5c6b
commit e171dafb2c
8 changed files with 58 additions and 23 deletions

7
TODO
View File

@ -1,3 +1,6 @@
- Differentiate multiple similar matches (show path or repository label) - Differentiate multiple similar matches (show path or repository label)
- Recognize file idioms such as './file.rb' and matching "./file/" @done - Allow better customization of repositories
- Custom recipes @done - Filter by pattern, ie: `accept '*.rb'` or `reject '*.o'` @done ... but code be better
- Customize collection phase (see LibraryRepository)
- Customize naming phase
- Match multiword args, ie: activerec 3. => activerec*3.* => activerecord-3.0.3

View File

@ -5,7 +5,7 @@ module Qwandry
class FlatRepository < Qwandry::Repository class FlatRepository < Qwandry::Repository
def scan(name) def scan(name)
results = [] results = []
Dir["#{@path}/*"].select do |path| all_paths.select do |path|
if File.basename(path).start_with?(name) if File.basename(path).start_with?(name)
results << package(File.basename(path), [path]) results << package(File.basename(path), [path])
end end

View File

@ -18,15 +18,22 @@ module Qwandry
custom_configuration! custom_configuration!
end end
# Adds a repository path to Qwandry's Launcher. # Adds a repository path to Qwandry's Launcher. `label` is used to label packages residing in the folder `path`.
# `label` is used to label packages residing in the folder `path`. #
# The `repository_type` controls the class used to index the `path`. # The `options` can be used to customize the repository.
def add(label, path, repository_type=Qwandry::FlatRepository) #
# [:class] Repository class, defaults to Qwandry::FlatRepository
# [:accept] Filters paths, only keeping ones matching the accept option
# [:reject] Filters paths, rejecting any paths matching the reject option
#
# `:accept` and `:reject` take patterns such as '*.py[oc]', procs, and regular expressions.
def add(label, path, options={})
if path.is_a?(Array) if path.is_a?(Array)
path.each{|p| add label, p, repository_type} path.each{|p| add label, p, options}
else else
repository_class = options[:class] || Qwandry::FlatRepository
label = label.to_s label = label.to_s
@repositories[label] << repository_type.new(label, File.expand_path(path)) @repositories[label] << repository_class.new(label, File.expand_path(path), options)
end end
end end
@ -67,7 +74,7 @@ module Qwandry
# Add ruby standard libraries: # Add ruby standard libraries:
paths.grep(/lib\/ruby/).each do |path| paths.grep(/lib\/ruby/).each do |path|
add :ruby, path, Qwandry::LibraryRepository add :ruby, path, :class=>Qwandry::LibraryRepository
end end
# Add gem repositories: # Add gem repositories:

View File

@ -1,13 +1,13 @@
module Qwandry module Qwandry
# Directories look like: # Directories look like:
# lib1.rb # lib1.rb
# ./lib1 # lib1/...
# lib2.py # lib2.py
# ./lib2 # lib2/...
class LibraryRepository < Qwandry::Repository class LibraryRepository < Qwandry::Repository
def scan(name) def scan(name)
results = Hash.new{|h,k| h[k] = package(k)} results = Hash.new{|h,k| h[k] = package(k)}
Dir["#{@path}/*"].select do |path| all_paths.select do |path|
basename = File.basename(path) basename = File.basename(path)
if basename.start_with?(name) if basename.start_with?(name)
# strip any file extension # strip any file extension

View File

@ -1,8 +1,8 @@
module Qwandry module Qwandry
class Package class Package
attr_reader :name attr_reader :name
attr_reader :repository
attr_reader :paths attr_reader :paths
attr_reader :repository
def initialize(name, paths, repository) def initialize(name, paths, repository)
@name = name @name = name

View File

@ -2,18 +2,38 @@ module Qwandry
class Repository class Repository
attr_reader :name attr_reader :name
attr_reader :path attr_reader :path
attr_reader :options
def initialize(name, path) def initialize(name, path, options={})
@name = name @name = name
@path = path.chomp('/') @path = path.chomp('/')
@options = options
end end
def scan(name) def scan(name)
[] []
end end
def all_paths
paths = Dir["#{@path}/*"]
paths = paths.select(&matcher(options[:accept])) if options[:accept]
paths = paths.reject(&matcher(options[:reject])) if options[:reject]
paths
end
def package(name, paths=[]) def package(name, paths=[])
Package.new(name, paths, self) Package.new(name, paths, self)
end end
private
def matcher(pattern)
case pattern
when Regexp then lambda{|p| p =~ pattern}
when String then lambda{|p| File.fnmatch?(pattern, p)}
when Proc then pattern
else raise ArgumentError, "Expected a Regexp, String, or Proc"
end
end
end end
end end

View File

@ -9,18 +9,18 @@ Gem::Specification.new do |s|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Adam Sanderson"] s.authors = ["Adam Sanderson"]
s.date = %q{2010-11-08} s.date = %q{2010-11-19}
s.default_executable = %q{qw} s.default_executable = %q{qw}
s.description = %q{ Open a gem or library's source directory with your default editor. s.description = %q{ Open a gem or library's source directory with your default editor.
} }
s.email = %q{netghost@gmail.com} s.email = %q{netghost@gmail.com}
s.executables = ["qw"] s.executables = ["qw"]
s.extra_rdoc_files = [ s.extra_rdoc_files = [
"README", "README.markdown",
"TODO" "TODO"
] ]
s.files = [ s.files = [
"README", "README.markdown",
"Rakefile", "Rakefile",
"TODO", "TODO",
"VERSION", "VERSION",

View File

@ -34,8 +34,10 @@
# add :ghc, "/usr/local/lib/ghc/" # add :ghc, "/usr/local/lib/ghc/"
# = Python # = Python
# Open python standard libraries: # Open python standard libraries, but ignore the *.pyo and *.pyc files:
# add :python, "/usr/lib/python2.6/", Qwandry::LibraryRepository # add :python, "/usr/lib/python2.6/",
# :class => Qwandry::LibraryRepository,
# :reject => '*.py[oc]'
# = Ruby # = Ruby
# Qwandry comes set up for ruby by default, however you may want to be able to # Qwandry comes set up for ruby by default, however you may want to be able to
@ -45,5 +47,8 @@
# add :cruby, "~/.rvm/src/ruby-1.9.1-p378/" # add :cruby, "~/.rvm/src/ruby-1.9.1-p378/"
# = Javascript / Node # = Javascript / Node
# Edit node.js and npm managed libraries: # Edit node.js and npm managed libraries.
# add :node, "/usr/local/lib/node/" # Configure a :node repository showing only the active versions of each library:
# add :node, "/usr/local/lib/node/", :reject=> /@/
# # Configure a :npm repository showing only the versioned libraries:
# add :npm, "/usr/local/lib/node/", :accept=> /@/