globby 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE.txt +1 -1
- data/README.md +28 -5
- data/lib/globby.rb +43 -44
- data/lib/globby/glob.rb +89 -0
- data/spec/gitignore_spec.rb +100 -0
- data/spec/globby_spec.rb +48 -120
- metadata +6 -4
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,15 +1,23 @@
|
|
1
1
|
# globby
|
2
2
|
|
3
|
-
globby is a [
|
3
|
+
globby is a [`.gitignore`](http://www.kernel.org/pub/software/scm/git/docs/gitignore.html)-compatible
|
4
|
+
file globber for ruby.
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Put `gem 'globby'` in your Gemfile.
|
4
9
|
|
5
10
|
## Usage
|
6
11
|
|
7
|
-
Globby.
|
12
|
+
Globby.select(rules) # all files matched by the rules
|
13
|
+
Globby.reject(rules) # all other files
|
8
14
|
|
9
15
|
### An example:
|
10
16
|
|
11
17
|
> rules = File.read('.gitignore').split(/\n/)
|
12
|
-
|
18
|
+
-> ["Gemfile.lock", "doc", "*.gem"]
|
19
|
+
|
20
|
+
> pp Globby.select(rules)
|
13
21
|
["Gemfile.lock",
|
14
22
|
"doc/Foreigner.html",
|
15
23
|
"doc/Foreigner/Adapter.html",
|
@@ -26,9 +34,24 @@ globby is a [.gitignore](http://www.kernel.org/pub/software/scm/git/docs/gitigno
|
|
26
34
|
with those files.
|
27
35
|
* You're writing a library/tool that will have its own list of ignored/tracked
|
28
36
|
files. My use case is for an I18n library that extracts strings from ruby
|
29
|
-
files... I need to provide users a nice configurable way to
|
37
|
+
files... I need to provide users a nice configurable way to blacklist given
|
30
38
|
files/directories/patterns.
|
31
39
|
|
40
|
+
## Compatibility Notes
|
41
|
+
|
42
|
+
globby is compatible with `.gitignore` rules; it respects negated patterns, and
|
43
|
+
ignores comments or empty patterns. That said, it supports some things that may
|
44
|
+
or may not work in your version of git. These platform-dependent `.gitignore`
|
45
|
+
behaviors are platform independent in globby and can always be used:
|
46
|
+
|
47
|
+
* Recursive wildcards à la ant/zsh/ruby. `**` matches directories recursively.
|
48
|
+
* [glob(7)](https://www.kernel.org/doc/man-pages/online/pages/man7/glob.7.html)-style
|
49
|
+
bracket expressions, i.e. character classes, ranges, complementation, named
|
50
|
+
character classes, collating symbols and equivalence class expressions. Note
|
51
|
+
that the syntax for some of these is slightly different than what you would
|
52
|
+
find in regular expressions. Refer to [the documentation](https://www.kernel.org/doc/man-pages/online/pages/man7/glob.7.html)
|
53
|
+
for more info.
|
54
|
+
|
32
55
|
## License
|
33
56
|
|
34
|
-
Copyright (c)
|
57
|
+
Copyright (c) 2013 Jon Jensen, released under the MIT license
|
data/lib/globby.rb
CHANGED
@@ -1,54 +1,53 @@
|
|
1
1
|
require 'set'
|
2
|
+
require '../globby/lib/globby/glob'
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
result.subtract matches_for(pattern[1..-1])
|
13
|
-
else
|
14
|
-
result.merge matches_for(pattern)
|
4
|
+
module Globby
|
5
|
+
class << self
|
6
|
+
def select(patterns, source = get_files_and_dirs, result = {:files => Set.new, :dirs => Set.new})
|
7
|
+
evaluate_patterns(patterns, source, result)
|
8
|
+
|
9
|
+
if result[:dirs] && result[:dirs].size > 0
|
10
|
+
# now go merge/subtract files under directories
|
11
|
+
dir_patterns = result[:dirs].map{ |dir| "/#{dir}**" }
|
12
|
+
evaluate_patterns(dir_patterns, {:files => source[:files]}, result)
|
15
13
|
end
|
16
|
-
end
|
17
|
-
result.to_a.sort
|
18
|
-
end
|
19
|
-
|
20
|
-
def matches_for(pattern)
|
21
|
-
return [] unless pattern = normalize(pattern)
|
22
|
-
expects_dir = pattern.sub!(/\/\z/, '')
|
23
14
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
15
|
+
result[:files].to_a.sort
|
16
|
+
end
|
17
|
+
|
18
|
+
def reject(patterns = [])
|
19
|
+
source = get_files_and_dirs
|
20
|
+
(source[:files] - select(patterns, source)).sort
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def evaluate_patterns(patterns, source, result)
|
26
|
+
patterns.each do |pattern|
|
27
|
+
next unless pattern =~ /\A[^#]/
|
28
|
+
evaluate_pattern pattern, source, result
|
32
29
|
end
|
33
30
|
end
|
34
|
-
result
|
35
|
-
end
|
36
31
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
32
|
+
def evaluate_pattern(pattern, source, result)
|
33
|
+
glob = Globby::Glob.new(pattern)
|
34
|
+
method, candidates = glob.inverse? ?
|
35
|
+
[:subtract, result] :
|
36
|
+
[:merge, source]
|
37
|
+
|
38
|
+
dir_matches = glob.match(candidates[:dirs])
|
39
|
+
file_matches = []
|
40
|
+
file_matches = glob.match(candidates[:files]) unless glob.directory? || glob.exact_match? && !dir_matches.empty?
|
41
|
+
result[:dirs].send method, dir_matches unless dir_matches.empty?
|
42
|
+
result[:files].send method, file_matches unless file_matches.empty?
|
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}
|
46
51
|
end
|
47
|
-
end
|
48
|
-
|
49
|
-
protected
|
50
|
-
|
51
|
-
def directory?(pattern)
|
52
|
-
File.directory?(pattern) && !File.symlink?(pattern)
|
53
52
|
end
|
54
53
|
end
|
data/lib/globby/glob.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
module Globby
|
2
|
+
class Glob
|
3
|
+
def initialize(pattern)
|
4
|
+
@inverse = pattern.sub!(/\A!/, '')
|
5
|
+
# remove meaningless wildcards
|
6
|
+
@pattern = pattern.
|
7
|
+
sub(/\A\/?(\*\*\/)+/, '').
|
8
|
+
sub(/(\/\*\*)+\/\*\z/, '/**')
|
9
|
+
end
|
10
|
+
|
11
|
+
def match(files)
|
12
|
+
return [] unless files
|
13
|
+
files.grep(to_regexp)
|
14
|
+
end
|
15
|
+
|
16
|
+
def inverse?
|
17
|
+
@inverse
|
18
|
+
end
|
19
|
+
|
20
|
+
def directory?
|
21
|
+
@pattern =~ /\/\z/
|
22
|
+
end
|
23
|
+
|
24
|
+
def exact_match?
|
25
|
+
@pattern =~ /\A\// && @pattern !~ /[\*\?]/
|
26
|
+
end
|
27
|
+
|
28
|
+
# see https://www.kernel.org/doc/man-pages/online/pages/man7/glob.7.html
|
29
|
+
GLOB_BRACKET_EXPR = /
|
30
|
+
\[ # brackets
|
31
|
+
!? # (maybe) negation
|
32
|
+
\]? # (maybe) right bracket
|
33
|
+
(?: # one or more:
|
34
|
+
\[[^\/\]]+\] # named character class, collating symbol or equivalence class
|
35
|
+
| [^\/\]] # non-right bracket character (could be part of a range)
|
36
|
+
)+
|
37
|
+
\]/x
|
38
|
+
GLOB_ESCAPED_CHAR = /\\./
|
39
|
+
GLOB_RECURSIVE_WILDCARD = /\/\*\*(?:\/|\z)/
|
40
|
+
GLOB_WILDCARD = /[\?\*]/
|
41
|
+
|
42
|
+
GLOB_TOKENIZER = /(
|
43
|
+
#{GLOB_BRACKET_EXPR} |
|
44
|
+
#{GLOB_ESCAPED_CHAR} |
|
45
|
+
#{GLOB_RECURSIVE_WILDCARD}
|
46
|
+
)/x
|
47
|
+
|
48
|
+
def to_regexp
|
49
|
+
parts = @pattern.split(GLOB_TOKENIZER) - [""]
|
50
|
+
|
51
|
+
result = parts.first.sub!(/\A\//, '') ? '\A' : '(\A|/)'
|
52
|
+
parts.each do |part|
|
53
|
+
result << part_to_regexp(part)
|
54
|
+
end
|
55
|
+
if result[-1, 1] == '/'
|
56
|
+
result << '\z'
|
57
|
+
elsif result[-2, 2] == '.*'
|
58
|
+
result.slice!(-2, 2)
|
59
|
+
else
|
60
|
+
result << '\/?\z'
|
61
|
+
end
|
62
|
+
Regexp.new result
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def part_to_regexp(part)
|
68
|
+
case part
|
69
|
+
when GLOB_BRACKET_EXPR
|
70
|
+
# fix negation and escape right bracket
|
71
|
+
part.sub(/\A\[!/, '[^').sub(/\A(\[\^?)\]/, '\1\]')
|
72
|
+
when GLOB_ESCAPED_CHAR
|
73
|
+
part
|
74
|
+
when GLOB_RECURSIVE_WILDCARD
|
75
|
+
part[-1, 1] == '/' ? "/(.+/)?" : "/.*"
|
76
|
+
when GLOB_WILDCARD
|
77
|
+
(part.split(/(#{GLOB_WILDCARD})/) - [""]).inject("") do |result, p|
|
78
|
+
result << case p
|
79
|
+
when '?'; '[^/]'
|
80
|
+
when '*'; '[^/]*'
|
81
|
+
else Regexp.escape(p)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
else # literal path component (maybe with slashes)
|
85
|
+
part
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'globby'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
RSpec.configure { |config| config.mock_framework = :mocha }
|
6
|
+
|
7
|
+
describe Globby do
|
8
|
+
around do |example|
|
9
|
+
gitignore_test { example.run }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe ".select" do
|
13
|
+
it "should match .gitignore perfectly" do
|
14
|
+
rules = prepare_gitignore
|
15
|
+
Globby.select(rules.split(/\n/)).should == all_files - git_files - untracked
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ".reject" do
|
20
|
+
it "should match the inverse of .gitignore, plus .git" do
|
21
|
+
rules = prepare_gitignore
|
22
|
+
Globby.reject(rules.split(/\n/)).should == git_files + untracked
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def gitignore_test
|
27
|
+
Dir.mktmpdir do |dir|
|
28
|
+
Dir.chdir(dir) do
|
29
|
+
prepare_files
|
30
|
+
`git init .`
|
31
|
+
yield
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def prepare_gitignore
|
37
|
+
ignore = <<-IGNORE.gsub(/^ +/, '')
|
38
|
+
# here we go...
|
39
|
+
|
40
|
+
# some dotfiles
|
41
|
+
.hidden
|
42
|
+
|
43
|
+
# html, but just in the root
|
44
|
+
/*.html
|
45
|
+
|
46
|
+
# all rb files anywhere
|
47
|
+
*.rb
|
48
|
+
|
49
|
+
# except rb files immediately under foobar
|
50
|
+
!foobar/*.rb
|
51
|
+
|
52
|
+
# this will match foo/bar but not bar
|
53
|
+
bar/
|
54
|
+
|
55
|
+
# this will match nothing
|
56
|
+
foo*bar/baz.pdf
|
57
|
+
|
58
|
+
# this will match baz/ and foobar/baz/
|
59
|
+
baz
|
60
|
+
IGNORE
|
61
|
+
File.open('.gitignore', 'w'){ |f| f.write ignore }
|
62
|
+
ignore
|
63
|
+
end
|
64
|
+
|
65
|
+
def prepare_files
|
66
|
+
files = <<-FILES.strip.split(/\s+/)
|
67
|
+
.gitignore
|
68
|
+
foo.rb
|
69
|
+
foo.html
|
70
|
+
bar
|
71
|
+
baz/lol.txt
|
72
|
+
foo/.hidden
|
73
|
+
foo/bar.rb
|
74
|
+
foo/bar.html
|
75
|
+
foo/bar/baz.pdf
|
76
|
+
foobar/.hidden
|
77
|
+
foobar/baz.txt
|
78
|
+
foobar/baz.rb
|
79
|
+
foobar/baz/lol.wut
|
80
|
+
FILES
|
81
|
+
files.each do |file|
|
82
|
+
FileUtils.mkdir_p File.dirname(file)
|
83
|
+
FileUtils.touch file
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def untracked
|
88
|
+
`git status -uall`.gsub(/.*#\n|#\s+|^nothing.*/m, '').split(/\n/)
|
89
|
+
end
|
90
|
+
|
91
|
+
def git_files
|
92
|
+
Dir.glob('.git/**/*', File::FNM_DOTMATCH).
|
93
|
+
select{ |f| File.symlink?(f) || File.file?(f) }.sort
|
94
|
+
end
|
95
|
+
|
96
|
+
def all_files
|
97
|
+
Dir.glob('**/*', File::FNM_DOTMATCH).
|
98
|
+
select{ |f| File.symlink?(f) || File.file?(f) }.sort
|
99
|
+
end
|
100
|
+
end
|
data/spec/globby_spec.rb
CHANGED
@@ -1,157 +1,85 @@
|
|
1
1
|
require 'globby'
|
2
|
-
RSpec.configure { |config| config.mock_framework = :mocha }
|
3
2
|
|
4
|
-
|
5
|
-
# readability.
|
6
|
-
#
|
7
|
-
# A line starting with # serves as a comment.
|
8
|
-
#
|
9
|
-
# An optional prefix ! which negates the pattern; any matching file excluded by
|
10
|
-
# a previous pattern will become included again. If a negated pattern matches,
|
11
|
-
# this will override lower precedence patterns sources.
|
12
|
-
#
|
13
|
-
# If the pattern ends with a slash, it is removed for the purpose of the
|
14
|
-
# following description, but it would only find a match with a directory. In
|
15
|
-
# other words, foo/ will match a directory foo and paths underneath it, but
|
16
|
-
# will not match a regular file or a symbolic link foo (this is consistent with
|
17
|
-
# the way how pathspec works in general in git).
|
18
|
-
#
|
19
|
-
# If the pattern does not contain a slash /, git treats it as a shell glob
|
20
|
-
# pattern and checks for a match against the pathname relative to the location
|
21
|
-
# of the .gitignore file (relative to the toplevel of the work tree if not from
|
22
|
-
# a .gitignore file).
|
23
|
-
#
|
24
|
-
# Otherwise, git treats the pattern as a shell glob suitable for consumption by
|
25
|
-
# fnmatch(3) with the FNM_PATHNAME flag: wildcards in the pattern will not
|
26
|
-
# match a / in the pathname. For example, "Documentation/*.html" matches
|
27
|
-
# "Documentation/git.html" but not "Documentation/ppc/ppc.html" or
|
28
|
-
# "tools/perf/Documentation/perf.html".
|
29
|
-
#
|
30
|
-
# A leading slash matches the beginning of the pathname. For example, "/*.c"
|
31
|
-
# matches "cat-file.c" but not "mozilla-sha1/sha1.c".
|
3
|
+
RSpec.configure { |config| config.mock_framework = :mocha }
|
32
4
|
|
33
5
|
describe Globby do
|
34
|
-
describe "
|
35
|
-
|
36
|
-
let(:globby) { Globby.new }
|
37
|
-
|
6
|
+
describe ".select" do
|
38
7
|
context "a blank line" do
|
39
8
|
it "should return nothing" do
|
40
|
-
|
41
|
-
|
9
|
+
files = files("foo")
|
10
|
+
Globby.select([""], files).should == []
|
42
11
|
end
|
43
12
|
end
|
44
13
|
|
45
14
|
context "a comment" do
|
46
15
|
it "should return nothing" do
|
47
|
-
|
48
|
-
|
16
|
+
files = files("foo")
|
17
|
+
Globby.select(["#"], files).should == []
|
49
18
|
end
|
50
19
|
end
|
51
20
|
|
52
21
|
context "a pattern ending in a slash" do
|
53
22
|
it "should return a matching directory's contents" do
|
54
|
-
|
55
|
-
|
56
|
-
globby.matches_for("foo/").should == ['foo/bar']
|
23
|
+
files = files(%w{foo/bar/baz foo/bar/baz2})
|
24
|
+
Globby.select(%w{bar/}, files).should == %w{foo/bar/baz foo/bar/baz2}
|
57
25
|
end
|
58
26
|
|
59
27
|
it "should ignore symlinks and regular files" do
|
60
|
-
|
61
|
-
|
62
|
-
globby.matches_for("foo/").should == []
|
28
|
+
files = files(%w{foo/bar bar/baz})
|
29
|
+
Globby.select(%w{bar/}, files).should == %w{bar/baz}
|
63
30
|
end
|
64
31
|
end
|
65
32
|
|
66
|
-
context "a pattern
|
67
|
-
it "should return
|
68
|
-
|
69
|
-
|
33
|
+
context "a pattern starting in a slash" do
|
34
|
+
it "should return only root glob matches" do
|
35
|
+
files = files(%w{foo/bar bar/foo})
|
36
|
+
Globby.select(%w{/foo}, files).should == %w{foo/bar}
|
70
37
|
end
|
71
38
|
end
|
72
39
|
|
73
|
-
context "a pattern with a
|
74
|
-
it "should return
|
75
|
-
|
76
|
-
|
40
|
+
context "a pattern with a *" do
|
41
|
+
it "should return matching files" do
|
42
|
+
files = files(%w{foo/bar foo/baz})
|
43
|
+
Globby.select(%w{*z}, files).should == %w{foo/baz}
|
77
44
|
end
|
78
|
-
end
|
79
45
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
globby.matches_for("/foo/bar")
|
46
|
+
it "should not glob slashes" do
|
47
|
+
files = files(%w{foo/bar foo/baz})
|
48
|
+
Globby.select(%w{foo*bar}, files).should == []
|
84
49
|
end
|
85
50
|
end
|
86
|
-
end
|
87
|
-
|
88
|
-
describe "#matches" do
|
89
|
-
it "should match gitignore perfectly" do
|
90
|
-
require 'tmpdir'
|
91
|
-
require 'fileutils'
|
92
|
-
|
93
|
-
files = <<-FILES.strip.split(/\s+/)
|
94
|
-
.gitignore
|
95
|
-
foo.rb
|
96
|
-
foo.html
|
97
|
-
bar
|
98
|
-
baz/lol.txt
|
99
|
-
foo/.hidden
|
100
|
-
foo/bar.rb
|
101
|
-
foo/bar.html
|
102
|
-
foo/bar/baz.pdf
|
103
|
-
foobar/.hidden
|
104
|
-
foobar/baz.txt
|
105
|
-
foobar/baz.rb
|
106
|
-
foobar/baz/lol.wut
|
107
|
-
FILES
|
108
|
-
|
109
|
-
ignore = <<-IGNORE.gsub(/^ +/, '')
|
110
|
-
# here we go...
|
111
|
-
|
112
|
-
# some dotfiles
|
113
|
-
.hidden
|
114
|
-
|
115
|
-
# html, but just in the root
|
116
|
-
/*.html
|
117
51
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
# this will match foo/bar but not bar
|
125
|
-
bar/
|
126
|
-
|
127
|
-
# this will match nothing
|
128
|
-
foo*bar/baz.pdf
|
129
|
-
|
130
|
-
# this will match baz/ and foobar/baz/
|
131
|
-
baz
|
132
|
-
IGNORE
|
52
|
+
context "a pattern with a ?" do
|
53
|
+
it "should return matching files" do
|
54
|
+
files = files(%w{foo/bar foo/baz})
|
55
|
+
Globby.select(%w{b?z}, files).should == %w{foo/baz}
|
56
|
+
end
|
133
57
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
FileUtils.touch file
|
140
|
-
end
|
58
|
+
it "should not glob slashes" do
|
59
|
+
files = files(%w{foo/bar foo/baz})
|
60
|
+
Globby.select(%w{foo?bar}, files).should == []
|
61
|
+
end
|
62
|
+
end
|
141
63
|
|
142
|
-
|
143
|
-
|
64
|
+
context "a pattern with a **" do
|
65
|
+
it "should match directories recursively" do
|
66
|
+
files = files(%w{foo/bar foo/baz foo/c/bar foo/c/c/bar})
|
67
|
+
Globby.select(%w{foo/**/bar}, files).should == %w{foo/bar foo/c/bar foo/c/c/bar}
|
68
|
+
end
|
69
|
+
end
|
144
70
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
reject{ |f| f =~ /^\.git\// }.
|
150
|
-
select{ |f| File.symlink?(f) || File.file?(f) }
|
151
|
-
|
152
|
-
all_files.sort.should == (untracked + ignored).sort
|
153
|
-
end
|
71
|
+
context "a pattern with bracket expressions" do
|
72
|
+
it "should return matching files" do
|
73
|
+
files = files(%w{boo fob f0o foo/bar poo/baz})
|
74
|
+
Globby.select(%w{[e-g][0-9[:alpha:]][!b]}, files).should == %w{f0o foo/bar}
|
154
75
|
end
|
155
76
|
end
|
156
77
|
end
|
78
|
+
|
79
|
+
def files(files)
|
80
|
+
files = Array(files)
|
81
|
+
files.sort!
|
82
|
+
dirs = files.grep(/\//).map { |file| file.sub(/[^\/]+\z/, '') }.uniq.sort
|
83
|
+
{:files => files, :dirs => dirs}
|
84
|
+
end
|
157
85
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: globby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
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-25 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description: find files using .gitignore-style globs
|
@@ -30,7 +30,9 @@ files:
|
|
30
30
|
- LICENSE.txt
|
31
31
|
- Rakefile
|
32
32
|
- README.md
|
33
|
+
- lib/globby/glob.rb
|
33
34
|
- lib/globby.rb
|
35
|
+
- spec/gitignore_spec.rb
|
34
36
|
- spec/globby_spec.rb
|
35
37
|
homepage: http://github.com/jenseng/globby
|
36
38
|
licenses: []
|