Skip to content

Commit f3fe7a3

Browse files
committed
Use MSBuild to find target framework
1 parent 21a1bec commit f3fe7a3

File tree

10 files changed

+193
-4
lines changed

10 files changed

+193
-4
lines changed

aws-extensions-for-dotnet-cli.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestNativeAotNet8WebApp", "
6767
EndProject
6868
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestIntegerFunction", "testapps\TestIntegerFunction\TestIntegerFunction.csproj", "{D7F1DFA4-066B-469C-B04C-DF032CF152C1}"
6969
EndProject
70+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestFunctionBuildProps", "testapps\TestFunctionBuildProps\TestFunctionBuildProps\TestFunctionBuildProps.csproj", "{AFA71B8E-F0AA-4704-8C4E-C11130F82B13}"
71+
EndProject
7072
Global
7173
GlobalSection(SolutionConfigurationPlatforms) = preSolution
7274
Debug|Any CPU = Debug|Any CPU
@@ -169,6 +171,10 @@ Global
169171
{D7F1DFA4-066B-469C-B04C-DF032CF152C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
170172
{D7F1DFA4-066B-469C-B04C-DF032CF152C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
171173
{D7F1DFA4-066B-469C-B04C-DF032CF152C1}.Release|Any CPU.Build.0 = Release|Any CPU
174+
{AFA71B8E-F0AA-4704-8C4E-C11130F82B13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
175+
{AFA71B8E-F0AA-4704-8C4E-C11130F82B13}.Debug|Any CPU.Build.0 = Debug|Any CPU
176+
{AFA71B8E-F0AA-4704-8C4E-C11130F82B13}.Release|Any CPU.ActiveCfg = Release|Any CPU
177+
{AFA71B8E-F0AA-4704-8C4E-C11130F82B13}.Release|Any CPU.Build.0 = Release|Any CPU
172178
EndGlobalSection
173179
GlobalSection(SolutionProperties) = preSolution
174180
HideSolutionNode = FALSE
@@ -200,6 +206,7 @@ Global
200206
{AD31D053-97C5-4262-B187-EC42BFD51A9F} = {BB3CF729-8213-4DDD-85AE-A5E7754F3944}
201207
{69FFA03C-D29F-40E0-9E7F-572D5E10AF77} = {BB3CF729-8213-4DDD-85AE-A5E7754F3944}
202208
{D7F1DFA4-066B-469C-B04C-DF032CF152C1} = {BB3CF729-8213-4DDD-85AE-A5E7754F3944}
209+
{AFA71B8E-F0AA-4704-8C4E-C11130F82B13} = {BB3CF729-8213-4DDD-85AE-A5E7754F3944}
203210
EndGlobalSection
204211
GlobalSection(ExtensibilityGlobals) = postSolution
205212
SolutionGuid = {DBFC70D6-49A2-40A1-AB08-5D9504AB7112}

src/Amazon.Common.DotNetCli.Tools/Amazon.Common.DotNetCli.Tools.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
<PackageReference Include="AWSSDK.SecurityToken" Version="3.7.300.81" />
1212
<PackageReference Include="AWSSDK.SSO" Version="3.7.300.80" />
1313
<PackageReference Include="AWSSDK.SSOOIDC" Version="3.7.301.75" />
14+
<None Include="Assets\**\*" CopyToOutputDirectory="PreserveNewest" CopyToPublishDirectory="PreserveNewest" />
1415
</ItemGroup>
1516
<PropertyGroup>
1617
<NoWarn>1701;1702;1705;1591</NoWarn>
1718
</PropertyGroup>
18-
1919
</Project>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project>
2+
<Target Name="_AmazonCommonToolsExtractTargetFrameworks">
3+
<ItemGroup>
4+
<_TargetFrameworks Include="$(TargetFramework)" Condition="'$(TargetFramework)' != ''" />
5+
<_TargetFrameworks Include="$(TargetFrameworks)" Condition="'$(TargetFrameworks)' != ''" />
6+
</ItemGroup>
7+
<WriteLinesToFile File="$(_AmazonCommonToolsTargetFrameworksFile)" Lines="@(_TargetFrameworks)" Overwrite="true" />
8+
</Target>
9+
</Project>
10+

src/Amazon.Common.DotNetCli.Tools/Utilities.cs

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,14 +207,85 @@ public static string DeterminePublishLocation(string workingDirectory, string pr
207207

208208
public static string LookupTargetFrameworkFromProjectFile(string projectLocation)
209209
{
210+
210211
var projectFile = FindProjectFileInDirectory(projectLocation);
212+
if (string.IsNullOrEmpty(projectFile))
213+
{
214+
throw new FileNotFoundException("Could not find a project file in the specified directory.");
215+
}
211216

212-
var xdoc = XDocument.Load(projectFile);
217+
var outputFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
218+
var targetsFile = FindTargetsFile();
219+
220+
if (!File.Exists(targetsFile))
221+
{
222+
throw new FileNotFoundException($"Could not find the custom .targets file at {targetsFile}");
223+
}
224+
225+
var arguments = new[]
226+
{
227+
"msbuild",
228+
projectFile,
229+
"/nologo",
230+
"/t:_AmazonCommonToolsExtractTargetFrameworks",
231+
$"/p:_AmazonCommonToolsTargetFrameworksFile={outputFile}",
232+
"/p:Configuration=Debug",
233+
$"\"/p:CustomAfterMicrosoftCommonTargets={targetsFile}\"",
234+
$"\"/p:CustomAfterMicrosoftCommonCrossTargetingTargets={targetsFile}\""
235+
};
236+
237+
var process = new Process
238+
{
239+
StartInfo = new ProcessStartInfo
240+
{
241+
FileName = "dotnet",
242+
Arguments = string.Join(" ", arguments),
243+
RedirectStandardOutput = true,
244+
RedirectStandardError = true,
245+
UseShellExecute = false,
246+
CreateNoWindow = true
247+
}
248+
};
249+
250+
process.Start();
251+
string output = process.StandardOutput.ReadToEnd();
252+
process.WaitForExit();
213253

214-
var element = xdoc.XPathSelectElement("//PropertyGroup/TargetFramework");
215-
return element?.Value;
254+
if (process.ExitCode != 0)
255+
{
256+
throw new Exception($"MSBuild process exited with code {process.ExitCode}. See log for details.");
257+
}
258+
259+
if (File.Exists(outputFile))
260+
{
261+
var targetFrameworks = File.ReadAllLines(outputFile);
262+
File.Delete(outputFile); // Clean up the temporary file
263+
264+
if (targetFrameworks.Length > 0)
265+
{
266+
return targetFrameworks[0]; // Return the first framework if there are multiple
267+
}
268+
}
269+
270+
return null;
216271
}
217272

273+
274+
private static string FindTargetsFile()
275+
{
276+
var assemblyDir = Path.GetDirectoryName(typeof(DotNetCLIWrapper).Assembly.Location);
277+
var searchPaths = new[]
278+
{
279+
Path.Combine(AppContext.BaseDirectory, "Assets"),
280+
Path.Combine(assemblyDir, "Assets"),
281+
AppContext.BaseDirectory,
282+
assemblyDir,
283+
};
284+
285+
return searchPaths.Select(p => Path.Combine(p, "AmazonCommonDotNetCliTools.targets")).FirstOrDefault(File.Exists);
286+
}
287+
288+
218289
/// <summary>
219290
/// Retrieve the `OutputType` property of a given project
220291
/// </summary>

test/Amazon.Common.DotNetCli.Tools.Test/UtilitiesTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public class UtilitiesTests
1313
[InlineData("../../../../../testapps/TestFunction", "net6.0")]
1414
[InlineData("../../../../../testapps/ServerlessWithYamlFunction", "net6.0")]
1515
[InlineData("../../../../../testapps/TestBeanstalkWebApp", "netcoreapp3.1")]
16+
[InlineData("../../../../../testapps/TestFunctionBuildProps/TestFunctionBuildProps", "net6.0")]
1617
public void CheckFramework(string projectPath, string expectedFramework)
1718
{
1819
var assembly = this.GetType().GetTypeInfo().Assembly;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<Project>
2+
<PropertyGroup>
3+
<TargetFramework>net6.0</TargetFramework>
4+
</PropertyGroup>
5+
</Project>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Amazon.Lambda.Core;
2+
3+
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
4+
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
5+
6+
namespace TestFunctionBuildProps;
7+
8+
public class Function
9+
{
10+
public string FunctionHandler(string input, ILambdaContext context)
11+
{
12+
return input.ToUpper();
13+
}
14+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# AWS Lambda Empty Function Project
2+
3+
This starter project consists of:
4+
* Function.cs - class file containing a class with a single function handler method
5+
* aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS
6+
7+
You may also have a test project depending on the options selected.
8+
9+
The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs.
10+
11+
## Here are some steps to follow from Visual Studio:
12+
13+
To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*.
14+
15+
To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree.
16+
17+
To perform testing against your deployed function use the Test Invoke tab in the opened Function View window.
18+
19+
To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window.
20+
21+
To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window.
22+
23+
To view execution logs of invocations of your function use the Logs tab in the opened Function View window.
24+
25+
## Here are some steps to follow to get started from the command line:
26+
27+
Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line.
28+
29+
Install Amazon.Lambda.Tools Global Tools if not already installed.
30+
```
31+
dotnet tool install -g Amazon.Lambda.Tools
32+
```
33+
34+
If already installed check if new version is available.
35+
```
36+
dotnet tool update -g Amazon.Lambda.Tools
37+
```
38+
39+
Execute unit tests
40+
```
41+
cd "TestFunctionBuildProps/test/TestFunctionBuildProps.Tests"
42+
dotnet test
43+
```
44+
45+
Deploy function to AWS Lambda
46+
```
47+
cd "TestFunctionBuildProps/src/TestFunctionBuildProps"
48+
dotnet lambda deploy-function
49+
```
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<ImplicitUsings>enable</ImplicitUsings>
4+
<Nullable>enable</Nullable>
5+
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
6+
<AWSProjectType>Lambda</AWSProjectType>
7+
<!-- This property makes the build directory similar to a publish directory and helps the AWS .NET Lambda Mock Test Tool find project dependencies. -->
8+
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
9+
<!-- Generate ready to run images during publishing to improve cold start time. -->
10+
<PublishReadyToRun>true</PublishReadyToRun>
11+
</PropertyGroup>
12+
<ItemGroup>
13+
<PackageReference Include="Amazon.Lambda.Core" Version="2.4.0" />
14+
<PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.4.4" />
15+
</ItemGroup>
16+
</Project>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"Information": [
3+
"This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.",
4+
"To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.",
5+
"dotnet lambda help",
6+
"All the command line options for the Lambda command can be specified in this file."
7+
],
8+
"profile": "default",
9+
"region": "us-west-2",
10+
"configuration": "Release",
11+
"function-architecture": "x86_64",
12+
"function-runtime": "dotnet8",
13+
"function-memory-size": 512,
14+
"function-timeout": 30,
15+
"function-handler": "TestFunctionBuildProps::TestFunctionBuildProps.Function::FunctionHandler"
16+
}

0 commit comments

Comments
 (0)