pork 1.5.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,4 @@
1
1
 
2
- require 'pork'
3
-
4
2
  module Pork
5
3
  module Color
6
4
  def msg_skip ; yellow(super); end
@@ -1,27 +1,27 @@
1
1
 
2
- require 'pork/executor'
3
-
4
2
  module Kernel
5
3
  def should *args, &block
6
- stat = Thread.current.group.list.find{ |t| t[:pork_stat] }[:pork_stat]
4
+ stat = Thread.current.group.list.find do |t|
5
+ t.thread_variable_get(:pork_stat)
6
+ end.thread_variable_get(:pork_stat)
7
7
  Pork::Expect.new(stat, self, *args, &block)
8
8
  end
9
9
  end
10
10
 
11
11
  module Pork
12
12
  module Should
13
- def execute mode, stat=Stat.new, *args
13
+ def execute stat=Stat.new, *args
14
14
  thread = Thread.current
15
15
  original_group, group = thread.group, ThreadGroup.new
16
- original_stat = thread[:pork_stat]
16
+ original_stat = thread.thread_variable_get(:pork_stat)
17
17
  group.add(thread)
18
- thread[:pork_stat] = stat
19
- super(mode, stat, *args)
18
+ thread.thread_variable_set(:pork_stat, stat)
19
+ super(stat, *args)
20
20
  ensure
21
- thread[:pork_stat] = original_stat
21
+ thread.thread_variable_set(:pork_stat, original_stat)
22
22
  original_group.add(thread)
23
23
  end
24
24
  end
25
25
 
26
- Executor.extend(Should)
26
+ execute_extensions << Should
27
27
  end
@@ -3,7 +3,7 @@ require 'pork/report/dot'
3
3
 
4
4
  module Pork
5
5
  class Description < Dot
6
- attr_accessor :last_executor
6
+ attr_accessor :last_suite
7
7
 
8
8
  def msg_pass
9
9
  msg = "\ro"
@@ -19,17 +19,17 @@ module Pork
19
19
  def msg_errored; "\r#{super}"; end
20
20
 
21
21
  def case_start context
22
- self.last_executor ||= Executor
23
- executor = context.class
24
- levels = executor.ancestors.drop(1).count{ |a| a <= Executor }
22
+ self.last_suite ||= Suite
23
+ suite = context.class
24
+ levels = suite.ancestors.drop(1).count{ |a| a <= Suite }
25
25
 
26
- if executor != Executor && last_executor != executor
27
- io.puts "#{' ' * (levels - 1)}#{executor.desc}"
26
+ if suite != Suite && last_suite != suite
27
+ io.puts "#{' ' * (levels - 1)}#{suite.desc}"
28
28
  end
29
29
 
30
30
  io.print "#{' ' * levels}#{context.pork_description}"
31
31
 
32
- self.last_executor = executor
32
+ self.last_suite = suite
33
33
  end
34
34
 
35
35
  def case_end
@@ -75,12 +75,11 @@ module Pork
75
75
  end
76
76
  end
77
77
 
78
- def case_pass ; end
79
78
  def case_skip ; end
80
79
  def case_failed ; self.failed = true; end
81
80
  def case_errored; self.failed = true; end
82
81
 
83
- def case_end
82
+ def case_pass
84
83
  bar.tick
85
84
  end
86
85
 
data/lib/pork/report.rb CHANGED
@@ -5,7 +5,8 @@ module Pork
5
5
  module Report::Imp
6
6
  def initialize o=$stdout
7
7
  super
8
- extend(*Pork.report_extensions.reverse) if Pork.report_extensions.any?
8
+ extensions = Pork.report_extensions
9
+ extend(*extensions.reverse) if extensions.any?
9
10
  end
10
11
 
11
12
  def case_start _; end
@@ -85,10 +86,16 @@ module Pork
85
86
  end
86
87
 
87
88
  def backtrace test, err
88
- if $VERBOSE
89
+ bt = if $VERBOSE
89
90
  err.backtrace
90
91
  else
91
- strip(reject_pork(test, err))
92
+ strip(reject_pork(test, err.backtrace))
93
+ end
94
+
95
+ if bt.empty?
96
+ ["#{test.source_location.join(':')}:in `block in would'"]
97
+ else
98
+ bt
92
99
  end
