From b7415502bfedf811851ad43739548d2b80c7c502 Mon Sep 17 00:00:00 2001 From: Ryan Nowak Date: Fri, 5 Jan 2018 19:20:51 -0800 Subject: [PATCH] Add RelativePhysicalPath The FilePath property on RPI isn't what we want for use in the compiler, it's more of a view engine concept. Adding a property that does what we want. --- .../FileSystemRazorProject.cs | 16 +++-- .../FileSystemRazorProjectItem.cs | 10 ++- .../RazorProjectItem.cs | 13 +++- .../FileSystemRazorProjectItemTest.cs | 9 +-- .../FileSystemRazorProjectTest.cs | 68 +++++++++++-------- 5 files changed, 76 insertions(+), 40 deletions(-) diff --git a/src/Microsoft.AspNetCore.Razor.Language/FileSystemRazorProject.cs b/src/Microsoft.AspNetCore.Razor.Language/FileSystemRazorProject.cs index 52ddafebe3..d6e623c4f1 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/FileSystemRazorProject.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/FileSystemRazorProject.cs @@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Razor.Language { throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(root)); } - + Root = root.Replace('\\', '/').TrimEnd('/'); } @@ -36,16 +36,24 @@ namespace Microsoft.AspNetCore.Razor.Language .EnumerateFiles("*.cshtml", SearchOption.AllDirectories) .Select(file => { - var relativePath = file.FullName.Substring(absoluteBasePath.Length).Replace(Path.DirectorySeparatorChar, '/'); - return new FileSystemRazorProjectItem(basePath, relativePath, file); + var relativePhysicalPath = file.FullName.Substring(absoluteBasePath.Length + 1); // Include leading separator + var filePath = "/" + relativePhysicalPath.Replace(Path.DirectorySeparatorChar, '/'); + + return new FileSystemRazorProjectItem(basePath, filePath, relativePhysicalPath, file); }); } public override RazorProjectItem GetItem(string path) { + var absoluteBasePath = NormalizeAndEnsureValidPath("/"); var absolutePath = NormalizeAndEnsureValidPath(path); - return new FileSystemRazorProjectItem("/", path, new FileInfo(absolutePath)); + var file = new FileInfo(absolutePath); + + var relativePhysicalPath = file.FullName.Substring(absoluteBasePath.Length + 1); // Include leading separator + var filePath = "/" + relativePhysicalPath.Replace(Path.DirectorySeparatorChar, '/'); + + return new FileSystemRazorProjectItem("/", filePath, relativePhysicalPath, new FileInfo(absolutePath)); } protected override string NormalizeAndEnsureValidPath(string path) diff --git a/src/Microsoft.AspNetCore.Razor.Language/FileSystemRazorProjectItem.cs b/src/Microsoft.AspNetCore.Razor.Language/FileSystemRazorProjectItem.cs index 96a45027c8..210670d06a 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/FileSystemRazorProjectItem.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/FileSystemRazorProjectItem.cs @@ -11,12 +11,14 @@ namespace Microsoft.AspNetCore.Razor.Language /// Initializes a new instance of . /// /// The base path. - /// The path. + /// The physical path of the base path. + /// The path. /// The . - public FileSystemRazorProjectItem(string basePath, string path, FileInfo file) + public FileSystemRazorProjectItem(string basePath, string filePath, string relativePhysicalPath, FileInfo file) { BasePath = basePath; - FilePath = path; + FilePath = filePath; + RelativePhysicalPath = relativePhysicalPath; File = file; } @@ -30,6 +32,8 @@ namespace Microsoft.AspNetCore.Razor.Language public override string PhysicalPath => File.FullName; + public override string RelativePhysicalPath { get; } + public override Stream Read() => new FileStream(PhysicalPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete); } } \ No newline at end of file diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorProjectItem.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorProjectItem.cs index 67b0e04dfd..cadd00710c 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/RazorProjectItem.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorProjectItem.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System; using System.Diagnostics; using System.IO; @@ -18,15 +19,23 @@ namespace Microsoft.AspNetCore.Razor.Language public abstract string BasePath { get; } /// - /// File path relative to . + /// File path relative to . This property uses the project path syntax, + /// using / as a path separator and does not follow the operating system's file system + /// conventions. /// public abstract string FilePath { get; } /// - /// The absolute path to the file, including the file name. + /// The absolute physical (file system) path to the file, including the file name. /// public abstract string PhysicalPath { get; } + /// + /// The relative physical (file system) path to the file, including the file name. Relative to the + /// physical path of the . + /// + public virtual string RelativePhysicalPath => null; + /// /// Gets the file contents as readonly . /// diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/FileSystemRazorProjectItemTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/FileSystemRazorProjectItemTest.cs index 638d898e0d..a5193f45f9 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/FileSystemRazorProjectItemTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/FileSystemRazorProjectItemTest.cs @@ -20,14 +20,15 @@ namespace Microsoft.AspNetCore.Razor.Language var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml")); // Act - var projectItem = new FileSystemRazorProjectItem("/Views", "/Home.cshtml", fileInfo); + var projectItem = new FileSystemRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", fileInfo); // Assert Assert.Equal("/Home.cshtml", projectItem.FilePath); - Assert.Equal("/Views", projectItem.BasePath); + Assert.Equal("/", projectItem.BasePath); Assert.True(projectItem.Exists); Assert.Equal("Home.cshtml", projectItem.FileName); Assert.Equal(fileInfo.FullName, projectItem.PhysicalPath); + Assert.Equal("Home.cshtml", projectItem.RelativePhysicalPath); } [Fact] @@ -37,7 +38,7 @@ namespace Microsoft.AspNetCore.Razor.Language var fileInfo = new FileInfo(Path.Combine(TestFolder, "Views", "FileDoesNotExist.cshtml")); // Act - var projectItem = new FileSystemRazorProjectItem("/Views", "/FileDoesNotExist.cshtml", fileInfo); + var projectItem = new FileSystemRazorProjectItem("/Views", "/FileDoesNotExist.cshtml", Path.Combine("Views", "FileDoesNotExist.cshtml"), fileInfo); // Assert Assert.False(projectItem.Exists); @@ -48,7 +49,7 @@ namespace Microsoft.AspNetCore.Razor.Language { // Arrange var fileInfo = new FileInfo(Path.Combine(TestFolder, "Home.cshtml")); - var projectItem = new FileSystemRazorProjectItem("/", "/Home.cshtml", fileInfo); + var projectItem = new FileSystemRazorProjectItem("/", "/Home.cshtml", "Home.cshtml", fileInfo); // Act var stream = projectItem.Read(); diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/FileSystemRazorProjectTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/FileSystemRazorProjectTest.cs index 98a22f4fc5..35f8b32117 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/FileSystemRazorProjectTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/FileSystemRazorProjectTest.cs @@ -73,24 +73,31 @@ namespace Microsoft.AspNetCore.Razor.Language var fileSystemProject = new FileSystemRazorProject(TestFolder); // Act - var files = fileSystemProject.EnumerateItems("/"); + var items = fileSystemProject.EnumerateItems("/"); // Assert - Assert.Collection(files.OrderBy(f => f.FilePath), - file => + Assert.Collection(items.OrderBy(f => f.FilePath), + item => { - Assert.Equal("/Home.cshtml", file.FilePath); - Assert.Equal("/", file.BasePath); + Assert.Equal("/Home.cshtml", item.FilePath); + Assert.Equal("/", item.BasePath); + Assert.Equal(Path.Combine(TestFolder, "Home.cshtml"), item.PhysicalPath); + Assert.Equal("Home.cshtml", item.RelativePhysicalPath); + }, - file => + item => { - Assert.Equal("/Views/About/About.cshtml", file.FilePath); - Assert.Equal("/", file.BasePath); + Assert.Equal("/Views/About/About.cshtml", item.FilePath); + Assert.Equal("/", item.BasePath); + Assert.Equal(Path.Combine(TestFolder, "Views", "About", "About.cshtml"), item.PhysicalPath); + Assert.Equal(Path.Combine("Views", "About", "About.cshtml"), item.RelativePhysicalPath); }, - file => + item => { - Assert.Equal("/Views/Home/Index.cshtml", file.FilePath); - Assert.Equal("/", file.BasePath); + Assert.Equal("/Views/Home/Index.cshtml", item.FilePath); + Assert.Equal("/", item.BasePath); + Assert.Equal(Path.Combine(TestFolder, "Views", "Home", "Index.cshtml"), item.PhysicalPath); + Assert.Equal(Path.Combine("Views", "Home", "Index.cshtml"), item.RelativePhysicalPath); }); } @@ -101,19 +108,23 @@ namespace Microsoft.AspNetCore.Razor.Language var fileSystemProject = new FileSystemRazorProject(TestFolder); // Act - var files = fileSystemProject.EnumerateItems("/Views"); + var items = fileSystemProject.EnumerateItems("/Views"); // Assert - Assert.Collection(files.OrderBy(f => f.FilePath), - file => + Assert.Collection(items.OrderBy(f => f.FilePath), + item => { - Assert.Equal("/About/About.cshtml", file.FilePath); - Assert.Equal("/Views", file.BasePath); + Assert.Equal("/About/About.cshtml", item.FilePath); + Assert.Equal("/Views", item.BasePath); + Assert.Equal(Path.Combine(TestFolder, "Views", "About", "About.cshtml"), item.PhysicalPath); + Assert.Equal(Path.Combine("About", "About.cshtml"), item.RelativePhysicalPath); }, - file => + item => { - Assert.Equal("/Home/Index.cshtml", file.FilePath); - Assert.Equal("/Views", file.BasePath); + Assert.Equal("/Home/Index.cshtml", item.FilePath); + Assert.Equal("/Views", item.BasePath); + Assert.Equal(Path.Combine(TestFolder, "Views", "Home", "Index.cshtml"), item.PhysicalPath); + Assert.Equal(Path.Combine("Home", "Index.cshtml"), item.RelativePhysicalPath); }); } @@ -124,25 +135,28 @@ namespace Microsoft.AspNetCore.Razor.Language var fileSystemProject = new FileSystemRazorProject(TestFolder); // Act - var files = fileSystemProject.EnumerateItems("/Does-Not-Exist"); + var items = fileSystemProject.EnumerateItems("/Does-Not-Exist"); // Assert - Assert.Empty(files); + Assert.Empty(items); } [Fact] public void GetItem_ReturnsFileFromDisk() { // Arrange - var path = "/Views/About/About.cshtml"; + var filePath = "/Views/About/About.cshtml"; var fileSystemProject = new FileSystemRazorProject(TestFolder); // Act - var file = fileSystemProject.GetItem(path); + var item = fileSystemProject.GetItem(filePath); // Assert - Assert.True(file.Exists); - Assert.Equal(path, file.FilePath); + Assert.True(item.Exists); + Assert.Equal(filePath, item.FilePath); + Assert.Equal("/", item.BasePath); + Assert.Equal(Path.Combine(TestFolder, "Views", "About", "About.cshtml"), item.PhysicalPath); + Assert.Equal(Path.Combine("Views", "About", "About.cshtml"), item.RelativePhysicalPath); } [Fact] @@ -153,10 +167,10 @@ namespace Microsoft.AspNetCore.Razor.Language var fileSystemProject = new FileSystemRazorProject(TestFolder); // Act - var file = fileSystemProject.GetItem(path); + var item = fileSystemProject.GetItem(path); // Assert - Assert.False(file.Exists); + Assert.False(item.Exists); } private class TestFileSystemRazorProject : FileSystemRazorProject