Skip to content

Commit

Permalink
4.1 Release
Browse files Browse the repository at this point in the history
  • Loading branch information
andrew-boyarshin committed Jul 22, 2019
1 parent add5b13 commit d5a5ba7
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 60 deletions.
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<Copyright>Copyright Hans van Bakel</Copyright>
<Description>Tool for converting a MSBuild project file to VS2017 format and beyond.</Description>
<PackageTags>dotnet csproj fsproj vbproj msbuild conversion vs2015 vs14 vs15 vs2017</PackageTags>
<Version>4.1.0-beta.5</Version>
<Version>4.1.0</Version>
<AssemblyVersion>4.1.0.0</AssemblyVersion>

<!-- SourceLink -->
Expand Down
15 changes: 14 additions & 1 deletion Project2015To2017.Core/ConversionOptions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using Project2015To2017.Transforms;
Expand Down Expand Up @@ -27,10 +28,12 @@ public sealed class ConversionOptions
/// <summary>
/// A collection of transforms executed before the execution of default ones
/// </summary>
[Obsolete("Use ITransformationSet as transformation collection, inherit transformations from ITransformationWithTargetMoment to set Early execution moment.")]
public IReadOnlyList<ITransformation> PreDefaultTransforms { get; set; } = ImmutableArray<ITransformation>.Empty;
/// <summary>
/// A collection of transforms executed after the execution of default ones
/// </summary>
[Obsolete("Use ITransformationSet as transformation collection, inherit transformations from ITransformationWithTargetMoment to set Late execution moment.")]
public IReadOnlyList<ITransformation> PostDefaultTransforms { get; set; } = ImmutableArray<ITransformation>.Empty;
/// <summary>
/// A collection of transform class names executed despite being intended for different project system,
Expand All @@ -46,6 +49,16 @@ public sealed class ConversionOptions
/// <summary>
/// Force conversion ignoring any checks we might do that prevent a conversion.
/// </summary>
public bool Force { get; set; }
[Obsolete("Use ForceOnUnsupportedProjects instead", true)]
public bool Force
{
get => ForceOnUnsupportedProjects;
set => ForceOnUnsupportedProjects = value;
}

/// <summary>
/// Force conversion of projects otherwise considered of an unsupported type.
/// </summary>
public bool ForceOnUnsupportedProjects { get; set; }
}
}
2 changes: 1 addition & 1 deletion Project2015To2017.Core/Reading/ProjectReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public ProjectReader(ILogger logger = null, ConversionOptions conversionOptions
this.logger = logger ?? NoopLogger.Instance;
this.projectCache = conversionOptions?.ProjectCache ?? Caching.NoProjectCache.Instance;
this.nuspecReader = new NuSpecReader(this.logger);
this.forceConversion = conversionOptions?.Force ?? false;
this.forceConversion = conversionOptions?.ForceOnUnsupportedProjects ?? false;
this.assemblyInfoReader = new AssemblyInfoReader(this.logger);
this.projectPropertiesReader = new ProjectPropertiesReader(this.logger, conversionOptions?.UnknownTargetFrameworkCallback);
}
Expand Down
2 changes: 1 addition & 1 deletion Project2015To2017.Migrate2017.Tool/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ private static int ProcessArgs(ParseResult result)
var conversionOptions = new ConversionOptions
{
ProjectCache = new DefaultProjectCache(),
Force = command.ValueOrDefault<bool>("force"),
ForceOnUnsupportedProjects = command.ValueOrDefault<bool>("force"),
KeepAssemblyInfo = command.ValueOrDefault<bool>("keep-assembly-info")
};

Expand Down
2 changes: 1 addition & 1 deletion Project2015To2017.Migrate2019.Tool/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private static int ProcessArgs(ParseResult result)
var conversionOptions = new ConversionOptions
{
ProjectCache = new DefaultProjectCache(),
Force = command.ValueOrDefault<bool>("force"),
ForceOnUnsupportedProjects = command.ValueOrDefault<bool>("force"),
KeepAssemblyInfo = command.ValueOrDefault<bool>("keep-assembly-info")
};

Expand Down
2 changes: 1 addition & 1 deletion Project2015To2017.MigrateXXXX.Tool/ProgramBase.Options.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ private static ArgumentsRule DefaultToCurrentDirectory(this ArgumentsRule rule)
rule.With(defaultValue: () => PathUtility.EnsureTrailingSlash(Directory.GetCurrentDirectory()));

internal static Option ForceOption => Create.Option("-f|--force",
"Force a conversion even if not all preconditions are met.");
"Force a conversion of projects otherwise considered of an unsupported type (e.g. Entity Framework/ASP.NET).");