93
100
  end
94
101
 
@@ -112,13 +119,8 @@ module Pork
112
119
  "#{err.class}: #{err.message}"
113
120
  end
114
121
 
115
- def reject_pork test, err
116
- bt = err.backtrace.reject{ |l| l =~ %r{/lib/pork(/\w+)*\.rb:\d+} }
117
- if bt.empty?
118
- ["#{test.source_location.join(':')}:in `block in would'"]
119
- else
120
- bt
121
- end
122
+ def reject_pork test, bt
123
+ bt.reject{ |l| l =~ %r{/lib/pork(/\w+)*\.rb:\d+} }
122
124
  end
123
125
 
124
126
  def strip bt
@@ -126,11 +128,13 @@ module Pork
126
128
  end
127
129
 
128
130
  def strip_home bt
129
- bt.map{ |path| path.sub(ENV['HOME'], '~') }
131
+ home = ENV['HOME']
132
+ bt.map{ |path| path.sub(home, '~') }
130
133
  end
131
134
 
132
135
  def strip_cwd bt
133
- bt.map{ |path| path.sub("#{Dir.pwd}/", '') }
136
+ cwd = Dir.pwd
137
+ bt.map{ |path| path.sub("#{cwd}/", '') }
134
138
  end
135
139
 
136
140
  def pork_test source_location
@@ -152,5 +156,5 @@ module Pork
152
156
  end
153
157
  end
154
158
 
155
- Report.__send__(:include, Report::Imp)
159
+ Report.include(Report::Imp)
156
160
  end
@@ -0,0 +1,54 @@
1
+
2
+ require 'pork/error'
3
+
4
+ module Pork
5
+ class Runner < Struct.new(:suite, :seed, :stat, :desc, :test, :env)
6
+ def run
7
+ assertions = stat.assertions
8
+ context = suite.new(stat, desc, [])
9
+
10
+ stat.reporter.case_start(context)
11
+
12
+ passed = protected do
13
+ env.run_before(context)
14
+ context.instance_eval(&test)
15
+ end
16
+
17
+ protected{ env.run_after(context) }
18
+
19
+ if passed
20
+ if assertions == stat.assertions
21
+ protected{ raise Error.new('Missing assertions') }
22
+ else
23
+ stat.reporter.case_pass
24
+ end
25
+ end
26
+
27
+ stat.incr_tests
28
+ stat.reporter.case_end
29
+ end
30
+
31
+ private
32
+ def protected
33
+ yield
34
+ true
35
+ rescue *stat.protected_exceptions => e
36
+ case e
37
+ when Skip
38
+ stat.incr_skips
39
+ stat.reporter.case_skip
40
+ else
41
+ err = [e, suite.description_for("would #{desc}"), test, seed]
42
+ case e
43
+ when Failure
44
+ stat.add_failure(err)
45
+ stat.reporter.case_failed
46
+ else
47
+ stat.add_error(err)
48
+ stat.reporter.case_errored
49
+ end
50
+ end
51
+ false
52
+ end
53
+ end
54
+ end
data/lib/pork/stat.rb CHANGED
@@ -63,5 +63,5 @@ module Pork
63
63
  end
64
64
  end
65
65
 
66
- Stat.__send__(:include, Stat::Imp)
66
+ Stat.include(Stat::Imp)
67
67
  end
