Adding a rule that turns off assembly info generation for attributes already defined when migrating.
This commit is contained in:
parent
4aa1c1bfb4
commit
f863630fd8
6 changed files with 336 additions and 1 deletions
14
TestAssets/TestProjects/AppWithAssemblyInfo/Program.cs
Normal file
14
TestAssets/TestProjects/AppWithAssemblyInfo/Program.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ConsoleApp1
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ConsoleApp1")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyFileVersion("")]
|
||||
[assembly: AssemblyInformationalVersion("")]
|
||||
[assembly: AssemblyTitle("")]
|
||||
[assembly: AssemblyVersion("1.0.0")]
|
||||
[assembly: NeutralResourcesLanguage("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("ab699746-eb43-467d-ab46-6095b4de9722")]
|
19
TestAssets/TestProjects/AppWithAssemblyInfo/project.json
Normal file
19
TestAssets/TestProjects/AppWithAssemblyInfo/project.json
Normal file
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"version": "1.0.0-*",
|
||||
"buildOptions": {
|
||||
"emitEntryPoint": true
|
||||
},
|
||||
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.App": {
|
||||
"type": "platform",
|
||||
"version": "1.0.1"
|
||||
}
|
||||
},
|
||||
|
||||
"frameworks": {
|
||||
"netcoreapp1.0": {
|
||||
"imports": "dnxcore50"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Build.Construction;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Microsoft.DotNet.ProjectJsonMigration;
|
||||
using Microsoft.DotNet.ProjectJsonMigration.Transforms;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.ProjectModel.Files;
|
||||
using Microsoft.DotNet.Tools.Common;
|
||||
using NuGet.Frameworks;
|
||||
|
||||
namespace Microsoft.DotNet.ProjectJsonMigration.Rules
|
||||
{
|
||||
public class MigrateAssemblyInfoRule : IMigrationRule
|
||||
{
|
||||
private static IReadOnlyDictionary<string, IReadOnlyList<string>> Suppresses { get; } = new Dictionary<string, IReadOnlyList<string>>
|
||||
{
|
||||
{ "csc", new string[] {"CS1701", "CS1702", "CS1705" } }
|
||||
};
|
||||
|
||||
private static IReadOnlyList<string> GenerateAssemblyInfoWhitelist = new List<string>()
|
||||
{
|
||||
"AssemblyCompany",
|
||||
"AssemblyConfiguration",
|
||||
"AssemblyCopyright",
|
||||
"AssemblyDescription",
|
||||
"AssemblyFileVersion",
|
||||
"AssemblyInformationalVersion",
|
||||
"AssemblyProduct",
|
||||
"AssemblyTitle",
|
||||
"AssemblyVersion",
|
||||
"NeutralResourcesLanguage"
|
||||
};
|
||||
|
||||
private readonly ITransformApplicator _transformApplicator;
|
||||
|
||||
public MigrateAssemblyInfoRule(ITransformApplicator transformApplicator = null)
|
||||
{
|
||||
_transformApplicator = transformApplicator ?? new TransformApplicator();
|
||||
}
|
||||
|
||||
public void Apply(MigrationSettings migrationSettings, MigrationRuleInputs migrationRuleInputs)
|
||||
{
|
||||
var projectContext = migrationRuleInputs.DefaultProjectContext;
|
||||
var compilationOptions = ResolveCompilationOptions(projectContext, "Debug");
|
||||
var sources = GetCompilationSources(projectContext, compilationOptions);
|
||||
var assemblyInfoList = GetAssemblyInfo(sources);
|
||||
|
||||
foreach(var assemblyInfo in assemblyInfoList)
|
||||
{
|
||||
var propertyTransform = new AddPropertyTransform<string>(
|
||||
$"Generate{assemblyInfo}Attribute",
|
||||
a => "false",
|
||||
a => true);
|
||||
|
||||
_transformApplicator.Execute(
|
||||
propertyTransform.Transform(assemblyInfo),
|
||||
migrationRuleInputs.CommonPropertyGroup,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetCompilationSources(ProjectContext project, CommonCompilerOptions compilerOptions)
|
||||
{
|
||||
if (compilerOptions.CompileInclude == null)
|
||||
{
|
||||
return project.ProjectFile.Files.SourceFiles;
|
||||
}
|
||||
|
||||
var includeFiles = IncludeFilesResolver.GetIncludeFiles(compilerOptions.CompileInclude, "/", diagnostics: null);
|
||||
|
||||
return includeFiles.Select(f => f.SourcePath);
|
||||
}
|
||||
|
||||
public List<string> GetAssemblyInfo(IEnumerable<string> sourceFiles)
|
||||
{
|
||||
var assemblyInfoList = new List<string>();
|
||||
foreach (var sourceFile in sourceFiles)
|
||||
{
|
||||
var tree = CSharpSyntaxTree.ParseText(File.ReadAllText(sourceFile));
|
||||
var root = tree.GetRoot();
|
||||
|
||||
// assembly attributes can be only on first level
|
||||
foreach (var attributeListSyntax in root.ChildNodes().OfType<AttributeListSyntax>())
|
||||
{
|
||||
if (attributeListSyntax.Target.Identifier.Kind() == SyntaxKind.AssemblyKeyword)
|
||||
{
|
||||
foreach (var attributeSyntax in attributeListSyntax
|
||||
.Attributes
|
||||
.Select(a => a.Name.ToString())
|
||||
.Where(a => GenerateAssemblyInfoWhitelist.Contains(a)))
|
||||
{
|
||||
assemblyInfoList.Add(attributeSyntax);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return assemblyInfoList;
|
||||
}
|
||||
|
||||
// used in incremental compilation for the key file
|
||||
private CommonCompilerOptions ResolveCompilationOptions(ProjectContext context, string configuration)
|
||||
{
|
||||
var compilerOptions = GetLanguageSpecificCompilerOptions(context, context.TargetFramework, configuration);
|
||||
|
||||
// Path to strong naming key in environment variable overrides path in project.json
|
||||
var environmentKeyFile = Environment.GetEnvironmentVariable(EnvironmentNames.StrongNameKeyFile);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(environmentKeyFile))
|
||||
{
|
||||
compilerOptions.KeyFile = environmentKeyFile;
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(compilerOptions.KeyFile))
|
||||
{
|
||||
// Resolve full path to key file
|
||||
compilerOptions.KeyFile =
|
||||
Path.GetFullPath(Path.Combine(context.ProjectFile.ProjectDirectory, compilerOptions.KeyFile));
|
||||
}
|
||||
return compilerOptions;
|
||||
}
|
||||
|
||||
private CommonCompilerOptions GetLanguageSpecificCompilerOptions(
|
||||
ProjectContext context,
|
||||
NuGetFramework framework,
|
||||
string configurationName)
|
||||
{
|
||||
var baseOption = context.ProjectFile.GetCompilerOptions(framework, configurationName);
|
||||
|
||||
IReadOnlyList<string> defaultSuppresses;
|
||||
var compilerName = baseOption.CompilerName ?? "csc";
|
||||
if (Suppresses.TryGetValue(compilerName, out defaultSuppresses))
|
||||
{
|
||||
baseOption.SuppressWarnings = (baseOption.SuppressWarnings ?? Enumerable.Empty<string>()).Concat(defaultSuppresses).Distinct();
|
||||
}
|
||||
|
||||
return baseOption;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -17,7 +17,8 @@
|
|||
"Microsoft.DotNet.ProjectModel": {
|
||||
"target": "project"
|
||||
},
|
||||
"Microsoft.Build": "15.1.319-preview5"
|
||||
"Microsoft.Build": "15.1.319-preview5",
|
||||
"Microsoft.CodeAnalysis.CSharp": "2.0.0-beta6-60922-08"
|
||||
},
|
||||
"frameworks": {
|
||||
"netcoreapp1.0": { }
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
// Copyright (c) .NET Foundation and contributors. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.Build.Construction;
|
||||
using Microsoft.DotNet.ProjectJsonMigration;
|
||||
using Microsoft.DotNet.ProjectModel;
|
||||
using Microsoft.DotNet.Tools.Test.Utilities;
|
||||
using NuGet.Frameworks;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
using FluentAssertions;
|
||||
using Microsoft.DotNet.ProjectJsonMigration.Rules;
|
||||
|
||||
namespace Microsoft.DotNet.ProjectJsonMigration.Tests
|
||||
{
|
||||
public class GivenThatIWantToMigrateAssemblyInfo : TestBase
|
||||
{
|
||||
private ProjectRootElement _mockProject;
|
||||
|
||||
public GivenThatIWantToMigrateAssemblyInfo()
|
||||
{
|
||||
var projectDirectory =
|
||||
TestAssetsManager.CreateTestInstance("AppWithAssemblyInfo", callingMethod: "i").Path;
|
||||
var projectContext =
|
||||
ProjectContext.Create(projectDirectory, FrameworkConstants.CommonFrameworks.NetCoreApp10);
|
||||
_mockProject = ProjectRootElement.Create();
|
||||
var testSettings = new MigrationSettings(projectDirectory, projectDirectory, "1.0.0", _mockProject, null);
|
||||
var testInputs = new MigrationRuleInputs(
|
||||
new[] {projectContext},
|
||||
_mockProject,
|
||||
_mockProject.AddItemGroup(),
|
||||
_mockProject.AddPropertyGroup());
|
||||
|
||||
new MigrateAssemblyInfoRule().Apply(testSettings, testInputs);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItSetsGenerateAssemblyCompanyAttributeToFalseWhenAssemblyCompanyExists()
|
||||
{
|
||||
var generateAssemblyAttributes =
|
||||
_mockProject.Properties.Where(p => p.Name.Equals("GenerateAssemblyCompanyAttribute", StringComparison.Ordinal));
|
||||
generateAssemblyAttributes.Count().Should().Be(1);
|
||||
generateAssemblyAttributes.First().Value.Should().Be("false");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItSetsGenerateAssemblyConfigurationAttributeToFalseWhenAssemblyConfigurationExists()
|
||||
{
|
||||
var generateAssemblyAttributes =
|
||||
_mockProject.Properties.Where(p => p.Name.Equals("GenerateAssemblyConfigurationAttribute", StringComparison.Ordinal));
|
||||
generateAssemblyAttributes.Count().Should().Be(1);
|
||||
generateAssemblyAttributes.First().Value.Should().Be("false");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItSetsGenerateAssemblyCopyrightAttributeToFalseWhenAssemblyCopyrightExists()
|
||||
{
|
||||
var generateAssemblyAttributes =
|
||||
_mockProject.Properties.Where(p => p.Name.Equals("GenerateAssemblyCopyrightAttribute", StringComparison.Ordinal));
|
||||
generateAssemblyAttributes.Count().Should().Be(1);
|
||||
generateAssemblyAttributes.First().Value.Should().Be("false");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItSetsGenerateAssemblyDescriptionAttributeToFalseWhenAssemblyDescriptionExists()
|
||||
{
|
||||
var generateAssemblyAttributes =
|
||||
_mockProject.Properties.Where(p => p.Name.Equals("GenerateAssemblyDescriptionAttribute", StringComparison.Ordinal));
|
||||
generateAssemblyAttributes.Count().Should().Be(1);
|
||||
generateAssemblyAttributes.First().Value.Should().Be("false");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItSetsGenerateAssemblyFileVersionAttributeToFalseWhenAssemblyFileVersionExists()
|
||||
{
|
||||
var generateAssemblyAttributes =
|
||||
_mockProject.Properties.Where(p => p.Name.Equals("GenerateAssemblyFileVersionAttribute", StringComparison.Ordinal));
|
||||
generateAssemblyAttributes.Count().Should().Be(1);
|
||||
generateAssemblyAttributes.First().Value.Should().Be("false");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItSetsGenerateAssemblyInformationalVersionAttributeToFalseWhenAssemblyInformationalVersionExists()
|
||||
{
|
||||
var generateAssemblyAttributes =
|
||||
_mockProject.Properties.Where(p => p.Name.Equals("GenerateAssemblyInformationalVersionAttribute", StringComparison.Ordinal));
|
||||
generateAssemblyAttributes.Count().Should().Be(1);
|
||||
generateAssemblyAttributes.First().Value.Should().Be("false");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItSetsGenerateAssemblyProductAttributeToFalseWhenAssemblyProductExists()
|
||||
{
|
||||
var generateAssemblyAttributes =
|
||||
_mockProject.Properties.Where(p => p.Name.Equals("GenerateAssemblyProductAttribute", StringComparison.Ordinal));
|
||||
generateAssemblyAttributes.Count().Should().Be(1);
|
||||
generateAssemblyAttributes.First().Value.Should().Be("false");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItSetsGenerateAssemblyTitleAttributeToFalseWhenAssemblyTitleExists()
|
||||
{
|
||||
var generateAssemblyAttributes =
|
||||
_mockProject.Properties.Where(p => p.Name.Equals("GenerateAssemblyTitleAttribute", StringComparison.Ordinal));
|
||||
generateAssemblyAttributes.Count().Should().Be(1);
|
||||
generateAssemblyAttributes.First().Value.Should().Be("false");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItSetsGenerateAssemblyVersionAttributeToFalseWhenAssemblyVersionExists()
|
||||
{
|
||||
var generateAssemblyAttributes =
|
||||
_mockProject.Properties.Where(p => p.Name.Equals("GenerateAssemblyVersionAttribute", StringComparison.Ordinal));
|
||||
generateAssemblyAttributes.Count().Should().Be(1);
|
||||
generateAssemblyAttributes.First().Value.Should().Be("false");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ItSetsGenerateNeutralResourcesLanguageAttributeToFalseWhenNeutralResourcesLanguageExists()
|
||||
{
|
||||
var generateAssemblyAttributes =
|
||||
_mockProject.Properties.Where(p => p.Name.Equals("GenerateNeutralResourcesLanguageAttribute", StringComparison.Ordinal));
|
||||
generateAssemblyAttributes.Count().Should().Be(1);
|
||||
generateAssemblyAttributes.First().Value.Should().Be("false");
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue