Fix handling of unconventional NuGet .NET Framework folders

This commit is contained in:
Aleksi Juvani 2017-07-31 16:01:27 +03:00
parent 3ac01d9607
commit 9638738404
4 changed files with 119 additions and 31 deletions

View File

@ -10,6 +10,7 @@ return {
"cs2005/test_files.lua",
"cs2005/test_icon.lua",
"cs2005/test_nuget_config.lua",
"cs2005/test_nuget_framework_folders.lua",
"cs2005/test_nuget_packages_config.lua",
"cs2005/test_output_props.lua",
"cs2005/projectelement.lua",

View File

@ -259,3 +259,30 @@
</ItemGroup>
]]
end
--
-- NuGet packages with unconventional folder structures should be handled
-- properly.
--
function suite.nuGetPackages_netFolder()
dotnetframework "4.5"
nuget { "MetroModernUI:1.4.0" }
prepare()
test.capture [[
<ItemGroup>
<Reference Include="MetroFramework.Design">
<HintPath>packages\MetroModernUI.1.4.0.0\lib\net\MetroFramework.Design.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MetroFramework">
<HintPath>packages\MetroModernUI.1.4.0.0\lib\net\MetroFramework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MetroFramework.Fonts">
<HintPath>packages\MetroModernUI.1.4.0.0\lib\net\MetroFramework.Fonts.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
]]
end

View File

@ -0,0 +1,42 @@
--
-- modules/vstudio/tests/cs2005/test_nuget_framework_folders.lua
-- Validate parsing of framework versions from folder names for
-- Visual Studio 2010 and newer
-- Copyright (c) 2017 Jason Perkins and the Premake project
--
local p = premake
local suite = test.declare("vstudio_cs2005_nuget_framework_folders")
local cs2005 = p.vstudio.cs2005
function suite.net()
test.isequal(cs2005.frameworkVersionForFolder("net451"), "4510000000")
test.isequal(cs2005.frameworkVersionForFolder("net45"), "4500000000")
test.isequal(cs2005.frameworkVersionForFolder("net20"), "2000000000")
test.isequal(cs2005.frameworkVersionForFolder("net35"), "3500000000")
test.isequal(cs2005.frameworkVersionForFolder("net"), "0000000000")
end
function suite.numeric()
test.isequal(cs2005.frameworkVersionForFolder("10"), "1000000000")
test.isequal(cs2005.frameworkVersionForFolder("11"), "1100000000")
test.isequal(cs2005.frameworkVersionForFolder("20"), "2000000000")
test.isequal(cs2005.frameworkVersionForFolder("45"), "4500000000")
end
function suite.numericWithDots()
test.isequal(cs2005.frameworkVersionForFolder("1.0"), "1000000000")
test.isequal(cs2005.frameworkVersionForFolder("1.1"), "1100000000")
test.isequal(cs2005.frameworkVersionForFolder("2.0"), "2000000000")
test.isequal(cs2005.frameworkVersionForFolder("4.5"), "4500000000")
end
function suite.invalid()
test.isnil(cs2005.frameworkVersionForFolder("netstandard1.3"))
test.isnil(cs2005.frameworkVersionForFolder("sl4"))
test.isnil(cs2005.frameworkVersionForFolder("sl5"))
test.isnil(cs2005.frameworkVersionForFolder("uap10"))
test.isnil(cs2005.frameworkVersionForFolder("wp8"))
test.isnil(cs2005.frameworkVersionForFolder("wp71"))
end

View File

@ -362,6 +362,45 @@
end
--
-- This is a bit janky. To compare versions, we extract all numbers from the
-- given string and right-pad the result with zeros. Then we can just do a
-- lexicographical compare on the resulting strings.
--
-- This is so that we can compare version strings such as "4.6" and "net451"
-- with each other.
--
function cs2005.makeVersionComparable(version)
local numbers = ""
for number in version:gmatch("%d") do
numbers = numbers .. number
end
return string.format("%-10d", numbers):gsub(" ", "0")
end
--
-- https://github.com/NuGet/NuGet.Client/blob/dev/test/NuGet.Core.Tests/NuGet.Frameworks.Test/NuGetFrameworkParseTests.cs
--
function cs2005.frameworkVersionForFolder(folder)
-- If this exporter ever supports frameworks such as "netstandard1.3",
-- "sl4", "sl5", "uap10", "wp8" or "wp71", this code will need changing
-- to match the right folders, depending on the current framework.
-- Right now this only matches folders for the .NET Framework.
if folder:match("^net%d+$") or folder:match("^[0-9%.]+$") then
return cs2005.makeVersionComparable(folder)
elseif folder == "net" then
return cs2005.makeVersionComparable("0")
end
end
--
-- Write the list of NuGet references.
--
@ -376,25 +415,7 @@
local action = p.action.current()
local targetFramework = cfg.dotnetframework or action.vstudio.targetFramework
-- This is a bit janky. To compare versions, we extract all
-- numbers from the given string and right-pad the result with
-- zeros. Then we can just do a lexicographical compare on the
-- resulting strings.
--
-- This is so that we can compare version strings such as
-- "4.6" and "net451" with each other.
local function makeVersionComparable(a)
local numbers = ""
for number in a:gmatch("%d") do
numbers = numbers .. number
end
return string.format("%-10d", numbers):gsub(" ", "0")
end
local targetVersion = makeVersionComparable(targetFramework)
local targetVersion = cs2005.makeVersionComparable(targetFramework)
-- Figure out what folder contains the files for the nearest
-- supported .NET Framework version.
@ -404,22 +425,19 @@
local bestVersion, bestFolder
for _, file in ipairs(packageAPIInfo.packageEntries) do
-- If this exporter ever supports frameworks such as
-- "netstandard1.3", "sl4", "sl5", "uap10", "wp8" or
-- "wp71", this code will need changing to match the right
-- folders.
local folder = file:match("^lib\\net(%d+)\\")
local folder = file:match("^lib\\(.+)\\")
if folder and path.hasextension(file, ".dll") then
files[folder] = files[folder] or {}
table.insert(files[folder], file)
local version = cs2005.frameworkVersionForFolder(folder)
local version = makeVersionComparable(file:match("lib\\net(%d+)\\"))
if version then
files[folder] = files[folder] or {}
table.insert(files[folder], file)
if version <= targetVersion and (not bestVersion or version > bestVersion) then
bestVersion = version
bestFolder = folder
if version <= targetVersion and (not bestVersion or version > bestVersion) then
bestVersion = version
bestFolder = folder
end
end
end
end