From f408406ef0ecbc7aa7acb5f29a9706772ce6b29b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Fri, 14 Jun 2013 08:29:21 -0700 Subject: [PATCH] Support symlinks in .relativize() and .contains() --- spec/app/directory-spec.coffee | 32 ++++++++++++++++++++++++++++ spec/app/project-spec.coffee | 7 ------- src/app/directory.coffee | 38 ++++++++++++++++++++++++++++++++++ src/app/project.coffee | 8 ++----- 4 files changed, 72 insertions(+), 13 deletions(-) diff --git a/spec/app/directory-spec.coffee b/spec/app/directory-spec.coffee index 3d8545d41..23d1f1d64 100644 --- a/spec/app/directory-spec.coffee +++ b/spec/app/directory-spec.coffee @@ -74,3 +74,35 @@ describe "Directory", -> expect(entry.symlink).toBeTruthy() else expect(entry.symlink).toBeFalsy() + + describe ".relativize(path)", -> + it "returns a relative path based on the directory's path", -> + absolutePath = directory.getPath() + expect(directory.relativize(path.join(absolutePath, "b"))).toBe "b" + expect(directory.relativize(path.join(absolutePath, "b/file.coffee"))).toBe "b/file.coffee" + expect(directory.relativize(path.join(absolutePath, "file.coffee"))).toBe "file.coffee" + + it "returns a relative path based on the directory's symlinked source path", -> + symlinkPath = path.join(fsUtils.resolveOnLoadPath('fixtures'), 'symlink-to-dir') + symlinkDirectory = new Directory(symlinkPath) + realFilePath = fsUtils.resolveOnLoadPath('fixtures/dir/a') + expect(symlinkDirectory.relativize(realFilePath)).toBe 'a' + + it "returns the full path if the directory's path is not a prefix of the path", -> + expect(directory.relativize('/not/relative')).toBe '/not/relative' + + describe ".contains(path)", -> + it "returns true if the path is a child of the directory's path", -> + absolutePath = directory.getPath() + expect(directory.contains(path.join(absolutePath, "b"))).toBe true + expect(directory.contains(path.join(absolutePath, "b/file.coffee"))).toBe true + expect(directory.contains(path.join(absolutePath, "file.coffee"))).toBe true + + it "returns true if the path is a child of the directory's symlinked source path", -> + symlinkPath = path.join(fsUtils.resolveOnLoadPath('fixtures'), 'symlink-to-dir') + symlinkDirectory = new Directory(symlinkPath) + realFilePath = fsUtils.resolveOnLoadPath('fixtures/dir/a') + expect(symlinkDirectory.contains(realFilePath)).toBe true + + it "returns false if the directory's path is not a prefix of the path", -> + expect(directory.contains('/not/relative')).toBe false diff --git a/spec/app/project-spec.coffee b/spec/app/project-spec.coffee index 4ee436805..7ae1e62cc 100644 --- a/spec/app/project-spec.coffee +++ b/spec/app/project-spec.coffee @@ -111,13 +111,6 @@ describe "Project", -> it "does not modify uris that begin with a scheme", -> expect(project.resolve('http://zombo.com')).toBe 'http://zombo.com' - describe ".relativize(path)", -> - it "returns an relative path based on the project's root", -> - absolutePath = fsUtils.resolveOnLoadPath('fixtures/dir') - expect(project.relativize(path.join(absolutePath, "b"))).toBe "b" - expect(project.relativize(path.join(absolutePath, "b/file.coffee"))).toBe "b/file.coffee" - expect(project.relativize(path.join(absolutePath, "file.coffee"))).toBe "file.coffee" - describe ".setPath(path)", -> describe "when path is a file", -> it "sets its path to the files parent directory and updates the root directory", -> diff --git a/src/app/directory.coffee b/src/app/directory.coffee index 6bc0434ed..95d997198 100644 --- a/src/app/directory.coffee +++ b/src/app/directory.coffee @@ -12,6 +12,7 @@ EventEmitter = require 'event-emitter' module.exports = class Directory path: null + realPath: null ### Public ### @@ -32,6 +33,43 @@ class Directory # Returns a {String}. getPath: -> @path + # Retrieves this directory's real path. + # + # Returns a {String}. + getRealPath: -> + unless @realPath? + try + @realPath = fs.realpathSync(@path) + catch e + @realPath = @path + @realPath + + # Is the given path inside this directory? + # + # pathToCheck - the {String} path to check. + # + # Returns a {Boolean}. + contains: (pathToCheck='') -> + if pathToCheck.indexOf(path.join(@getPath(), path.sep)) is 0 + true + else if pathToCheck.indexOf(path.join(@getRealPath(), path.sep)) is 0 + true + else + false + + # Make a full path relative to this directory's path. + # + # fullPath - The {String} path to convert. + # + # Returns a {String}. + relativize: (fullPath='') -> + if fullPath.indexOf(path.join(@getPath(), path.sep)) is 0 + fullPath.substring(@getPath().length + 1) + else if fullPath.indexOf(path.join(@getRealPath(), path.sep)) is 0 + fullPath.substring(@getRealPath().length + 1) + else + fullPath + # Retrieves the file entries in the directory. # # This does follow symlinks. diff --git a/src/app/project.coffee b/src/app/project.coffee index cce48d8e3..ef053f3d3 100644 --- a/src/app/project.coffee +++ b/src/app/project.coffee @@ -122,8 +122,7 @@ class Project # # Returns a {String}. relativize: (fullPath) -> - return fullPath unless fullPath.lastIndexOf(@getPath()) is 0 - fullPath.replace(@getPath(), "").replace(/^\//, '') + @rootDirectory?.relativize(fullPath) ? fullPath # Is the given path inside this project? # @@ -131,10 +130,7 @@ class Project # # Returns a {Boolean}. contains: (pathToCheck) -> - if pathToCheck - if projectPath = @getPath() - return pathToCheck.indexOf(path.join(projectPath, path.sep)) is 0 - false + @rootDirectory?.contains(pathToCheck) ? false # Identifies if the project is using soft tabs. #