Merge pull request #4505 from livarcocc/assembly_info_migration

Assembly info migration
This commit is contained in:
Livar 2016-10-26 17:00:22 -07:00 committed by GitHub
commit 53dc665e9b
8 changed files with 338 additions and 1 deletions

View 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)
{
}
}
}

View file

@ -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")]

View 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"
}
}
}

View file

@ -22,6 +22,7 @@ namespace Microsoft.DotNet.ProjectJsonMigration
new MigratePackageDependenciesAndToolsRule(),
new MigrateConfigurationsRule(),
new MigrateScriptsRule(),
new MigrateAssemblyInfoRule(),
new RemoveDefaultsFromProjectRule(),
new CleanOutputProjectRule(),
new SaveOutputProjectRule()

View file

@ -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;
}
}
}

View file

@ -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": { }

View file

@ -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");
}
}
}

View file

@ -21,6 +21,7 @@ namespace Microsoft.DotNet.Migration.Tests
[Theory]
[InlineData("TestAppWithRuntimeOptions")]
[InlineData("TestAppWithContents")]
[InlineData("AppWithAssemblyInfo")]
public void It_migrates_apps(string projectName)
{
var projectDirectory = TestAssetsManager.CreateTestInstance(projectName, callingMethod: "i")