data/lib/pork/suite.rb ADDED
@@ -0,0 +1,74 @@
1
+
2
+ require 'fiber'
3
+
4
+ require 'pork/runner'
5
+ require 'pork/context'
6
+
7
+ module Pork
8
+ class Suite < Struct.new(:pork_stat, :pork_description, :pork_fibers)
9
+ module Imp
10
+ attr_reader :desc, :tests
11
+
12
+ def before &block; @tests << [:before, block]; end
13
+ def after &block; @tests << [:after , block]; end
14
+
15
+ def around &block
16
+ before do
17
+ fiber = Fiber.new{ instance_exec(Fiber.method(:yield), &block) }
18
+ pork_fibers << fiber
19
+ fiber.resume
20
+ end
21
+
22
+ after do
23
+ fiber = pork_fibers.pop
24
+ fiber.resume if fiber.alive?
25
+ end
26
+ end
27
+
28
+ def copy desc=:default, &suite
29
+ @stash[desc] = suite
30
+ end
31
+ def paste desc=:default, *args
32
+ module_exec(*args, &search_stash(desc))
33
+ end
34
+
35
+ def describe desc=:default, opts={}, &suite
36
+ executor = Class.new(self){ init(desc) }
37
+ executor.module_eval(&suite)
38
+ @tests << [:describe, executor, suite, opts]
39
+ end
40
+
41
+ def would desc=:default, opts={}, &test
42
+ raise ArgumentError.new("no block given") unless test
43
+ @tests << [:would , desc , test, opts]
44
+ end
45
+
46
+ def description_for name=''
47
+ if @super_executor
48
+ "#{@super_executor.description_for}#{@desc}: #{name}"
49
+ else
50
+ name
51
+ end
52
+ end
53
+
54
+ def run *args
55
+ Runner.new(self, Pork.reseed, *args).run
56
+ end
57
+
58
+ private
59
+ def init desc=''
60
+ @desc, @tests, @stash = desc, [], {}
61
+ @super_executor = ancestors[1..-1].find{ |a| a <= Suite }
62
+ end
63
+
64
+ protected
65
+ def search_stash desc
66
+ @stash[desc] or @super_executor && @super_executor.search_stash(desc)
67
+ end
68
+ end
69
+
70
+ extend Imp
71
+ include Context
72
+ init
73
+ end
74
+ end
data/lib/pork/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Pork
3
- VERSION = '1.5.0'
3
+ VERSION = '2.1.0'
4
4
  end
data/lib/pork.rb CHANGED
@@ -1,17 +1,9 @@
1
1
 
2
+ require 'pork/api'
3
+ require 'pork/stat'
2
4
  require 'pork/executor'
3
5
 
4
6
  module Pork
5
- module API
6
- module_function
7
- def before &block; Executor.before(&block); end
8
- def after &block; Executor.after( &block); end
9
- def copy desc=:default, &block; Executor.copy( desc, &block); end
10
- def paste desc=:default, *args ; Executor.paste( desc, *args ); end
11
- def describe desc=:default, &suite; Executor.describe(desc, &suite); end
12
- def would desc=:default, &test ; Executor.would( desc, &test ); end
13
- end
14
-
15
7
  # default to :shuffled while eliminating warnings for uninitialized ivar
16
8
  def self.execute_mode mode=nil
17
9
  @execute_mode = mode || @execute_mode ||= :shuffled
@@ -31,6 +23,10 @@ module Pork
31
23
  @report_extensions ||= []
32
24
  end
33
25
 
26
+ def self.execute_extensions
27
+ @execute_extensions ||= []
28
+ end
29
+
34
30
  def self.protected_exceptions
35
31
  @protected_exceptions ||= [Pork::Error, StandardError]
36
32
  end
@@ -50,11 +46,7 @@ module Pork
50
46
  end
51
47
 
52
48
  def self.seed
53
- @seed ||= if Random.const_defined?(:DEFAULT)
54
- Random::DEFAULT.seed
55
- else
56
- Thread.current.randomizer.seed # Rubinius (rbx)
57
- end
49
+ @seed ||= Random.seed
58
50
  end
59
51
 
60
52
  def self.reseed
@@ -87,13 +79,13 @@ module Pork
87
79
  def self.execute
88
80
  if ENV['PORK_TEST']
89
81
  if tests = Executor[ENV['PORK_TEST']]
90
- @stat = Executor.execute(execute_mode, stat, tests)
82
+ @stat = Executor.execute(:paths => tests)
91
83
  else
92
84
  puts "Cannot find test: #{ENV['PORK_TEST']}"
93
85
  exit 254
94
86
  end
95
87
  else
96
- @stat = Executor.execute(execute_mode, stat)
88
+ @stat = Executor.execute
97
89
  end
98
90
  end
99
91
 
@@ -102,7 +94,7 @@ module Pork
102
94
  execute_mode(ENV['PORK_MODE'])
103
95
  report_mode(ENV['PORK_REPORT'])
104
96
  trap
