-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'papilip/git_shellout'
- Loading branch information
Showing
10 changed files
with
478 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Copyright (c) 2014 Jon Jensen | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# globby | ||
|
||
[<img src="https://travis-ci.org/jenseng/globby.svg" />](http://travis-ci.org/jenseng/globby) | ||
|
||
globby is a [`.gitignore`](http://www.kernel.org/pub/software/scm/git/docs/gitignore.html)-style | ||
file globber for ruby. | ||
|
||
## Installation | ||
|
||
Put `gem 'globby'` in your Gemfile. | ||
|
||
## Usage | ||
|
||
# all files matched by the rules | ||
Globby.select(rules) | ||
|
||
# all other files | ||
Globby.reject(rules) | ||
|
||
# ooh chaining! | ||
Globby.select(rules).reject(other_rules) | ||
|
||
### An example: | ||
|
||
> rules = File.read('.gitignore').split(/\n/) | ||
-> ["Gemfile.lock", "doc", "*.gem"] | ||
|
||
> pp Globby.select(rules) | ||
["Gemfile.lock", | ||
"doc/Foreigner.html", | ||
"doc/Foreigner/Adapter.html", | ||
"doc/Gemfile.html", | ||
"doc/Immigrant.html", | ||
... | ||
"immigrant-0.1.3.gem", | ||
"immigrant-0.1.4.gem"] | ||
=> nil | ||
|
||
## Why on earth would I ever use this? | ||
|
||
* You're curious what is getting `.gitignore`'d and/or you want to do something | ||
with those files. | ||
* You're writing a library/tool that will have its own list of ignored/tracked | ||
files. My use case is for an I18n library that extracts strings from ruby | ||
files... I need to provide users a nice configurable way to blacklist given | ||
files/directories/patterns. | ||
|
||
## Compatibility Notes | ||
|
||
globby is compatible with `.gitignore` rules; it respects negated patterns, and | ||
ignores comments or empty patterns. That said, it supports some things that may | ||
or may not work in your version of git. These platform-dependent `.gitignore` | ||
behaviors are platform independent in globby and can always be used: | ||
|
||
* Recursive wildcards à la ant/zsh/ruby. `**` matches directories recursively. | ||
* [glob(7)](https://www.kernel.org/doc/man-pages/online/pages/man7/glob.7.html)-style | ||
bracket expressions, i.e. character classes, ranges, complementation, named | ||
character classes, collating symbols and equivalence class expressions. Note | ||
that the syntax for some of these is slightly different than what you would | ||
find in regular expressions. Refer to [the documentation](https://www.kernel.org/doc/man-pages/online/pages/man7/glob.7.html) | ||
for more info. | ||
|
||
## License | ||
|
||
Copyright (c) 2013-2016 Jon Jensen, released under the MIT license |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
require 'rake' | ||
|
||
require 'rspec/core' | ||
require 'rspec/core/rake_task' | ||
RSpec::Core::RakeTask.new(:spec) do |spec| | ||
spec.pattern = FileList['spec/**/*_spec.rb'] | ||
end | ||
|
||
task :default => :spec |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
require 'set' | ||
require 'globby/glob' | ||
require 'globby/globject' | ||
require 'globby/result' | ||
|
||
module Globby | ||
class << self | ||
def select(patterns, source = GlObject.all) | ||
result = GlObject.new | ||
evaluate_patterns(patterns, source, result) | ||
|
||
if result.dirs && result.dirs.size > 0 | ||
# now go merge/subtract files under directories | ||
dir_patterns = result.dirs.map{ |dir| "/#{dir}**" } | ||
evaluate_patterns(dir_patterns, GlObject.new(source.files), result) | ||
end | ||
|
||
Result.new result.files, source.dirs | ||
end | ||
|
||
def reject(patterns, source = GlObject.all) | ||
Result.new(source.files - select(patterns, source), source.dirs) | ||
end | ||
|
||
private | ||
|
||
def evaluate_patterns(patterns, source, result) | ||
patterns.each do |pattern| | ||
next unless pattern =~ /\A[^#]/ | ||
evaluate_pattern pattern, source, result | ||
end | ||
end | ||
|
||
def evaluate_pattern(pattern, source, result) | ||
glob = Globby::Glob.new(pattern) | ||
method, candidates = glob.inverse? ? | ||
[:subtract, result] : | ||
[:merge, source] | ||
|
||
dir_matches = glob.match(candidates.dirs) | ||
file_matches = [] | ||
file_matches = glob.match(candidates.files) unless glob.directory? || glob.exact_match? && !dir_matches.empty? | ||
result.dirs.send method, dir_matches unless dir_matches.empty? | ||
result.files.send method, file_matches unless file_matches.empty? | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
module Globby | ||
class Glob | ||
def initialize(pattern) | ||
pattern = pattern.dup | ||
@inverse = pattern.sub!(/\A!/, '') | ||
# remove meaningless wildcards | ||
pattern.sub!(/\A\/?(\*\*\/)+/, '') | ||
pattern.sub!(/(\/\*\*)+\/\*\z/, '/**') | ||
@pattern = pattern | ||
end | ||
|
||
def match(files) | ||
return [] unless files | ||
files.grep(to_regexp) | ||
end | ||
|
||
def inverse? | ||
@inverse | ||
end | ||
|
||
def directory? | ||
@pattern =~ /\/\z/ | ||
end | ||
|
||
def exact_match? | ||
@pattern =~ /\A\// && @pattern !~ /[\*\?]/ | ||
end | ||
|
||
# see https://www.kernel.org/doc/man-pages/online/pages/man7/glob.7.html | ||
GLOB_BRACKET_EXPR = / | ||
\[ # brackets | ||
!? # (maybe) negation | ||
\]? # (maybe) right bracket | ||
(?: # one or more: | ||
\[[^\/\]]+\] # named character class, collating symbol or equivalence class | ||
| [^\/\]] # non-right bracket character (could be part of a range) | ||
)+ | ||
\]/x | ||
GLOB_ESCAPED_CHAR = /\\./ | ||
GLOB_RECURSIVE_WILDCARD = /\/\*\*(?:\/|\z)/ | ||
GLOB_WILDCARD = /[\?\*]/ | ||
|
||
GLOB_TOKENIZER = /( | ||
#{GLOB_BRACKET_EXPR} | | ||
#{GLOB_ESCAPED_CHAR} | | ||
#{GLOB_RECURSIVE_WILDCARD} | ||
)/x | ||
|
||
def to_regexp | ||
parts = @pattern.split(GLOB_TOKENIZER) - [""] | ||
|
||
result = parts.first.sub!(/\A\//, '') ? '\A' : '(\A|/)' | ||
parts.each do |part| | ||
result << part_to_regexp(part) | ||
end | ||
if result[-1, 1] == '/' | ||
result << '\z' | ||
elsif result[-2, 2] == '.*' | ||
result.slice!(-2, 2) | ||
else | ||
result << '\/?\z' | ||
end | ||
Regexp.new result | ||
end | ||
|
||
private | ||
|
||
def part_to_regexp(part) | ||
case part | ||
when GLOB_BRACKET_EXPR | ||
# fix negation and escape right bracket | ||
part.sub(/\A\[!/, '[^').sub(/\A(\[\^?)\]/, '\1\]') | ||
when GLOB_ESCAPED_CHAR | ||
part | ||
when GLOB_RECURSIVE_WILDCARD | ||
part[-1, 1] == '/' ? "/(.+/)?" : "/.*" | ||
when GLOB_WILDCARD | ||
(part.split(/(#{GLOB_WILDCARD})/) - [""]).inject("") do |result, p| | ||
result << case p | ||
when '?'; '[^/]' | ||
when '*'; '[^/]' + (result.end_with?("/") ? '+' : '*') | ||
else Regexp.escape(p) | ||
end | ||
end | ||
else # literal path component (maybe with slashes) | ||
part | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
module Globby | ||
class GlObject | ||
attr_reader :files, :dirs | ||
|
||
def initialize(files = Set.new, dirs = Set.new) | ||
@files = files | ||
@dirs = dirs | ||
end | ||
|
||
def self.all | ||
files, dirs = Dir.glob('**/*', File::FNM_DOTMATCH). | ||
reject { |f| f =~ /(\A|\/)\.\.?\z/ }. | ||
partition { |f| File.file?(f) || File.symlink?(f) } | ||
dirs.map!{ |d| d + "/" } | ||
new(files, dirs) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
module Globby | ||
class Result < Array | ||
def initialize(files, dirs) | ||
@dirs = dirs | ||
super files.sort | ||
end | ||
|
||
def select(patterns) | ||
Globby::select(patterns, to_globject) | ||
end | ||
|
||
def reject(patterns) | ||
Globby::reject(patterns, to_globject) | ||
end | ||
|
||
def to_globject | ||
GlObject.new(self, @dirs) | ||
end | ||
end | ||
end |
Oops, something went wrong.