Skip to content

Commit

Permalink
Add (non-working) .NET Core CLI commands
Browse files Browse the repository at this point in the history
Part of #3925
  • Loading branch information
bricelam committed Feb 10, 2016
1 parent f47d5e5 commit 05a5ffd
Show file tree
Hide file tree
Showing 28 changed files with 1,020 additions and 58 deletions.
14 changes: 14 additions & 0 deletions EntityFramework.sln
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.EntityFrameworkCo
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.EntityFrameworkCore.Sqlite.Design.Tests", "test\Microsoft.EntityFrameworkCore.Sqlite.Design.Tests\Microsoft.EntityFrameworkCore.Sqlite.Design.Tests.xproj", "{BFF1BBE8-C6CE-4103-9C75-6184C8B8D936}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-ef", "src\dotnet-ef\dotnet-ef.xproj", "{5C1B3280-F11D-4E4E-81B3-BCDA4942E097}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "dotnet-ef.Tests", "test\dotnet-ef.Tests\dotnet-ef.Tests.xproj", "{93D7AB4E-2E04-4217-BBE5-43EC0D54344F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -199,6 +203,14 @@ Global
{BFF1BBE8-C6CE-4103-9C75-6184C8B8D936}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BFF1BBE8-C6CE-4103-9C75-6184C8B8D936}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BFF1BBE8-C6CE-4103-9C75-6184C8B8D936}.Release|Any CPU.Build.0 = Release|Any CPU
{5C1B3280-F11D-4E4E-81B3-BCDA4942E097}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5C1B3280-F11D-4E4E-81B3-BCDA4942E097}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5C1B3280-F11D-4E4E-81B3-BCDA4942E097}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5C1B3280-F11D-4E4E-81B3-BCDA4942E097}.Release|Any CPU.Build.0 = Release|Any CPU
{93D7AB4E-2E04-4217-BBE5-43EC0D54344F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{93D7AB4E-2E04-4217-BBE5-43EC0D54344F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93D7AB4E-2E04-4217-BBE5-43EC0D54344F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{93D7AB4E-2E04-4217-BBE5-43EC0D54344F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -235,5 +247,7 @@ Global
{D4A29871-788D-4EA3-B637-1F8D14DA23B4} = {C605BAB7-B06E-4BDF-80B2-E661B7670E25}
{000FF28B-AA1E-4DD2-8582-0259CF07B025} = {E7D68B03-3A5D-4710-9A1F-20D198E41F78}
{BFF1BBE8-C6CE-4103-9C75-6184C8B8D936} = {C605BAB7-B06E-4BDF-80B2-E661B7670E25}
{5C1B3280-F11D-4E4E-81B3-BCDA4942E097} = {E7D68B03-3A5D-4710-9A1F-20D198E41F78}
{93D7AB4E-2E04-4217-BBE5-43EC0D54344F} = {C605BAB7-B06E-4BDF-80B2-E661B7670E25}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
Expand All @@ -24,23 +25,23 @@ public class DatabaseOperations

public DatabaseOperations(
[NotNull] ILoggerProvider loggerProvider,
[NotNull] string assemblyName,
[NotNull] string startupAssemblyName,
[NotNull] Assembly assembly,
[NotNull] Assembly startupAssembly,
[CanBeNull] string environment,
[NotNull] string projectDir,
[NotNull] string rootNamespace)
{
Check.NotNull(loggerProvider, nameof(loggerProvider));
Check.NotEmpty(assemblyName, nameof(assemblyName));
Check.NotEmpty(startupAssemblyName, nameof(startupAssemblyName));
Check.NotNull(assembly, nameof(assembly));
Check.NotNull(startupAssembly, nameof(startupAssembly));
Check.NotNull(projectDir, nameof(projectDir));
Check.NotNull(rootNamespace, nameof(rootNamespace));

_loggerProvider = loggerProvider;
_projectDir = projectDir;
_rootNamespace = rootNamespace;

var startup = new StartupInvoker(startupAssemblyName, environment);
var startup = new StartupInvoker(startupAssembly, environment);
_servicesBuilder = new DesignTimeServicesBuilder(startup);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,32 @@ namespace Microsoft.EntityFrameworkCore.Design
public class DbContextOperations
{
private readonly ILoggerProvider _loggerProvider;
private readonly string _assemblyName;
private readonly string _startupAssemblyName;
private readonly Assembly _assembly;
private readonly Assembly _startupAssembly;
private readonly string _projectDir;
private readonly LazyRef<ILogger> _logger;
private readonly IServiceProvider _runtimeServices;
private readonly DesignTimeServicesBuilder _servicesBuilder;

public DbContextOperations(
[NotNull] ILoggerProvider loggerProvider,
[NotNull] string assemblyName,
[NotNull] string startupAssemblyName,
[NotNull] Assembly assembly,
[NotNull] Assembly startupAssembly,
[NotNull] string projectDir,
[CanBeNull] string environment)
{
Check.NotNull(loggerProvider, nameof(loggerProvider));
Check.NotEmpty(assemblyName, nameof(assemblyName));
Check.NotEmpty(startupAssemblyName, nameof(startupAssemblyName));
Check.NotNull(assembly, nameof(assembly));
Check.NotNull(startupAssembly, nameof(startupAssembly));
Check.NotEmpty(projectDir, nameof(projectDir));

_loggerProvider = loggerProvider;
_assemblyName = assemblyName;
_startupAssemblyName = startupAssemblyName;
_assembly = assembly;
_startupAssembly = startupAssembly;
_projectDir = projectDir;
_logger = new LazyRef<ILogger>(() => _loggerProvider.CreateCommandsLogger());

var startup = new StartupInvoker(startupAssemblyName, environment);
var startup = new StartupInvoker(startupAssembly, environment);
_runtimeServices = startup.ConfigureServices();

_servicesBuilder = new DesignTimeServicesBuilder(startup);
Expand Down Expand Up @@ -125,11 +125,10 @@ private IDictionary<Type, Func<DbContext>> FindContextTypes()
{
_logger.Value.LogDebug(CommandsStrings.LogFindingContexts);

var startupAssembly = Assembly.Load(new AssemblyName(_startupAssemblyName));
var contexts = new Dictionary<Type, Func<DbContext>>();

// Look for IDbContextFactory implementations
var contextFactories = startupAssembly.GetConstructibleTypes()
var contextFactories = _startupAssembly.GetConstructibleTypes()
.Where(t => typeof(IDbContextFactory<DbContext>).GetTypeInfo().IsAssignableFrom(t));
foreach (var factory in contextFactories)
{
Expand Down Expand Up @@ -157,18 +156,8 @@ where i.GetTypeInfo().IsGenericType
}

// Look for DbContext classes in assemblies
Assembly assembly;
try
{
assembly = Assembly.Load(new AssemblyName(_assemblyName));
}
catch (Exception ex)
{
throw new OperationException(CommandsStrings.UnreferencedAssembly(_assemblyName, _startupAssemblyName), ex);
}

var types = startupAssembly.GetConstructibleTypes()
.Concat(assembly.GetConstructibleTypes())
var types = _startupAssembly.GetConstructibleTypes()
.Concat(_assembly.GetConstructibleTypes())
.Select(i => i.AsType());
var contextTypes = types.Where(t => typeof(DbContext).IsAssignableFrom(t))
.Concat(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,15 @@ public class StartupInvoker
private readonly string _environment;

public StartupInvoker(
[NotNull] string startupAssemblyName,
[NotNull] Assembly startupAssembly,
[CanBeNull] string environment)
{
Check.NotEmpty(startupAssemblyName, nameof(startupAssemblyName));
Check.NotNull(startupAssembly, nameof(startupAssembly));

_environment = !string.IsNullOrEmpty(environment)
? environment
: "Development";

var startupAssembly = Assembly.Load(new AssemblyName(startupAssemblyName));
_startupType = startupAssembly.DefinedTypes.Where(t => t.Name == "Startup" + _environment)
.Concat(startupAssembly.DefinedTypes.Where(t => t.Name == "Startup"))
.Concat(startupAssembly.DefinedTypes.Where(t => t.Name == "Program"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,23 @@ public class MigrationsOperations
{
private readonly ILoggerProvider _loggerProvider;
private readonly LazyRef<ILogger> _logger;
private readonly string _assemblyName;
private readonly Assembly _assembly;
private readonly string _projectDir;
private readonly string _rootNamespace;
private readonly DesignTimeServicesBuilder _servicesBuilder;
private readonly DbContextOperations _contextOperations;

public MigrationsOperations(
[NotNull] ILoggerProvider loggerProvider,
[NotNull] string assemblyName,
[NotNull] string startupAssemblyName,
[NotNull] Assembly assembly,
[NotNull] Assembly startupAssembly,
[CanBeNull] string environment,
[NotNull] string projectDir,
[NotNull] string rootNamespace)
{
Check.NotNull(loggerProvider, nameof(loggerProvider));
Check.NotEmpty(assemblyName, nameof(assemblyName));
Check.NotEmpty(startupAssemblyName, nameof(startupAssemblyName));
Check.NotNull(assembly, nameof(assembly));
Check.NotNull(startupAssembly, nameof(startupAssembly));
Check.NotNull(projectDir, nameof(projectDir));
Check.NotNull(rootNamespace, nameof(rootNamespace));

Expand All @@ -48,17 +48,17 @@ public MigrationsOperations(

_loggerProvider = loggerProvider;
_logger = new LazyRef<ILogger>(() => loggerFactory.CreateCommandsLogger());
_assemblyName = assemblyName;
_assembly = assembly;
_projectDir = projectDir;
_rootNamespace = rootNamespace;
_contextOperations = new DbContextOperations(
loggerProvider,
assemblyName,
startupAssemblyName,
assembly,
startupAssembly,
projectDir,
environment);

var startup = new StartupInvoker(startupAssemblyName, environment);
var startup = new StartupInvoker(startupAssembly, environment);
_servicesBuilder = new DesignTimeServicesBuilder(startup);
}

Expand Down Expand Up @@ -162,13 +162,16 @@ private void EnsureServices(IServiceProvider services)
throw new OperationException(CommandsStrings.NonRelationalProvider(providerServices.InvariantName));
}

var assemblyName = _assembly.GetName();
var options = services.GetRequiredService<IDbContextOptions>();
var contextType = services.GetRequiredService<DbContext>().GetType();
var assemblyName = RelationalOptionsExtension.Extract(options).MigrationsAssembly
var migrationsAssemblyName = RelationalOptionsExtension.Extract(options).MigrationsAssembly
?? contextType.GetTypeInfo().Assembly.GetName().Name;
if (_assemblyName != assemblyName)
if (assemblyName.Name != migrationsAssemblyName
&& assemblyName.FullName != migrationsAssemblyName)
{
throw new OperationException(CommandsStrings.MigrationsAssemblyMismatch(_assemblyName, assemblyName));
throw new OperationException(
CommandsStrings.MigrationsAssemblyMismatch(assemblyName.Name, migrationsAssemblyName));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Design.Internal;
using Microsoft.EntityFrameworkCore.Internal;
Expand Down Expand Up @@ -34,25 +35,37 @@ public OperationExecutor([NotNull] object logHandler, [NotNull] IDictionary args
var projectDir = (string)args["projectDir"];
var rootNamespace = (string)args["rootNamespace"];

var startupAssembly = Assembly.Load(new AssemblyName(startupTargetName));

Assembly assembly;
try
{
assembly = Assembly.Load(new AssemblyName(targetName));
}
catch (Exception ex)
{
throw new OperationException(CommandsStrings.UnreferencedAssembly(targetName, startupTargetName), ex);
}

_contextOperations = new LazyRef<DbContextOperations>(
() => new DbContextOperations(
loggerProvider,
targetName,
startupTargetName,
assembly,
startupAssembly,
projectDir, environment));
_databaseOperations = new LazyRef<DatabaseOperations>(
() => new DatabaseOperations(
loggerProvider,
targetName,
startupTargetName,
assembly,
startupAssembly,
environment,
projectDir,
rootNamespace));
_migrationsOperations = new LazyRef<MigrationsOperations>(
() => new MigrationsOperations(
loggerProvider,
targetName,
startupTargetName,
assembly,
startupAssembly,
environment,
projectDir,
rootNamespace));
Expand Down Expand Up @@ -318,7 +331,7 @@ private IEnumerable<string> ReverseEngineerImpl(

public class ScaffoldRuntimeDirectives : OperationBase
{
public ScaffoldRuntimeDirectives([NotNull] OperationExecutor executor, [NotNull] object resultHandler, [NotNull] IDictionary args)
public ScaffoldRuntimeDirectives([NotNull] OperationExecutor executor, [NotNull] object resultHandler, [NotNull] IDictionary args)
: base(resultHandler)
{
Check.NotNull(executor, nameof(executor));
Expand Down
32 changes: 32 additions & 0 deletions src/dotnet-ef/ConsoleCommandLogger.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.EntityFrameworkCore.Design.Internal;
using Microsoft.DotNet.Cli.Utils;
using JetBrains.Annotations;

namespace Microsoft.EntityFrameworkCore.Commands
{
public class ConsoleCommandLogger : CommandLogger
{
public ConsoleCommandLogger([NotNull] string name)
: base(name)
{
}

protected override void WriteDebug(string message)
=> Reporter.Verbose.WriteLine(message.Bold().Black());

protected override void WriteError(string message)
=> Reporter.Error.WriteLine(message.Bold().Red());

protected override void WriteInformation(string message)
=> Reporter.Error.WriteLine(message);

protected override void WriteTrace(string message)
=> Reporter.Verbose.WriteLine(message.Bold().Black());

protected override void WriteWarning(string message)
=> Reporter.Error.WriteLine(message.Bold().Yellow());
}
}
22 changes: 22 additions & 0 deletions src/dotnet-ef/DatabaseCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using JetBrains.Annotations;
using Microsoft.Extensions.CommandLineUtils;

namespace Microsoft.EntityFrameworkCore.Commands
{
public class DatabaseCommand
{
public static void Configure([NotNull] CommandLineApplication command)
{
command.Description = "Commands to manage your database";

command.HelpOption("-h|--help");

command.Command("update", DatabaseUpdateCommand.Configure);

command.OnExecute(() => command.ShowHelp());
}
}
}
43 changes: 43 additions & 0 deletions src/dotnet-ef/DatabaseUpdateCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using JetBrains.Annotations;
using Microsoft.Extensions.CommandLineUtils;

namespace Microsoft.EntityFrameworkCore.Commands
{
public class DatabaseUpdateCommand
{
public static void Configure([NotNull] CommandLineApplication command)
{
command.Description = "Updates the database to a specified migration";

var migration = command.Argument(
"[migration]",
"The target migration. If '0', all migrations will be reverted. If omitted, all pending migrations will be applied");

var context = command.Option(
"-c|--context <context>",
"The DbContext to use. If omitted, the default DbContext is used");
var startupProject = command.Option(
"-s|--startupProject <project>",
"The startup project to use. If omitted, the current project is used.");
var environment = command.Option(
"-e|--environment <environment>",
"The environment to use. If omitted, \"Development\" is used.");
command.HelpOption("-h|--help");

command.OnExecute(
() => Execute(migration.Value, context.Value(), startupProject.Value(), environment.Value()));
}

private static int Execute(string migration, string context, string startupProject, string environment)
{
new OperationsFactory(startupProject, environment)
.CreateMigrationsOperations()
.UpdateDatabase(migration, context);

return 0;
}
}
}
Loading

0 comments on commit 05a5ffd

Please sign in to comment.