105
- stat.loaded(@at, @files)
97
+ stat.loaded(@at, @files) if instance_variable_defined?(:@at)
106
98
  execute
107
99
  stat.report
108
100
  end
data/pork.gemspec CHANGED
@@ -1,20 +1,20 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: pork 1.5.0 ruby lib
2
+ # stub: pork 2.1.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "pork".freeze
6
- s.version = "1.5.0"
6
+ s.version = "2.1.0"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib".freeze]
10
10
  s.authors = ["Lin Jen-Shin (godfat)".freeze]
11
- s.date = "2016-03-10"
11
+ s.date = "2022-12-28"
12
12
  s.description = "Pork -- Simple and clean and modular testing library.\n\nInspired by [Bacon][].\n\n[Bacon]: https://github.com/chneukirchen/bacon".freeze
13
13
  s.email = ["godfat (XD) godfat.org".freeze]
14
14
  s.files = [
15
15
  ".gitignore".freeze,
16
+ ".gitlab-ci.yml".freeze,
16
17
  ".gitmodules".freeze,
17
- ".travis.yml".freeze,
18
18
  "CHANGES.md".freeze,
19
19
  "Gemfile".freeze,
20
20
  "LICENSE".freeze,
@@ -22,6 +22,7 @@ Gem::Specification.new do |s|
22
22
  "Rakefile".freeze,
23
23
  "TODO.md".freeze,
24
24
  "lib/pork.rb".freeze,
25
+ "lib/pork/api.rb".freeze,
25
26
  "lib/pork/auto.rb".freeze,
26
27
  "lib/pork/context.rb".freeze,
27
28
  "lib/pork/env.rb".freeze,
@@ -30,9 +31,8 @@ Gem::Specification.new do |s|
30
31
  "lib/pork/expect.rb".freeze,
31
32
  "lib/pork/extra/rainbows.rb".freeze,
32
33
  "lib/pork/extra/show_source.rb".freeze,
33
- "lib/pork/imp.rb".freeze,
34
34
  "lib/pork/inspect.rb".freeze,
35
- "lib/pork/isolate.rb".freeze,
35
+ "lib/pork/isolator.rb".freeze,
36
36
  "lib/pork/mode/parallel.rb".freeze,
37
37
  "lib/pork/mode/sequential.rb".freeze,
38
38
  "lib/pork/mode/shuffled.rb".freeze,
@@ -44,46 +44,46 @@ Gem::Specification.new do |s|
44
44
  "lib/pork/report/description.rb".freeze,
45
45
  "lib/pork/report/dot.rb".freeze,
46
46
  "lib/pork/report/progressbar.rb".freeze,
47
+ "lib/pork/runner.rb".freeze,
47
48
  "lib/pork/stat.rb".freeze,
49
+ "lib/pork/suite.rb".freeze,
48
50
  "lib/pork/test.rb".freeze,
49
51
  "lib/pork/version.rb".freeze,
50
52
  "pork.gemspec".freeze,
51
53
  "task/README.md".freeze,
52
54
  "task/gemgem.rb".freeze,
55
+ "test/test_around.rb".freeze,
53
56
  "test/test_bacon.rb".freeze,
54
57
  "test/test_expect.rb".freeze,
55
58
  "test/test_inspect.rb".freeze,
59
+ "test/test_isolator.rb".freeze,
60
+ "test/test_meta.rb".freeze,
56
61
  "test/test_nested.rb".freeze,
57
62
  "test/test_pork_test.rb".freeze,
58
63
  "test/test_readme.rb".freeze,
59
64
  "test/test_should.rb".freeze,
60
- "test/test_stat.rb".freeze]
65
+ "test/test_stat.rb".freeze,
66
+ "test/test_suite.rb".freeze]
61
67
  s.homepage = "https://github.com/godfat/pork".freeze
62
- s.licenses = ["Apache License 2.0".freeze]
63
- s.rubygems_version = "2.6.1".freeze
68
+ s.licenses = ["Apache-2.0".freeze]
69
+ s.rubygems_version = "3.4.1".freeze
64
70
  s.summary = "Pork -- Simple and clean and modular testing library.".freeze
