pathological-v2 0.3.1
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.
- checksums.yaml +7 -0
- data/.travis.yml +3 -0
- data/.yardopts +1 -0
- data/Gemfile +4 -0
- data/LICENSE +19 -0
- data/README.md +197 -0
- data/Rakefile +15 -0
- data/TODO.md +66 -0
- data/lib/pathological.rb +3 -0
- data/lib/pathological/base.rb +264 -0
- data/lib/pathological/bundlerize.rb +9 -0
- data/lib/pathological/debug.rb +4 -0
- data/lib/pathological/excluderoot.rb +4 -0
- data/lib/pathological/noexceptions.rb +4 -0
- data/lib/pathological/parentdir.rb +8 -0
- data/lib/pathological/version.rb +3 -0
- data/pathological.gemspec +34 -0
- data/test/unit/pathological/base_test.rb +296 -0
- metadata +144 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2282cfdb2f31372fd8740f570abfaf4a9adb81480ea7f536e74a2bdfa48b894f
|
4
|
+
data.tar.gz: 394d74d57b85f8d461b15b5016b15e59b404b081bf22ea5195a9ef2ea74e81c7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d7fc1436cf05fa81fb3647b89d25fd82cfe78a40cce8e9c2313d514e25ff67df8edf1e027983347f087d926fb6e443f25a3114cbcd89d1cc0b65bd41cdc91f4e
|
7
|
+
data.tar.gz: ae0c8ace2fafd593eb2afea7b71d679a0bbe900a8d5acc7cce28f9e4b60964600aed3488479785f6d9c994140f7726932d1927f558767712856dd4a8f1a59b78
|
data/.travis.yml
ADDED
data/.yardopts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--no-private lib/pathological/base.rb - README.md LICENSE
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2011 Ooyala, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,197 @@
|
|
1
|
+
# Pathological
|
2
|
+
|
3
|
+
Pathological is a Ruby tool that provides a lightweight mechanism for managing your project's load path.
|
4
|
+
|
5
|
+
[](http://travis-ci.org/ooyala/pathological)
|
6
|
+
|
7
|
+
## The problem
|
8
|
+
|
9
|
+
When you're writing a gem, you don't have to worry about paths much, because Rubygems makes sure that `lib/`
|
10
|
+
makes it into your path for you. On the other hand, if you have large Ruby projects which aren't organized as
|
11
|
+
gems, you may encounter some of the following problems:
|
12
|
+
|
13
|
+
* If you don't have relative requires, you have to run your project from the project root.
|
14
|
+
* If you want relative requires, you have something nasty like this in your code:
|
15
|
+
|
16
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'myfile'))
|
17
|
+
|
18
|
+
* Ruby 1.9.2 breaks your load path if you are expecting `.` to be in it. You might have to use
|
19
|
+
`require_relative` or similar to remedy this.
|
20
|
+
* You have symlinks to shared libraries or non-gemified vendor code living all over your project in order
|
21
|
+
to keep your load paths sane.
|
22
|
+
|
23
|
+
Pathological provides one way to manage these issues.
|
24
|
+
|
25
|
+
## Using pathological
|
26
|
+
|
27
|
+
Getting started with pathological is easy. First, make a file called `Pathfile` at your project root:
|
28
|
+
|
29
|
+
$ cd path/to/myproject
|
30
|
+
$ touch Pathfile
|
31
|
+
|
32
|
+
Now require the gem at the start of any executable ruby file:
|
33
|
+
|
34
|
+
``` ruby
|
35
|
+
#!/usr/bin/env ruby
|
36
|
+
|
37
|
+
require "bundler/setup" # If you're using bundler
|
38
|
+
require "pathological"
|
39
|
+
|
40
|
+
# other requires...
|
41
|
+
```
|
42
|
+
|
43
|
+
Now your project root will be in your load path. If your project has, for example, `lib/foo.rb`, then `require
|
44
|
+
lib/foo` will work in any of your ruby files. This works because when Pathological is required it will search
|
45
|
+
up the directory tree until it finds a `Pathfile`. (It will raise an error if one cannot be found).
|
46
|
+
|
47
|
+
Note that Pathological should be the first require in your main file so that it will be loaded first. An
|
48
|
+
exception to this is when you're using Bundler, in which case you should `require bundler/setup` before
|
49
|
+
Pathological (and of course you should have `gem "pathological"` in your `Gemfile`).
|
50
|
+
|
51
|
+
`Pathfile`s should be kept in version control.
|
52
|
+
|
53
|
+
## Adding other paths to your load path
|
54
|
+
|
55
|
+
To add more paths to your load path, just put the paths in your `Pathfile`. The paths are relative to the
|
56
|
+
location of the `Pathfile`. The paths will be inserted in the order they appear; the project root itself will
|
57
|
+
be first. If any of the paths are not valid directories, then an exception will be raised when Pathological is
|
58
|
+
required.
|
59
|
+
|
60
|
+
#### Example
|
61
|
+
|
62
|
+
Suppose that you have a directory structure like this:
|
63
|
+
|
64
|
+
repos/
|
65
|
+
|-shared_lib/
|
66
|
+
| `-common.rb
|
67
|
+
`-my_project/
|
68
|
+
|-Pathfile
|
69
|
+
|-run_my_project.rb
|
70
|
+
`-foo.rb
|
71
|
+
|
72
|
+
and that `Pathfile` contains the following:
|
73
|
+
|
74
|
+
../shared_lib
|
75
|
+
|
76
|
+
Then inside `run_my_project.rb`:
|
77
|
+
|
78
|
+
``` ruby
|
79
|
+
require "pathological"
|
80
|
+
require "foo"
|
81
|
+
require "common"
|
82
|
+
# ...
|
83
|
+
```
|
84
|
+
|
85
|
+
## Installation
|
86
|
+
|
87
|
+
Pathological is packaged as a Rubygem and hence can be trivially installed with
|
88
|
+
|
89
|
+
$ gem install pathological
|
90
|
+
|
91
|
+
## Advanced usage
|
92
|
+
|
93
|
+
In some cases, you might want slightly different behavior. This customization is done through the use of
|
94
|
+
custom modes. You may use any combination of modes.
|
95
|
+
|
96
|
+
#### debug
|
97
|
+
|
98
|
+
This adds debugging statements to `STDOUT` that explain what Pathological is doing.
|
99
|
+
|
100
|
+
#### excluderoot
|
101
|
+
|
102
|
+
In this mode, the project root (where the `Pathfile` is located) is not added to the load path (so only paths
|
103
|
+
specified *in* the `Pathfile` will be loaded).
|
104
|
+
|
105
|
+
#### noexceptions
|
106
|
+
|
107
|
+
This is used if you don't want to raise exceptions if you have bad paths (i.e. non-existent paths or not
|
108
|
+
directories) in your `Pathfile`.
|
109
|
+
|
110
|
+
#### bundlerize
|
111
|
+
|
112
|
+
Bundlerize mode enables Bundler to work with your project regardless of your current directory, in the same
|
113
|
+
way as Pathological, by attempting to set the `BUNDLE_GEMFILE` environment variable to match the directory
|
114
|
+
where the `Pathfile` is located. Note that you have to run this before requiring `bundler/setup`. Also, this
|
115
|
+
will not take effect if you are running with `bundle exec`.
|
116
|
+
|
117
|
+
#### parentdir
|
118
|
+
|
119
|
+
This mode makes Pathological add the unique parents of all paths it finds (instead of the paths themselves).
|
120
|
+
The purpose of parentdir is to enable Pathological to work in a drop-in fashion with legacy code written with
|
121
|
+
all requires being relative to the root of the codebase. Note that this will allow one to require files
|
122
|
+
located in any child of the parents, not just from the directories specified in the `Pathfile`. This mode
|
123
|
+
should be avoided if possible.
|
124
|
+
|
125
|
+
There are two ways to specify modes. First, you can enable any modes you want using the Pathological API:
|
126
|
+
|
127
|
+
``` ruby
|
128
|
+
require "pathological/base"
|
129
|
+
Pathological.debug_mode
|
130
|
+
Pathological.parentdir_mode
|
131
|
+
Pathological.add_paths!
|
132
|
+
```
|
133
|
+
|
134
|
+
A quicker way is also provided: if you only need to use one special mode, then there is a dedicated file you
|
135
|
+
can require:
|
136
|
+
|
137
|
+
``` ruby
|
138
|
+
require "pathological/debug"
|
139
|
+
```
|
140
|
+
|
141
|
+
## Public API
|
142
|
+
|
143
|
+
For even more configurable custom integration with Pathological, a public API is provided. See the generated
|
144
|
+
documentation for details on the following public methods:
|
145
|
+
|
146
|
+
* `Pathological#add_paths!`
|
147
|
+
* `Pathological#find_load_paths`
|
148
|
+
* `Pathological#find_pathfile`
|
149
|
+
* `Pathological#reset!`
|
150
|
+
* `Pathological#copy_outside_paths!`
|
151
|
+
|
152
|
+
## Notes and gotchas
|
153
|
+
|
154
|
+
Pathological is intended as a replacement for manually munging the load path in your application when you want
|
155
|
+
to load code from other locations. If you can turn each of your dependencies into a gem and then use bundler
|
156
|
+
to manage the dependencies, **do that instead**.
|
157
|
+
|
158
|
+
Pathological does its best to figure out where the Pathfile it should use is located, based on the call stack.
|
159
|
+
For instance, if you run `/foo/bar.rb` and that requires Pathological, then it will search for `/foo/Pathfile`
|
160
|
+
and -- failing that -- `/Pathfile`. However, if `/foo/bar.rb` does not require Pathological, but loads a ruby
|
161
|
+
file in `/baz/quux.rb`, and *that* file requires Pathological, then Pathological searches for `/baz/Pathfile`
|
162
|
+
and then `/Pathfile`.
|
163
|
+
|
164
|
+
Any code loading situation which does not preserve a sane load path will be incompatible with Pathological.
|
165
|
+
For instance, if you `eval()` some code that requires Pathological, Pathological has no way of telling where
|
166
|
+
that code originally lived, and will probably behave in an unexpected way. One place this commonly occurs is
|
167
|
+
with rack webservers (e.g., Rackup, Unicorn) that load a `config.ru`. This file is `instance_eval`ed and so
|
168
|
+
requiring Pathological from your `config.ru` will not work as expected. In these cases, require Pathological
|
169
|
+
in your app directly.
|
170
|
+
|
171
|
+
## Authors
|
172
|
+
|
173
|
+
Pathological was written by the following Ooyala engineers:
|
174
|
+
|
175
|
+
* [Daniel MacDougall](mailto:dmac@ooyala.com)
|
176
|
+
* [Caleb Spare](mailto:caleb@ooyala.com)
|
177
|
+
* [Sami Abu-El-Haija](mailto:sami@ooyala.com)
|
178
|
+
* [Evan Chan](mailto:ev@ooyala.com)
|
179
|
+
|
180
|
+
## Credits
|
181
|
+
|
182
|
+
* Harry Robertson for the idea to *not* use a dot-prefixed configuration file
|
183
|
+
|
184
|
+
## Metadata
|
185
|
+
|
186
|
+
* [Hosted on Github](https://github.com/ooyala/pathological)
|
187
|
+
* [Rubygems page](https://rubygems.org/gems/pathological)
|
188
|
+
* [Documentation](http://rubydoc.info/github/ooyala/pathological/master/frames)
|
189
|
+
|
190
|
+
## Contributing
|
191
|
+
|
192
|
+
If you would like to commit a patch, great! Just do the usual github pull request stuff and we'll check it
|
193
|
+
out[.](http://www.randomkittengenerator.com/)
|
194
|
+
|
195
|
+
## License
|
196
|
+
|
197
|
+
Pathological is licensed under the MIT license.
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "bundler"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
Bundler::GemHelper.install_tasks
|
5
|
+
|
6
|
+
task :test => ["test:units"]
|
7
|
+
|
8
|
+
namespace :test do
|
9
|
+
Rake::TestTask.new(:units) do |task|
|
10
|
+
task.libs << "test"
|
11
|
+
task.test_files = FileList["test/unit/**/*_test.rb"]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
task :default => ["test:units"]
|
data/TODO.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
TODO
|
2
|
+
====
|
3
|
+
|
4
|
+
Tasks
|
5
|
+
-----
|
6
|
+
|
7
|
+
* Get all loaded files that come from Pathological directories (probably only in 1.9)
|
8
|
+
|
9
|
+
Design decisions
|
10
|
+
----------------
|
11
|
+
|
12
|
+
* Should we allow for including other Pathfiles? Proposed syntaxes:
|
13
|
+
|
14
|
+
include path/to/other/Pathfile
|
15
|
+
import path/to/other/Pathfile # Rakefile
|
16
|
+
i path/to/other/Pathfile
|
17
|
+
source path/to/other/Pathfile # Bash
|
18
|
+
. path/to/other/Pathfile # Bash
|
19
|
+
path/to/other/Pathfile # Distinguishable from regular path if Pathfile is not a directory
|
20
|
+
|
21
|
+
**Not needed now --Caleb**
|
22
|
+
|
23
|
+
* Do we like `>` to signify directives? Alternatives:
|
24
|
+
|
25
|
+
> exclude-root # Current syntax
|
26
|
+
exclude-root # Only problem is if you want to include a directory with the same name as a directive
|
27
|
+
|
28
|
+
We could also prefix each type of line to make things unambiguous:
|
29
|
+
|
30
|
+
p path/to/lib/
|
31
|
+
d exclude-root
|
32
|
+
|
33
|
+
**Fine for now --Caleb**
|
34
|
+
|
35
|
+
* Right now there's a small problem with comments: if your path includes the character `#`, then the rest
|
36
|
+
will be chopped off (interpreted as a comment). We could remedy this by only allowing for comments to
|
37
|
+
start at the beginning of lines:
|
38
|
+
|
39
|
+
# Yes
|
40
|
+
../lib/ # No
|
41
|
+
|
42
|
+
**Let's leave this alone for now; probably a non-issue --Caleb**
|
43
|
+
|
44
|
+
* Right our require paths tend to look like this (using `shared_lib/` as an example):
|
45
|
+
|
46
|
+
``` ruby
|
47
|
+
require "shared_lib/utils/foo_util"
|
48
|
+
```
|
49
|
+
|
50
|
+
To support this, you would need your `Pathfile` to include the directory *above* `shared_lib/`. The
|
51
|
+
downside of this is that it doesn't play well with the idea of using our `Pathfile`s to tell our deploy
|
52
|
+
scripts what to include. We could potentially add a new construct to allow the user to specify which
|
53
|
+
subdirectories they would be using. Example (just off the top of my head):
|
54
|
+
|
55
|
+
path/to/repo/dir/{shared_lib, common, vendor}
|
56
|
+
|
57
|
+
However, we'd still have to add `path/to/repo/dir` to the `$LOAD_PATH`, so the only way to enforce this at
|
58
|
+
require time would be to use a custom `require`. This is all quite a high cost to pay in terms of design
|
59
|
+
simplicity, but yet being able to use Pathfiles as a single place to document what dependencies to pull in
|
60
|
+
seems very appealing. Any ideas?
|
61
|
+
|
62
|
+
**After chatting with some people, we're going to leave this as is and truncate the `shared_lib` from our
|
63
|
+
paths. --Caleb**
|
64
|
+
|
65
|
+
**Actually, I think I'm going to add an optional mode to add one directory _above_ to the load path
|
66
|
+
instead of the given path, in order to accomomdate this use case. --Caleb**
|
data/lib/pathological.rb
ADDED
@@ -0,0 +1,264 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
module Pathological
|
4
|
+
PATHFILE_NAME = "Pathfile"
|
5
|
+
|
6
|
+
class PathologicalException < RuntimeError; end
|
7
|
+
class NoPathfileException < PathologicalException; end
|
8
|
+
|
9
|
+
# Add paths to the load path.
|
10
|
+
#
|
11
|
+
# @param [String] load_path the load path to use.
|
12
|
+
# @param [Array<String>] paths the array of new load paths (if +nil+, the result of {find_load_paths}).
|
13
|
+
def self.add_paths!(load_path = $LOAD_PATH, paths = nil)
|
14
|
+
begin
|
15
|
+
paths ||= find_load_paths
|
16
|
+
rescue NoPathfileException
|
17
|
+
STDERR.puts "Warning: using Pathological, but no Pathfile was found."
|
18
|
+
return
|
19
|
+
end
|
20
|
+
paths.each do |path|
|
21
|
+
if load_path.include? path
|
22
|
+
debug "Skipping <#{path}>, which is already in the load path."
|
23
|
+
else
|
24
|
+
debug "Adding <#{path}> to load path."
|
25
|
+
load_path << path
|
26
|
+
@@loaded_paths << path
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# For some pathfile, parse it and find all the load paths that it references.
|
32
|
+
#
|
33
|
+
# @param [String, nil] pathfile the pathfile to inspect. Uses {find_pathfile} if +nil+.
|
34
|
+
# @return [Array<String>] the resulting array of paths.
|
35
|
+
def self.find_load_paths(pathfile = nil)
|
36
|
+
pathfile ||= find_pathfile
|
37
|
+
raise NoPathfileException unless pathfile
|
38
|
+
begin
|
39
|
+
pathfile_handle = File.open(pathfile)
|
40
|
+
rescue Errno::ENOENT
|
41
|
+
raise NoPathfileException
|
42
|
+
rescue
|
43
|
+
raise PathologicalException, "There was an error opening the pathfile <#{pathfile}>."
|
44
|
+
end
|
45
|
+
parse_pathfile(pathfile_handle)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Find the pathfile by searching up from a starting directory. Symlinks are expanded out.
|
49
|
+
#
|
50
|
+
# @param [String] directory the starting directory. Defaults to the directory containing the running file.
|
51
|
+
# @return [String, nil] the absolute path to the pathfile (if it exists), otherwise +nil+.
|
52
|
+
def self.find_pathfile(directory = nil)
|
53
|
+
# If we're in IRB, use the working directory as the root of the search path for the Pathfile.
|
54
|
+
if $0 != __FILE__ && $0 == "irb"
|
55
|
+
directory = Dir.pwd
|
56
|
+
debug "In IRB -- using the cwd (#{directory}) as the search root for Pathfile."
|
57
|
+
end
|
58
|
+
return nil if directory && !File.directory?(directory)
|
59
|
+
# Find the full, absolute path of this directory, resolving symlinks. If no directory was given, use the
|
60
|
+
# directory where the file requiring pathological resides.
|
61
|
+
full_path = real_path(directory || requiring_filename)
|
62
|
+
current_path = directory ? full_path : File.dirname(full_path)
|
63
|
+
loop do
|
64
|
+
debug "Searching <#{current_path}> for Pathfile."
|
65
|
+
pathfile = File.join(current_path, PATHFILE_NAME)
|
66
|
+
if File.file? pathfile
|
67
|
+
debug "Pathfile found: <#{pathfile}>."
|
68
|
+
return pathfile
|
69
|
+
end
|
70
|
+
new_path = File.dirname current_path
|
71
|
+
if new_path == current_path
|
72
|
+
debug "Reached filesystem root, but no Pathfile found."
|
73
|
+
return nil
|
74
|
+
end
|
75
|
+
current_path = new_path
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Copies directories in pathfile to a destination, such that the destination has no references to
|
80
|
+
# directories outside of the destination in the load path.
|
81
|
+
#
|
82
|
+
# Hierarchy of destination directory:
|
83
|
+
# destination/
|
84
|
+
# Pathfile # new paths
|
85
|
+
# dependency_directory/
|
86
|
+
# dependency1 # Copied from original location
|
87
|
+
#
|
88
|
+
# This is very useful for deployment, for example.
|
89
|
+
#
|
90
|
+
# @param [String] copy_outside_paths the directory to stage dependencies in
|
91
|
+
# @param [String] dependency_directory the subdir within destination to put dependencies in
|
92
|
+
# @param [String] pathfile_search_path the directory at which to begin the search for the Pathfile by
|
93
|
+
# walking up the directory tree
|
94
|
+
#
|
95
|
+
# TODO(ev): Break this function up into a set of more functional primitives
|
96
|
+
def self.copy_outside_paths!(destination, options = {})
|
97
|
+
options = { :dependency_directory => "pathological_dependencies" }.merge(options)
|
98
|
+
saved_exclude_root = @@exclude_root
|
99
|
+
begin
|
100
|
+
self.excluderoot_mode
|
101
|
+
pathfile = self.find_pathfile(options[:pathfile_search_path])
|
102
|
+
# Nothing to do if there's no Pathfile
|
103
|
+
return unless pathfile && File.file?(pathfile)
|
104
|
+
|
105
|
+
foreign_paths = self.find_load_paths(pathfile).uniq
|
106
|
+
return if foreign_paths.empty?
|
107
|
+
|
108
|
+
path_root = File.join(destination, options[:dependency_directory])
|
109
|
+
FileUtils.mkdir_p path_root
|
110
|
+
|
111
|
+
# Copy in each path and save the relative paths to write to the rewritten Pathfile. We copy each unique
|
112
|
+
# path into the folder not as the basename, but as the longest suffix of the path necessary to make it
|
113
|
+
# unique. (Otherwise this won't work if you have two entries with the same basename in the Pathfile,
|
114
|
+
# such as "foo/lib" and "bar/lib".)
|
115
|
+
common_prefix = find_longest_common_prefix(foreign_paths)
|
116
|
+
new_pathfile_paths = foreign_paths.map do |foreign_path|
|
117
|
+
path_short_name = foreign_path.gsub(/^#{common_prefix}/, "")
|
118
|
+
symlinked_name = File.join(path_root, path_short_name)
|
119
|
+
FileUtils.mkdir_p File.split(symlinked_name)[0]
|
120
|
+
debug "About to move #{foreign_path} to #{symlinked_name}..."
|
121
|
+
copy_directory(foreign_path, symlinked_name)
|
122
|
+
File.join(options[:dependency_directory], path_short_name)
|
123
|
+
end
|
124
|
+
# Overwrite the Pathfile with the new relative paths.
|
125
|
+
File.open(File.join(destination, "Pathfile"), "w") do |file|
|
126
|
+
new_pathfile_paths.each { |path| file.puts path }
|
127
|
+
end
|
128
|
+
ensure
|
129
|
+
@@exclude_root = saved_exclude_root
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Convenience functions for the various modes in which Pathological may run.
|
134
|
+
|
135
|
+
def self.debug_mode; @@debug = true; end
|
136
|
+
def self.bundlerize_mode
|
137
|
+
pathfile = self.find_pathfile
|
138
|
+
raise NoPathfileException unless pathfile
|
139
|
+
bundle_gemfile = File.join(File.dirname(pathfile), "Gemfile")
|
140
|
+
unless File.file? bundle_gemfile
|
141
|
+
raise PathologicalException, "No Gemfile found in #{File.dirname(pathfile)}."
|
142
|
+
end
|
143
|
+
ENV["BUNDLE_GEMFILE"] = bundle_gemfile
|
144
|
+
end
|
145
|
+
def self.parentdir_mode; @@add_parents = true; end
|
146
|
+
def self.noexceptions_mode; @@no_exceptions = true; end
|
147
|
+
def self.excluderoot_mode; @@exclude_root = true; end
|
148
|
+
|
149
|
+
# Reset all Pathological options (useful if you want to require a different Pathfile)
|
150
|
+
def self.reset!
|
151
|
+
# Debug mode -- print out information about load paths
|
152
|
+
@@debug = false
|
153
|
+
# Parentdir mode -- add unique parents of specified directories.
|
154
|
+
@@add_parents = false
|
155
|
+
# Noexceptions mode -- don't raise exceptions if the Pathfile contains bad paths
|
156
|
+
@@no_exceptions = false
|
157
|
+
# Excluderoot mode -- don't add the project root (where the Pathfile lives) to the load path
|
158
|
+
@@exclude_root = false
|
159
|
+
|
160
|
+
@@loaded_paths ||= []
|
161
|
+
@@loaded_paths.each { |path| $LOAD_PATH.delete path }
|
162
|
+
@@loaded_paths = []
|
163
|
+
end
|
164
|
+
|
165
|
+
# private module methods
|
166
|
+
|
167
|
+
# Print debugging info
|
168
|
+
#
|
169
|
+
# @private
|
170
|
+
# @param [String] message the debugging message
|
171
|
+
# @return [void]
|
172
|
+
def self.debug(message); puts "[Pathological Debug] >> #{message}" if @@debug; end
|
173
|
+
|
174
|
+
# Turn a path into an absolute path with no useless parts and no symlinks.
|
175
|
+
#
|
176
|
+
# @private
|
177
|
+
# @param [String] the path
|
178
|
+
# @return [String] the absolute real path
|
179
|
+
def self.real_path(path); Pathname.new(path).realpath.to_s; end
|
180
|
+
|
181
|
+
# Parse a pathfile and return the appropriate paths.
|
182
|
+
#
|
183
|
+
# @private
|
184
|
+
# @param [IO] pathfile handle to the pathfile to parse
|
185
|
+
# @return [Array<String>] array of paths found
|
186
|
+
def self.parse_pathfile(pathfile)
|
187
|
+
root = File.dirname(real_path(pathfile.path))
|
188
|
+
raw_paths = [root]
|
189
|
+
pathfile.each do |line|
|
190
|
+
# Trim comments
|
191
|
+
line = line.split(/#/, 2)[0].strip
|
192
|
+
next if line.empty?
|
193
|
+
raw_path = Pathname.new(line).absolute? ? line : File.expand_path(File.join(root, line))
|
194
|
+
raw_paths << (@@add_parents ? File.dirname(raw_path) : raw_path)
|
195
|
+
end
|
196
|
+
|
197
|
+
paths = []
|
198
|
+
raw_paths.each do |path|
|
199
|
+
unless File.directory? path
|
200
|
+
unless @@no_exceptions
|
201
|
+
raise PathologicalException, "Bad path in Pathfile: #{path}"
|
202
|
+
end
|
203
|
+
debug "Ignoring non-existent path: #{path}"
|
204
|
+
next
|
205
|
+
end
|
206
|
+
next if @@exclude_root && File.expand_path(path) == File.expand_path(root)
|
207
|
+
paths << path
|
208
|
+
end
|
209
|
+
@@exclude_root ? paths.reject { |path| File.expand_path(path) == File.expand_path(root) } : paths
|
210
|
+
end
|
211
|
+
|
212
|
+
# Find the longest common path prefix amongst a list of paths
|
213
|
+
#
|
214
|
+
# @private
|
215
|
+
# @param [List<String>] a list of paths
|
216
|
+
# @return [String] the longest common prefix, or "/"
|
217
|
+
def self.find_longest_common_prefix(paths)
|
218
|
+
if paths.size == 1
|
219
|
+
common_prefix = File.split(paths[0])[0]
|
220
|
+
else
|
221
|
+
common_prefix = "/"
|
222
|
+
paths[0].split("/").reject(&:empty?).each do |part|
|
223
|
+
new_prefix = "#{common_prefix}#{part}/"
|
224
|
+
break unless paths.all? { |path| path.start_with? new_prefix }
|
225
|
+
common_prefix = new_prefix
|
226
|
+
end
|
227
|
+
end
|
228
|
+
common_prefix
|
229
|
+
end
|
230
|
+
|
231
|
+
# Copies a directory and all its symlinks to a destination.
|
232
|
+
# @private
|
233
|
+
def self.copy_directory(source, dest)
|
234
|
+
rsync_command = "rsync -r --archive --links --copy-unsafe-links --delete #{source}/ '#{dest}'"
|
235
|
+
debug `#{rsync_command}`
|
236
|
+
end
|
237
|
+
|
238
|
+
# Searches the call stack for the file that required pathological. If no file can be found, falls back to
|
239
|
+
# the currently executing file ($0). This handles the case where the app was launched by another executable
|
240
|
+
# (rake, thin, etc.)
|
241
|
+
#
|
242
|
+
# @return [String] name of file requiring pathological, or the currently executing file.
|
243
|
+
def self.requiring_filename
|
244
|
+
# Match paths like .../gems/pathological-0.2.2.1/lib/pathological/base.rb and also
|
245
|
+
# .../gems/pathological-0.2.2.1/lib/pathological.rb
|
246
|
+
pathological_file_pattern = %r{/pathological(/[^/]+|)\.rb}
|
247
|
+
requiring_file = Kernel.caller.find do |stack_line|
|
248
|
+
trimed_ruby_version = RUBY_VERSION[0..3].to_f rescue 1.9
|
249
|
+
if trimed_ruby_version >= 1.9
|
250
|
+
# In Ruby >=1.9, top-level files will have the string "top (required)" included in the stack listing.
|
251
|
+
stack_line.include?("top (required)") && stack_line !~ pathological_file_pattern
|
252
|
+
else
|
253
|
+
# In Ruby <=1.8, top-level files are listed with their relative path and without a line number.
|
254
|
+
stack_line !~ /:\d+:in/ && stack_line !~ pathological_file_pattern
|
255
|
+
end
|
256
|
+
end
|
257
|
+
requiring_file ? requiring_file.match(/(.+):\d+/)[1] : $0 rescue $0
|
258
|
+
end
|
259
|
+
|
260
|
+
private_class_method :debug, :real_path, :parse_pathfile, :find_longest_common_prefix, :copy_directory
|
261
|
+
|
262
|
+
# Reset options
|
263
|
+
Pathological.reset!
|
264
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# Make bundler compatible with Pathological (that is, enable Bundler projects to be run from anywhere as
|
2
|
+
# Pathological allows) by setting the BUNDLE_GEMFILE env variable.
|
3
|
+
#
|
4
|
+
# To use this, you *must* require pathological/bundlerize before you require bundler/setup.
|
5
|
+
|
6
|
+
require "pathological/base"
|
7
|
+
|
8
|
+
Pathological.bundlerize_mode
|
9
|
+
Pathological.add_paths!
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# In parentdir mode, Pathological will not add the individual specified paths to $LOAD_PATH, but will instead
|
2
|
+
# add the unique parents of the specified paths. This is to enable compatibility with legacy code where
|
3
|
+
# require paths are all written relative to a common repository root.
|
4
|
+
|
5
|
+
require "pathological/base"
|
6
|
+
|
7
|
+
Pathological.parentdir_mode
|
8
|
+
Pathological.add_paths!
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.unshift File.expand_path("../lib", __FILE__)
|
3
|
+
require "pathological/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "pathological-v2"
|
7
|
+
s.version = Pathological::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">=2.3.0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.specification_version = 2 if s.respond_to? :specification_version=
|
12
|
+
|
13
|
+
s.authors = "Maheshwaran G"
|
14
|
+
s.email = "maheshwarang@brightcove.com"
|
15
|
+
s.homepage = "http://www.ooyala.com"
|
16
|
+
s.rubyforge_project = "pathological-v2"
|
17
|
+
|
18
|
+
s.summary = "A nice way to manage your project's require paths."
|
19
|
+
s.description = <<-DESCRIPTION
|
20
|
+
Extension of Pathological Gem to support Ruby > 1.9 version
|
21
|
+
indicates all directories to include in the load path.
|
22
|
+
DESCRIPTION
|
23
|
+
|
24
|
+
s.files = `git ls-files`.split("\n").reject { |f| f == ".gitignore" }
|
25
|
+
s.require_paths = ["lib"]
|
26
|
+
|
27
|
+
# Require rr >= 1.0.3 and scope >= 0.2.3 for mutual compatibility.
|
28
|
+
s.add_development_dependency "rr", "=1.0.4"
|
29
|
+
s.add_development_dependency "scope", "~> 0.2.3"
|
30
|
+
s.add_development_dependency "fakefs", "~> 0.4.0"
|
31
|
+
s.add_development_dependency "rake", "~>0.9.2.2"
|
32
|
+
s.add_development_dependency "minitest", "=4.3.3"
|
33
|
+
s.add_development_dependency "dedent"
|
34
|
+
end
|
@@ -0,0 +1,296 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "scope"
|
3
|
+
require "rr"
|
4
|
+
require "minitest/autorun"
|
5
|
+
require "stringio"
|
6
|
+
require "fakefs/safe"
|
7
|
+
require "dedent"
|
8
|
+
|
9
|
+
# It's kind of funny that we need to do this hack, given that Pathological is intended to work around it...
|
10
|
+
$:.unshift(File.join(File.dirname(__FILE__), "../../lib"))
|
11
|
+
require "pathological/base"
|
12
|
+
|
13
|
+
module Pathological
|
14
|
+
class BaseTest < Scope::TestCase
|
15
|
+
include RR::Adapters::MiniTest
|
16
|
+
def assert_load_path(expected_load_path)
|
17
|
+
assert_equal expected_load_path.uniq.sort, @load_path.uniq.sort
|
18
|
+
end
|
19
|
+
|
20
|
+
context "Pathological" do
|
21
|
+
setup_once { FakeFS.activate! }
|
22
|
+
setup do
|
23
|
+
Pathological.reset!
|
24
|
+
@load_path = []
|
25
|
+
FakeFS::FileSystem.clear
|
26
|
+
# FakeFS has not implemented the necessary calls for Pathname#realpath to work.
|
27
|
+
stub(Pathological).real_path(anything) { |p| p }
|
28
|
+
end
|
29
|
+
teardown_once { FakeFS.deactivate! }
|
30
|
+
|
31
|
+
context "#add_paths!" do
|
32
|
+
should "not raise an error but print a warning when there's no pathfile" do
|
33
|
+
mock(Pathological).find_pathfile { nil }
|
34
|
+
mock(STDERR).puts(anything) { |m| assert_match /^Warning/, m }
|
35
|
+
Pathological.add_paths! @load_path
|
36
|
+
assert_load_path []
|
37
|
+
end
|
38
|
+
|
39
|
+
should "append the requested paths" do
|
40
|
+
paths = ["foo"]
|
41
|
+
Pathological.add_paths! @load_path, paths
|
42
|
+
assert_load_path paths
|
43
|
+
end
|
44
|
+
|
45
|
+
should "append the paths that #find_load_paths finds" do
|
46
|
+
paths = ["foo"]
|
47
|
+
mock(Pathological).find_load_paths { paths }
|
48
|
+
Pathological.add_paths! @load_path
|
49
|
+
assert_load_path paths
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "#find_load_paths" do
|
54
|
+
should "raise a NoPathfileException on a nil pathfile" do
|
55
|
+
mock(Pathological).find_pathfile { nil }
|
56
|
+
assert_raises(NoPathfileException) { Pathological.find_load_paths(nil) }
|
57
|
+
end
|
58
|
+
|
59
|
+
should "use #find_pathfile to find the Pathfile and #parse_pathfile to parse it." do
|
60
|
+
paths = ["path1"]
|
61
|
+
mock(Pathological).find_pathfile { "foo" }
|
62
|
+
mock(File).open("foo") { "bar" }
|
63
|
+
mock(Pathological).parse_pathfile("bar") { paths }
|
64
|
+
assert_equal paths, Pathological.find_load_paths
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "#find_pathfile" do
|
69
|
+
setup do
|
70
|
+
@working_directory = "/foo/bar/baz"
|
71
|
+
FileUtils.mkdir_p @working_directory
|
72
|
+
FileUtils.cd @working_directory
|
73
|
+
end
|
74
|
+
|
75
|
+
should "find a pathfile in this directory" do
|
76
|
+
pathfile = "/foo/bar/baz/Pathfile"
|
77
|
+
FileUtils.touch pathfile
|
78
|
+
assert_equal pathfile, Pathological.find_pathfile(@working_directory)
|
79
|
+
end
|
80
|
+
|
81
|
+
should "find a pathfile in a parent directory" do
|
82
|
+
pathfile = "/foo/bar/Pathfile"
|
83
|
+
FileUtils.touch pathfile
|
84
|
+
assert_equal pathfile, Pathological.find_pathfile(@working_directory)
|
85
|
+
end
|
86
|
+
|
87
|
+
should "find a pathfile at the root" do
|
88
|
+
pathfile = "/Pathfile"
|
89
|
+
FileUtils.touch pathfile
|
90
|
+
assert_equal pathfile, Pathological.find_pathfile(@working_directory)
|
91
|
+
end
|
92
|
+
|
93
|
+
should "locate a pathfile in the real path even if we're running from a symlinked directory" do
|
94
|
+
pathfile = "/foo/bar/baz/Pathfile"
|
95
|
+
FileUtils.touch pathfile
|
96
|
+
FileUtils.touch "/Pathfile" # Shouldn't find this one
|
97
|
+
symlinked_directory = "/foo/bar/quux"
|
98
|
+
FileUtils.ln_s @working_directory, symlinked_directory
|
99
|
+
stub(Pathological).real_path(anything) { |path| path.gsub("quux", "baz") }
|
100
|
+
assert_equal pathfile, Pathological.find_pathfile(@working_directory)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "#requiring_filename" do
|
105
|
+
setup do
|
106
|
+
@full_19_stacktrace = <<-EOS.dedent.split("\n").reject(&:empty?)
|
107
|
+
/Users/test/ruby/gems/1.9.1/gems/pathological-0.2.2.1/lib/pathological/base.rb:61:in `find_pathfile'
|
108
|
+
/Users/test/gems/pathological-0.2.2.1/lib/pathological/base.rb:36:in `find_load_paths'
|
109
|
+
/Users/test/gems/pathological-0.2.2.1/lib/pathological/base.rb:15:in `add_paths!'
|
110
|
+
/Users/test/gems/pathological-0.2.2.1/lib/pathological.rb:3:in `<top (required)>'
|
111
|
+
/Users/test/ruby/1.9.1/rubygems/custom_require.rb:59:in `require'
|
112
|
+
/Users/test/ruby/1.9.1/rubygems/custom_require.rb:59:in `rescue in require'
|
113
|
+
/Users/test/ruby/1.9.1/rubygems/custom_require.rb:35:in `require'
|
114
|
+
/Users/test/repos/pathological/test/rackup/app.rb:1:in `<top (required)>'
|
115
|
+
/Users/test/.rubies/1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:36:in `require'
|
116
|
+
EOS
|
117
|
+
@full_18_stacktrace = <<-EOS.dedent.split("\n").reject(&:empty?)
|
118
|
+
/Users/test/ruby/gems/1.8/gems/pathological-0.2.5/lib/pathological/base.rb:61:in `find_pathfile'
|
119
|
+
/Users/test/ruby/gems/1.8/gems/pathological-0.2.5/lib/pathological/base.rb:36:in `find_load_paths'
|
120
|
+
/Users/test/ruby/gems/1.8/gems/pathological-0.2.5/lib/pathological/base.rb:15:in `add_paths!'
|
121
|
+
/Users/test/ruby/gems/1.8/gems/pathological-0.2.5/lib/pathological.rb:3
|
122
|
+
/Users/test/ruby/site_ruby/1.8/rubygems/custom_require.rb:58:in `gem_original_require'
|
123
|
+
/Users/test/ruby/site_ruby/1.8/rubygems/custom_require.rb:58:in `require'
|
124
|
+
app.rb:2
|
125
|
+
EOS
|
126
|
+
@bad_stacktrace = <<-EOS.dedent.split("\n").reject(&:empty?)
|
127
|
+
/Users/test/repos/pathological/test/rackup/app.rb !!! `<top (required)>'
|
128
|
+
EOS
|
129
|
+
@empty_stacktrace = []
|
130
|
+
end
|
131
|
+
|
132
|
+
should "find root file from a stacktrace" do
|
133
|
+
if RUBY_VERSION.start_with?("1.9") || RUBY_VERSION.start_with?("2.3")
|
134
|
+
stub(Kernel).caller { @full_19_stacktrace }
|
135
|
+
else
|
136
|
+
stub(Kernel).caller { @full_18_stacktrace }
|
137
|
+
end
|
138
|
+
assert_equal "app.rb", File.basename(Pathological.requiring_filename)
|
139
|
+
end
|
140
|
+
|
141
|
+
should "return executing file from malformed stacktrace" do
|
142
|
+
stub(Kernel).caller { @bad_stacktrace }
|
143
|
+
assert Pathological.requiring_filename
|
144
|
+
end
|
145
|
+
|
146
|
+
should "return executing file if unable to find root file in stacktrace" do
|
147
|
+
stub(Kernel).caller { @empty_stacktrace }
|
148
|
+
assert Pathological.requiring_filename
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
context "loading pathological" do
|
153
|
+
setup do
|
154
|
+
@pathfile_contents = ""
|
155
|
+
@pathfile = "/Pathfile"
|
156
|
+
$0 = "/my_file"
|
157
|
+
FileUtils.touch @pathfile
|
158
|
+
FileUtils.cd "/"
|
159
|
+
end
|
160
|
+
|
161
|
+
# Load in pathfile contents and load Pathological
|
162
|
+
def load_and_run!
|
163
|
+
File.open(@pathfile, "w") { |f| f.write(@pathfile_contents) }
|
164
|
+
Pathological.add_paths!(@load_path)
|
165
|
+
end
|
166
|
+
|
167
|
+
should "use an empty Pathfile correctly" do
|
168
|
+
load_and_run!
|
169
|
+
assert_load_path ["/"]
|
170
|
+
end
|
171
|
+
|
172
|
+
should "add some paths as appropriate" do
|
173
|
+
paths = ["/foo/bar", "/baz"]
|
174
|
+
paths.each do |path|
|
175
|
+
FileUtils.mkdir_p path
|
176
|
+
@pathfile_contents << "#{path}\n"
|
177
|
+
end
|
178
|
+
load_and_run!
|
179
|
+
assert_load_path(paths << "/")
|
180
|
+
end
|
181
|
+
|
182
|
+
should "throw exceptions on bad load paths" do
|
183
|
+
path = "/foo/bar"
|
184
|
+
@pathfile_contents << "#{path}"
|
185
|
+
assert_raises(PathologicalException) { load_and_run! }
|
186
|
+
end
|
187
|
+
|
188
|
+
should "respect absolute paths" do
|
189
|
+
other = "/a/b"
|
190
|
+
@pathfile = "/src/Pathfile"
|
191
|
+
FileUtils.mkdir "/src"
|
192
|
+
FileUtils.mkdir_p other
|
193
|
+
FileUtils.touch @pathfile
|
194
|
+
File.open(@pathfile, "w") { |f| f.write(other) }
|
195
|
+
assert Pathological.find_load_paths("/src/Pathfile").include? other
|
196
|
+
end
|
197
|
+
|
198
|
+
should "print some debug info in debug mode" do
|
199
|
+
Pathological.debug_mode
|
200
|
+
mock(Pathological).puts(anything).at_least(3)
|
201
|
+
Pathological.add_paths!
|
202
|
+
end
|
203
|
+
|
204
|
+
should "set $BUNDLE_GEMFILE correctly in bundlerize mode" do
|
205
|
+
FileUtils.touch "/Gemfile"
|
206
|
+
Pathological.bundlerize_mode
|
207
|
+
Pathological.add_paths!
|
208
|
+
assert_equal "/Gemfile", ENV["BUNDLE_GEMFILE"]
|
209
|
+
end
|
210
|
+
|
211
|
+
should "add the correct directories in parentdir mode" do
|
212
|
+
paths = ["/foo/bar/baz1", "/foo/bar/baz2", "/foo/quux"]
|
213
|
+
paths.each { |path| FileUtils.mkdir_p path }
|
214
|
+
@pathfile_contents = paths.join("\n")
|
215
|
+
Pathological.parentdir_mode
|
216
|
+
load_and_run!
|
217
|
+
assert_load_path ["/", "/foo/bar", "/foo"]
|
218
|
+
end
|
219
|
+
|
220
|
+
should "not raise exceptions on bad paths in noexceptions mode" do
|
221
|
+
path = "/foo/bar"
|
222
|
+
@pathfile_contents << path
|
223
|
+
Pathological.noexceptions_mode
|
224
|
+
load_and_run!
|
225
|
+
assert_load_path ["/"]
|
226
|
+
end
|
227
|
+
|
228
|
+
should "not add the project root in excluderoot mode" do
|
229
|
+
path = "/foo/bar"
|
230
|
+
FileUtils.mkdir_p path
|
231
|
+
@pathfile_contents << path
|
232
|
+
Pathological.excluderoot_mode
|
233
|
+
load_and_run!
|
234
|
+
assert_load_path ["/foo/bar"]
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context "#copy_outside_paths!" do
|
239
|
+
setup do
|
240
|
+
@destination = "/tmp/staging"
|
241
|
+
@pathfile = "/Pathfile"
|
242
|
+
FileUtils.cd "/"
|
243
|
+
FileUtils.mkdir_p @destination
|
244
|
+
@source_paths = ["/src/github1", "/src/moofoo"]
|
245
|
+
@source_paths.each { |src_dir| FileUtils.mkdir_p src_dir }
|
246
|
+
end
|
247
|
+
|
248
|
+
should "return immediately if there is no Pathfile" do
|
249
|
+
mock(Pathological).find_pathfile(nil) { nil }
|
250
|
+
Pathological.copy_outside_paths! @destination
|
251
|
+
refute File.directory?(File.join(@destination, "pathological_dependencies"))
|
252
|
+
end
|
253
|
+
|
254
|
+
should "return immediately if Pathfile is empty" do
|
255
|
+
File.open(@pathfile, "w") { |f| f.puts "\n# What the heck is this file?\n\n" }
|
256
|
+
Pathological.copy_outside_paths! @destination
|
257
|
+
refute File.directory?(File.join(@destination, "pathological_dependencies"))
|
258
|
+
end
|
259
|
+
|
260
|
+
should "copy source dirs as links and rewrite Pathfile" do
|
261
|
+
File.open(@pathfile, "w") { |f| f.puts @source_paths.join("\n") }
|
262
|
+
|
263
|
+
final_path = File.join(@destination, "pathological_dependencies")
|
264
|
+
@source_paths.each do |source_path|
|
265
|
+
mock(Pathological).copy_directory(source_path, final_path + source_path.gsub("/src", "")).once
|
266
|
+
end
|
267
|
+
Pathological.copy_outside_paths! @destination
|
268
|
+
|
269
|
+
assert File.directory?(final_path)
|
270
|
+
destination_paths = @source_paths.map do |source_path|
|
271
|
+
"pathological_dependencies#{source_path.gsub("/src", "")}"
|
272
|
+
end
|
273
|
+
assert_equal destination_paths, File.read(File.join(@destination, "Pathfile")).split("\n")
|
274
|
+
end
|
275
|
+
|
276
|
+
should "copy source dirs as links and rewrite Pathfile in a different directory" do
|
277
|
+
other = "other/dir"
|
278
|
+
FileUtils.mkdir_p other
|
279
|
+
File.open(File.join(other, "Pathfile"), "w") { |f| f.puts @source_paths.join("\n") }
|
280
|
+
|
281
|
+
final_path = File.join(@destination, "pathological_dependencies")
|
282
|
+
@source_paths.each do |source_path|
|
283
|
+
mock(Pathological).copy_directory(source_path, final_path + source_path.gsub("/src", "")).once
|
284
|
+
end
|
285
|
+
Pathological.copy_outside_paths! @destination, :pathfile_search_path => other
|
286
|
+
|
287
|
+
assert File.directory?(final_path)
|
288
|
+
destination_paths = @source_paths.map do |source_path|
|
289
|
+
"pathological_dependencies#{source_path.gsub("/src", "")}"
|
290
|
+
end
|
291
|
+
assert_equal destination_paths, File.read(File.join(@destination, "Pathfile")).split("\n")
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
metadata
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pathological-v2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Maheshwaran G
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-01-27 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rr
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.0.4
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.0.4
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: scope
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.2.3
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.2.3
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: fakefs
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.4.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.4.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.9.2.2
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.9.2.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 4.3.3
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 4.3.3
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: dedent
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: |2
|
98
|
+
Extension of Pathological Gem to support Ruby > 1.9 version
|
99
|
+
indicates all directories to include in the load path.
|
100
|
+
email: maheshwarang@brightcove.com
|
101
|
+
executables: []
|
102
|
+
extensions: []
|
103
|
+
extra_rdoc_files: []
|
104
|
+
files:
|
105
|
+
- ".travis.yml"
|
106
|
+
- ".yardopts"
|
107
|
+
- Gemfile
|
108
|
+
- LICENSE
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- TODO.md
|
112
|
+
- lib/pathological.rb
|
113
|
+
- lib/pathological/base.rb
|
114
|
+
- lib/pathological/bundlerize.rb
|
115
|
+
- lib/pathological/debug.rb
|
116
|
+
- lib/pathological/excluderoot.rb
|
117
|
+
- lib/pathological/noexceptions.rb
|
118
|
+
- lib/pathological/parentdir.rb
|
119
|
+
- lib/pathological/version.rb
|
120
|
+
- pathological.gemspec
|
121
|
+
- test/unit/pathological/base_test.rb
|
122
|
+
homepage: http://www.ooyala.com
|
123
|
+
licenses: []
|
124
|
+
metadata: {}
|
125
|
+
post_install_message:
|
126
|
+
rdoc_options: []
|
127
|
+
require_paths:
|
128
|
+
- lib
|
129
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 2.3.0
|
139
|
+
requirements: []
|
140
|
+
rubygems_version: 3.1.2
|
141
|
+
signing_key:
|
142
|
+
specification_version: 2
|
143
|
+
summary: A nice way to manage your project's require paths.
|
144
|
+
test_files: []
|