From f609ddcc0d9a5f40527dd276dff39413df382841 Mon Sep 17 00:00:00 2001 From: Daniel Cazzulino Date: Fri, 12 Aug 2022 02:09:06 -0300 Subject: [PATCH] Allow including content in the package readme from a URL Fixes #216 --- src/NuGetizer.Tasks/IncludesResolver.cs | 44 +++++++++++++++++--- src/NuGetizer.Tests/Content/url.md | 1 + src/NuGetizer.Tests/IncludesResolverTests.cs | 8 ++++ src/NuGetizer.Tests/NuGetizer.Tests.csproj | 6 +++ 4 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 src/NuGetizer.Tests/Content/url.md diff --git a/src/NuGetizer.Tasks/IncludesResolver.cs b/src/NuGetizer.Tasks/IncludesResolver.cs index 64d5bd05..fd766901 100644 --- a/src/NuGetizer.Tasks/IncludesResolver.cs +++ b/src/NuGetizer.Tasks/IncludesResolver.cs @@ -1,21 +1,54 @@ using System; using System.Collections.Generic; using System.IO; +using System.Net.Http; using System.Text.RegularExpressions; +using System.Threading; +using System.Threading.Tasks; namespace NuGetizer; public class IncludesResolver { static readonly Regex IncludeRegex = new Regex(@"", RegexOptions.Compiled); + static readonly HttpClient http = new(); public static string Process(string filePath) { - var content = File.ReadAllText(filePath).Trim(); + string content = null; + + if (Uri.TryCreate(filePath, UriKind.Absolute, out var uri)) + { + var ev = new ManualResetEventSlim(); + Exception ex = null; + + Task.Run(() => http.GetStringAsync(uri)).ContinueWith(t => + { + ex = t.Exception?.InnerException; + if (ex == null) + content = t.Result.Trim(); + + ev.Set(); + }); + + ev.Wait(); + if (ex != null) + throw ex; + } + else + { + content = File.ReadAllText(filePath).Trim(); + } + + // TODO: removing this for now, since this would prevent a consumer of the + // resolve includes github action (see https://github.com/marketplace/actions/resolve-file-includes) + // from excluding the readme from CI-based resolution, while still keeping + // this (100% compatible) pack-time resolution. + // Allow self-excluding files for processing. Could be useful if the file itself // documents the include/exclude mechanism, for example. - if (content.StartsWith("") || content.EndsWith("")) - return content; + //if (content.StartsWith("") || content.EndsWith("")) + // return content; var replacements = new Dictionary(); @@ -29,11 +62,12 @@ public static string Process(string filePath) includedPath = includedPath.Split('#')[0]; } + var isUri = Uri.IsWellFormedUriString(includedPath, UriKind.Absolute); var includedFullPath = Path.Combine(Path.GetDirectoryName(filePath), includedPath).Replace(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar); - if (File.Exists(includedFullPath)) + if (isUri || File.Exists(includedFullPath)) { // Resolve nested includes - var includedContent = Process(includedFullPath); + var includedContent = Process(isUri ? includedPath : includedFullPath); if (fragment != null) { var anchor = $""; diff --git a/src/NuGetizer.Tests/Content/url.md b/src/NuGetizer.Tests/Content/url.md new file mode 100644 index 00000000..b3a194bb --- /dev/null +++ b/src/NuGetizer.Tests/Content/url.md @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/NuGetizer.Tests/IncludesResolverTests.cs b/src/NuGetizer.Tests/IncludesResolverTests.cs index 014e607a..81dc1ab1 100644 --- a/src/NuGetizer.Tests/IncludesResolverTests.cs +++ b/src/NuGetizer.Tests/IncludesResolverTests.cs @@ -17,4 +17,12 @@ public void ResolveIncludes() Assert.Contains("section#3", content); Assert.Contains("@kzu", content); } + + [Fact] + public void ResolveUrlInclude() + { + var content = IncludesResolver.Process("Content/url.md"); + + Assert.Contains("Daniel Cazzulino", content); + } } diff --git a/src/NuGetizer.Tests/NuGetizer.Tests.csproj b/src/NuGetizer.Tests/NuGetizer.Tests.csproj index 1a90ad1d..aec35d8f 100644 --- a/src/NuGetizer.Tests/NuGetizer.Tests.csproj +++ b/src/NuGetizer.Tests/NuGetizer.Tests.csproj @@ -52,6 +52,12 @@ + + + PreserveNewest + + +