internal static Option HelpOption() =>
Create.Option("-h|--help",
Expand Down
2 changes: 1 addition & 1 deletion Project2015To2017.Tests/ProjectPropertiesReadTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public async Task ReadsUnsupportedProjectTypeWhenForced()
</PropertyGroup>
</Project>";

var project = await ParseAndTransform(xml, nameof(ReadsUnsupportedProjectTypeWhenForced), new ConversionOptions { Force = true }).ConfigureAwait(false);
var project = await ParseAndTransform(xml, nameof(ReadsUnsupportedProjectTypeWhenForced), new ConversionOptions { ForceOnUnsupportedProjects = true }).ConfigureAwait(false);

Assert.AreEqual(ApplicationType.ClassLibrary, project.Type);
}
Expand Down
121 changes: 68 additions & 53 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
[![Build status](https://ci.appveyor.com/api/projects/status/bpo5n2yehpqrxbc4?svg=true)](https://ci.appveyor.com/project/hvanbakel/csprojtovs2017)
[![NuGet Version](https://img.shields.io/nuget/v/Project2015To2017.svg?label=Nupkg%20Version)](https://www.nuget.org/packages/Project2015To2017)
[![NuGet Downloads](https://img.shields.io/nuget/dt/Project2015To2017.svg?label=Nupkg%20Downloads)](https://www.nuget.org/packages/Project2015To2017)
[![Global Tool NuGet Version](https://img.shields.io/nuget/v/Project2015To2017.Migrate2017.Tool.svg?label=Global%20Tool%20Version)](https://www.nuget.org/packages/Project2015To2017.Migrate2017.Tool)
[![Global Tool NuGet Downloads](https://img.shields.io/nuget/dt/Project2015To2017.Migrate2017.Tool.svg?label=Global%20Tool%20Downloads)](https://www.nuget.org/packages/Project2015To2017.Migrate2017.Tool)
[![VS15 Global Tool NuGet Version](https://img.shields.io/nuget/v/Project2015To2017.Migrate2017.Tool.svg?label=Global%20Tool%20Version)](https://www.nuget.org/packages/Project2015To2017.Migrate2017.Tool)
[![VS15 Global Tool NuGet Downloads](https://img.shields.io/nuget/dt/Project2015To2017.Migrate2017.Tool.svg?label=Global%20Tool%20Downloads)](https://www.nuget.org/packages/Project2015To2017.Migrate2017.Tool)
[![VS16 Global Tool NuGet Version](https://img.shields.io/nuget/v/Project2015To2017.Migrate2019.Tool.svg?label=Global%20Tool%20Version)](https://www.nuget.org/packages/Project2015To2017.Migrate2019.Tool)
[![VS16 Global Tool NuGet Downloads](https://img.shields.io/nuget/dt/Project2015To2017.Migrate2019.Tool.svg?label=Global%20Tool%20Downloads)](https://www.nuget.org/packages/Project2015To2017.Migrate2019.Tool)

# Convert your old project files to the new 2017 format
# Convert your old project files to the new 2017/2019 format
With the introduction of Visual Studio 2017, Microsoft added some optimizations to how a project file can be set up. However, no tooling was made available that performed this conversion as it was not necessary to do since Visual Studio 2017 would work with the old format too.

This project converts an existing csproj to the new format, shortening the project file and using all the nice new features that are part of Visual Studio 2017.
This project converts an existing csproj to the new format, shortening the project file and using all the nice new features that are part of modern Visual Studio versions.

## What does it fix?
There are a number of things [that VS2017 handles differently](http://www.natemcmaster.com/blog/2017/03/09/vs2015-to-vs2017-upgrade/) that are performed by this tool:
There are a number of things [that VS2017+ handles differently](http://www.natemcmaster.com/blog/2017/03/09/vs2015-to-vs2017-upgrade/) that are performed by this tool:
1. Include files using a wildcard as opposed to specifying every single file
2. A more succinct way of defining project references
3. A more succinct way of handling NuGet package references
Expand All @@ -20,33 +22,42 @@ There are a number of things [that VS2017 handles differently](http://www.natemc
## Quick Start
Assuming you have .NET Core 2.1+ installed you can run this on the command line:
```
> dotnet tool install --global Project2015To2017.Migrate2017.Tool
> dotnet tool install --global Project2015To2017.Migrate2019.Tool
```

This will install the tool for you to use it anywhere you would like. You can then call the tool as shown in the examples below.

```
> dotnet migrate-2017 wizard "D:\Path\To\My\TestProject.csproj"
> dotnet migrate-2019 wizard "D:\Path\To\My\TestProject.csproj"
```

Or

```
> dotnet migrate-2017 wizard "D:\Path\To\My\TestProject.sln"
> dotnet migrate-2019 wizard "D:\Path\To\My\TestProject.sln"
```

Or

```
> dotnet migrate-2017 wizard "D:\Path\To\My\Directory"
> dotnet migrate-2019 wizard .\MyProjectDirectory
```

Or even

```
> dotnet migrate-2019 wizard **\*
```

This will start the interactive wizard, which will guide you through the conversion process.
You will have an option to create backups before all critical conversion stages.

There is no need to specify paths if there is only one convertible object (project or solution) in your current working directory.
**Note:** There is no need to specify paths if there is only one convertible object (project or solution) in your current working directory.
The tool will discover them automatically, or inform you in case it can't make definite (and safest) decision.

**Note:** in case you need to migrate to VS2017, not VS2019, install `Project2015To2017.Migrate2017.Tool` instead.
It will provide `dotnet migrate-2017` command with a few tiny behavioral differences to support older VS versions.

## Commands
* `wizard` will run interactive conversion wizard as shown above
* `migrate` will run non-interactive migration (useful for scripts or advanced users)
Expand All @@ -68,27 +79,28 @@ Not all flags are supported by all commands, verify help output of the command t
In case you need to specify multiple values for option, specify it multiple times:

```
> dotnet migrate-2017 migrate -t net40 -t net45
> dotnet migrate-2019 migrate -t net40 -t net45
```

## Use as a NuGet library from your own code

For additional control of the project migration process, you can use the NuGet packages directly from your code.

Add the `Project2015To2017.Migrate2017.Library` package to your project e.g.

Add the `Project2015To2017.Migrate2019.Library` package to your project e.g.
```
dotnet add package Project2015To2017.Migrate2017.Library
> dotnet add package Project2015To2017.Migrate2019.Library
```

Then, to apply the default project migration:

```c#
using Project2015To2017;
using Project2015To2017.Analysis;
using Project2015To2017.Migrate2017;
using Project2015To2017.Migrate2019.Library;
using Project2015To2017.Writing;

//We use Serilog, but you can use any logging provider
// We use Serilog, but you can use any logging provider
using Serilog;
using Serilog.Extensions.Logging;

Expand All @@ -99,21 +111,26 @@ namespace Acme.ProjectMigration
static void Main(string[] args)
{
var logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.MinimumLevel.Debug()
.WriteTo.Console()
.CreateLogger();
.Enrich.FromLogContext()
.MinimumLevel.Debug()
.WriteTo.Console()
.CreateLogger();

var genericLogger = new SerilogLoggerProvider(logger).CreateLogger(nameof(Serilog));
var genericLogger = new SerilogLoggerProvider(logger)
.CreateLogger(nameof(Serilog));

var facility = new MigrationFacility(genericLogger);

facility.ExecuteMigrate(
new[] { @"c:\full-path-to-solution-or-project-file.sln" },
Vs15TransformationSet.Instance, //the default set of project file transformations
new ConversionOptions(), //control over things like target framework and AssemblyInfo treatment
new ProjectWriteOptions() //control over backup creation and custom source control logic
);
new[] { @"C:\full-path-to-solution-or-project-file.sln" },
Vs16TransformationSet.Instance, // the default set of project file transformations
// The rest are optional, will use sane defaults if not specified
new ConversionOptions(), // control over things like target framework and AssemblyInfo treatment
new ProjectWriteOptions(), // control over backup creation and custom source control logic
new AnalysisOptions() // control over diagnostics which will be run after migration
);
}
}
}
Expand All @@ -122,34 +139,32 @@ namespace Acme.ProjectMigration
To provide a custom set of project transforms, provide these to the `ExecuteMigrate` function call:

```c#
var preTransforms = new BasicTransformationSet(
//Note that these should implement
//ITransformationWithTargetMoment in order
//to make sure that they run before
//the standard transforms
new MyCustomPreTransform1(),
new MyCustomPreTransform2()
);

var postTransforms = new BasicTransformationSet(
//Note that these should implement
//ITransformationWithTargetMoment in order
//to make sure that they run after
//the standard transforms
new MyCustomPostTransform1(),
new MyCustomPostTransform2()
);

var customTransforms = new ChainTransformationSet(
preTransforms,
Vs15TransformationSet.Instance,
postTransforms
);
var customTransforms = new BasicTransformationSet(
// Note that these should implement ITransformationWithTargetMoment
// in order to make sure that they run before or after
// the majority of standard transforms.
// You can also implement ITransformationWithDependencies to ensure
// that your transformation always runs after some other
// standard or user-specified transformations.
new MyCustomPreTransform1(),
new MyCustomPreTransform2(),
new MyCustomPostTransform1(),
new MyCustomPostTransform2()
);

// Mix transformations from Vs16TransformationSet and from customTransforms.
// The correct order will be resolved by the library based on
// dependency graph topological ordering within each execution moment
// (early, normal, late).
var resultTransforms = new ChainTransformationSet(
Vs16TransformationSet.Instance,
customTransforms
);

facility.ExecuteMigrate(
new[] { @"c:\full-path-to-solution-or-project-file.sln" },
customTransforms,
new ConversionOptions(),
new ProjectWriteOptions()
);
new[] { @"C:\full-path-to-solution-or-project-file.sln" },
resultTransforms
);
```

0 comments on commit d5a5ba7

Please sign in to comment.