Skip to content
Permalink
Browse files
[Truffle] Fix path resolution: either absolute or relative.
* No more resolution based on unintended CWD.
* Rename fileName to path since it is a full path.
  • Loading branch information
eregon committed Feb 23, 2015
1 parent f70ef66 commit 150c794b20c440df1bd28adf062832fd55bc7d6f
Showing with 32 additions and 32 deletions.
  1. +32 −32 truffle/src/main/java/org/jruby/truffle/runtime/subsystems/FeatureManager.java
@@ -58,24 +58,20 @@ public boolean require(String path, String feature, RubyNode currentNode) throws
return true;
}

// Try as a full path

if (requireFile(feature, currentNode)) {
return true;
}

if (requireFile(feature + ".rb", currentNode)) {
return true;
}

// Try each load path in turn

for (Object pathObject : context.getCoreLibrary().getLoadPath().slowToArray()) {
final String loadPath = pathObject.toString();

if (requireInPath(loadPath, feature, currentNode)) {
if (new File(feature).isAbsolute()) {
// Try as a full path
if (requireInPath(null, feature, currentNode)) {
return true;
}
} else {
// Try each load path in turn
for (Object pathObject : context.getCoreLibrary().getLoadPath().slowToArray()) {
final String loadPath = pathObject.toString();

if (requireInPath(loadPath, feature, currentNode)) {
return true;
}
}
}
}

@@ -90,31 +86,33 @@ public boolean require(String path, String feature, RubyNode currentNode) throws
}

private boolean requireInPath(String path, String feature, RubyNode currentNode) throws IOException {
if (requireFile(new File(path, feature).getPath(), currentNode)) {
String fullPath = new File(path, feature).getPath();

if (requireFile(fullPath, currentNode)) {
return true;
}

if (requireFile(new File(path, feature).getPath() + ".rb", currentNode)) {
if (requireFile(fullPath + ".rb", currentNode)) {
return true;
}

return false;
}

private boolean requireFile(String fileName, RubyNode currentNode) throws IOException {
private boolean requireFile(String path, RubyNode currentNode) throws IOException {
// We expect '/' in various classpath URLs, so normalize Windows file paths to use '/'
fileName = fileName.replace('\\', '/');
path = path.replace('\\', '/');

if (fileName.startsWith("uri:classloader:/")) {
if (path.startsWith("uri:classloader:/")) {
// TODO CS 13-Feb-15 this uri:classloader:/ and core:/ thing is a hack - simplify it

for (Object loaded : Arrays.asList(context.getCoreLibrary().getLoadedFeatures().slowToArray())) {
if (loaded.toString().equals(fileName)) {
if (loaded.toString().equals(path)) {
return true;
}
}

String coreFileName = fileName.substring("uri:classloader:/".length());
String coreFileName = path.substring("uri:classloader:/".length());

coreFileName = FileSystems.getDefault().getPath(coreFileName).normalize().toString();

@@ -123,36 +121,38 @@ private boolean requireFile(String fileName, RubyNode currentNode) throws IOExce
}

context.getCoreLibrary().loadRubyCore(coreFileName, "uri:classloader:/");
context.getCoreLibrary().getLoadedFeatures().slowPush(context.makeString(fileName));
context.getCoreLibrary().getLoadedFeatures().slowPush(context.makeString(path));

return true;
}
else if (fileName.startsWith("core:/")) {
else if (path.startsWith("core:/")) {
for (Object loaded : Arrays.asList(context.getCoreLibrary().getLoadedFeatures().slowToArray())) {
if (loaded.toString().equals(fileName)) {
if (loaded.toString().equals(path)) {
return true;
}
}

final String coreFileName = fileName.substring("core:/".length());
final String coreFileName = path.substring("core:/".length());

if (context.getRuntime().getLoadService().getClassPathResource(context.getRuntime().getJRubyClassLoader(), coreFileName) == null) {
return false;
}


context.getCoreLibrary().loadRubyCore(coreFileName, "core:/");
context.getCoreLibrary().getLoadedFeatures().slowPush(context.makeString(fileName));
context.getCoreLibrary().getLoadedFeatures().slowPush(context.makeString(path));

return true;
} else {
final File file = new File(fileName);
final File file = new File(path);

assert file.isAbsolute();

if (!file.isFile()) {
if (!file.isAbsolute() || !file.isFile()) {

This comment has been minimized.

Copy link
@chrisseaton

chrisseaton Mar 1, 2015

Contributor

I think this patch makes it so that you can't require_relative 'foo' any more - as the path is .. and that fails the isAbsolute test.

This comment has been minimized.

Copy link
@eregon

eregon Mar 1, 2015

Author Member

require_relative should provide a full path to FeatureManager.require, so this is fine.
But, isAbsolute() does not work well in callers since it should also consider core:/ and such as absolute or full paths.
require_relative is currently broken from main file because the value of __FILE__ or the Source.getPath is not a absolute path (which is OK) for __FILE__, but is also not expanded in require_relative.

return false;
}

final String expandedPath = RubyFile.expandPath(context, fileName);
final String expandedPath = RubyFile.expandPath(context, path);

for (Object loaded : Arrays.asList(context.getCoreLibrary().getLoadedFeatures().slowToArray())) {
if (loaded.toString().equals(expandedPath)) {
@@ -163,7 +163,7 @@ else if (fileName.startsWith("core:/")) {
context.getCoreLibrary().getLoadedFeatures().slowPush(context.makeString(expandedPath));

// TODO (nirvdrum 15-Jan-15): If we fail to load, we should remove the path from the loaded features because subsequent requires of the same statement may succeed.
context.loadFile(fileName, currentNode);
context.loadFile(path, currentNode);
}

return true;

0 comments on commit 150c794

Please sign in to comment.