Skip to content

Commit a63558b

Browse files
committed
Migrating from project.json to MSBuild model for CSX based package
references
1 parent 6aba53f commit a63558b

File tree

35 files changed

+1913
-2330
lines changed

35 files changed

+1913
-2330
lines changed

appveyor.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@ test_script:
3939
4040
# see results in app insights AntaresDemo 'functionse2eai'
4141
42-
dotnet test .\test\WebJobs.Script.Tests -v q --no-build -l appinsights
42+
dotnet test .\test\WebJobs.Script.Tests -v q --no-build
4343
4444
$success = $success -and $?
4545
46-
dotnet test .\test\WebJobs.Script.Tests.Integration\ -v q --no-build --filter Tests.NodeEndToEndTests -l appinsights
46+
dotnet test .\test\WebJobs.Script.Tests.Integration\ -v q --no-build --filter Tests.NodeEndToEndTests
4747
4848
$success = $success -and $?
4949
50-
dotnet test .\test\WebJobs.Script.Tests.Integration\ -v q --no-build --filter NodeContentTests -l appinsights
50+
dotnet test .\test\WebJobs.Script.Tests.Integration\ -v q --no-build --filter NodeContentTests
5151
5252
$success = $success -and $?
5353

sample/HttpTrigger-CSharp/run.csx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
using System.Net;
22
using Microsoft.AspNetCore.Mvc;
33
using Microsoft.Extensions.Primitives;
4+
using Twilio;
45

56
public static IActionResult Run(HttpRequest req, TraceWriter log)
67
{
78
log.Info("C# HTTP trigger function processed a request.");
89

910
if (req.Query.TryGetValue("name", out StringValues value))
1011
{
11-
return new OkObjectResult($"Hello, {value.First()}");
12+
return new OkObjectResult($"Hello, {value.ToString()}");
1213
}
1314

1415
return new BadRequestObjectResult("Please pass a name on the query string or in the request body");

sample/host.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@
2222
"prefetchCount": 1000,
2323
"batchCheckpointFrequency": 1
2424
},
25-
"functionTimeout": "00:05:00"
25+
"functionTimeout": "00:05:00",
26+
"functions": ["HttpTrigger-CSharp"]
2627
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
/*
5+
// This file is used by Code Analysis to maintain SuppressMessage
6+
// attributes that are applied to this project.
7+
// Project-level suppressions either have no target or are given
8+
// a specific target and scoped to a namespace, type, member, etc.
9+
*/
10+
11+
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.NamingRules", "SA1313:Parameter names should begin with lower-case letter", Justification = "<Pending>", Scope = "type", Target = "~T:Microsoft.Azure.WebJobs.Script.WebHost.Diagnostics.EventGenerator.FunctionsSystemLogsEventSource")]

src/WebJobs.Script/Description/DotNet/DotNetConstants.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ public static class DotNetConstants
77
{
88
public const string PrivateAssembliesFolderName = "bin";
99
public const string CompilationReferenceAssembliesFolderName = "compilationrefs";
10-
public const string ProjectFileName = "project.json";
11-
public const string ProjectLockFileName = "project.lock.json";
10+
public const string ProjectFileName = "function.proj";
11+
public const string ProjectLockFileName = "project.assets.json";
1212

1313
public const string MissingFunctionEntryPointCompilationCode = "AF001";
1414
public const string AmbiguousFunctionEntryPointsCompilationCode = "AF002";

src/WebJobs.Script/Description/DotNet/FunctionMetadataResolver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public bool TryGetPackageReference(string referenceName, out PackageReference pa
143143

144144
package = _packageAssemblyResolver.Packages.FirstOrDefault(p =>
145145
string.Compare(referenceName, p.Name, StringComparison.OrdinalIgnoreCase) == 0 ||
146-
p.Assemblies.Keys.Any(a => string.Compare(a.Name, referenceName) == 0));
146+
p.CompileTimeAssemblies.Keys.Any(a => string.Compare(a.Name, referenceName) == 0));
147147

148148
return package != null;
149149
}

src/WebJobs.Script/Description/DotNet/PackageAssemblyResolver.cs

Lines changed: 41 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@
88
using System.IO;
99
using System.Linq;
1010
using System.Reflection;
11+
using Microsoft.Azure.WebJobs.Host;
1112
using Newtonsoft.Json.Linq;
13+
using NuGet.Frameworks;
14+
using NuGet.ProjectModel;
1215

1316
namespace Microsoft.Azure.WebJobs.Script.Description
1417
{
@@ -18,7 +21,6 @@ namespace Microsoft.Azure.WebJobs.Script.Description
1821
public sealed class PackageAssemblyResolver
1922
{
2023
private const string EmptyFolderFileMarker = "_._";
21-
private const string FrameworkTargetName = ".NETFramework,Version=v4.6";
2224

2325
private readonly ImmutableArray<PackageReference> _packages;
2426

@@ -41,7 +43,7 @@ public IEnumerable<string> AssemblyReferences
4143
{
4244
return _packages.Aggregate(new List<string>(), (assemblies, p) =>
4345
{
44-
assemblies.AddRange(p.Assemblies.Values);
46+
assemblies.AddRange(p.CompileTimeAssemblies.Values);
4547
assemblies.AddRange(p.FrameworkAssemblies.Values);
4648
return assemblies;
4749
}).Distinct();
@@ -55,68 +57,65 @@ private static ImmutableArray<PackageReference> InitializeAssemblyRegistry(strin
5557

5658
if (File.Exists(fileName))
5759
{
58-
var jobject = JObject.Parse(File.ReadAllText(fileName));
59-
60-
var target = jobject.SelectTokens(string.Format(CultureInfo.InvariantCulture, "$.targets['{0}']", FrameworkTargetName)).FirstOrDefault();
61-
62-
if (target != null)
60+
LockFile lockFile = null;
61+
try
6362
{
64-
string nugetHome = PackageManager.GetNugetPackagesPath();
63+
var reader = new LockFileFormat();
64+
lockFile = reader.Read(fileName);
65+
66+
var target = lockFile.Targets
67+
.FirstOrDefault(t => string.Equals(t.TargetFramework.DotNetFrameworkName, FrameworkConstants.CommonFrameworks.NetStandard20.DotNetFrameworkName));
6568

66-
foreach (JProperty token in target)
69+
if (target != null)
6770
{
68-
var referenceNameParts = token.Name.Split('/');
69-
if (referenceNameParts.Length != 2)
71+
string nugetCachePath = PackageManager.GetNugetPackagesPath();
72+
73+
// Get all the referenced libraries for the target, excluding the framework references we add by default
74+
var libraries = target.Libraries.Where(s => !DotNetConstants.FrameworkReferences.Contains(s.Name));
75+
foreach (var library in libraries)
7076
{
71-
throw new FormatException(string.Format(CultureInfo.InvariantCulture, "The package name '{0}' is not correctly formatted.", token.Name));
72-
}
77+
var package = new PackageReference(library.Name, library.Version.ToFullString());
7378

74-
var package = new PackageReference(referenceNameParts[0], referenceNameParts[1]);
79+
var assemblies = GetAssembliesList(library.CompileTimeAssemblies, nugetCachePath, package);
7580

76-
var references = token.SelectTokens("$..compile").FirstOrDefault();
77-
if (references != null)
78-
{
79-
foreach (JProperty reference in references)
80-
{
81-
if (!reference.Name.EndsWith(EmptyFolderFileMarker, StringComparison.Ordinal))
82-
{
83-
string path = Path.Combine(nugetHome, token.Name, reference.Name);
84-
path = path.Replace('/', '\\');
85-
86-
if (File.Exists(path))
87-
{
88-
package.Assemblies.Add(AssemblyName.GetAssemblyName(path), path);
89-
}
90-
}
91-
}
92-
}
81+
package.CompileTimeAssemblies.AddRange(assemblies);
9382

94-
var frameworkAssemblies = token.SelectTokens("$..frameworkAssemblies").FirstOrDefault();
95-
if (frameworkAssemblies != null)
96-
{
97-
foreach (var assembly in frameworkAssemblies)
98-
{
99-
string assemblyName = assembly.ToString();
100-
package.FrameworkAssemblies.Add(new AssemblyName(assemblyName), assemblyName);
101-
}
102-
}
83+
assemblies = GetAssembliesList(library.RuntimeAssemblies, nugetCachePath, package);
10384

104-
builder.Add(package);
85+
package.RuntimeAssemblies.AddRange(assemblies);
86+
87+
var frameworkAssemblies = library.FrameworkAssemblies.ToDictionary(a => new AssemblyName(a));
88+
package.FrameworkAssemblies.AddRange(frameworkAssemblies);
89+
90+
builder.Add(package);
91+
}
10592
}
10693
}
94+
catch (FileFormatException)
95+
{
96+
return ImmutableArray<PackageReference>.Empty;
97+
}
10798
}
10899

109100
return builder.ToImmutableArray();
110101
}
111102

103+
private static IReadOnlyDictionary<AssemblyName, string> GetAssembliesList(IList<LockFileItem> compileTimeAssemblies, string nugetCachePath, PackageReference package)
104+
{
105+
string packagePath = Path.Combine(nugetCachePath, package.Name, package.Version.ToString());
106+
return compileTimeAssemblies.Select(i => Path.Combine(packagePath, i.Path))
107+
.Where(p => !p.EndsWith(EmptyFolderFileMarker) && File.Exists(p))
108+
.ToDictionary(p => AssemblyName.GetAssemblyName(p), p => new Uri(p).LocalPath);
109+
}
110+
112111
public bool TryResolveAssembly(string name, out string path)
113112
{
114113
path = null;
115114
var assemblyName = new AssemblyName(name);
116115

117116
foreach (var package in _packages)
118117
{
119-
if (package.Assemblies.TryGetValue(assemblyName, out path) ||
118+
if (package.RuntimeAssemblies.TryGetValue(assemblyName, out path) ||
120119
package.FrameworkAssemblies.TryGetValue(assemblyName, out path))
121120
{
122121
break;

0 commit comments

Comments
 (0)