65
71
  s.test_files = [
72
+ "test/test_around.rb".freeze,
66
73
  "test/test_bacon.rb".freeze,
67
74
  "test/test_expect.rb".freeze,
68
75
  "test/test_inspect.rb".freeze,
76
+ "test/test_isolator.rb".freeze,
77
+ "test/test_meta.rb".freeze,
69
78
  "test/test_nested.rb".freeze,
70
79
  "test/test_pork_test.rb".freeze,
71
80
  "test/test_readme.rb".freeze,
72
81
  "test/test_should.rb".freeze,
73
- "test/test_stat.rb".freeze]
82
+ "test/test_stat.rb".freeze,
83
+ "test/test_suite.rb".freeze]
74
84
 
75
- if s.respond_to? :specification_version then
76
- s.specification_version = 4
85
+ s.specification_version = 4
77
86
 
78
- if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
79
- s.add_development_dependency(%q<method_source>.freeze, [">= 0"])
80
- s.add_development_dependency(%q<ruby-progressbar>.freeze, [">= 0"])
81
- else
82
- s.add_dependency(%q<method_source>.freeze, [">= 0"])
83
- s.add_dependency(%q<ruby-progressbar>.freeze, [">= 0"])
84
- end
85
- else
86
- s.add_dependency(%q<method_source>.freeze, [">= 0"])
87
- s.add_dependency(%q<ruby-progressbar>.freeze, [">= 0"])
88
- end
87
+ s.add_development_dependency(%q<method_source>.freeze, [">= 0"])
88
+ s.add_development_dependency(%q<ruby-progressbar>.freeze, [">= 0"])
89
89
  end
data/task/README.md CHANGED
@@ -4,16 +4,16 @@
4
4
 
5
5
  Provided tasks:
6
6
 
7
- rake clean # Remove ignored files
7
+ rake clean # Trash ignored files
8
8
  rake gem:build # Build gem
9
9
  rake gem:install # Install gem
10
10
  rake gem:release # Release gem
11
11
  rake gem:spec # Generate gemspec
12
- rake test # Run tests in memory
12
+ rake test # Run tests
13
13
 
14
14
  ## REQUIREMENTS:
15
15
 
16
- * Tested with MRI (official CRuby) 1.9.3, 2.0.0, Rubinius and JRuby.
16
+ * Tested with MRI (official CRuby) and JRuby.
17
17
 
18
18
  ## INSTALLATION:
19
19
 
@@ -23,13 +23,13 @@ And in Rakefile:
23
23
 
