buildpack-support 1.0.0
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 +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
|