buildpack-support 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +202 -0
- data/NOTICE +2 -0
- data/docs/cache.md +77 -0
- data/docs/component.md +1 -0
- data/docs/configuration.md +27 -0
- data/docs/logging.md +54 -0
- data/docs/other.md +1 -0
- data/docs/rake.md +1 -0
- data/docs/repository.md +116 -0
- data/docs/test.md +1 -0
- data/lib/buildpack_support.rb +18 -0
- data/lib/buildpack_support/base_buildpack.rb +166 -0
- data/lib/buildpack_support/buildpack_version.rb +124 -0
- data/lib/buildpack_support/cache.rb +24 -0
- data/lib/buildpack_support/cache/application_cache.rb +41 -0
- data/lib/buildpack_support/cache/cached_file.rb +103 -0
- data/lib/buildpack_support/cache/download_cache.rb +280 -0
- data/lib/buildpack_support/cache/inferred_network_failure.rb +26 -0
- data/lib/buildpack_support/cache/internet_availability.rb +64 -0
- data/lib/buildpack_support/component.rb +24 -0
- data/lib/buildpack_support/component/application.rb +76 -0
- data/lib/buildpack_support/component/base_component.rb +78 -0
- data/lib/buildpack_support/component/base_droplet.rb +96 -0
- data/lib/buildpack_support/component/downloads.rb +88 -0
- data/lib/buildpack_support/component/services.rb +84 -0
- data/lib/buildpack_support/component/versioned_dependency_component.rb +71 -0
- data/lib/buildpack_support/component/versioned_downloads.rb +57 -0
- data/lib/buildpack_support/component/with_timing.rb +40 -0
- data/lib/buildpack_support/configuration_utils.rb +58 -0
- data/lib/buildpack_support/constantize.rb +46 -0
- data/lib/buildpack_support/dash_case.rb +29 -0
- data/lib/buildpack_support/directory_finder.rb +45 -0
- data/lib/buildpack_support/filtering_pathname.rb +227 -0
- data/lib/buildpack_support/format_duration.rb +57 -0
- data/lib/buildpack_support/logging.rb +22 -0
- data/lib/buildpack_support/logging/delegating_logger.rb +48 -0
- data/lib/buildpack_support/logging/logger_factory.rb +148 -0
- data/lib/buildpack_support/qualify_path.rb +36 -0
- data/lib/buildpack_support/rake.rb +22 -0
- data/lib/buildpack_support/rake/buildpack_stage_task.rb +86 -0
- data/lib/buildpack_support/rake/cached_artifact_finder.rb +99 -0
- data/lib/buildpack_support/rake/check_api_doc_task.rb +70 -0
- data/lib/buildpack_support/rake/dependency_cache_task.rb +87 -0
- data/lib/buildpack_support/rake/disable_remote_downloads_task.rb +80 -0
- data/lib/buildpack_support/rake/package_task.rb +133 -0
- data/lib/buildpack_support/rake/package_zip_task.rb +80 -0
- data/lib/buildpack_support/rake/repository_configuration_finder.rb +66 -0
- data/lib/buildpack_support/rake/write_version_file_task.rb +82 -0
- data/lib/buildpack_support/repository.rb +24 -0
- data/lib/buildpack_support/repository/configured_item.rb +81 -0
- data/lib/buildpack_support/repository/repository_index.rb +98 -0
- data/lib/buildpack_support/repository/wildcard_version_resolver.rb +75 -0
- data/lib/buildpack_support/shell.rb +41 -0
- data/lib/buildpack_support/snake_case.rb +30 -0
- data/lib/buildpack_support/space_case.rb +29 -0
- data/lib/buildpack_support/test/application_helper.rb +41 -0
- data/lib/buildpack_support/test/base_component_helper.rb +59 -0
- data/lib/buildpack_support/test/base_droplet_helper.rb +36 -0
- data/lib/buildpack_support/test/console_helper.rb +57 -0
- data/lib/buildpack_support/test/environment_helper.rb +32 -0
- data/lib/buildpack_support/test/internet_availability_helper.rb +29 -0
- data/lib/buildpack_support/test/logging_helper.rb +50 -0
- data/lib/buildpack_support/test/scratch_helper.rb +32 -0
- data/lib/buildpack_support/test/versioned_dependency_component_helper.rb +32 -0
- data/lib/buildpack_support/test/with_load_path_helper.rb +27 -0
- data/lib/buildpack_support/to_b.rb +38 -0
- data/lib/buildpack_support/tokenized_version.rb +157 -0
- data/lib/buildpack_support/version.rb +23 -0
- data/spec/buildpack_support/base_buildpack_spec.rb +112 -0
- data/spec/buildpack_support/buildpack_version_spec.rb +122 -0
- data/spec/buildpack_support/cache/application_cache_spec.rb +56 -0
- data/spec/buildpack_support/cache/cached_file_spec.rb +94 -0
- data/spec/buildpack_support/cache/download_cache_spec.rb +293 -0
- data/spec/buildpack_support/cache/internet_availability_spec.rb +57 -0
- data/spec/buildpack_support/cache/yield_file_with_content.rb +30 -0
- data/spec/buildpack_support/component/application_spec.rb +81 -0
- data/spec/buildpack_support/component/base_component_spec.rb +81 -0
- data/spec/buildpack_support/component/base_droplet_spec.rb +72 -0
- data/spec/buildpack_support/component/downloads_spec.rb +63 -0
- data/spec/buildpack_support/component/services_spec.rb +80 -0
- data/spec/buildpack_support/component/versioned_dependency_component_spec.rb +58 -0
- data/spec/buildpack_support/component/versioned_downloads_spec.rb +58 -0
- data/spec/buildpack_support/component/with_timing_spec.rb +30 -0
- data/spec/buildpack_support/configuration_utils_spec.rb +39 -0
- data/spec/buildpack_support/constantize_spec.rb +34 -0
- data/spec/buildpack_support/dash_case_spec.rb +41 -0
- data/spec/buildpack_support/directory_finder_spec.rb +41 -0
- data/spec/buildpack_support/filtering_pathname_spec.rb +443 -0
- data/spec/buildpack_support/format_duration_spec.rb +60 -0
- data/spec/buildpack_support/logging/delegating_logger_spec.rb +62 -0
- data/spec/buildpack_support/logging/logger_factory_spec.rb +262 -0
- data/spec/buildpack_support/qualify_path_spec.rb +42 -0
- data/spec/buildpack_support/rake/buildpack_stage_task_spec.rb +88 -0
- data/spec/buildpack_support/rake/cached_artifact_finder_spec.rb +73 -0
- data/spec/buildpack_support/rake/check_api_doc_task_spec.rb +69 -0
- data/spec/buildpack_support/rake/dependency_cache_task_spec.rb +133 -0
- data/spec/buildpack_support/rake/disable_remote_downloads_task_spec.rb +91 -0
- data/spec/buildpack_support/rake/package_task_spec.rb +335 -0
- data/spec/buildpack_support/rake/package_zip_task_spec.rb +91 -0
- data/spec/buildpack_support/rake/repository_configuration_finder_spec.rb +61 -0
- data/spec/buildpack_support/rake/write_version_file_task_spec.rb +96 -0
- data/spec/buildpack_support/repository/configured_item_spec.rb +78 -0
- data/spec/buildpack_support/repository/repository_index_spec.rb +118 -0
- data/spec/buildpack_support/repository/wildcard_version_resolver_spec.rb +73 -0
- data/spec/buildpack_support/shell_spec.rb +32 -0
- data/spec/buildpack_support/snake_case_spec.rb +45 -0
- data/spec/buildpack_support/space_case_spec.rb +41 -0
- data/spec/buildpack_support/to_b_spec.rb +41 -0
- data/spec/buildpack_support/tokenized_version_spec.rb +132 -0
- data/spec/fixtures/application/test-file +0 -0
- data/spec/fixtures/config/found-config.yml +2 -0
- data/spec/fixtures/droplet-resources/droplet-resource +0 -0
- data/spec/fixtures/stub-download-with-top-level.zip +0 -0
- data/spec/fixtures/stub-download.tar.gz +0 -0
- data/spec/fixtures/stub-download.zip +0 -0
- data/spec/fixtures/test-cache.yml +18 -0
- data/spec/fixtures/test-index.yml +2 -0
- data/spec/fixtures/test_component.rb +0 -0
- data/spec/fixtures/zip-contents/test-directory/test-deep-file +0 -0
- data/spec/fixtures/zip-contents/test-file +0 -0
- data/spec/spec_helper.rb +30 -0
- metadata +416 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
# Copyright 2013-2014 the original author or authors.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'buildpack_support/component'
|
17
|
+
|
18
|
+
module BuildpackSupport
|
19
|
+
module Component
|
20
|
+
|
21
|
+
# A mixin for printing out a caption and timing when executing a block
|
22
|
+
module WithTiming
|
23
|
+
|
24
|
+
# Wrap the execution of a block with timing information
|
25
|
+
#
|
26
|
+
# @param [String] caption the caption to print when timing starts
|
27
|
+
# @return [Void]
|
28
|
+
def with_timing(caption)
|
29
|
+
start_time = Time.now
|
30
|
+
print " #{caption} "
|
31
|
+
|
32
|
+
yield
|
33
|
+
|
34
|
+
puts "(#{(Time.now - start_time).duration})"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
# Copyright 2013-2014 the original author or authors.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'buildpack_support'
|
17
|
+
require 'buildpack_support/directory_finder'
|
18
|
+
require 'buildpack_support/logging/logger_factory'
|
19
|
+
require 'pathname'
|
20
|
+
require 'yaml'
|
21
|
+
|
22
|
+
module BuildpackSupport
|
23
|
+
|
24
|
+
# Utilities for dealing with Configuration files
|
25
|
+
class ConfigurationUtils
|
26
|
+
include DirectoryFinder
|
27
|
+
|
28
|
+
# Creates a new instance
|
29
|
+
#
|
30
|
+
# @param [Boolean] should_log whether the contents of the configuration file should be logged. This value should be
|
31
|
+
# left to its default and exists to allow the logger to use the utility.
|
32
|
+
def initialize(should_log = true)
|
33
|
+
@config_directory = load_path_peer 'config'
|
34
|
+
@logger = BuildpackSupport::Logging::LoggerFactory.instance.get_logger ConfigurationUtils if should_log
|
35
|
+
end
|
36
|
+
|
37
|
+
# Loads a configuration file from the buildpack configuration directory. If the configuration file does not exist,
|
38
|
+
# returns an empty hash.
|
39
|
+
#
|
40
|
+
# @param [String] identifier the identifier of the configuration
|
41
|
+
# @return [Hash] the configuration or an empty hash if the configuration file does not exist
|
42
|
+
def load(identifier)
|
43
|
+
file = @config_directory + "#{identifier}.yml"
|
44
|
+
|
45
|
+
configuration = {}
|
46
|
+
if file.exist?
|
47
|
+
configuration = YAML.load_file(file)
|
48
|
+
@logger.debug { "Configuration from #{file}: #{configuration}" } if @logger
|
49
|
+
else
|
50
|
+
@logger.debug { "No configuration file #{file} found" } if @logger
|
51
|
+
end
|
52
|
+
|
53
|
+
configuration
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
# Copyright 2013-2014 the original author or authors.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
# A mixin that adds the ability to turn a +String+ into a constant.
|
17
|
+
class String
|
18
|
+
|
19
|
+
# Tries to find a constant with the name specified by this +String+:
|
20
|
+
#
|
21
|
+
# "Module".constantize # => Module
|
22
|
+
# "Test::Unit".constantize # => Test::Unit
|
23
|
+
#
|
24
|
+
# The name is assumed to be the one of a top-level constant, no matter whether
|
25
|
+
# it starts with "::" or not. No lexical context is taken into account:
|
26
|
+
#
|
27
|
+
# C = 'outside'
|
28
|
+
# module M
|
29
|
+
# C = 'inside'
|
30
|
+
# C # => 'inside'
|
31
|
+
# "C".constantize # => 'outside', same as ::C
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# @return [String] The constantized rendering of this +String+.
|
35
|
+
# @raise NameError if the name is not in CamelCase or the constant is unknown.
|
36
|
+
def constantize
|
37
|
+
names = split('::')
|
38
|
+
names.shift if names.empty? || names.first.empty?
|
39
|
+
|
40
|
+
constant = Object
|
41
|
+
names.each do |name|
|
42
|
+
constant = constant.const_defined?(name, false) ? constant.const_get(name) : constant.const_missing(name)
|
43
|
+
end
|
44
|
+
constant
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
# Copyright 2013-2014 the original author or authors.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
# A mixin that adds the ability to turn a +String+ into dash case
|
17
|
+
class String
|
18
|
+
|
19
|
+
# Converts a string to dash case. For example, the String +Foo::DashCase+ would become +dash-case+.
|
20
|
+
#
|
21
|
+
# @return [String] The dash case rendering of this +String+
|
22
|
+
def dash_case
|
23
|
+
split('::').last
|
24
|
+
.gsub(/([A-Z]+)([A-Z][a-z])/, '\1-\2')
|
25
|
+
.gsub(/([a-z\d])([A-Z])/, '\1-\2')
|
26
|
+
.downcase
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
# Copyright 2013-2014 the original author or authors.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'buildpack_support'
|
17
|
+
require 'pathname'
|
18
|
+
|
19
|
+
module BuildpackSupport
|
20
|
+
|
21
|
+
# A module encapsulating all of the code for the directory finding utilities
|
22
|
+
module DirectoryFinder
|
23
|
+
|
24
|
+
# Finds a directory that is a peer of the +$LOAD_PATH+
|
25
|
+
#
|
26
|
+
# @param [String] name the name of the peer directory
|
27
|
+
# @return [Pathname] the path to the found directory if it exists, otherwise a path to the current working directory
|
28
|
+
def load_path_peer(name)
|
29
|
+
directory = Pathname.new('.nil')
|
30
|
+
|
31
|
+
$LOAD_PATH.each do |path|
|
32
|
+
candidate = Pathname.new(path) + '..' + name
|
33
|
+
|
34
|
+
next unless candidate.exist?
|
35
|
+
|
36
|
+
directory = candidate
|
37
|
+
break
|
38
|
+
end
|
39
|
+
|
40
|
+
directory
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
# Encoding: utf-8
|
2
|
+
# Copyright 2013-2014 the original author or authors.
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
|
16
|
+
require 'buildpack_support'
|
17
|
+
require 'pathname'
|
18
|
+
require 'set'
|
19
|
+
|
20
|
+
module BuildpackSupport
|
21
|
+
|
22
|
+
# This class conforms to the interface of +Pathname+, but filters the set of files that can be accessed and does not
|
23
|
+
# support +Pathname+'s class methods. This class also provides a +glob+ instance method which filters its output.
|
24
|
+
#
|
25
|
+
# If a +Pathname+ method which mutates the file system is called, it will throw an exception unless the instance is
|
26
|
+
# created as mutable.
|
27
|
+
#
|
28
|
+
# If the underlying filesystem is modified once an instance of this path has been created, the view provided
|
29
|
+
# by the instance will not change unless a file or directory allowed by the instance's filter is created, modified, or
|
30
|
+
# deleted.
|
31
|
+
class FilteringPathname
|
32
|
+
|
33
|
+
# Create a +FilteringPathname+ which behaves like the given pathname, but which applies the given filter to all files.
|
34
|
+
#
|
35
|
+
# The filesystem underpinning the given pathname must not contain a file or directory whose name is the name of the
|
36
|
+
# given pathname with '.nil' appended to it. This must be true for the lifetime of the +FilteringPathname+.
|
37
|
+
#
|
38
|
+
# The filter is applied to files which are accessed via the given pathname.
|
39
|
+
# If the filter returns +true+ for a particular pathname, the pathname behaves normally for this instance.
|
40
|
+
# If the filter returns +false+ for a particular pathname, the pathname behaves as if it does not exist.
|
41
|
+
#
|
42
|
+
# Note that the filter must obey the following rule: if the filter accepts Pathnames p and r, where p is a parent
|
43
|
+
# directory of r, then the filter must accept every Pathname q where p is a parent directory of q and q is a parent
|
44
|
+
# directory of r. FilteringPathname does not check that the filter obeys this rule.
|
45
|
+
#
|
46
|
+
# The +FilteringPathname+ may be immutable in which case calling a mutator method causes an exception to be thrown.
|
47
|
+
# Alternatively, the +FilteringPathname+ may be mutable in which case calling a mutator method may mutate the
|
48
|
+
# file system. The results of mutating the file system will be subject to filtering by the given filter.
|
49
|
+
#
|
50
|
+
# @param [Pathname] pathname the +Pathname+ which is to be filtered
|
51
|
+
# @param [Proc] filter a lambda which takes a +Pathname+ and returns either +true+ (to 'keep' the pathname) or
|
52
|
+
# +false+ (to filter out the pathname). Defaults to keeping everything
|
53
|
+
# @param [Boolean] mutable +true+ if and only if the +FilteringPathname+ may be used to mutate the file system
|
54
|
+
def initialize(pathname, filter, mutable)
|
55
|
+
fail 'Non-absolute pathname' unless pathname.absolute?
|
56
|
+
|
57
|
+
@pathname = pathname
|
58
|
+
@filter = filter
|
59
|
+
@mutable = mutable
|
60
|
+
|
61
|
+
@non_existent = Pathname.new "#{pathname}.nil"
|
62
|
+
check_file_does_not_exist @non_existent
|
63
|
+
|
64
|
+
@delegated_pathname = filter(@pathname) ? @pathname : @non_existent
|
65
|
+
end
|
66
|
+
|
67
|
+
# @see Pathname.
|
68
|
+
def <=>(other)
|
69
|
+
@pathname <=> comparison_target(other)
|
70
|
+
end
|
71
|
+
|
72
|
+
# @see Pathname.
|
73
|
+
def ==(other)
|
74
|
+
@pathname == comparison_target(other)
|
75
|
+
end
|
76
|
+
|
77
|
+
# @see Pathname.
|
78
|
+
def ===(other)
|
79
|
+
@pathname === comparison_target(other) # rubocop:disable CaseEquality
|
80
|
+
end
|
81
|
+
|
82
|
+
# Dispatch superclass methods via method_missing.
|
83
|
+
undef_method :taint
|
84
|
+
undef_method :untaint
|
85
|
+
|
86
|
+
# @see Pathname.
|
87
|
+
def +(other)
|
88
|
+
filtered_pathname(@pathname + other)
|
89
|
+
end
|
90
|
+
|
91
|
+
# @see Pathname.
|
92
|
+
def each_entry(&block)
|
93
|
+
delegate_and_yield_visible(:each_entry, &block)
|
94
|
+
end
|
95
|
+
|
96
|
+
# @see Pathname.
|
97
|
+
def entries
|
98
|
+
visible delegate.entries
|
99
|
+
end
|
100
|
+
|
101
|
+
# @see Pathname.
|
102
|
+
def open(mode = nil, *args, &block)
|
103
|
+
check_mutable if mode =~ /[wa]/
|
104
|
+
delegate.open(mode, *args, &block)
|
105
|
+
end
|
106
|
+
|
107
|
+
# @see Pathname.
|
108
|
+
def to_s
|
109
|
+
@pathname.to_s
|
110
|
+
end
|
111
|
+
|
112
|
+
# @see Pathname.
|
113
|
+
def children(with_directory = true)
|
114
|
+
if with_directory
|
115
|
+
super # delegate to method_missing
|
116
|
+
else
|
117
|
+
visible delegate.children(false)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# @see Pathname.
|
122
|
+
def each_child(with_directory = true, &block)
|
123
|
+
if with_directory
|
124
|
+
super # delegate to method_missing
|
125
|
+
else
|
126
|
+
delegate_and_yield_visible(:each_child, false, &block)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
# Execute this +FilteringPathname+ as a glob.
|
131
|
+
def glob(flags = 0)
|
132
|
+
if block_given?
|
133
|
+
Pathname.glob(@pathname, flags) do |file|
|
134
|
+
yield filtered_pathname(file) if visible file
|
135
|
+
end
|
136
|
+
else
|
137
|
+
result = Pathname.glob(@pathname, flags)
|
138
|
+
convert_result_if_necessary(result)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
attr_reader :pathname
|
143
|
+
|
144
|
+
protected :pathname
|
145
|
+
|
146
|
+
private
|
147
|
+
|
148
|
+
MUTATORS = [:chmod, :chown, :delete, :lchmod, :lchown, :make_link, :make_symlink, :mkdir, :mkpath, :rename, :rmdir, :rmtree, :taint, :unlink, :untaint].to_set.freeze
|
149
|
+
|
150
|
+
private_constant :MUTATORS
|
151
|
+
|
152
|
+
def check_file_does_not_exist(file)
|
153
|
+
fail "#{file} should not exist" if file.exist?
|
154
|
+
end
|
155
|
+
|
156
|
+
def check_mutable
|
157
|
+
fail 'FilteringPathname is immutable' unless @mutable
|
158
|
+
end
|
159
|
+
|
160
|
+
def comparison_target(other)
|
161
|
+
other.instance_of?(FilteringPathname) ? other.pathname : other
|
162
|
+
end
|
163
|
+
|
164
|
+
def convert_if_necessary(r)
|
165
|
+
if r.instance_of?(Pathname) && r.absolute?
|
166
|
+
filter(r) ? filtered_pathname(r) : nil
|
167
|
+
else
|
168
|
+
r
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def convert_result_if_necessary(result)
|
173
|
+
if result.instance_of? Array
|
174
|
+
result.map { |r| convert_if_necessary(r) }.compact
|
175
|
+
else
|
176
|
+
result ? convert_if_necessary(result) || filtered_pathname(@non_existent) : nil
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
def delegate
|
181
|
+
check_file_does_not_exist @non_existent
|
182
|
+
@delegated_pathname
|
183
|
+
end
|
184
|
+
|
185
|
+
def delegate_and_yield_visible(method, *args)
|
186
|
+
delegate.send(method, *args) do |y|
|
187
|
+
yield y if visible y
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def filtered_pathname(pathname)
|
192
|
+
FilteringPathname.new(pathname, @filter, @mutable)
|
193
|
+
end
|
194
|
+
|
195
|
+
def method_missing(method, *args)
|
196
|
+
check_mutable if MUTATORS.member? method
|
197
|
+
if block_given?
|
198
|
+
result = delegate.send(method, *args) do |*values|
|
199
|
+
converted_values = values.map { |value| convert_if_necessary(value) }.compact
|
200
|
+
yield(*converted_values) unless converted_values.empty?
|
201
|
+
end
|
202
|
+
else
|
203
|
+
result = delegate.send(method, *args)
|
204
|
+
end
|
205
|
+
convert_result_if_necessary(result)
|
206
|
+
end
|
207
|
+
|
208
|
+
def respond_to_missing?(symbol, include_private = false)
|
209
|
+
delegate.respond_to?(symbol, include_private)
|
210
|
+
end
|
211
|
+
|
212
|
+
def visible(entry)
|
213
|
+
if entry.instance_of? Array
|
214
|
+
entry.select { |child| visible(child) }
|
215
|
+
else
|
216
|
+
filter(@pathname + entry)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def filter(pathname)
|
221
|
+
fail 'Non-absolute pathname' unless pathname.absolute?
|
222
|
+
@filter.call(pathname.cleanpath)
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
226
|
+
|
227
|
+
end
|