24
24
  ``` ruby
25
25
  begin
26
- require "#{dir = File.dirname(__FILE__)}/task/gemgem"
26
+ require "#{__dir__}/task/gemgem"
27
27
  rescue LoadError
28
- sh 'git submodule update --init'
28
+ sh 'git submodule update --init --recursive'
29
29
  exec Gem.ruby, '-S', $PROGRAM_NAME, *ARGV
30
30
  end
31
31
 
32
- Gemgem.init(dir) do |s|
32
+ Gemgem.init(__dir__, :submodules => %w[your-dep]) do |s|
33
33
  s.name = 'your-gem'
34
34
  s.version = '0.1.0'
35
35
  end
@@ -37,9 +37,9 @@ end
37
37
 
38
38
  ## LICENSE:
39
39
 
40
- Apache License 2.0
40
+ Apache License 2.0 (Apache-2.0)
41
41
 
42
- Copyright (c) 2011-2013, Lin Jen-Shin (godfat)
42
+ Copyright (c) 2011-2021, Lin Jen-Shin (godfat)
43
43
 
44
44
  Licensed under the Apache License, Version 2.0 (the "License");
45
45
  you may not use this file except in compliance with the License.
data/task/gemgem.rb CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Gemgem
3
3
  class << self
4
- attr_accessor :dir, :spec, :spec_create
4
+ attr_accessor :dir, :spec, :submodules, :spec_create
5
5
  end
6
6
 
7
7
  module_function
@@ -11,12 +11,14 @@ module Gemgem
11
11
  def pkg_dir ; "#{dir}/pkg" ; end
12
12
  def escaped_dir; @escaped_dir ||= Regexp.escape(dir); end
13
13
 
14
- def init dir, &block
14
+ def init dir, options={}, &block
15
15
  self.dir = dir
16
- $LOAD_PATH.unshift("#{dir}/lib")
17
16
  ENV['RUBYLIB'] = "#{dir}/lib:#{ENV['RUBYLIB']}"
18
17
  ENV['PATH'] = "#{dir}/bin:#{ENV['PATH']}"
18
+ self.submodules = options[:submodules] || []
19
19
  self.spec_create = block
20
+
21
+ $LOAD_PATH.unshift("#{dir}/lib", *submodules_libs)
20
22
  end
21
23
 
22
24
  def create
@@ -26,7 +28,7 @@ module Gemgem
26
28
 
27
29
  s.description = description.join
28
30
  s.summary = description.first
29
- s.license = readme['LICENSE'].sub(/.+\n\n/, '').lines.first.strip
31
+ s.license = license
30
32
 
31
33
  s.date = Time.now.strftime('%Y-%m-%d')
32
34
  s.files = gem_files
@@ -40,6 +42,7 @@ module Gemgem
40
42
 
41
43
  def gem_install
42
44
  require 'rubygems/commands/install_command'
45
+ require 'rubygems/package'
43
46
  # read ~/.gemrc
44
47
  Gem.use_paths(Gem.configuration[:gemhome], Gem.configuration[:gempath])
45
48
  Gem::Command.extra_args = Gem.configuration[:gem]
@@ -49,7 +52,8 @@ module Gemgem
49
52
  cmd.handle_options([])
50
53
 
51
54
  # install
52
- install = Gem::Installer.new(gem_path, cmd.options)
55
+ gem_package = Gem::Package.new(gem_path)
56
+ install = Gem::Installer.new(gem_package, cmd.options)
53
57
  install.install
54
58
  puts "\e[35mGem installed: \e[33m#{strip_path(install.gem_dir)}\e[0m"
55
59
  end
@@ -115,6 +119,7 @@ module Gemgem
115
119
  SimpleCov.start do
116
120
  add_filter('test/')
117
121
  add_filter('test.rb')
122
+ submodules_libs.each(&method(:add_filter))
118
123
  end
119
124
  end
120
125
 
@@ -159,11 +164,15 @@ module Gemgem
159
164
  end
160
165
 
161
166
  def strip_home_path path
162
- path.sub(ENV['HOME'], '~')
167
+ path.sub(/\A#{Regexp.escape(ENV['HOME'])}\//, '~/')
163
168
  end
164
169
 
165
170
  def strip_cwd_path path
166
- path.sub(Dir.pwd, '.')
171
+ path.sub(/\A#{Regexp.escape(Dir.pwd)}\//, '')
172
+ end
173
+
174
+ def submodules_libs
175
+ submodules.map{ |path| "#{dir}/#{path}/lib" }
167
176
  end
168
177
 
169
178
  def git *args
@@ -201,6 +210,11 @@ module Gemgem
201
210
  @description ||= (readme['DESCRIPTION']||'').sub(/.+\n\n/, '').lines.to_a
202
211
  end
203
212
 
213
+ def license
214
+ readme['LICENSE'].sub(/.+\n\n/, '').lines.first.
215
+ split(/[()]/).map(&:strip).reject(&:empty?).last
216
+ end
217
+
204
218
  def all_files
205
219
  @all_files ||= fold_files(glob).sort
206
220
  end
@@ -221,7 +235,8 @@ module Gemgem
221
235
 
222
236
  def gem_files
223
237
  @gem_files ||= all_files.reject{ |f|
224
- f =~ ignored_pattern && !git_files.include?(f)
238
+ f =~ submodules_pattern ||
239
+ (f =~ ignored_pattern && !git_files.include?(f))
225
240
  }
226
241
  end
227
242
 
@@ -253,6 +268,15 @@ module Gemgem
253
268
  end
254
269
  end
255
270
 
271
+ def submodules_pattern
272
+ @submodules_pattern ||= if submodules.empty?
273
+ /^$/
274
+ else
275
+ Regexp.new(submodules.map{ |path|
276
+ "^#{Regexp.escape(path)}/" }.join('|'))
277
+ end
278
+ end
279
+
256
280
  def expand_patterns pathes
257
281
  # http://git-scm.com/docs/gitignore
258
282
  pathes.flat_map{ |path|