hike 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +6 -6
  3. data/lib/hike.rb +1 -1
  4. data/lib/hike/index.rb +53 -13
  5. data/lib/hike/trail.rb +69 -1
  6. metadata +18 -38
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010 Sam Stephenson
1
+ Copyright (c) 2011 Sam Stephenson
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -9,8 +9,8 @@ implement search paths, load paths, and the like.
9
9
  Find Ruby files in this project:
10
10
 
11
11
  trail = Hike::Trail.new "/Users/sam/Projects/hike"
12
- trail.extensions.push ".rb"
13
- trail.paths.push "lib", "test"
12
+ trail.append_extension ".rb"
13
+ trail.append_paths "lib", "test"
14
14
 
15
15
  trail.find "hike/trail"
16
16
  # => "/Users/sam/Projects/hike/lib/hike/trail.rb"
@@ -21,8 +21,8 @@ Find Ruby files in this project:
21
21
  Explore your Ruby load path:
22
22
 
23
23
  trail = Hike::Trail.new "/"
24
- trail.extensions.push ".rb", ".bundle"
25
- trail.paths.replace $:
24
+ trail.append_extensions ".rb", ".bundle"
25
+ trail.append_paths *$:
26
26
 
27
27
  trail.find "net/http"
28
28
  # => "/Users/sam/.rvm/rubies/ree-1.8.7-2010.02/lib/ruby/1.8/net/http.rb"
@@ -33,7 +33,7 @@ Explore your Ruby load path:
33
33
  Explore your shell path:
34
34
 
35
35
  trail = Hike::Trail.new "/"
36
- trail.paths.replace ENV["PATH"].split(":")
36
+ trail.append_paths *ENV["PATH"].split(":")
37
37
 
38
38
  trail.find "ls"
39
39
  # => "/bin/ls"
@@ -47,6 +47,6 @@ Explore your shell path:
47
47
 
48
48
  # License
49
49
 
50
- Copyright (c) 2010 Sam Stephenson.
50
+ Copyright (c) 2011 Sam Stephenson.
51
51
 
52
52
  Released under the MIT license. See `LICENSE` for details.
@@ -1,5 +1,5 @@
1
1
  module Hike
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
 
4
4
  autoload :Extensions, "hike/extensions"
5
5
  autoload :Index, "hike/index"
@@ -11,16 +11,23 @@ module Hike
11
11
  # `Index#extensions` is an immutable `Extensions` collection.
12
12
  attr_reader :extensions
13
13
 
14
+ # `Index#aliases` is an immutable `Hash` mapping an extension to
15
+ # an `Array` of aliases.
16
+ attr_reader :aliases
17
+
14
18
  # `Index.new` is an internal method. Instead of constructing it
15
19
  # directly, create a `Trail` and call `Trail#index`.
16
- def initialize(root, paths, extensions)
20
+ def initialize(root, paths, extensions, aliases)
17
21
  @root = root
18
22
 
19
23
  # Freeze is used here so an error is throw if a mutator method
20
- # is called on the array. Mutating `@paths` or `@extensions`
21
- # would have unpredictable results.
24
+ # is called on the array. Mutating `@paths`, `@extensions`, or
25
+ # `@aliases` would have unpredictable results.
22
26
  @paths = paths.dup.freeze
23
27
  @extensions = extensions.dup.freeze
28
+ @aliases = aliases.inject({}) { |h, (k, a)|
29
+ h[k] = a.dup.freeze; h
30
+ }.freeze
24
31
  @pathnames = paths.map { |path| Pathname.new(path) }
25
32
 
26
33
  @stats = {}
@@ -65,11 +72,12 @@ module Hike
65
72
  end
66
73
  end
67
74
 
68
- # A cached version of `Dir.entries` that filters out `.` and
69
- # `..`. Returns an empty `Array` if the directory does not exist.
75
+ # A cached version of `Dir.entries` that filters out `.` files and
76
+ # `~` swap files. Returns an empty `Array` if the directory does
77
+ # not exist.
70
78
  def entries(path)
71
79
  key = path.to_s
72
- @entries[key] ||= Pathname.new(path).entries.reject { |entry| entry.to_s =~ /^\.\.?$/ }
80
+ @entries[key] ||= Pathname.new(path).entries.reject { |entry| entry.to_s =~ /^\.|~$|^\#.*\#$/ }
73
81
  rescue Errno::ENOENT
74
82
  @entries[key] = []
75
83
  end
@@ -141,23 +149,55 @@ module Hike
141
149
  paths.any? { |path| dirname.to_s[0, path.length] == path }
142
150
  end
143
151
 
152
+ # Cache results of `build_pattern_for`
153
+ def pattern_for(basename)
154
+ @patterns[basename] ||= build_pattern_for(basename)
155
+ end
156
+
144
157
  # Returns a `Regexp` that matches the allowed extensions.
145
158
  #
146
- # pattern_for("index.html") #=> /^index.html(.builder|.erb)+$/
147
- def pattern_for(basename)
148
- @patterns[basename] ||= begin
149
- extension_pattern = extensions.map { |e| Regexp.escape(e) }.join("|")
150
- /^#{Regexp.escape(basename.to_s)}(?:#{extension_pattern}|)+$/
159
+ # pattern_for("index.html") #=> /^index(.html|.htm)(.builder|.erb)*$/
160
+ def build_pattern_for(basename)
161
+ extname = basename.extname
162
+ aliases = find_aliases_for(extname)
163
+
164
+ if aliases.any?
165
+ basename = basename.basename(extname)
166
+ aliases = [extname] + aliases
167
+ aliases_pattern = aliases.map { |e| Regexp.escape(e) }.join("|")
168
+ basename_re = Regexp.escape(basename.to_s) + "(?:#{aliases_pattern})"
169
+ else
170
+ basename_re = Regexp.escape(basename.to_s)
151
171
  end
172
+
173
+ extension_pattern = extensions.map { |e| Regexp.escape(e) }.join("|")
174
+ /^#{basename_re}(?:#{extension_pattern})*$/
152
175
  end
153
176
 
154
177
  # Sorts candidate matches by their extension
155
178
  # priority. Extensions in the front of the `extensions` carry
156
179
  # more weight.
157
180
  def sort_matches(matches, basename)
181
+ aliases = find_aliases_for(basename.extname)
182
+
158
183
  matches.sort_by do |match|
159
- extnames = match.to_s[basename.to_s.length..-1].scan(/.[^.]+/)
160
- extnames.inject(0) { |sum, ext| sum + extensions.index(ext) + 1 }
184
+ extnames = match.sub(basename.to_s, '').to_s.scan(/\.[^.]+/)
185
+ extnames.inject(0) do |sum, ext|
186
+ if i = extensions.index(ext)
187
+ sum + i + 1
188
+ elsif i = aliases.index(ext)
189
+ sum + i + 11
190
+ else
191
+ sum
192
+ end
193
+ end
194
+ end
195
+ end
196
+
197
+ def find_aliases_for(extension)
198
+ @aliases.inject([]) do |aliases, (key, value)|
199
+ aliases.push(key) if value == extension
200
+ aliases
161
201
  end
162
202
  end
163
203
  end
@@ -28,6 +28,20 @@ module Hike
28
28
  # allows you to require files with specifiying `foo.rb`.
29
29
  attr_reader :extensions
30
30
 
31
+ # `Index#aliases` is a mutable `Hash` mapping an extension to
32
+ # an `Array` of aliases.
33
+ #
34
+ # trail = Hike::Trail.new
35
+ # trail.paths.push "~/Projects/hike/site"
36
+ # trail.aliases['.htm'] = 'html'
37
+ # trail.aliases['.xhtml'] = 'html'
38
+ # trail.aliases['.php'] = 'html'
39
+ #
40
+ # Aliases provide a fallback when the primary extension is not
41
+ # matched. In the example above, a lookup for "foo.html" will
42
+ # check for the existence of "foo.htm", "foo.xhtml", or "foo.php".
43
+ attr_reader :aliases
44
+
31
45
  # A Trail accepts an optional root path that defaults to your
32
46
  # current working directory. Any relative paths added to
33
47
  # `Trail#paths` will expanded relative to the root.
@@ -35,6 +49,7 @@ module Hike
35
49
  @root = Pathname.new(root).expand_path
36
50
  @paths = Paths.new(@root)
37
51
  @extensions = Extensions.new
52
+ @aliases = Hash.new { |h, k| h[k] = Extensions.new }
38
53
  end
39
54
 
40
55
  # `Trail#root` returns root path as a `String`. This attribute is immutable.
@@ -42,6 +57,50 @@ module Hike
42
57
  @root.to_s
43
58
  end
44
59
 
60
+ # Prepend `path` to `Paths` collection
61
+ def prepend_paths(*paths)
62
+ self.paths.unshift(*paths)
63
+ end
64
+ alias_method :prepend_path, :prepend_paths
65
+
66
+ # Append `path` to `Paths` collection
67
+ def append_paths(*paths)
68
+ self.paths.push(*paths)
69
+ end
70
+ alias_method :append_path, :append_paths
71
+
72
+ # Remove `path` from `Paths` collection
73
+ def remove_path(path)
74
+ self.paths.delete(path)
75
+ end
76
+
77
+ # Prepend `extension` to `Extensions` collection
78
+ def prepend_extensions(*extensions)
79
+ self.extensions.unshift(*extensions)
80
+ end
81
+ alias_method :prepend_extension, :prepend_extensions
82
+
83
+ # Append `extension` to `Extensions` collection
84
+ def append_extensions(*extensions)
85
+ self.extensions.push(*extensions)
86
+ end
87
+ alias_method :append_extension, :append_extensions
88
+
89
+ # Remove `extension` from `Extensions` collection
90
+ def remove_extension(extension)
91
+ self.extensions.delete(extension)
92
+ end
93
+
94
+ # Alias `new_extension` to `old_extension`
95
+ def alias_extension(new_extension, old_extension)
96
+ aliases[normalize_extension(new_extension)] = normalize_extension(old_extension)
97
+ end
98
+
99
+ # Remove the alias for `extension`
100
+ def unalias_extension(extension)
101
+ aliases.delete(normalize_extension(extension))
102
+ end
103
+
45
104
  # `Trail#find` returns a the expand path for a logical path in the
46
105
  # path collection.
47
106
  #
@@ -91,7 +150,7 @@ module Hike
91
150
  # index.find "test_trail"
92
151
  #
93
152
  def index
94
- Index.new(root, paths, extensions)
153
+ Index.new(root, paths, extensions, aliases)
95
154
  end
96
155
 
97
156
  # `Trail#entries` is equivalent to `Dir#entries`. It is not
@@ -107,5 +166,14 @@ module Hike
107
166
  def stat(*args)
108
167
  index.stat(*args)
109
168
  end
169
+
170
+ private
171
+ def normalize_extension(extension)
172
+ if extension[/^\./]
173
+ extension
174
+ else
175
+ ".#{extension}"
176
+ end
177
+ end
110
178
  end
111
179
  end
metadata CHANGED
@@ -1,34 +1,24 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: hike
3
- version: !ruby/object:Gem::Version
4
- hash: 19
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0
5
5
  prerelease:
6
- segments:
7
- - 1
8
- - 1
9
- - 0
10
- version: 1.1.0
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Sam Stephenson
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-06-14 00:00:00 -05:00
12
+ date: 2011-07-18 00:00:00.000000000 -05:00
19
13
  default_executable:
20
14
  dependencies: []
21
-
22
15
  description: A Ruby library for finding files in a set of paths.
23
- email:
16
+ email:
24
17
  - sstephenson@gmail.com
25
18
  executables: []
26
-
27
19
  extensions: []
28
-
29
20
  extra_rdoc_files: []
30
-
31
- files:
21
+ files:
32
22
  - README.md
33
23
  - LICENSE
34
24
  - lib/hike/extensions.rb
@@ -40,36 +30,26 @@ files:
40
30
  has_rdoc: true
41
31
  homepage: http://github.com/sstephenson/hike
42
32
  licenses: []
43
-
44
33
  post_install_message:
45
34
  rdoc_options: []
46
-
47
- require_paths:
35
+ require_paths:
48
36
  - lib
49
- required_ruby_version: !ruby/object:Gem::Requirement
37
+ required_ruby_version: !ruby/object:Gem::Requirement
50
38
  none: false
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- hash: 3
55
- segments:
56
- - 0
57
- version: "0"
58
- required_rubygems_version: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ! '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
44
  none: false
60
- requirements:
61
- - - ">="
62
- - !ruby/object:Gem::Version
63
- hash: 3
64
- segments:
65
- - 0
66
- version: "0"
45
+ requirements:
46
+ - - ! '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
67
49
  requirements: []
68
-
69
50
  rubyforge_project:
70
51
  rubygems_version: 1.6.2
71
52
  signing_key:
72
53
  specification_version: 3
73
54
  summary: Find files in a set of paths
74
55
  test_files: []
75
-