globby 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +9 -3
- data/lib/globby.rb +19 -25
- data/lib/globby/glob.rb +2 -2
- data/lib/globby/globject.rb +18 -0
- data/lib/globby/result.rb +20 -0
- data/spec/gitignore_spec.rb +7 -7
- data/spec/globby_spec.rb +12 -2
- metadata +6 -4
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# globby
|
2
2
|
|
3
|
-
globby is a [`.gitignore`](http://www.kernel.org/pub/software/scm/git/docs/gitignore.html)-
|
3
|
+
globby is a [`.gitignore`](http://www.kernel.org/pub/software/scm/git/docs/gitignore.html)-style
|
4
4
|
file globber for ruby.
|
5
5
|
|
6
6
|
## Installation
|
@@ -9,8 +9,14 @@ Put `gem 'globby'` in your Gemfile.
|
|
9
9
|
|
10
10
|
## Usage
|
11
11
|
|
12
|
-
|
13
|
-
Globby.
|
12
|
+
# all files matched by the rules
|
13
|
+
Globby.select(rules)
|
14
|
+
|
15
|
+
# all other files
|
16
|
+
Globby.reject(rules)
|
17
|
+
|
18
|
+
# ooh chaining!
|
19
|
+
Globby.select(rules).reject(other_rules)
|
14
20
|
|
15
21
|
### An example:
|
16
22
|
|
data/lib/globby.rb
CHANGED
@@ -1,27 +1,29 @@
|
|
1
1
|
require 'set'
|
2
2
|
require '../globby/lib/globby/glob'
|
3
|
+
require '../globby/lib/globby/globject'
|
4
|
+
require '../globby/lib/globby/result'
|
3
5
|
|
4
6
|
module Globby
|
5
7
|
class << self
|
6
|
-
def select(patterns, source =
|
8
|
+
def select(patterns, source = GlObject.all)
|
9
|
+
result = GlObject.new
|
7
10
|
evaluate_patterns(patterns, source, result)
|
8
|
-
|
9
|
-
if result
|
11
|
+
|
12
|
+
if result.dirs && result.dirs.size > 0
|
10
13
|
# now go merge/subtract files under directories
|
11
|
-
dir_patterns = result
|
12
|
-
evaluate_patterns(dir_patterns,
|
14
|
+
dir_patterns = result.dirs.map{ |dir| "/#{dir}**" }
|
15
|
+
evaluate_patterns(dir_patterns, GlObject.new(source.files), result)
|
13
16
|
end
|
14
17
|
|
15
|
-
result
|
18
|
+
Result.new result.files, source.dirs
|
16
19
|
end
|
17
|
-
|
18
|
-
def reject(patterns =
|
19
|
-
source
|
20
|
-
(source[:files] - select(patterns, source)).sort
|
20
|
+
|
21
|
+
def reject(patterns, source = GlObject.all)
|
22
|
+
Result.new(source.files - select(patterns, source), source.dirs)
|
21
23
|
end
|
22
|
-
|
24
|
+
|
23
25
|
private
|
24
|
-
|
26
|
+
|
25
27
|
def evaluate_patterns(patterns, source, result)
|
26
28
|
patterns.each do |pattern|
|
27
29
|
next unless pattern =~ /\A[^#]/
|
@@ -34,20 +36,12 @@ module Globby
|
|
34
36
|
method, candidates = glob.inverse? ?
|
35
37
|
[:subtract, result] :
|
36
38
|
[:merge, source]
|
37
|
-
|
38
|
-
dir_matches = glob.match(candidates
|
39
|
+
|
40
|
+
dir_matches = glob.match(candidates.dirs)
|
39
41
|
file_matches = []
|
40
|
-
file_matches = glob.match(candidates
|
41
|
-
result
|
42
|
-
result
|
43
|
-
end
|
44
|
-
|
45
|
-
def get_files_and_dirs
|
46
|
-
files, dirs = Dir.glob('**/*', File::FNM_DOTMATCH).
|
47
|
-
reject { |f| f =~ /(\A|\/)\.\.?\z/ }.
|
48
|
-
partition { |f| File.file?(f) || File.symlink?(f) }
|
49
|
-
dirs.map!{ |d| d + "/" }
|
50
|
-
{:files => files, :dirs => dirs}
|
42
|
+
file_matches = glob.match(candidates.files) unless glob.directory? || glob.exact_match? && !dir_matches.empty?
|
43
|
+
result.dirs.send method, dir_matches unless dir_matches.empty?
|
44
|
+
result.files.send method, file_matches unless file_matches.empty?
|
51
45
|
end
|
52
46
|
end
|
53
47
|
end
|
data/lib/globby/glob.rb
CHANGED
@@ -27,7 +27,7 @@ module Globby
|
|
27
27
|
|
28
28
|
# see https://www.kernel.org/doc/man-pages/online/pages/man7/glob.7.html
|
29
29
|
GLOB_BRACKET_EXPR = /
|
30
|
-
\[ # brackets
|
30
|
+
\[ # brackets
|
31
31
|
!? # (maybe) negation
|
32
32
|
\]? # (maybe) right bracket
|
33
33
|
(?: # one or more:
|
@@ -47,7 +47,7 @@ module Globby
|
|
47
47
|
|
48
48
|
def to_regexp
|
49
49
|
parts = @pattern.split(GLOB_TOKENIZER) - [""]
|
50
|
-
|
50
|
+
|
51
51
|
result = parts.first.sub!(/\A\//, '') ? '\A' : '(\A|/)'
|
52
52
|
parts.each do |part|
|
53
53
|
result << part_to_regexp(part)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Globby
|
2
|
+
class GlObject
|
3
|
+
attr_reader :files, :dirs
|
4
|
+
|
5
|
+
def initialize(files = Set.new, dirs = Set.new)
|
6
|
+
@files = files
|
7
|
+
@dirs = dirs
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.all
|
11
|
+
files, dirs = Dir.glob('**/*', File::FNM_DOTMATCH).
|
12
|
+
reject { |f| f =~ /(\A|\/)\.\.?\z/ }.
|
13
|
+
partition { |f| File.file?(f) || File.symlink?(f) }
|
14
|
+
dirs.map!{ |d| d + "/" }
|
15
|
+
new(files, dirs)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Globby
|
2
|
+
class Result < Array
|
3
|
+
def initialize(files, dirs)
|
4
|
+
@dirs = dirs
|
5
|
+
super files.sort
|
6
|
+
end
|
7
|
+
|
8
|
+
def select(patterns)
|
9
|
+
Globby::select(patterns, to_globject)
|
10
|
+
end
|
11
|
+
|
12
|
+
def reject(patterns)
|
13
|
+
Globby::reject(patterns, to_globject)
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_globject
|
17
|
+
GlObject.new(self, @dirs)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/spec/gitignore_spec.rb
CHANGED
@@ -36,25 +36,25 @@ describe Globby do
|
|
36
36
|
def prepare_gitignore
|
37
37
|
ignore = <<-IGNORE.gsub(/^ +/, '')
|
38
38
|
# here we go...
|
39
|
-
|
39
|
+
|
40
40
|
# some dotfiles
|
41
41
|
.hidden
|
42
|
-
|
42
|
+
|
43
43
|
# html, but just in the root
|
44
44
|
/*.html
|
45
|
-
|
45
|
+
|
46
46
|
# all rb files anywhere
|
47
47
|
*.rb
|
48
|
-
|
48
|
+
|
49
49
|
# except rb files immediately under foobar
|
50
50
|
!foobar/*.rb
|
51
|
-
|
51
|
+
|
52
52
|
# this will match foo/bar but not bar
|
53
53
|
bar/
|
54
|
-
|
54
|
+
|
55
55
|
# this will match nothing
|
56
56
|
foo*bar/baz.pdf
|
57
|
-
|
57
|
+
|
58
58
|
# this will match baz/ and foobar/baz/
|
59
59
|
baz
|
60
60
|
IGNORE
|
data/spec/globby_spec.rb
CHANGED
@@ -3,6 +3,13 @@ require 'globby'
|
|
3
3
|
RSpec.configure { |config| config.mock_framework = :mocha }
|
4
4
|
|
5
5
|
describe Globby do
|
6
|
+
it "should support chaining" do
|
7
|
+
files = files(%w{foo/bar.rb foo/baz.rb foo/c/bar.html foo/c/c/bar.rb})
|
8
|
+
Globby.select(%w{*rb}, files).
|
9
|
+
reject(%w{baz*}).
|
10
|
+
select(%w{c}).should == %w{foo/c/c/bar.rb}
|
11
|
+
end
|
12
|
+
|
6
13
|
describe ".select" do
|
7
14
|
context "a blank line" do
|
8
15
|
it "should return nothing" do
|
@@ -79,7 +86,10 @@ describe Globby do
|
|
79
86
|
def files(files)
|
80
87
|
files = Array(files)
|
81
88
|
files.sort!
|
82
|
-
dirs = files.grep(/\//).map { |file|
|
83
|
-
|
89
|
+
dirs = files.grep(/\//).map(&:dup).inject([]) { |ary, file|
|
90
|
+
ary << file while file.sub!(/[^\/]+\z/, '')
|
91
|
+
ary
|
92
|
+
}.uniq.sort
|
93
|
+
Globby::GlObject.new files, dirs
|
84
94
|
end
|
85
95
|
end
|
metadata
CHANGED
@@ -5,9 +5,9 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.2
|
10
|
+
version: 0.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jon Jensen
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2013-01-
|
18
|
+
date: 2013-01-29 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description: find files using .gitignore-style globs
|
@@ -31,6 +31,8 @@ files:
|
|
31
31
|
- Rakefile
|
32
32
|
- README.md
|
33
33
|
- lib/globby/glob.rb
|
34
|
+
- lib/globby/globject.rb
|
35
|
+
- lib/globby/result.rb
|
34
36
|
- lib/globby.rb
|
35
37
|
- spec/gitignore_spec.rb
|
36
38
|
- spec/globby_spec.rb
|
@@ -70,7 +72,7 @@ rubyforge_project:
|
|
70
72
|
rubygems_version: 1.8.24
|
71
73
|
signing_key:
|
72
74
|
specification_version: 3
|
73
|
-
summary: .gitignore-
|
75
|
+
summary: .gitignore-style file globber
|
74
76
|
test_files: []
|
75
77
|
|
76
78
|
has_rdoc:
|