Skip to content
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

Generate appconfig for full framework project #2447

Merged
merged 1 commit into from
Aug 8, 2018

Conversation

wli3
Copy link

@wli3 wli3 commented Jul 31, 2018

Fix #2319

@wli3 wli3 changed the title WIP Generate appconfig for full framework project Generate appconfig for full framework project Jul 31, 2018
}

// intersection of https://docs.microsoft.com/en-us/nuget/reference/target-frameworks
// and https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/startup/supportedruntime-element#version
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use this map is good enough? Also, net30 is not a tfm in dotnet core. So, this is not a valid tfm

[InlineData("net30")]
[InlineData("net999")]
[InlineData("netstandard20")]
public void It_does_not_generate_version_and_sku_for_non_supported(string targetframework)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is not a valid TFM, no supportedRuntime is generated

</ItemGroup>

<!--Override the AppConfigWithTargetPath for downstream target-->
<ItemGroup>
Copy link
Author

@wli3 wli3 Jul 31, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This override I am not sure. PrepareForBuild will find and put AppConfigWithTargetPath. And GenerateBindingRedirects will read AppConfigWithTargetPath, and add binding redirect on top of it.

And this task will point AppConfigWithTargetPath to its intermediate result. So GenerateBindingRedirects will use the generated file.

@wli3 wli3 changed the title Generate appconfig for full framework project WIP Generate appconfig for full framework project Aug 1, 2018
@wli3 wli3 changed the title WIP Generate appconfig for full framework project Generate appconfig for full framework project Aug 2, 2018
@wli3 wli3 requested review from nguerrera, dsplaisted and a team August 2, 2018 04:47
@wli3 wli3 added this to the 2.2.1xx milestone Aug 2, 2018
Copy link
Member

@dsplaisted dsplaisted left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't have time to review the whole thing, but I did leave some feedback.


namespace Microsoft.NET.Build.Tasks.UnitTests
{
public class GivenAGenerateAppConfig
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename this class/file to GivenAGeneratedAppConfig (it's missing a "d").

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, forget to run through a round of spell checker

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

public class GivenAGenerateAppConfig
{
[Fact]
public void It_creates_startup_and_supportedRuntime_nod_when_there_is_not_any()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in method name: nod -> node

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

public ITaskItem AppConfigFile { get; set; }

[Required]
public string TargetFramework { get; set; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This task should be based on the TargetFrameworkIdentifier and TargetFrameworkVersion properties (which are by default inferred from TargetFramework) instead of directly depending on TargetFramework.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

used TargetFrameworkIdentifier and TargetFrameworkVersion instead

{
if (targetFrameworkParsed.Version.Major < 4)
{
if (_targetFrameworkBelow40RuntimeVersionMap.TryGetValue(targetFrameworkParsed.GetShortFolderName(), out string value))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using a map here, I would just use if statements, which check the range of values. IE any version >= 2.0 but < 4.0 should use v2.0.50727 in the app.config.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, check between version range


[Required]
public string TargetFrameworkVersion { get; set; }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For completeness, this should have optional TargetFrameworkProfile as well.

Copy link
Author

@wli3 wli3 Aug 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, added TargetFrameworkProfile

new XElement(
"supportedRuntime",
new XAttribute("version", "v4.0"),
new XAttribute("sku", $"{targetFrameworkIdentifier},Version={targetFrameworkVersion}"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For completeness, sku should include Profile (if any) as well in TFM. We don't support net40-client directly with our target framework inference, but I believe some folks do it explicitly or use community "extras" package to do it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an example? And is there a easy way to test it to make sure profile and tfm is in correct "format"? I am afraid of adding more property and it ends up cannot be read by runtime. Today, I avoid this issue by matching exactly to the following doc.

https://github.com/dotnet/docs/blob/master/docs/framework/configure-apps/file-schema/startup/supportedruntime-element.md

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find it, it is also a doc

https://docs.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/startup/supportedruntime-element

So it will just do Profile="${TargetFrameworkProfile}"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You will need to make profile optional and only use it if set.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, it is optional. Only add it when it is set

supportedRuntime = null;

if (targetFrameworkIdentifier == ".NETFramework"
&& NuGetVersion.TryParse(targetFrameworkVersion.TrimStart('v', 'V'), out NuGetVersion parsedVersion))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TargetFrameworkVersion should parse as System.Version

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, used System.Version.Parse

if (File.Exists(OutputAppConfigFile.ItemSpec))
{
File.Delete(OutputAppConfigFile.ItemSpec);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem necessary: FileMode.Create below will truncate the existing file.

Create Specifies that the operating system should create a new file. If the file already exists, it will be overwritten. This requires FileIOPermissionAccess.Write permission. FileMode.Create is equivalent to requesting that if the file does not exist, use CreateNew; otherwise, use Truncate. If the file already exists but is a hidden file, an UnauthorizedAccessException exception is thrown.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, removed File.Exists File.Delete

FileMode.Create,
FileAccess.Write,
FileShare.Read);
using (var stream = new StreamWriter(fileStream))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: newline here.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

<Target Name="GenerateAppConfig"
Condition="'$(GenerateAppConfig)' != 'false' and '$(TargetFrameworkIdentifier)' == '.NETFramework' and '$(HasRuntimeOutput)' == 'true'"
DependsOnTargets="_WriteAppConfig"
BeforeTargets="GenerateBindingRedirects">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that if I set GenerateBindingRedirects to false, but GenerateAppConfig to true, that it won't work? I think in practice all SDK projects should generate binding redirects, but it feels a little clunky to tie them together.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, beforetargets ResolveReferences.

<_GenerateAppConfigIntermediateAppConfig>$(IntermediateOutputPath)$(TargetFileName).withSupportedRuntime.config</_GenerateAppConfigIntermediateAppConfig>
</PropertyGroup>

<Target Name="GenerateAppConfig"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if GenerateAppConfig is a good name. Probably better to say what in app config we're generating to match GenerateBindingRedirects. GenerateSupportedRuntime, perhaps? It is a common case for netfx apps to already have an app.config for other reasons so we aren't always generating one from scratch, but that's what the name reads like to me.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, renamed target to GenerateSupportedRuntime and the task is called WriteAppConfigWithSupportedRuntime (since it will create one)

@wli3 wli3 force-pushed the gen-app-config-2 branch 2 times, most recently from 7f3d8aa to c3719c1 Compare August 6, 2018 19:50
<Target Name="GenerateSupportedRuntime"
Condition="'$(GenerateSupportedRuntime)' != 'false' and '$(TargetFrameworkIdentifier)' == '.NETFramework' and '$(HasRuntimeOutput)' == 'true'"
DependsOnTargets="_WriteAppConfigWithSupportedRuntime"
BeforeTargets="GenerateBindingRedirects">
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rainersigwald this is the issue I asked. We are worried about if this target can still run when GenerateBindingRedirects is disable.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before a target is executed or skipped, any target that lists it in a BeforeTargets attribute is run.

https://docs.microsoft.com/en-us/visualstudio/msbuild/target-build-order#determine-the-target-build-order

@nguerrera plus I tested out disable AutoGenerateBindingRedirects=false . it is fine to use BeforeTargets="GenerateBindingRedirects"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, ok, I always get confused by that.

@wli3
Copy link
Author

wli3 commented Aug 8, 2018

@nguerrera all comments are addressed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants