Skip to content

Recognize pinned pre-release package references #544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@
<Description>A MetadataReferenceResolver that allows inline nuget references to be specified in script(csx) files.</Description>
<Authors>dotnet-script</Authors>
<Company>dotnet-script</Company>
<LangVersion>latest</LangVersion>
</PropertyGroup>

<ItemGroup>
<Compile Include="..\Dotnet.Script.DependencyModel\ProjectSystem\ScriptParserInternal.cs" Link="ScriptParserInternal.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="3.6.0" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.CodeAnalysis;
using Dotnet.Script.DependencyModel.ProjectSystem;

namespace Dotnet.Script.DependencyModel.NuGet
{
Expand All @@ -15,7 +14,6 @@ public class NuGetSourceReferenceResolver : SourceReferenceResolver
{
private readonly SourceReferenceResolver _sourceReferenceResolver;
private readonly IDictionary<string, IReadOnlyList<string>> _scriptMap;
private static readonly Regex PackageNameMatcher = new Regex(@"\s*nuget\s*:\s*(.*)\s*,", RegexOptions.Compiled | RegexOptions.IgnoreCase);

public NuGetSourceReferenceResolver(SourceReferenceResolver sourceReferenceResolver, IDictionary<string, IReadOnlyList<string>> scriptMap)
{
Expand Down Expand Up @@ -48,9 +46,8 @@ public override string NormalizePath(string path, string baseFilePath)

public override string ResolveReference(string path, string baseFilePath)
{
if (path.StartsWith("nuget:", StringComparison.OrdinalIgnoreCase))
if (ScriptParser.TryParseNuGetPackageReference(path, out var packageName, out _))
{
var packageName = PackageNameMatcher.Match(path).Groups[1].Value;
if (_scriptMap.TryGetValue(packageName, out var scripts))
{
if (scripts.Count == 1)
Expand All @@ -66,9 +63,8 @@ public override string ResolveReference(string path, string baseFilePath)

public override Stream OpenRead(string resolvedPath)
{
if (resolvedPath.StartsWith("nuget:", StringComparison.OrdinalIgnoreCase))
if (ScriptParser.TryParseNuGetPackageReference(resolvedPath, out var packageName, out _))
{
var packageName = PackageNameMatcher.Match(resolvedPath).Groups[1].Value;
var scripts = _scriptMap[packageName];
if (scripts.Count == 1)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@
<None Remove="NuGet\NuGet430.exe" />
</ItemGroup>

<ItemGroup>
<Compile Update="ProjectSystem\ScriptParserInternal.cs">
<DependentUpon>ScriptParser.cs</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="ProjectSystem\csproj.template" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,38 @@ namespace Dotnet.Script.DependencyModel.ProjectSystem
/// </summary>
public class PackageVersion : IEquatable<PackageVersion>
{
private static readonly Regex IsPinnedRegex = new Regex(@"^(?>\[\d+[^,\]]+(?<!\.)\]|\d+(\.\d+){2,})$", RegexOptions.Compiled);
// Following patterns are "inspired" from SemVer 2.0 grammar:
//
// Source: https://semver.org/spec/v2.0.0.html#backusnaur-form-grammar-for-valid-semver-versions

// <numeric identifier> ::= "0"
// | <positive digit>
// | <positive digit> <digits>
//
// <digits> ::= <digit>
// | <digit> <digits>
//
// <digit> ::= "0"
// | <positive digit>
//
// <positive digit> ::= "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"

const string NumericPattern = @"(?:0|[1-9][0-9]*)";

// <valid semver> ::= <version core>
// | <version core> "-" <pre-release>
// | <version core> "+" <build>
// | <version core> "-" <pre-release> "+" <build>
//
// <version core> ::= <major> "." <minor> "." <patch>

const string MajorPlusVersionPattern = NumericPattern + @"(?:\." + NumericPattern + @")";
const string VersionSuffixPattern = @"(?:[+-][\w][\w+.-]*)?";

private static readonly Regex IsPinnedRegex =
new Regex(@"^(?>\[" + MajorPlusVersionPattern + @"{1,4}" + VersionSuffixPattern + @"\]"
+ @"|" + MajorPlusVersionPattern + @"{2,3}" + VersionSuffixPattern + @")$",
RegexOptions.Compiled);

/// <summary>
/// Initializes a new instance of the <see cref="PackageVersion"/> class.
Expand Down
11 changes: 1 addition & 10 deletions src/Dotnet.Script.DependencyModel/ProjectSystem/ScriptParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace Dotnet.Script.DependencyModel.ProjectSystem
{
public class ScriptParser
public partial class ScriptParser
{
private readonly Logger _logger;

Expand Down Expand Up @@ -37,15 +37,6 @@ public ParseResult ParseFromFiles(IEnumerable<string> csxFiles)
return new ParseResult(allPackageReferences);
}

const string Hws = @"[\x20\t]*"; // hws = horizontal whitespace

const string DirectivePatternPrefix = @"^"
+ Hws + @"#";
const string DirectivePatternSuffix = Hws + @"""nuget:"
// https://github.com/NuGet/docs.microsoft.com-nuget/issues/543#issue-270039223
+ Hws + @"(\w+(?:[_.-]\w+)*)"
+ @"(?:" + Hws + "," + Hws + @"(.+?))?""";

private static IEnumerable<PackageReference> ReadPackageReferencesFromReferenceDirective(string fileContent)
{
const string pattern = DirectivePatternPrefix + "r" + DirectivePatternSuffix;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Text.RegularExpressions;

namespace Dotnet.Script.DependencyModel.ProjectSystem
{
partial class ScriptParser
{
const string Hws = @"[\x20\t]*"; // hws = horizontal whitespace

const string NuGetPattern = @"nuget:"
// https://github.com/NuGet/docs.microsoft.com-nuget/issues/543#issue-270039223
+ Hws + @"(\w+(?:[_.-]\w+)*)"
+ @"(?:" + Hws + "," + Hws + @"(.+?))?";

const string WholeNuGetPattern = @"^" + NuGetPattern + @"$";

const string DirectivePatternPrefix = @"^" + Hws + @"#";
const string DirectivePatternSuffix = Hws + @"""" + NuGetPattern + @"""";

internal static bool TryParseNuGetPackageReference(string input,
out string id, out string version)
{
bool success;
(success, id, version) =
Regex.Match(input, WholeNuGetPattern, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase)
is {} match && match.Success
? (true, match.Groups[1].Value, match.Groups[2].Value)
: default;
return success;
}
}
}
4 changes: 4 additions & 0 deletions src/Dotnet.Script.Tests/PackageVersionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public class PackageVersionTests
[Theory]
[InlineData("1.2.3")]
[InlineData("1.2.3.4")]
[InlineData("1.2.3-beta1")]
[InlineData("0.1.4-beta")] // See: https://github.com/filipw/dotnet-script/issues/407#issuecomment-563363947
[InlineData("2.0.0-preview3.20122.2")] // See: https://github.com/filipw/dotnet-script/issues/407#issuecomment-631122591
[InlineData("1.0.0-ci-20180920T1656")]
[InlineData("[1.2]")]
[InlineData("[1.2.3]")]
[InlineData("[1.2.3-beta1]")]
Expand Down