pathological-v2 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://secure.travis-ci.org/ooyala/pathological.png)](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: []
|