diff --git a/EntityFramework.sln b/EntityFramework.sln index c56e37f616..f5f36cf955 100644 --- a/EntityFramework.sln +++ b/EntityFramework.sln @@ -15,12 +15,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework.NuGet", "sr EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework", "src\EntityFramework\EntityFramework.csproj", "{E06D1C12-EFE8-4413-A15C-AE01FC158F2F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework.PowerShell", "src\EntityFramework.PowerShell\EntityFramework.PowerShell.csproj", "{1F3817E9-8070-4429-B134-9674698DD78C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EntityFramework.PowerShell.Utility", "src\EntityFramework.PowerShell.Utility\EntityFramework.PowerShell.Utility.csproj", "{73636C32-5633-4D12-AA7B-88DCC26ACDB7}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Migrate", "src\Migrate\Migrate.csproj", "{0D77532F-7478-4BBB-9790-95F52A3DADDA}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{24A9C4D1-E189-4D3A-A2D7-36D3ED51D277}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests", "test\EntityFramework\UnitTests\UnitTests.csproj", "{E8E91C5F-E54C-41B1-AE1B-62E047BF49D5}" @@ -55,18 +49,6 @@ Global {E06D1C12-EFE8-4413-A15C-AE01FC158F2F}.Debug|Any CPU.Build.0 = Debug|Any CPU {E06D1C12-EFE8-4413-A15C-AE01FC158F2F}.Release|Any CPU.ActiveCfg = Release|Any CPU {E06D1C12-EFE8-4413-A15C-AE01FC158F2F}.Release|Any CPU.Build.0 = Release|Any CPU - {1F3817E9-8070-4429-B134-9674698DD78C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1F3817E9-8070-4429-B134-9674698DD78C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1F3817E9-8070-4429-B134-9674698DD78C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1F3817E9-8070-4429-B134-9674698DD78C}.Release|Any CPU.Build.0 = Release|Any CPU - {73636C32-5633-4D12-AA7B-88DCC26ACDB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {73636C32-5633-4D12-AA7B-88DCC26ACDB7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {73636C32-5633-4D12-AA7B-88DCC26ACDB7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {73636C32-5633-4D12-AA7B-88DCC26ACDB7}.Release|Any CPU.Build.0 = Release|Any CPU - {0D77532F-7478-4BBB-9790-95F52A3DADDA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0D77532F-7478-4BBB-9790-95F52A3DADDA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0D77532F-7478-4BBB-9790-95F52A3DADDA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0D77532F-7478-4BBB-9790-95F52A3DADDA}.Release|Any CPU.Build.0 = Release|Any CPU {E8E91C5F-E54C-41B1-AE1B-62E047BF49D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E8E91C5F-E54C-41B1-AE1B-62E047BF49D5}.Debug|Any CPU.Build.0 = Debug|Any CPU {E8E91C5F-E54C-41B1-AE1B-62E047BF49D5}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/eng/Versions.props b/eng/Versions.props index 853f5d6afe..601838a001 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -8,13 +8,10 @@ False - 8.0.2 16.0.461 16.0.461 - 1.0.0 4.0.8876.1 14.0.1016.290 - 8.0.50728 4.7.145 6.7.2-beta-ef6 diff --git a/src/EntityFramework.PowerShell.Utility/DomainDispatcher.cs b/src/EntityFramework.PowerShell.Utility/DomainDispatcher.cs deleted file mode 100644 index c9eb224ea5..0000000000 --- a/src/EntityFramework.PowerShell.Utility/DomainDispatcher.cs +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations.Utilities -{ - using System.Management.Automation; - using EnvDTE; - - /// - /// This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. - /// - /// Provides a way of dispatching specific calls form the PowerShell commands' - /// AppDomain to the Visual Studio's main AppDomain. - /// - public class DomainDispatcher : MarshalByRefObject - { - private readonly PSCmdlet _cmdlet; - private readonly DTE _dte; - - /// - /// This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. - /// - /// Initializes a new instance of the class. - /// - public DomainDispatcher() - { - // Testing - } - - /// - /// This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. - /// - /// Initializes a new instance of the class. - /// - /// The PowerShell command that is being executed. - [CLSCompliant(false)] - public DomainDispatcher(PSCmdlet cmdlet) - { - // Not using Check here because this assembly is very small and without resources - if (cmdlet == null) - { - throw new ArgumentNullException("cmdlet"); - } - - _cmdlet = cmdlet; - _dte = (DTE)cmdlet.GetVariableValue("DTE"); - } - - /// - /// This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. - /// - /// Writes a line of text to the UI. - /// - /// The text to write. - public void WriteLine(string text) - { - // Not using Check here because this assembly is very small and without resources - if (string.IsNullOrWhiteSpace(text)) - { - throw new ArgumentNullException("text"); - } - - _cmdlet.Host.UI.WriteLine(text); - } - - /// - /// This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. - /// - /// Writes a warning to the UI. - /// - /// The text to write. - public void WriteWarning(string text) - { - // Not using Check here because this assembly is very small and without resources - if (string.IsNullOrWhiteSpace(text)) - { - throw new ArgumentNullException("text"); - } - - _cmdlet.WriteWarning(text); - } - - /// - /// This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. - /// - /// Writes verbose information to the UI. - /// - /// The text to write. - public void WriteVerbose(string text) - { - // Not using Check here because this assembly is very small and without resources - if (string.IsNullOrWhiteSpace(text)) - { - throw new ArgumentNullException("text"); - } - - _cmdlet.WriteVerbose(text); - } - - /// - /// This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. - /// - /// Opens the file given file in Visual Studio. - /// - /// Path of the file to open. - public virtual void OpenFile(string fileName) - { - // Not using Check here because this assembly is very small and without resources - if (string.IsNullOrWhiteSpace(fileName)) - { - throw new ArgumentNullException("fileName"); - } - - _dte.ItemOperations.OpenFile(fileName); - } - - /// - /// This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. - /// - /// Opens a new text file in Visual Studio without creating the file on disk. - /// - /// The text to add to the new file. - /// - /// The virtual path to the item template to use for the new file based on the tree nodes - /// from the left pane of the new item dialog box and the item name from the right pane. - /// - public void NewTextFile(string text, string item = @"General\Text File") - { - var window = _dte.ItemOperations.NewFile(item); - var textDocument = (TextDocument)window.Document.Object("TextDocument"); - var editPoint = textDocument.StartPoint.CreateEditPoint(); - editPoint.Insert(text); - } - } -} diff --git a/src/EntityFramework.PowerShell.Utility/EntityFramework.PowerShell.Utility.csproj b/src/EntityFramework.PowerShell.Utility/EntityFramework.PowerShell.Utility.csproj deleted file mode 100644 index a659d00aa7..0000000000 --- a/src/EntityFramework.PowerShell.Utility/EntityFramework.PowerShell.Utility.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - System.Data.Entity.Migrations.Utilities - True - net45 - EntityFramework.PowerShell.Utility.dll - 6.0.0.0 - - - - - - - - - - Properties\SharedAssemblyInfo.cs - - - Properties\SharedAssemblyVersionInfo.cs - - - - diff --git a/src/EntityFramework.PowerShell.Utility/Properties/AssemblyInfo.cs b/src/EntityFramework.PowerShell.Utility/Properties/AssemblyInfo.cs deleted file mode 100644 index 2d8640904d..0000000000 --- a/src/EntityFramework.PowerShell.Utility/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System.Reflection; - -[assembly: AssemblyDefaultAlias("EntityFramework.Powershell.Utility.dll")] diff --git a/src/EntityFramework.PowerShell/EntityFramework.PowerShell.csproj b/src/EntityFramework.PowerShell/EntityFramework.PowerShell.csproj deleted file mode 100644 index 444a640942..0000000000 --- a/src/EntityFramework.PowerShell/EntityFramework.PowerShell.csproj +++ /dev/null @@ -1,36 +0,0 @@ - - - - System.Data.Entity - True - net45 - EntityFramework.PowerShell.dll - 6.0.0.0 - - - - - - - - - - - - - Properties\Resources.PowerShell.cs - - - Properties\SharedAssemblyInfo.cs - - - Properties\SharedAssemblyVersionInfo.cs - - - - - - - - - diff --git a/src/EntityFramework.PowerShell/Migrations/AddMigrationCommand.cs b/src/EntityFramework.PowerShell/Migrations/AddMigrationCommand.cs deleted file mode 100644 index 7d6a867705..0000000000 --- a/src/EntityFramework.PowerShell/Migrations/AddMigrationCommand.cs +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Data.Entity.Migrations.Design; - using System.Data.Entity.Migrations.Extensions; - using System.Data.Entity.Migrations.Resources; - using System.Data.Entity.Migrations.Utilities; - using System.Data.Entity.Utilities; - using System.IO; - using System.Linq; - - internal class AddMigrationCommand : MigrationsDomainCommand - { - public AddMigrationCommand() - { - // Testing - } - - public AddMigrationCommand(string name, bool force, bool ignoreChanges) - { - DebugCheck.NotEmpty(name); - - Execute(() => Execute(name, force, ignoreChanges)); - } - - public void Execute(string name, bool force, bool ignoreChanges) - { - DebugCheck.NotEmpty(name); - - using (var facade = GetFacade()) - { - var scaffoldedMigration - = facade.Scaffold( - name, Project.GetLanguage(), Project.GetRootNamespace(), ignoreChanges); - - WriteLine( - !scaffoldedMigration.IsRescaffold - ? Strings.ScaffoldingMigration(name) - : Strings.RescaffoldingMigration(name)); - - var userCodePath - = WriteMigration(name, force, scaffoldedMigration, scaffoldedMigration.IsRescaffold); - - if (!scaffoldedMigration.IsRescaffold) - { - WriteWarning(Strings.SnapshotBehindWarning(name)); - - var databaseMigrations - = facade.GetDatabaseMigrations().Take(2).ToList(); - - var lastDatabaseMigration = databaseMigrations.FirstOrDefault(); - - if ((lastDatabaseMigration != null) - && string.Equals(lastDatabaseMigration.MigrationName(), name, StringComparison.Ordinal)) - { - var revertTargetMigration - = databaseMigrations.ElementAtOrDefault(1); - - WriteWarning( - Environment.NewLine - + Strings.DidYouMeanToRescaffold( - name, - revertTargetMigration ?? "$InitialDatabase", - Path.GetFileName(userCodePath))); - } - } - - Project.OpenFile(userCodePath); - } - } - - protected virtual string WriteMigration(string name, bool force, ScaffoldedMigration scaffoldedMigration, bool rescaffolding) - { - return new MigrationWriter(this).Write(scaffoldedMigration, rescaffolding, force, name); - } - } -} diff --git a/src/EntityFramework.PowerShell/Migrations/Extensions/IEnumerableExtensions.cs b/src/EntityFramework.PowerShell/Migrations/Extensions/IEnumerableExtensions.cs deleted file mode 100644 index 17e94a21c1..0000000000 --- a/src/EntityFramework.PowerShell/Migrations/Extensions/IEnumerableExtensions.cs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations.Extensions -{ - using System.Collections.Generic; - using System.Data.Entity.Utilities; - using System.Diagnostics; - using System.Linq; - - [DebuggerStepThrough] - internal static class IEnumerableExtensions - { - public static void Each(this IEnumerable ts, Action action) - { - DebugCheck.NotNull(ts); - DebugCheck.NotNull(action); - - foreach (var t in ts) - { - action(t); - } - } - - public static string Join(this IEnumerable ts, Func selector = null, string separator = ", ") - { - DebugCheck.NotNull(ts); - - selector = selector ?? (t => t.ToString()); - - return string.Join(separator, ts.Where(t => !ReferenceEquals(t, null)).Select(selector)); - } - } -} diff --git a/src/EntityFramework.PowerShell/Migrations/Extensions/ProjectExtensions.cs b/src/EntityFramework.PowerShell/Migrations/Extensions/ProjectExtensions.cs deleted file mode 100644 index bdc44e724f..0000000000 --- a/src/EntityFramework.PowerShell/Migrations/Extensions/ProjectExtensions.cs +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations.Extensions -{ - using System.Collections.Generic; - using System.Data.Entity.Migrations.Utilities; - using System.Data.Entity.Utilities; - using System.Diagnostics; - using System.IO; - using System.Linq; - using System.Runtime.InteropServices; - using EnvDTE; - using Microsoft.VisualStudio.Shell.Interop; - - internal static class ProjectExtensions - { - public const int S_OK = 0; - public const string WebApplicationProjectTypeGuid = "{349C5851-65DF-11DA-9384-00065B846F21}"; - public const string WebSiteProjectTypeGuid = "{E24C65DC-7377-472B-9ABA-BC803B73C61A}"; - public const string VsProjectItemKindPhysicalFolder = "{6BB5F8EF-4483-11D3-8BCF-00C04F8EC28C}"; - - public static string GetTargetName(this Project project) - { - DebugCheck.NotNull(project); - - return project.GetPropertyValue("AssemblyName"); - } - - public static string GetProjectDir(this Project project) - { - DebugCheck.NotNull(project); - - return project.GetPropertyValue("FullPath"); - } - - public static string GetTargetDir(this Project project) - { - DebugCheck.NotNull(project); - - var fullPath = project.GetProjectDir(); - - var outputPath - = project.IsWebSiteProject() - ? "Bin" - : project.GetConfigurationPropertyValue("OutputPath"); - - return Path.Combine(fullPath, outputPath); - } - - // - // Gets the string abbreviation for the language of a VS project. - // - public static string GetLanguage(this Project project) - { - DebugCheck.NotNull(project); - - switch (project.CodeModel.Language) - { - case CodeModelLanguageConstants.vsCMLanguageVB: - return "vb"; - - case CodeModelLanguageConstants.vsCMLanguageCSharp: - return "cs"; - } - - return null; - } - - // - // Gets the root namespace configured for a VS project. - // - public static string GetRootNamespace(this Project project) - { - DebugCheck.NotNull(project); - - return project.GetPropertyValue("RootNamespace"); - } - - public static string GetFileName(this Project project, string projectItemName) - { - DebugCheck.NotNull(project); - DebugCheck.NotEmpty(projectItemName); - - ProjectItem projectItem; - - try - { - projectItem = project.ProjectItems.Item(projectItemName); - } - catch - { - return Path.Combine(project.GetProjectDir(), projectItemName); - } - - Debug.Assert(projectItem.FileCount == 1); - - return projectItem.FileNames[0]; - } - - public static bool IsWebProject(this Project project) - { - DebugCheck.NotNull(project); - - return project.GetProjectTypes().Any( - g => g.EqualsIgnoreCase(WebApplicationProjectTypeGuid) - || g.EqualsIgnoreCase(WebSiteProjectTypeGuid)); - } - - public static bool IsWebSiteProject(this Project project) - { - DebugCheck.NotNull(project); - - return project.GetProjectTypes().Any(g => g.EqualsIgnoreCase(WebSiteProjectTypeGuid)); - } - - public static void EditFile(this Project project, string path) - { - DebugCheck.NotNull(project); - DebugCheck.NotEmpty(path); - Debug.Assert(!Path.IsPathRooted(path)); - - var absolutePath = Path.Combine(project.GetProjectDir(), path); - var dte = project.DTE; - - if (dte.SourceControl != null - && dte.SourceControl.IsItemUnderSCC(absolutePath) - && !dte.SourceControl.IsItemCheckedOut(absolutePath)) - { - dte.SourceControl.CheckOutItem(absolutePath); - } - } - - public static void AddFile(this Project project, string path, string contents) - { - DebugCheck.NotNull(project); - DebugCheck.NotEmpty(path); - Debug.Assert(!Path.IsPathRooted(path)); - - var absolutePath = Path.Combine(project.GetProjectDir(), path); - - project.EditFile(path); - Directory.CreateDirectory(Path.GetDirectoryName(absolutePath)); - File.WriteAllText(absolutePath, contents, Text.Encoding.UTF8); - - project.AddFile(path); - } - - public static void AddFile(this Project project, string path) - { - DebugCheck.NotNull(project); - DebugCheck.NotEmpty(path); - Debug.Assert(!Path.IsPathRooted(path)); - - var directory = Path.GetDirectoryName(path); - var fileName = Path.GetFileName(path); - var projectDir = project.GetProjectDir(); - var absolutePath = Path.Combine(projectDir, path); - - var projectItems - = directory - .Split(Path.DirectorySeparatorChar) - .Aggregate( - project.ProjectItems, - (pi, dir) => - { - Debug.Assert(pi != null); - Debug.Assert(pi.Kind == VsProjectItemKindPhysicalFolder); - - projectDir = Path.Combine(projectDir, dir); - - try - { - var projectItem = pi.Item(dir); - - return projectItem.ProjectItems; - } - catch - { - } - - return pi.AddFromDirectory(projectDir).ProjectItems; - }); - - try - { - projectItems.Item(fileName); - } - catch - { - projectItems.AddFromFileCopy(absolutePath); - } - } - - public static void OpenFile(this Project project, string path) - { - DebugCheck.NotNull(project); - DebugCheck.NotEmpty(path); - Debug.Assert(!Path.IsPathRooted(path)); - - var absolutePath = Path.Combine(project.GetProjectDir(), path); - - GetDispatcher().OpenFile(absolutePath); - } - - public static void NewSqlFile(this Project project, string contents) - { - DebugCheck.NotNull(project); - - var dispatcher = GetDispatcher(); - - try - { - dispatcher.NewTextFile(contents, @"General\Sql File"); - } - catch - { - var fileName = Path.GetTempFileName(); - File.Delete(fileName); - fileName = Path.GetFileName(fileName); - fileName = Path.ChangeExtension(fileName, ".sql"); - - var intermediatePath = project.GetConfigurationPropertyValue("IntermediatePath"); - - var sqlFile = Path.Combine(project.GetProjectDir(), intermediatePath, fileName); - File.WriteAllText(sqlFile, contents); - - dispatcher.OpenFile(sqlFile); - } - } - - private static T GetPropertyValue(this Project project, string propertyName) - { - DebugCheck.NotNull(project); - DebugCheck.NotEmpty(propertyName); - - var property = project.Properties.Item(propertyName); - - if (property == null) - { - return default(T); - } - - return (T)property.Value; - } - - private static T GetConfigurationPropertyValue(this Project project, string propertyName) - { - DebugCheck.NotNull(project); - DebugCheck.NotEmpty(propertyName); - - var property = project.ConfigurationManager.ActiveConfiguration.Properties.Item(propertyName); - - if (property == null) - { - return default(T); - } - - return (T)property.Value; - } - - // - // Gets all aggregate project type GUIDs for the given project. - // Note that when running in Visual Studio app domain (which is how this code is used in - // production) a shellVersion of 10 is fine because VS has binding redirects to cause the - // latest version to be loaded. When running tests is may be desirable to explicitly pass - // a different version. See CodePlex 467. - // - public static IEnumerable GetProjectTypes(this Project project, int shellVersion = 10) - { - DebugCheck.NotNull(project); - - IVsHierarchy hierarchy; - - var serviceProviderType = Type.GetType(string.Format( - "Microsoft.VisualStudio.Shell.ServiceProvider, Microsoft.VisualStudio.Shell, Version={0}.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", - shellVersion)); - - Debug.Assert(serviceProviderType != null); - - var serviceProvider = (IServiceProvider)Activator.CreateInstance( - serviceProviderType, - (Microsoft.VisualStudio.OLE.Interop.IServiceProvider)project.DTE); - - var solution = (IVsSolution)serviceProvider.GetService(typeof(IVsSolution)); - var hr = solution.GetProjectOfUniqueName(project.UniqueName, out hierarchy); - - if (hr != S_OK) - { - Marshal.ThrowExceptionForHR(hr); - } - - string projectTypeGuidsString; - - var aggregatableProject = (IVsAggregatableProject)hierarchy; - hr = aggregatableProject.GetAggregateProjectTypeGuids(out projectTypeGuidsString); - - if (hr != S_OK) - { - Marshal.ThrowExceptionForHR(hr); - } - - return projectTypeGuidsString.Split(';'); - } - - private static DomainDispatcher GetDispatcher() - { - return (DomainDispatcher)AppDomain.CurrentDomain.GetData("efDispatcher"); - } - } -} diff --git a/src/EntityFramework.PowerShell/Migrations/GetMigrationsCommand.cs b/src/EntityFramework.PowerShell/Migrations/GetMigrationsCommand.cs deleted file mode 100644 index f0198bbd2b..0000000000 --- a/src/EntityFramework.PowerShell/Migrations/GetMigrationsCommand.cs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Data.Entity.Migrations.Resources; - using System.Linq; - - internal class GetMigrationsCommand : MigrationsDomainCommand - { - public GetMigrationsCommand() - { - Execute( - () => - { - using (var facade = GetFacade()) - { - WriteLine(Strings.GetMigrationsCommand_Intro); - - var migrations = facade.GetDatabaseMigrations(); - - if (migrations.Any()) - { - foreach (var migration in migrations) - { - WriteLine(migration); - } - } - else - { - WriteLine(Strings.GetMigrationsCommand_NoHistory); - } - } - }); - } - } -} diff --git a/src/EntityFramework.PowerShell/Migrations/MigrationsDomainCommand.cs b/src/EntityFramework.PowerShell/Migrations/MigrationsDomainCommand.cs deleted file mode 100644 index 2355ae12ff..0000000000 --- a/src/EntityFramework.PowerShell/Migrations/MigrationsDomainCommand.cs +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Data.Entity.Infrastructure; - using System.Data.Entity.Migrations.Design; - using System.Data.Entity.Migrations.Extensions; - using System.Data.Entity.Migrations.Utilities; - using System.Data.Entity.Utilities; - using System.IO; - using EnvDTE; - - internal abstract class MigrationsDomainCommand - { - private readonly AppDomain _domain; - private readonly DomainDispatcher _dispatcher; - - protected MigrationsDomainCommand() - { - _domain = AppDomain.CurrentDomain; - _dispatcher = (DomainDispatcher)_domain.GetData("efDispatcher"); - } - - public virtual Project Project - { - get { return (Project)_domain.GetData("project"); } - } - - public Project StartUpProject - { - get { return (Project)_domain.GetData("startUpProject"); } - } - - public Project ContextProject - { - get { return (Project)_domain.GetData("contextProject"); } - } - - public string ContextAssemblyName - { - get { return (string)_domain.GetData("contextAssemblyName"); } - } - - public string AppDomainBaseDirectory - { - get { return (string)_domain.GetData("appDomainBaseDirectory"); } - } - - protected AppDomain Domain - { - get { return _domain; } - } - - public void Execute(Action command) - { - DebugCheck.NotNull(command); - - Init(); - - try - { - command(); - } - catch (Exception ex) - { - Throw(ex); - } - } - - public virtual void WriteLine(string message) - { - DebugCheck.NotEmpty(message); - - _dispatcher.WriteLine(message); - } - - public virtual void WriteWarning(string message) - { - DebugCheck.NotEmpty(message); - - _dispatcher.WriteWarning(message); - } - - public void WriteVerbose(string message) - { - DebugCheck.NotEmpty(message); - - _dispatcher.WriteVerbose(message); - } - - public virtual ToolingFacade GetFacade(string configurationTypeName = null, bool useContextWorkingDirectory = false) - { - if (configurationTypeName == null) - { - configurationTypeName = (string)Domain.GetData("configurationTypeName"); - } - - var connectionStringName = (string)Domain.GetData("connectionStringName"); - var connectionString = (string)Domain.GetData("connectionString"); - var connectionProviderName = (string)Domain.GetData("connectionProviderName"); - DbConnectionInfo connectionStringInfo = null; - - if (!string.IsNullOrWhiteSpace(connectionStringName)) - { - connectionStringInfo = new DbConnectionInfo(connectionStringName); - } - else if (!string.IsNullOrWhiteSpace(connectionString)) - { - connectionStringInfo = new DbConnectionInfo(connectionString, connectionProviderName); - } - - var startUpProject = StartUpProject; - var assemblyName = Project.GetTargetName(); - - var contextAssemblyName = !string.IsNullOrWhiteSpace(ContextAssemblyName) - ? ContextAssemblyName - : ContextProject.GetTargetName(); - - var workingDirectory = !string.IsNullOrWhiteSpace(AppDomainBaseDirectory) - ? AppDomainBaseDirectory - : (useContextWorkingDirectory ? ContextProject.GetTargetDir() : Project.GetTargetDir()); - - string configurationFile; - string dataDirectory = null; - - if (startUpProject.IsWebProject()) - { - var startUpProjectDir = startUpProject.GetProjectDir(); - - configurationFile = startUpProject.GetFileName("Web.config"); - dataDirectory = Path.Combine(startUpProjectDir, "App_Data"); - } - else - { - configurationFile = startUpProject.GetFileName("App.config"); - } - - return new ToolingFacade( - assemblyName, - contextAssemblyName, - configurationTypeName, - workingDirectory, - configurationFile, - dataDirectory, - connectionStringInfo) - { - LogInfoDelegate = WriteLine, - LogWarningDelegate = WriteWarning, - LogVerboseDelegate = WriteVerbose - }; - } - - public T GetAnonymousArgument(string name) - { - return (T)_domain.GetData(name); - } - - private void Init() - { - _domain.SetData("wasError", false); - _domain.SetData("error.Message", null); - _domain.SetData("error.TypeName", null); - _domain.SetData("error.StackTrace", null); - } - - private void Throw(Exception ex) - { - DebugCheck.NotNull(ex); - - _domain.SetData("wasError", true); - - var toolEx = ex as ToolingException; - - if (toolEx == null) - { - _domain.SetData("error.Message", ex.Message); - _domain.SetData("error.TypeName", ex.GetType().FullName); - _domain.SetData("error.StackTrace", ex.ToString()); - } - else - { - _domain.SetData("error.Message", toolEx.Message); - _domain.SetData("error.TypeName", toolEx.InnerType); - _domain.SetData("error.StackTrace", toolEx.InnerStackTrace); - } - } - } -} diff --git a/src/EntityFramework.PowerShell/Migrations/ProjectTypeNotSupportedException.cs b/src/EntityFramework.PowerShell/Migrations/ProjectTypeNotSupportedException.cs deleted file mode 100644 index f56a0de425..0000000000 --- a/src/EntityFramework.PowerShell/Migrations/ProjectTypeNotSupportedException.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Data.Entity.Migrations.Infrastructure; - - /// - /// This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. - /// - /// Represents an error because migrations does not support the given type of project. - /// - [Serializable] - public sealed class ProjectTypeNotSupportedException : MigrationsException - { - /// - /// This API supports the Entity Framework infrastructure and is not intended to be used directly from your code. - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - public ProjectTypeNotSupportedException(string message) - : base(message) - { - } - } -} diff --git a/src/EntityFramework.PowerShell/Migrations/UpdateDatabaseCommand.cs b/src/EntityFramework.PowerShell/Migrations/UpdateDatabaseCommand.cs deleted file mode 100644 index a4d6769bcc..0000000000 --- a/src/EntityFramework.PowerShell/Migrations/UpdateDatabaseCommand.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations -{ - using System.Data.Entity.Migrations.Design; - using System.Data.Entity.Migrations.Extensions; - using System.Data.Entity.Migrations.Infrastructure; - using System.Data.Entity.Migrations.Resources; - using System.Diagnostics; - - internal class UpdateDatabaseCommand : MigrationsDomainCommand - { - public UpdateDatabaseCommand( - string sourceMigration, string targetMigration, bool script, bool force, bool verbose) - { - Debug.Assert( - string.IsNullOrWhiteSpace(sourceMigration) || script, - "sourceMigration can only be specified when script is true"); - - Execute( - () => - { - var project = Project; - - using (var facade = GetFacade()) - { - if (script) - { - var sql = facade.ScriptUpdate(sourceMigration, targetMigration, force); - - project.NewSqlFile(sql); - } - else - { - if (!verbose) - { - WriteLine(Strings.UpdateDatabaseCommand_VerboseInstructions); - } - - try - { - facade.Update(targetMigration, force); - } - catch (ToolingException ex) - { - if (ex.InnerType - == typeof(AutomaticMigrationsDisabledException).FullName) - { - facade.LogWarningDelegate(ex.Message); - facade.LogWarningDelegate(Strings.AutomaticMigrationDisabledInfo); - } - else - { - throw; - } - } - } - } - }); - } - } -} diff --git a/src/EntityFramework.PowerShell/Migrations/Utilities/MigrationWriter.cs b/src/EntityFramework.PowerShell/Migrations/Utilities/MigrationWriter.cs deleted file mode 100644 index d512c76135..0000000000 --- a/src/EntityFramework.PowerShell/Migrations/Utilities/MigrationWriter.cs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations.Utilities -{ - using System.Collections.Generic; - using System.Data.Entity.Migrations.Design; - using System.Data.Entity.Migrations.Extensions; - using System.Data.Entity.Migrations.Resources; - using System.Data.Entity.Utilities; - using System.Diagnostics; - using System.IO; - using System.Resources; - - internal class MigrationWriter - { - private readonly MigrationsDomainCommand _command; - - public MigrationWriter(MigrationsDomainCommand command) - { - DebugCheck.NotNull(command); - - _command = command; - } - - public string Write(ScaffoldedMigration scaffoldedMigration, bool rescaffolding = false, bool force = false, string name = null) - { - DebugCheck.NotNull(scaffoldedMigration); - - var userCodeFileName = scaffoldedMigration.MigrationId + "." + scaffoldedMigration.Language; - var userCodePath = Path.Combine(scaffoldedMigration.Directory, userCodeFileName); - var designerCodeFileName = scaffoldedMigration.MigrationId + ".Designer." - + scaffoldedMigration.Language; - var designerCodePath = Path.Combine(scaffoldedMigration.Directory, designerCodeFileName); - var resourcesFileName = scaffoldedMigration.MigrationId + ".resx"; - var resourcesPath = Path.Combine(scaffoldedMigration.Directory, resourcesFileName); - - if (rescaffolding && !force) - { - var absoluteUserCodePath = Path.Combine(_command.Project.GetProjectDir(), userCodePath); - - if (!string.Equals(scaffoldedMigration.UserCode, File.ReadAllText(absoluteUserCodePath))) - { - Debug.Assert(!string.IsNullOrWhiteSpace(name)); - - _command.WriteWarning(Strings.RescaffoldNoForce(name)); - } - } - else - { - _command.Project.AddFile(userCodePath, scaffoldedMigration.UserCode); - } - - WriteResources(userCodePath, resourcesPath, scaffoldedMigration.Resources); - _command.Project.AddFile(designerCodePath, scaffoldedMigration.DesignerCode); - - return userCodePath; - } - - private void WriteResources(string userCodePath, string resourcesPath, IDictionary resources) - { - DebugCheck.NotEmpty(userCodePath); - DebugCheck.NotEmpty(resourcesPath); - DebugCheck.NotNull(resources); - - var absoluteResourcesPath = Path.Combine(_command.Project.GetProjectDir(), resourcesPath); - - _command.Project.EditFile(resourcesPath); - - using (var writer = new ResXResourceWriter(absoluteResourcesPath)) - { - resources.Each(i => writer.AddResource(i.Key, i.Value)); - } - - _command.Project.AddFile(resourcesPath); - } - } -} diff --git a/src/EntityFramework.PowerShell/Properties/AssemblyInfo.cs b/src/EntityFramework.PowerShell/Properties/AssemblyInfo.cs deleted file mode 100644 index 341484eb4b..0000000000 --- a/src/EntityFramework.PowerShell/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System.Reflection; - -[assembly: AssemblyDefaultAlias("EntityFramework.Powershell.dll")] diff --git a/src/EntityFramework.PowerShell/Properties/InternalsVisibleTo.cs b/src/EntityFramework.PowerShell/Properties/InternalsVisibleTo.cs deleted file mode 100644 index 6076be54b2..0000000000 --- a/src/EntityFramework.PowerShell/Properties/InternalsVisibleTo.cs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System.Runtime.CompilerServices; - -// for Moq - -[assembly: - InternalsVisibleTo( - "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7" - )] -[assembly: - InternalsVisibleTo( - "EntityFramework.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293" - )] diff --git a/src/EntityFramework.PowerShell/Utilities/Check.cs b/src/EntityFramework.PowerShell/Utilities/Check.cs deleted file mode 100644 index b8189d6453..0000000000 --- a/src/EntityFramework.PowerShell/Utilities/Check.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Utilities -{ - using System.Data.Entity.Migrations.Resources; - - internal class Check - { - public static T NotNull(T value, string parameterName) where T : class - { - if (value == null) - { - throw new ArgumentNullException(parameterName); - } - - return value; - } - - public static T? NotNull(T? value, string parameterName) where T : struct - { - if (value == null) - { - throw new ArgumentNullException(parameterName); - } - - return value; - } - - public static string NotEmpty(string value, string parameterName) - { - if (string.IsNullOrWhiteSpace(value)) - { - throw new ArgumentException(Strings.ArgumentIsNullOrWhitespace(parameterName)); - } - - return value; - } - } -} diff --git a/src/EntityFramework.PowerShell/Utilities/DebugCheck.cs b/src/EntityFramework.PowerShell/Utilities/DebugCheck.cs deleted file mode 100644 index 84a8b37593..0000000000 --- a/src/EntityFramework.PowerShell/Utilities/DebugCheck.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Utilities -{ - using System.Diagnostics; - - internal class DebugCheck - { - [Conditional("DEBUG")] - public static void NotNull(T value) where T : class - { - Debug.Assert(value != null); - } - - [Conditional("DEBUG")] - public static void NotNull(T? value) where T : struct - { - Debug.Assert(value != null); - } - - [Conditional("DEBUG")] - public static void NotEmpty(string value) - { - Debug.Assert(!string.IsNullOrWhiteSpace(value)); - } - } -} diff --git a/src/EntityFramework/EntityFramework.csproj b/src/EntityFramework/EntityFramework.csproj index 56c7c3b6b1..479e7e3fe9 100644 --- a/src/EntityFramework/EntityFramework.csproj +++ b/src/EntityFramework/EntityFramework.csproj @@ -35,24 +35,6 @@ - - - - - - - - Resources.Migrate.tt - True - True - - - Resources.PowerShell.tt - True - True - - - Component @@ -71,16 +53,6 @@ - - TextTemplatingFileGenerator - Resources.Migrate.cs - System.Data.Entity.Migrations.Console - - - TextTemplatingFileGenerator - Resources.PowerShell.cs - System.Data.Entity.Migrations - TextTemplatingFileGenerator Resources.cs @@ -88,15 +60,6 @@ - - - System.Data.Entity.Migrations.Console.Properties - - - System.Data.Entity.Migrations.Properties - - - diff --git a/src/EntityFramework/Infrastructure/Design/Executor.cs b/src/EntityFramework/Infrastructure/Design/Executor.cs index d6a962acab..7e3cb94d30 100644 --- a/src/EntityFramework/Infrastructure/Design/Executor.cs +++ b/src/EntityFramework/Infrastructure/Design/Executor.cs @@ -10,6 +10,7 @@ namespace System.Data.Entity.Infrastructure.Design using System.Data.Entity.Migrations.Design; using System.Data.Entity.Migrations.History; using System.Data.Entity.Migrations.Infrastructure; + using System.Data.Entity.Migrations.Utilities; using System.Data.Entity.Resources; using System.Data.Entity.Utilities; using System.Diagnostics.CodeAnalysis; @@ -170,28 +171,16 @@ public GetProviderServices( } } - internal virtual IDictionary ScaffoldInitialCreateInternal( + private void OverrideConfiguration( + DbMigrationsConfiguration configuration, DbConnectionInfo connectionInfo, - string contextTypeName, - string contextAssemblyName, - string migrationsNamespace, - bool auto, - string migrationsDir) + bool force = false) { - var contextAssembly = LoadAssembly(contextAssemblyName) ?? _assembly; - var configuration = new DbMigrationsConfiguration - { - ContextType = contextAssembly.GetType(contextTypeName, throwOnError: true), - MigrationsAssembly = _assembly, - MigrationsNamespace = migrationsNamespace, - AutomaticMigrationsEnabled = auto, - MigrationsDirectory = migrationsDir - }; - if (connectionInfo != null) { configuration.TargetDatabase = connectionInfo; } + if (string.Equals(_language, "VB", StringComparison.OrdinalIgnoreCase) && configuration.CodeGenerator is CSharpMigrationCodeGenerator) { @@ -199,6 +188,14 @@ internal virtual IDictionary ScaffoldInitialCreateInternal( configuration.CodeGenerator = new VisualBasicMigrationCodeGenerator(); } + if (force) + { + configuration.AutomaticMigrationDataLossAllowed = true; + } + } + + private MigrationScaffolder CreateMigrationScaffolder(DbMigrationsConfiguration configuration) + { var scaffolder = new MigrationScaffolder(configuration); var @namespace = configuration.MigrationsNamespace; @@ -225,9 +222,11 @@ internal virtual IDictionary ScaffoldInitialCreateInternal( scaffolder.Namespace = @namespace; - var result = scaffolder.ScaffoldInitialCreate(); + return scaffolder; + } - return result == null + private static IDictionary ToHashtable(ScaffoldedMigration result) + => result == null ? null : new Hashtable { @@ -239,6 +238,31 @@ internal virtual IDictionary ScaffoldInitialCreateInternal( ["Resources"] = result.Resources, ["IsRescaffold"] = result.IsRescaffold }; + + internal virtual IDictionary ScaffoldInitialCreateInternal( + DbConnectionInfo connectionInfo, + string contextTypeName, + string contextAssemblyName, + string migrationsNamespace, + bool auto, + string migrationsDir) + { + var contextAssembly = LoadAssembly(contextAssemblyName) ?? _assembly; + var configuration = new DbMigrationsConfiguration + { + ContextType = contextAssembly.GetType(contextTypeName, throwOnError: true), + MigrationsAssembly = _assembly, + MigrationsNamespace = migrationsNamespace, + AutomaticMigrationsEnabled = auto, + MigrationsDirectory = migrationsDir + }; + OverrideConfiguration(configuration, connectionInfo); + + var scaffolder = CreateMigrationScaffolder(configuration); + + var result = scaffolder.ScaffoldInitialCreate(); + + return ToHashtable(result); } public class ScaffoldInitialCreate : OperationBase @@ -270,6 +294,169 @@ public ScaffoldInitialCreate(Executor executor, object resultHandler, IDictionar } } + private DbMigrationsConfiguration GetMigrationsConfiguration(string migrationsConfigurationName) + => new MigrationsConfigurationFinder(new TypeFinder(_assembly)) + .FindMigrationsConfiguration( + contextType: null, + migrationsConfigurationName, + Error.AssemblyMigrator_NoConfiguration, + (assembly, types) => Error.AssemblyMigrator_MultipleConfigurations(assembly), + Error.AssemblyMigrator_NoConfigurationWithName, + Error.AssemblyMigrator_MultipleConfigurationsWithName); + + internal virtual IDictionary ScaffoldInternal( + string name, + DbConnectionInfo connectionInfo, + string migrationsConfigurationName, + bool ignoreChanges) + { + var configuration = GetMigrationsConfiguration(migrationsConfigurationName); + OverrideConfiguration(configuration, connectionInfo); + + var scaffolder = CreateMigrationScaffolder(configuration); + + var result = scaffolder.Scaffold(name, ignoreChanges); + + return ToHashtable(result); + } + + public class Scaffold : OperationBase + { + public Scaffold(Executor executor, object resultHandler, IDictionary args) + : base(resultHandler) + { + Check.NotNull(executor, nameof(executor)); + Check.NotNull(resultHandler, nameof(resultHandler)); + Check.NotNull(args, nameof(args)); + + var name = (string)args["name"]; + var connectionStringName = (string)args["connectionStringName"]; + var connectionString = (string)args["connectionString"]; + var connectionProviderName = (string)args["connectionProviderName"]; + var migrationsConfigurationName = (string)args["migrationsConfigurationName"]; + var ignoreChanges = (bool)args["ignoreChanges"]; + + Execute( + () => executor.ScaffoldInternal( + name, + CreateConnectionInfo(connectionStringName, connectionString, connectionProviderName), + migrationsConfigurationName, + ignoreChanges)); + } + } + + internal IEnumerable GetDatabaseMigrationsInternal( + DbConnectionInfo connectionInfo, + string migrationsConfigurationName) + { + var configuration = GetMigrationsConfiguration(migrationsConfigurationName); + OverrideConfiguration(configuration, connectionInfo); + + return CreateMigrator(configuration).GetDatabaseMigrations(); + } + + public class GetDatabaseMigrations : OperationBase + { + public GetDatabaseMigrations(Executor executor, object resultHandler, IDictionary args) + : base(resultHandler) + { + Check.NotNull(executor, nameof(executor)); + Check.NotNull(resultHandler, nameof(resultHandler)); + Check.NotNull(args, nameof(args)); + + var connectionStringName = (string)args["connectionStringName"]; + var connectionString = (string)args["connectionString"]; + var connectionProviderName = (string)args["connectionProviderName"]; + var migrationsConfigurationName = (string)args["migrationsConfigurationName"]; + + Execute( + () => executor.GetDatabaseMigrationsInternal( + CreateConnectionInfo(connectionStringName, connectionString, connectionProviderName), + migrationsConfigurationName)); + } + } + + internal string ScriptUpdateInternal( + string sourceMigration, + string targetMigration, + bool force, + DbConnectionInfo connectionInfo, + string migrationsConfigurationName) + { + var configuration = GetMigrationsConfiguration(migrationsConfigurationName); + OverrideConfiguration(configuration, connectionInfo, force); + + return new MigratorScriptingDecorator(CreateMigrator(configuration)) + .ScriptUpdate(sourceMigration, targetMigration); + } + + public class ScriptUpdate : OperationBase + { + public ScriptUpdate(Executor executor, object resultHandler, IDictionary args) + : base(resultHandler) + { + Check.NotNull(executor, nameof(executor)); + Check.NotNull(resultHandler, nameof(resultHandler)); + Check.NotNull(args, nameof(args)); + + var sourceMigration = (string)args["sourceMigration"]; + var targetMigration = (string)args["targetMigration"]; + var force = (bool)args["force"]; + var connectionStringName = (string)args["connectionStringName"]; + var connectionString = (string)args["connectionString"]; + var connectionProviderName = (string)args["connectionProviderName"]; + var migrationsConfigurationName = (string)args["migrationsConfigurationName"]; + + Execute( + () => executor.ScriptUpdateInternal( + sourceMigration, + targetMigration, + force, + CreateConnectionInfo(connectionStringName, connectionString, connectionProviderName), + migrationsConfigurationName)); + } + } + + internal void UpdateInternal( + string targetMigration, + bool force, + DbConnectionInfo connectionInfo, + string migrationsConfigurationName) + { + var configuration = GetMigrationsConfiguration(migrationsConfigurationName); + OverrideConfiguration(configuration, connectionInfo, force); + + CreateMigrator(configuration).Update(targetMigration); + } + + public class Update : OperationBase + { + public Update(Executor executor, object resultHandler, IDictionary args) + : base(resultHandler) + { + Check.NotNull(executor, nameof(executor)); + Check.NotNull(resultHandler, nameof(resultHandler)); + Check.NotNull(args, nameof(args)); + + var targetMigration = (string)args["targetMigration"]; + var force = (bool)args["force"]; + var connectionStringName = (string)args["connectionStringName"]; + var connectionString = (string)args["connectionString"]; + var connectionProviderName = (string)args["connectionProviderName"]; + var migrationsConfigurationName = (string)args["migrationsConfigurationName"]; + + Execute( + () => executor.UpdateInternal( + targetMigration, + force, + CreateConnectionInfo(connectionStringName, connectionString, connectionProviderName), + migrationsConfigurationName)); + } + } + + private MigratorBase CreateMigrator(DbMigrationsConfiguration configuration) + => new MigratorLoggingDecorator(new DbMigrator(configuration), new ToolLogger(_reporter)); + /// /// Represents an operation. /// @@ -350,5 +537,24 @@ protected virtual void Execute(Func> action) Execute(() => _handler.SetResult(action().ToArray())); } } + + private class ToolLogger : MigrationsLogger + { + private readonly Reporter _reporter; + + public ToolLogger(Reporter reporter) + { + _reporter = reporter; + } + + public override void Info(string message) + => _reporter.WriteInformation(message); + + public override void Warning(string message) + => _reporter.WriteWarning(message); + + public override void Verbose(string sql) + => _reporter.WriteVerbose(sql); + } } } diff --git a/src/EntityFramework/Migrations/Design/ToolingException.cs b/src/EntityFramework/Migrations/Design/ToolingException.cs index 863c8b9f50..163989205d 100644 --- a/src/EntityFramework/Migrations/Design/ToolingException.cs +++ b/src/EntityFramework/Migrations/Design/ToolingException.cs @@ -11,6 +11,7 @@ namespace System.Data.Entity.Migrations.Design /// Represents an exception that occurred while running an operation in another AppDomain in the /// . /// + [Obsolete("Use System.Data.Entity.Infrastructure.Design.IErrorHandler instead.")] [SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors", Justification = "SerializeObjectState used instead")] [Serializable] diff --git a/src/EntityFramework/Migrations/Design/ToolingFacade.cs b/src/EntityFramework/Migrations/Design/ToolingFacade.cs index 40ab737468..9fc64abedc 100644 --- a/src/EntityFramework/Migrations/Design/ToolingFacade.cs +++ b/src/EntityFramework/Migrations/Design/ToolingFacade.cs @@ -27,7 +27,7 @@ namespace System.Data.Entity.Migrations.Design /// The App/Web.config file from the startup project is also copied /// to ensure that any configuration is applied. /// - // TODO: Move this functionality to System.Data.Entity.Infrastructure.Design.Executor + [Obsolete("Use System.Data.Entity.Infrastructure.Design.Executor instead.")] public class ToolingFacade : IDisposable { private readonly string _migrationsAssemblyName; diff --git a/src/EntityFramework/Properties/Resources.Migrate.cs b/src/EntityFramework/Properties/Resources.Migrate.cs deleted file mode 100644 index bbc9a8a1df..0000000000 --- a/src/EntityFramework/Properties/Resources.Migrate.cs +++ /dev/null @@ -1,514 +0,0 @@ -// - -namespace System.Data.Entity.Migrations.Console.Resources -{ - using System.CodeDom.Compiler; - using System.Globalization; - using System.Resources; - using System.Reflection; - using System.Threading; - - // - // Strongly-typed and parameterized string resources. - // - [GeneratedCode("Resources.Migrate.tt", "1.0.0.0")] - internal static class Strings - { - // - // A string like "Code First Migrations Command Line Utility" - // - internal static string MigrateTitle - { - get { return EntityRes.GetString(EntityRes.MigrateTitle); } - } - - // - // A string like "Applies any pending migrations to the database." - // - internal static string MigrateDescription - { - get { return EntityRes.GetString(EntityRes.MigrateDescription); } - } - - // - // A string like "ERROR: {0}" - // - internal static string ErrorMessage(object p0) - { - return EntityRes.GetString(EntityRes.ErrorMessage, p0); - } - - // - // A string like "WARNING: {0}" - // - internal static string WarningMessage(object p0) - { - return EntityRes.GetString(EntityRes.WarningMessage, p0); - } - - // - // A string like "VERBOSE: {0}" - // - internal static string VerboseMessage(object p0) - { - return EntityRes.GetString(EntityRes.VerboseMessage, p0); - } - - // - // A string like "Duplicate Command "{0}"" - // - internal static string DuplicateCommand(object p0) - { - return EntityRes.GetString(EntityRes.DuplicateCommand, p0); - } - - // - // A string like "Duplicate Parameter Index [{0}] on Property "{1}"" - // - internal static string DuplicateParameterIndex(object p0, object p1) - { - return EntityRes.GetString(EntityRes.DuplicateParameterIndex, p0, p1); - } - - // - // A string like "Out of order parameter "{0}" should have be at parameter index {1} but was found at {2}" - // - internal static string ParameterOutOfOrder(object p0, object p1, object p2) - { - return EntityRes.GetString(EntityRes.ParameterOutOfOrder, p0, p1, p2); - } - - // - // A string like ""{0}" is not a valid choice, valid keys are "{1}"" - // - internal static string InvalidKey(object p0, object p1) - { - return EntityRes.GetString(EntityRes.InvalidKey, p0, p1); - } - - // - // A string like "Press any key to continue..." - // - internal static string PressAnyKey - { - get { return EntityRes.GetString(EntityRes.PressAnyKey); } - } - - // - // A string like "Unsupported property type {0}" - // - internal static string UnsupportedPropertyType(object p0) - { - return EntityRes.GetString(EntityRes.UnsupportedPropertyType, p0); - } - - // - // A string like "Invalid ParameterIndex value on property "{0}"" - // - internal static string InvalidPropertyParameterIndexValue(object p0) - { - return EntityRes.GetString(EntityRes.InvalidPropertyParameterIndexValue, p0); - } - - // - // A string like "assembly" - // - internal static string AssemblyNameArgument - { - get { return EntityRes.GetString(EntityRes.AssemblyNameArgument); } - } - - // - // A string like "contextAssembly" - // - internal static string ContextAssemblyNameArgument - { - get { return EntityRes.GetString(EntityRes.ContextAssemblyNameArgument); } - } - - // - // A string like "configurationType" - // - internal static string ConfigurationTypeNameArgument - { - get { return EntityRes.GetString(EntityRes.ConfigurationTypeNameArgument); } - } - - // - // A string like "Specifies the name of the assembly that contains the migrations configuration type." - // - internal static string AssemblyNameDescription - { - get { return EntityRes.GetString(EntityRes.AssemblyNameDescription); } - } - - // - // A string like "Specifies the name of the assembly that contains the DbContext type if different from the assembly that contains the migrations configuration type." - // - internal static string ContextAssemblyNameDescription - { - get { return EntityRes.GetString(EntityRes.ContextAssemblyNameDescription); } - } - - // - // A string like "Specifies the name of the migrations configuration type. If omitted, Code First Migrations will attempt to locate a single migrations configuration type in the specified assembly." - // - internal static string ConfigurationTypeNameDescription - { - get { return EntityRes.GetString(EntityRes.ConfigurationTypeNameDescription); } - } - - // - // A string like "Specifies the name of a particular migration to update the database to. If omitted, the current model will be used." - // - internal static string TargetMigrationDescription - { - get { return EntityRes.GetString(EntityRes.TargetMigrationDescription); } - } - - // - // A string like "Specifies the working directory of your application." - // - internal static string WorkingDirectoryDescription - { - get { return EntityRes.GetString(EntityRes.WorkingDirectoryDescription); } - } - - // - // A string like "Specifies the Web.config or App.config file of your application." - // - internal static string ConfigurationFileDescription - { - get { return EntityRes.GetString(EntityRes.ConfigurationFileDescription); } - } - - // - // A string like "Specifies the directory to use when resolving connection strings containing the |DataDirectory| substitution string." - // - internal static string DataDirectoryDescription - { - get { return EntityRes.GetString(EntityRes.DataDirectoryDescription); } - } - - // - // A string like "Specifies the name of the connection string to use from the specified configuration file. If omitted, the context's default connection will be used." - // - internal static string ConnectionStringNameDescription - { - get { return EntityRes.GetString(EntityRes.ConnectionStringNameDescription); } - } - - // - // A string like "Specifies the connection string to use. If omitted, the context's default connection will be used." - // - internal static string ConnectionStringDescription - { - get { return EntityRes.GetString(EntityRes.ConnectionStringDescription); } - } - - // - // A string like "Specifies the provider invariant name of the connection string." - // - internal static string ConnectionProviderNameDescription - { - get { return EntityRes.GetString(EntityRes.ConnectionProviderNameDescription); } - } - - // - // A string like "Indicates that automatic migrations which might incur data loss should be allowed." - // - internal static string ForceDescription - { - get { return EntityRes.GetString(EntityRes.ForceDescription); } - } - - // - // A string like "Indicates that the executing SQL and additional diagnostic information should be output to the console window." - // - internal static string VerboseDescription - { - get { return EntityRes.GetString(EntityRes.VerboseDescription); } - } - - // - // A string like "Display this help message." - // - internal static string HelpDescription - { - get { return EntityRes.GetString(EntityRes.HelpDescription); } - } - - // - // A string like "Only one of '{0}' and '{1}' can be assigned to." - // - internal static string AmbiguousAttributeValues(object p0, object p1) - { - return EntityRes.GetString(EntityRes.AmbiguousAttributeValues, p0, p1); - } - - // - // A string like "Only one of /connectionStringName or /connectionString can be specified." - // - internal static string AmbiguousConnectionString - { - get { return EntityRes.GetString(EntityRes.AmbiguousConnectionString); } - } - - // - // A string like "/connectionString and /connectionProviderName must be specified together." - // - internal static string MissingConnectionInfo - { - get { return EntityRes.GetString(EntityRes.MissingConnectionInfo); } - } - - // - // A string like "Invalid ParameterIndex value" - // - internal static string InvalidParameterIndexValue - { - get { return EntityRes.GetString(EntityRes.InvalidParameterIndexValue); } - } - - // - // A string like "Invalid argument "{0}" at parameter index {1} in command line "{2}"" - // - internal static string InvalidCommandLineArgument(object p0, object p1, object p2) - { - return EntityRes.GetString(EntityRes.InvalidCommandLineArgument, p0, p1, p2); - } - - // - // A string like "Invalid command "{0}" at index {1} in command line "{2}"" - // - internal static string InvalidCommandLineCommand(object p0, object p1, object p2) - { - return EntityRes.GetString(EntityRes.InvalidCommandLineCommand, p0, p1, p2); - } - - // - // A string like "Missing required parameter {0} "{1}" in command line "{2}"" - // - internal static string MissingCommandLineParameter(object p0, object p1, object p2) - { - return EntityRes.GetString(EntityRes.MissingCommandLineParameter, p0, p1, p2); - } - - // - // A string like "Specifies the output file where to write the SQL script being generated. Specifying this option will not apply changes to the database." - // - internal static string ScriptFileDescription - { - get { return EntityRes.GetString(EntityRes.ScriptFileDescription); } - } - - // - // A string like "Specifies the name of a particular migration to update the database from. If omitted, the current model will be used." - // - internal static string SourceMigrationDescription - { - get { return EntityRes.GetString(EntityRes.SourceMigrationDescription); } - } - } - - // - // Strongly-typed and parameterized exception factory. - // - [GeneratedCode("Resources.Migrate.tt", "1.0.0.0")] - internal static class Error - { - // - // InvalidOperationException with message like "Only one of '{0}' and '{1}' can be assigned to." - // - internal static Exception AmbiguousAttributeValues(object p0, object p1) - { - return new InvalidOperationException(Strings.AmbiguousAttributeValues(p0, p1)); - } - - // - // CmdLine.CommandLineException with message like "Only one of /connectionStringName or /connectionString can be specified." - // - internal static Exception AmbiguousConnectionString() - { - return new CmdLine.CommandLineException(Strings.AmbiguousConnectionString); - } - - // - // CmdLine.CommandLineException with message like "/connectionString and /connectionProviderName must be specified together." - // - internal static Exception MissingConnectionInfo() - { - return new CmdLine.CommandLineException(Strings.MissingConnectionInfo); - } - - // - // CmdLine.CommandLineException with message like "Invalid ParameterIndex value" - // - internal static Exception InvalidParameterIndexValue() - { - return new CmdLine.CommandLineException(Strings.InvalidParameterIndexValue); - } - - // - // The exception that is thrown when the value of an argument is outside the allowable range of values as defined by the invoked method. - // - internal static Exception ArgumentOutOfRange(string paramName) - { - return new ArgumentOutOfRangeException(paramName); - } - - // - // The exception that is thrown when the author has yet to implement the logic at this point in the program. This can act as an exception based TODO tag. - // - internal static Exception NotImplemented() - { - return new NotImplementedException(); - } - - // - // The exception that is thrown when an invoked method is not supported, or when there is an attempt to - // read, seek, or write to a stream that does not support the invoked functionality. - // - internal static Exception NotSupported() - { - return new NotSupportedException(); - } - } - - // - // AutoGenerated resource class. Usage: - // string s = EntityRes.GetString(EntityRes.MyIdenfitier); - // - [GeneratedCode("Resources.Migrate.tt", "1.0.0.0")] - internal sealed class EntityRes - { - internal const string MigrateTitle = "MigrateTitle"; - internal const string MigrateDescription = "MigrateDescription"; - internal const string ErrorMessage = "ErrorMessage"; - internal const string WarningMessage = "WarningMessage"; - internal const string VerboseMessage = "VerboseMessage"; - internal const string DuplicateCommand = "DuplicateCommand"; - internal const string DuplicateParameterIndex = "DuplicateParameterIndex"; - internal const string ParameterOutOfOrder = "ParameterOutOfOrder"; - internal const string InvalidKey = "InvalidKey"; - internal const string PressAnyKey = "PressAnyKey"; - internal const string UnsupportedPropertyType = "UnsupportedPropertyType"; - internal const string InvalidPropertyParameterIndexValue = "InvalidPropertyParameterIndexValue"; - internal const string AssemblyNameArgument = "AssemblyNameArgument"; - internal const string ContextAssemblyNameArgument = "ContextAssemblyNameArgument"; - internal const string ConfigurationTypeNameArgument = "ConfigurationTypeNameArgument"; - internal const string AssemblyNameDescription = "AssemblyNameDescription"; - internal const string ContextAssemblyNameDescription = "ContextAssemblyNameDescription"; - internal const string ConfigurationTypeNameDescription = "ConfigurationTypeNameDescription"; - internal const string TargetMigrationDescription = "TargetMigrationDescription"; - internal const string WorkingDirectoryDescription = "WorkingDirectoryDescription"; - internal const string ConfigurationFileDescription = "ConfigurationFileDescription"; - internal const string DataDirectoryDescription = "DataDirectoryDescription"; - internal const string ConnectionStringNameDescription = "ConnectionStringNameDescription"; - internal const string ConnectionStringDescription = "ConnectionStringDescription"; - internal const string ConnectionProviderNameDescription = "ConnectionProviderNameDescription"; - internal const string ForceDescription = "ForceDescription"; - internal const string VerboseDescription = "VerboseDescription"; - internal const string HelpDescription = "HelpDescription"; - internal const string AmbiguousAttributeValues = "AmbiguousAttributeValues"; - internal const string AmbiguousConnectionString = "AmbiguousConnectionString"; - internal const string MissingConnectionInfo = "MissingConnectionInfo"; - internal const string InvalidParameterIndexValue = "InvalidParameterIndexValue"; - internal const string InvalidCommandLineArgument = "InvalidCommandLineArgument"; - internal const string InvalidCommandLineCommand = "InvalidCommandLineCommand"; - internal const string MissingCommandLineParameter = "MissingCommandLineParameter"; - internal const string ScriptFileDescription = "ScriptFileDescription"; - internal const string SourceMigrationDescription = "SourceMigrationDescription"; - - private static EntityRes loader; - private readonly ResourceManager resources; - - private EntityRes() - { - resources = new ResourceManager( - "System.Data.Entity.Properties.Resources.Migrate", -#if NET40 - typeof(System.Data.Entity.DbContext).Assembly); -#else - typeof(System.Data.Entity.DbContext).GetTypeInfo().Assembly); -#endif - } - - private static EntityRes GetLoader() - { - if (loader == null) - { - var sr = new EntityRes(); - Interlocked.CompareExchange(ref loader, sr, null); - } - return loader; - } - - private static CultureInfo Culture - { - get { return null /*use ResourceManager default, CultureInfo.CurrentUICulture*/; } - } - - public static ResourceManager Resources - { - get { return GetLoader().resources; } - } - - public static string GetString(string name, params object[] args) - { - var sys = GetLoader(); - if (sys == null) - { - return null; - } - - var res = sys.resources.GetString(name, Culture); - - if (args != null - && args.Length > 0) - { - for (var i = 0; i < args.Length; i ++) - { - var value = args[i] as String; - if (value != null - && value.Length > 1024) - { - args[i] = value.Substring(0, 1024 - 3) + "..."; - } - } - return String.Format(CultureInfo.CurrentCulture, res, args); - } - else - { - return res; - } - } - - public static string GetString(string name) - { - var sys = GetLoader(); - if (sys == null) - { - return null; - } - return sys.resources.GetString(name, Culture); - } - - public static string GetString(string name, out bool usedFallback) - { - // always false for this version of gensr - usedFallback = false; - return GetString(name); - } - - public static object GetObject(string name) - { - var sys = GetLoader(); - if (sys == null) - { - return null; - } - return sys.resources.GetObject(name, Culture); - } - } -} diff --git a/src/EntityFramework/Properties/Resources.Migrate.resx b/src/EntityFramework/Properties/Resources.Migrate.resx deleted file mode 100644 index 2246d4e9b0..0000000000 --- a/src/EntityFramework/Properties/Resources.Migrate.resx +++ /dev/null @@ -1,235 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Code First Migrations Command Line Utility - - - Applies any pending migrations to the database. - - - ERROR: {0} - - - WARNING: {0} - - - VERBOSE: {0} - - - Duplicate Command "{0}" - - - Duplicate Parameter Index [{0}] on Property "{1}" - - - Out of order parameter "{0}" should have be at parameter index {1} but was found at {2} - - - "{0}" is not a valid choice, valid keys are "{1}" - - - Press any key to continue... - - - Unsupported property type {0} - - - Invalid ParameterIndex value on property "{0}" - - - assembly - - - contextAssembly - - - configurationType - - - Specifies the name of the assembly that contains the migrations configuration type. - - - Specifies the name of the assembly that contains the DbContext type if different from the assembly that contains the migrations configuration type. - - - Specifies the name of the migrations configuration type. If omitted, Code First Migrations will attempt to locate a single migrations configuration type in the specified assembly. - - - Specifies the name of a particular migration to update the database to. If omitted, the current model will be used. - - - Specifies the working directory of your application. - - - Specifies the Web.config or App.config file of your application. - - - Specifies the directory to use when resolving connection strings containing the |DataDirectory| substitution string. - - - Specifies the name of the connection string to use from the specified configuration file. If omitted, the context's default connection will be used. - - - Specifies the connection string to use. If omitted, the context's default connection will be used. - - - Specifies the provider invariant name of the connection string. - - - Indicates that automatic migrations which might incur data loss should be allowed. - - - Indicates that the executing SQL and additional diagnostic information should be output to the console window. - - - Display this help message. - - - Only one of '{0}' and '{1}' can be assigned to. - ## ExceptionType=InvalidOperationException - - - Only one of /connectionStringName or /connectionString can be specified. - ## ExceptionType=CmdLine.CommandLineException - - - /connectionString and /connectionProviderName must be specified together. - ## ExceptionType=CmdLine.CommandLineException - - - Invalid ParameterIndex value - ## ExceptionType=CmdLine.CommandLineException - - - Invalid argument "{0}" at parameter index {1} in command line "{2}" - - - Invalid command "{0}" at index {1} in command line "{2}" - - - Missing required parameter {0} "{1}" in command line "{2}" - - - Specifies the output file where to write the SQL script being generated. Specifying this option will not apply changes to the database. - - - Specifies the name of a particular migration to update the database from. If omitted, the current model will be used. - - \ No newline at end of file diff --git a/src/EntityFramework/Properties/Resources.Migrate.tt b/src/EntityFramework/Properties/Resources.Migrate.tt deleted file mode 100644 index 47ceea1a7f..0000000000 --- a/src/EntityFramework/Properties/Resources.Migrate.tt +++ /dev/null @@ -1 +0,0 @@ -<#@ include file="Resources.tt" #> \ No newline at end of file diff --git a/src/EntityFramework/Properties/Resources.PowerShell.cs b/src/EntityFramework/Properties/Resources.PowerShell.cs deleted file mode 100644 index 38406b841a..0000000000 --- a/src/EntityFramework/Properties/Resources.PowerShell.cs +++ /dev/null @@ -1,296 +0,0 @@ -// - -namespace System.Data.Entity.Migrations.Resources -{ - using System.CodeDom.Compiler; - using System.Data.Entity.Utilities; - using System.Globalization; - using System.Resources; - using System.Threading; - - // - // Strongly-typed and parameterized string resources. - // - [GeneratedCode("Resources.PowerShell.tt", "1.0.0.0")] - internal static class Strings - { - // - // A string like "Specify the '-Verbose' flag to view the SQL statements being applied to the target database." - // - internal static string UpdateDatabaseCommand_VerboseInstructions - { - get { return EntityRes.GetString(EntityRes.UpdateDatabaseCommand_VerboseInstructions); } - } - - // - // A string like "No migrations have been applied to the target database." - // - internal static string GetMigrationsCommand_NoHistory - { - get { return EntityRes.GetString(EntityRes.GetMigrationsCommand_NoHistory); } - } - - // - // A string like "Scaffolding migration '{0}'." - // - internal static string ScaffoldingMigration(object p0) - { - return EntityRes.GetString(EntityRes.ScaffoldingMigration, p0); - } - - // - // A string like "Only the Designer Code for migration '{0}' was re-scaffolded. To re-scaffold the entire migration, use the -Force parameter." - // - internal static string RescaffoldNoForce(object p0) - { - return EntityRes.GetString(EntityRes.RescaffoldNoForce, p0); - } - - // - // A string like "The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration {0}' again." - // - internal static string SnapshotBehindWarning(object p0) - { - return EntityRes.GetString(EntityRes.SnapshotBehindWarning, p0); - } - - // - // A string like "You can use the Add-Migration command to write the pending model changes to a code-based migration." - // - internal static string AutomaticMigrationDisabledInfo - { - get { return EntityRes.GetString(EntityRes.AutomaticMigrationDisabledInfo); } - } - - // - // A string like "Code First Migrations enabled for project {0}." - // - internal static string EnableMigrations_Success(object p0) - { - return EntityRes.GetString(EntityRes.EnableMigrations_Success, p0); - } - - // - // A string like "Checking if the context targets an existing database..." - // - internal static string EnableMigrations_BeginInitialScaffold - { - get { return EntityRes.GetString(EntityRes.EnableMigrations_BeginInitialScaffold); } - } - - // - // A string like "Detected database created with a database initializer. Scaffolded migration '{0}' corresponding to existing database. To use an automatic migration instead, delete the Migrations folder and re-run Enable-Migrations specifying the -EnableAutomaticMigrations parameter." - // - internal static string EnableMigrations_InitialScaffold(object p0) - { - return EntityRes.GetString(EntityRes.EnableMigrations_InitialScaffold, p0); - } - - // - // A string like "Retrieving migrations that have been applied to the target database." - // - internal static string GetMigrationsCommand_Intro - { - get { return EntityRes.GetString(EntityRes.GetMigrationsCommand_Intro); } - } - - // - // A string like "Migrations have already been enabled in project '{0}'. To overwrite the existing migrations configuration, use the -Force parameter." - // - internal static string MigrationsAlreadyEnabled(object p0) - { - return EntityRes.GetString(EntityRes.MigrationsAlreadyEnabled, p0); - } - - // - // A string like "The 'MigrationsDirectory' parameter was set to the absolute path '{0}'. The migrations directory must be set to a relative path for a sub-directory under the Visual Studio project root." - // - internal static string MigrationsDirectoryParamIsRooted(object p0) - { - return EntityRes.GetString(EntityRes.MigrationsDirectoryParamIsRooted, p0); - } - - // - // A string like "Failed to add the Entity Framework 'defaultConnectionFactory' entry to the .config file '{0}' in the current project. The default LocalDbConnectionFactory configured for '(localdb)\MSSQLLocalDB' will be used unless you either add the 'defaultConnectionFactory' entry to the .config file manually or specify connection strings in code. See inner exception for details." - // - internal static string SaveConnectionFactoryInConfigFailed(object p0) - { - return EntityRes.GetString(EntityRes.SaveConnectionFactoryInConfigFailed, p0); - } - - // - // A string like "Re-scaffolding migration '{0}'." - // - internal static string RescaffoldingMigration(object p0) - { - return EntityRes.GetString(EntityRes.RescaffoldingMigration, p0); - } - - // - // A string like "A previous migration called '{0}' was already applied to the target database. If you meant to re-scaffold '{0}', revert it by running 'Update-Database -TargetMigration {1}', then delete '{2}' and run 'Add-Migration {0}' again." - // - internal static string DidYouMeanToRescaffold(object p0, object p1, object p2) - { - return EntityRes.GetString(EntityRes.DidYouMeanToRescaffold, p0, p1, p2); - } - - // - // A string like "The argument '{0}' cannot be null, empty or contain only white space." - // - internal static string ArgumentIsNullOrWhitespace(object p0) - { - return EntityRes.GetString(EntityRes.ArgumentIsNullOrWhitespace, p0); - } - } - - // - // Strongly-typed and parameterized exception factory. - // - [GeneratedCode("Resources.PowerShell.tt", "1.0.0.0")] - internal static class Error - { - // - // Migrations.Infrastructure.MigrationsException with message like "Migrations have already been enabled in project '{0}'. To overwrite the existing migrations configuration, use the -Force parameter." - // - internal static Exception MigrationsAlreadyEnabled(object p0) - { - return new Migrations.Infrastructure.MigrationsException(Strings.MigrationsAlreadyEnabled(p0)); - } - - // - // The exception that is thrown when the value of an argument is outside the allowable range of values as defined by the invoked method. - // - internal static Exception ArgumentOutOfRange(string paramName) - { - return new ArgumentOutOfRangeException(paramName); - } - - // - // The exception that is thrown when the author has yet to implement the logic at this point in the program. This can act as an exception based TODO tag. - // - internal static Exception NotImplemented() - { - return new NotImplementedException(); - } - - // - // The exception that is thrown when an invoked method is not supported, or when there is an attempt to - // read, seek, or write to a stream that does not support the invoked functionality. - // - internal static Exception NotSupported() - { - return new NotSupportedException(); - } - } - - // - // AutoGenerated resource class. Usage: - // string s = EntityRes.GetString(EntityRes.MyIdenfitier); - // - [GeneratedCode("Resources.PowerShell.tt", "1.0.0.0")] - internal sealed class EntityRes - { - internal const string UpdateDatabaseCommand_VerboseInstructions = "UpdateDatabaseCommand_VerboseInstructions"; - internal const string GetMigrationsCommand_NoHistory = "GetMigrationsCommand_NoHistory"; - internal const string ScaffoldingMigration = "ScaffoldingMigration"; - internal const string RescaffoldNoForce = "RescaffoldNoForce"; - internal const string SnapshotBehindWarning = "SnapshotBehindWarning"; - internal const string AutomaticMigrationDisabledInfo = "AutomaticMigrationDisabledInfo"; - internal const string EnableMigrations_Success = "EnableMigrations_Success"; - internal const string EnableMigrations_BeginInitialScaffold = "EnableMigrations_BeginInitialScaffold"; - internal const string EnableMigrations_InitialScaffold = "EnableMigrations_InitialScaffold"; - internal const string GetMigrationsCommand_Intro = "GetMigrationsCommand_Intro"; - internal const string MigrationsAlreadyEnabled = "MigrationsAlreadyEnabled"; - internal const string MigrationsDirectoryParamIsRooted = "MigrationsDirectoryParamIsRooted"; - internal const string SaveConnectionFactoryInConfigFailed = "SaveConnectionFactoryInConfigFailed"; - internal const string RescaffoldingMigration = "RescaffoldingMigration"; - internal const string DidYouMeanToRescaffold = "DidYouMeanToRescaffold"; - internal const string ArgumentIsNullOrWhitespace = "ArgumentIsNullOrWhitespace"; - - private static EntityRes loader; - private readonly ResourceManager resources; - - private EntityRes() - { - resources = new ResourceManager( - "System.Data.Entity.Properties.Resources.PowerShell", typeof(System.Data.Entity.DbContext).Assembly); - } - - private static EntityRes GetLoader() - { - if (loader == null) - { - var sr = new EntityRes(); - Interlocked.CompareExchange(ref loader, sr, null); - } - return loader; - } - - private static CultureInfo Culture - { - get { return null /*use ResourceManager default, CultureInfo.CurrentUICulture*/; } - } - - public static ResourceManager Resources - { - get { return GetLoader().resources; } - } - - public static string GetString(string name, params object[] args) - { - var sys = GetLoader(); - if (sys == null) - { - return null; - } - - var res = sys.resources.GetString(name, Culture); - - if (args != null - && args.Length > 0) - { - for (var i = 0; i < args.Length; i ++) - { - var value = args[i] as String; - if (value != null - && value.Length > 1024) - { - args[i] = value.Substring(0, 1024 - 3) + "..."; - } - } - return String.Format(CultureInfo.CurrentCulture, res, args); - } - else - { - return res; - } - } - - public static string GetString(string name) - { - var sys = GetLoader(); - if (sys == null) - { - return null; - } - return sys.resources.GetString(name, Culture); - } - - public static string GetString(string name, out bool usedFallback) - { - // always false for this version of gensr - usedFallback = false; - return GetString(name); - } - - public static object GetObject(string name) - { - var sys = GetLoader(); - if (sys == null) - { - return null; - } - return sys.resources.GetObject(name, Culture); - } - } -} diff --git a/src/EntityFramework/Properties/Resources.PowerShell.resx b/src/EntityFramework/Properties/Resources.PowerShell.resx deleted file mode 100644 index c414debbdc..0000000000 --- a/src/EntityFramework/Properties/Resources.PowerShell.resx +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Specify the '-Verbose' flag to view the SQL statements being applied to the target database. - - - No migrations have been applied to the target database. - - - Scaffolding migration '{0}'. - - - Only the Designer Code for migration '{0}' was re-scaffolded. To re-scaffold the entire migration, use the -Force parameter. - - - The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration {0}' again. - - - You can use the Add-Migration command to write the pending model changes to a code-based migration. - - - Code First Migrations enabled for project {0}. - - - Checking if the context targets an existing database... - - - Detected database created with a database initializer. Scaffolded migration '{0}' corresponding to existing database. To use an automatic migration instead, delete the Migrations folder and re-run Enable-Migrations specifying the -EnableAutomaticMigrations parameter. - - - Retrieving migrations that have been applied to the target database. - - - Migrations have already been enabled in project '{0}'. To overwrite the existing migrations configuration, use the -Force parameter. - ## ExceptionType=Migrations.Infrastructure.MigrationsException - - - The 'MigrationsDirectory' parameter was set to the absolute path '{0}'. The migrations directory must be set to a relative path for a sub-directory under the Visual Studio project root. - - - Failed to add the Entity Framework 'defaultConnectionFactory' entry to the .config file '{0}' in the current project. The default LocalDbConnectionFactory configured for '(localdb)\MSSQLLocalDB' will be used unless you either add the 'defaultConnectionFactory' entry to the .config file manually or specify connection strings in code. See inner exception for details. - - - Re-scaffolding migration '{0}'. - - - A previous migration called '{0}' was already applied to the target database. If you meant to re-scaffold '{0}', revert it by running 'Update-Database -TargetMigration {1}', then delete '{2}' and run 'Add-Migration {0}' again. - - - The argument '{0}' cannot be null, empty or contain only white space. - - \ No newline at end of file diff --git a/src/EntityFramework/Properties/Resources.PowerShell.tt b/src/EntityFramework/Properties/Resources.PowerShell.tt deleted file mode 100644 index 47ceea1a7f..0000000000 --- a/src/EntityFramework/Properties/Resources.PowerShell.tt +++ /dev/null @@ -1 +0,0 @@ -<#@ include file="Resources.tt" #> \ No newline at end of file diff --git a/src/Migrate/Arguments.cs b/src/Migrate/Arguments.cs deleted file mode 100644 index 184ec75a3e..0000000000 --- a/src/Migrate/Arguments.cs +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations.Console -{ - using System.Data.Entity.Migrations.Console.Resources; - using CmdLine; - - [CommandLineArguments( - Program = "migrate", - TitleResourceId = EntityRes.MigrateTitle, - DescriptionResourceId = EntityRes.MigrateDescription)] - internal class Arguments - { - [CommandLineParameter( - ParameterIndex = 1, - NameResourceId = EntityRes.AssemblyNameArgument, - Required = true, - DescriptionResourceId = EntityRes.AssemblyNameDescription)] - public string AssemblyName { get; set; } - - [CommandLineParameter( - ParameterIndex = 2, - NameResourceId = EntityRes.ConfigurationTypeNameArgument, - DescriptionResourceId = EntityRes.ConfigurationTypeNameDescription)] - public string ConfigurationTypeName { get; set; } - - [CommandLineParameter( - ParameterIndex = 3, - NameResourceId = EntityRes.ContextAssemblyNameArgument, - Required = false, - DescriptionResourceId = EntityRes.ContextAssemblyNameDescription)] - public string ContextAssemblyName { get; set; } - - [CommandLineParameter( - Command = "targetMigration", - DescriptionResourceId = EntityRes.TargetMigrationDescription)] - public string TargetMigration { get; set; } - - [CommandLineParameter( - Command = "startUpDirectory", - DescriptionResourceId = EntityRes.WorkingDirectoryDescription)] - public string WorkingDirectory { get; set; } - - [CommandLineParameter( - Command = "scriptFile", - DescriptionResourceId = EntityRes.ScriptFileDescription)] - public string ScriptFile { get; set; } - - [CommandLineParameter( - Command = "sourceMigration", - DescriptionResourceId = EntityRes.SourceMigrationDescription)] - public string SourceMigration { get; set; } - - [CommandLineParameter( - Command = "startUpConfigurationFile", - DescriptionResourceId = EntityRes.ConfigurationFileDescription)] - public string ConfigurationFile { get; set; } - - [CommandLineParameter( - Command = "startUpDataDirectory", - DescriptionResourceId = EntityRes.DataDirectoryDescription)] - public string DataDirectory { get; set; } - - [CommandLineParameter( - Command = "connectionStringName", - DescriptionResourceId = EntityRes.ConnectionStringNameDescription)] - public string ConnectionStringName { get; set; } - - [CommandLineParameter( - Command = "connectionString", - DescriptionResourceId = EntityRes.ConnectionStringDescription)] - public string ConnectionString { get; set; } - - [CommandLineParameter( - Command = "connectionProviderName", - DescriptionResourceId = EntityRes.ConnectionProviderNameDescription)] - public string ConnectionProviderName { get; set; } - - [CommandLineParameter( - Command = "force", - DescriptionResourceId = EntityRes.ForceDescription)] - public bool Force { get; set; } - - [CommandLineParameter( - Command = "verbose", - DescriptionResourceId = EntityRes.VerboseDescription)] - public bool Verbose { get; set; } - - [CommandLineParameter( - Command = "?", - IsHelp = true, - DescriptionResourceId = EntityRes.HelpDescription)] - public bool Help { get; set; } - - internal void Validate() - { - if (!string.IsNullOrWhiteSpace(ConnectionStringName) - && !string.IsNullOrWhiteSpace(ConnectionString)) - { - throw Error.AmbiguousConnectionString(); - } - - if (string.IsNullOrWhiteSpace(ConnectionString) - != string.IsNullOrWhiteSpace(ConnectionProviderName)) - { - throw Error.MissingConnectionInfo(); - } - } - - internal void Standardize() - { - AssemblyName = Standardize(AssemblyName); - ContextAssemblyName = Standardize(ContextAssemblyName); - } - - private static string Standardize(string assemblyName) - { - if (assemblyName != null - && (assemblyName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) - || assemblyName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase))) - { - assemblyName = assemblyName.Substring(0, assemblyName.Length - 4); - } - return assemblyName; - } - } -} diff --git a/src/Migrate/CmdLine/CommandArgument.cs b/src/Migrate/CmdLine/CommandArgument.cs deleted file mode 100644 index 2f53f7fd1b..0000000000 --- a/src/Migrate/CmdLine/CommandArgument.cs +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace CmdLine -{ - using System; - using System.Text; - using System.Text.RegularExpressions; - - // - // Represents a command line argument - // - [Serializable] - internal class CommandArgument - { - private const int TokenGroup = 0; - - private int parameterIndex = -1; - - private string value; - - // - // Initializes a CommandArgument from a Regex match - // - public CommandArgument(Match match) - { - Token = GetGroupValue(match, TokenGroup); - SwitchSeparator = GetGroupValue(match, CommandLine.SwitchSeparatorGroup); - Command = GetGroupValue(match, CommandLine.SwitchNameGroup); - SwitchOption = GetGroupValue(match, CommandLine.SwitchOptionGroup); - Value = GetGroupValue(match, CommandLine.ValueGroup); - } - - public CommandArgument(string token, int parameterIndex) - { - Token = token; - ParameterIndex = parameterIndex; - } - - public string SwitchOption { get; set; } - - public string Token { get; set; } - - public string SwitchSeparator { get; set; } - - public string Command { get; set; } - - public string Value - { - get - { - return string.IsNullOrWhiteSpace(value) && ParameterIndex != -1 - ? Token - : value; - } - set { this.value = value; } - } - - public int ParameterIndex - { - get { return parameterIndex; } - set { parameterIndex = value; } - } - - // - // Returns the value used by the property cache for the key - // - // - // If the Command property has a value use that, otherwise use the formatted position value - // - internal string Key - { - get - { - return IsParameter() - ? CommandLineParameterAttribute.GetParameterKey(ParameterIndex) - : CommandLine.CaseSensitive ? Command : Command.ToLowerInvariant(); - } - } - - public bool IsCommand() - { - return !string.IsNullOrWhiteSpace(Command); - } - - public bool IsParameter() - { - return !IsCommand(); - } - - private static string GetGroupValue(Match match, string group) - { - return match.Groups[group].Success - ? match.Groups[group].Value.Trim() - : null; - } - - private static string GetGroupValue(Match match, int group) - { - return match.Groups[group].Success - ? match.Groups[group].Value.Trim() - : null; - } - - public override string ToString() - { - var stringBuilder = new StringBuilder("CommandArgument"); - - AppendProperty(stringBuilder, "Token"); - AppendProperty(stringBuilder, "Command"); - AppendProperty(stringBuilder, "SwitchSeparator"); - AppendProperty(stringBuilder, "SwitchOption"); - AppendProperty(stringBuilder, "Value"); - AppendProperty(stringBuilder, "ParameterIndex"); - - return stringBuilder.ToString(); - } - - private void AppendProperty(StringBuilder stringBuilder, string propertyName) - { - var property = GetType().GetProperty(propertyName); - var propValue = property.GetValue(this, null); - - stringBuilder.AppendFormat(" {0}: \"{1}\"", propertyName, propValue); - } - } -} diff --git a/src/Migrate/CmdLine/CommandArgumentHelp.cs b/src/Migrate/CmdLine/CommandArgumentHelp.cs deleted file mode 100644 index b995995b9a..0000000000 --- a/src/Migrate/CmdLine/CommandArgumentHelp.cs +++ /dev/null @@ -1,206 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace CmdLine -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Reflection; - using System.Text; - using System.Text.RegularExpressions; - - [Serializable] - internal class CommandArgumentHelp - { - #region Constants and Fields - - private readonly List validArguments = new List(); - - #endregion - - #region Constructors and Destructors - - public CommandArgumentHelp(PropertyInfo property, string message) - : this(property.DeclaringType, message) - { - } - - public CommandArgumentHelp(Type argumentClassType, string message) - { - Message = message; - var cmdLineAttribute = CommandLineArgumentsAttribute.Get(argumentClassType); - - if (cmdLineAttribute != null) - { - Title = cmdLineAttribute.Title; - Description = cmdLineAttribute.Description; - Program = cmdLineAttribute.Program; - } - - foreach (var parameterAttribute in CommandLineParameterAttribute.GetAllPropertyParameters(argumentClassType) - ) - { - validArguments.Add(parameterAttribute); - } - } - - public CommandArgumentHelp(Type argumentClassType) - : this(argumentClassType, string.Empty) - { - } - - #endregion - - #region Properties - - public string CommandLine - { - get { return CmdLine.CommandLine.Text; } - } - - public string Description { get; set; } - - public CommandArgument InvalidArgument { get; set; } - - public int InvalidPosition { get; set; } - - public string Message { get; set; } - - public string Program { get; set; } - - public string Title { get; set; } - - public IEnumerable ValidArguments - { - get { return validArguments; } - } - - #endregion - - #region Public Methods - - public string GetHelpText(int maxWidth, int margin = 5) - { - var sb = new StringBuilder(); - sb.AppendLine(Title); - sb.AppendLine(Description); - sb.AppendLine(); - var maxParameterWidth = AppendCommandLineExample(sb, maxWidth, margin); - - AppendParameters(sb, maxWidth, maxParameterWidth, margin); - return sb.ToString(); - } - - #endregion - - #region Methods - - private static void AppendLines( - StringBuilder sb, int maxParameterWidth, IList firstColumn, IList secondColumn) - { - var format = string.Format("{{0,-{0}}}{{1}}", maxParameterWidth + 1); - for (var i = 0; i < firstColumn.Count || i < secondColumn.Count; i++) - { - sb.AppendLine( - string.Format( - format, i < firstColumn.Count ? firstColumn[i] : string.Empty, - i < secondColumn.Count ? secondColumn[i] : string.Empty)); - } - } - - private static string CommandName(CommandLineParameterAttribute parameter) - { - return parameter.Command; - } - - private static string FormatCommandArgument(CommandLineParameterAttribute parameter) - { - return string.Format( - parameter.Required ? "{0}{1} " : "[{0}{1}] ", CmdLine.CommandLine.CommandSeparators.First(), - parameter.Command); - } - - private static string FormatCommandLineParameter(CommandLineParameterAttribute parameter) - { - return parameter.IsCommand() ? FormatCommandArgument(parameter) : FormatParameterArgument(parameter); - } - - private static string FormatParameterArgument(CommandLineParameterAttribute parameter) - { - return string.Format(parameter.Required ? "{0} " : "[{0}] ", parameter.Name); - } - - private static bool IsCommand(CommandLineParameterAttribute parameter) - { - return parameter.IsCommand(); - } - - private static bool IsParameter(CommandLineParameterAttribute parameter) - { - return parameter.IsParameter(); - } - - private static int ParameterIndex(CommandLineParameterAttribute parameter) - { - return parameter.ParameterIndex; - } - - private static IList WrapText(string text, int width) - { - // (.{1,})(\s+|$\n?) - var format = string.Format(@"(.{{1,{0}}})(\s+|$\n?)", width); - var matches = Regex.Matches(text, format); - var result = new List(matches.Count); - result.AddRange( - from object match in matches - select match.ToString()); - return result; - } - - private int AppendCommandLineExample(StringBuilder sb, int maxWidth, int margin) - { - var paramSb = new StringBuilder(); - - var maxParameterWidth = 0; - foreach (var parameterName in ValidArguments.OrderBy(IsCommand).Select(FormatCommandLineParameter)) - { - paramSb.AppendFormat("{0} ", parameterName); - if (parameterName.Length > maxParameterWidth) - { - maxParameterWidth = parameterName.Length; - } - } - var parms = paramSb.ToString(); - var width = Program.Length; - var nameLines = WrapText(Program, width); - var descriptionLines = WrapText(parms, maxWidth - width - margin); - AppendLines(sb, width, nameLines, descriptionLines); - - sb.AppendLine(); - return maxParameterWidth; - } - - private void AppendParameter( - StringBuilder sb, CommandLineParameterAttribute parameter, int maxWidth, int maxParameterWidth, int margin) - { - var nameLines = WrapText(FormatCommandLineParameter(parameter), maxParameterWidth + margin); - var descriptionLines = WrapText(parameter.Description, maxWidth - maxParameterWidth - margin); - - AppendLines(sb, maxParameterWidth, nameLines, descriptionLines); - } - - private void AppendParameters(StringBuilder sb, int maxWidth, int maxParameterWidth, int margin) - { - foreach (var parameter in ValidArguments.Where(IsParameter).OrderBy(ParameterIndex)) - { - AppendParameter(sb, parameter, maxWidth, maxParameterWidth, margin); - } - foreach (var parameter in ValidArguments.Where(IsCommand).OrderBy(CommandName)) - { - AppendParameter(sb, parameter, maxWidth, maxParameterWidth, margin); - } - } - - #endregion - } -} diff --git a/src/Migrate/CmdLine/CommandEnvironment.cs b/src/Migrate/CmdLine/CommandEnvironment.cs deleted file mode 100644 index 1a8bae5e05..0000000000 --- a/src/Migrate/CmdLine/CommandEnvironment.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace CmdLine -{ - using System; - - internal class CommandEnvironment : ICommandEnvironment - { - public string CommandLine - { - get { return Environment.CommandLine; } - } - - private string[] args; - - public string[] GetCommandLineArgs() - { - return args ?? (args = Environment.GetCommandLineArgs()); - } - - public string Program - { - get { return GetCommandLineArgs()[0]; } - } - } -} diff --git a/src/Migrate/CmdLine/CommandLine.cs b/src/Migrate/CmdLine/CommandLine.cs deleted file mode 100644 index 9a8309ea04..0000000000 --- a/src/Migrate/CmdLine/CommandLine.cs +++ /dev/null @@ -1,441 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace CmdLine -{ - using System; - using System.Collections.Generic; - using System.Data.Entity.Migrations.Console.Resources; - using System.Linq; - using System.Reflection; - using System.Text; - using System.Text.RegularExpressions; - - // - // Class for parsing command line arguments - // - internal static class CommandLine - { - #region Constants and Fields - - private static readonly string[] _defaultSwitchSeparators = new[] { "/", "-" }; - - private static readonly string[] _defaultValueSeparators = new[] { ":", "=" }; - - internal const string SwitchNameGroup = "SwitchName"; - - internal const string SwitchOptionGroup = "SwitchOption"; - - internal const string SwitchSeparatorGroup = "SwitchSeparator"; - - internal const string ValueGroup = "Value"; - - internal const string ValueSeparatorGroup = "ValueSeparator"; - - // - // Expression for a switch with a value i.e. /S:Value or /S:Some Value - // - // - // This expression divides the token into groups - // - private const string TokenizeExpressionFormat = - @"(?{0}i) # Case Sensitive Option -# Capture the switch begin of string or preceded by whitespace -(?\A[{1}]) -# Capture the switch name -(?[^{2}+-]+) -# Capture switch option or end of string -(?[{2}+-]|\z) -# Capture the switch value or end of string -(?.*)\Z"; - - private static string[] args; - - private static ICommandEnvironment commandEnvironment = new CommandEnvironment(); - - private static List commandSeparatorList = new List(_defaultSwitchSeparators); - - private static CommandLineParametersCollection parameters; - - private static List valueSeparatorList = new List(_defaultValueSeparators); - - #endregion - - #region Properties - - public static string[] Args - { - get - { - // GetCommandLineArgs puts the program in element 0 - // The args passed to Main do not do this so remove it - var commandLineArgs = CommandEnvironment.GetCommandLineArgs(); - args = new string[commandLineArgs.Length - 1]; - for (var i = 0; i < commandLineArgs.Length - 1; i++) - { - args[i] = commandLineArgs[i + 1]; - } - - return args; - } - internal set { args = value; } - } - - public static bool CaseSensitive { get; set; } - - public static ICommandEnvironment CommandEnvironment - { - get { return commandEnvironment; } - set { commandEnvironment = value; } - } - - public static IEnumerable CommandSeparators - { - get { return commandSeparatorList; } - set { commandSeparatorList = new List(value); } - } - - public static string Program - { - get { return CommandEnvironment.GetCommandLineArgs()[0]; } - } - - public static string Text - { - get { return CommandEnvironment.CommandLine; } - } - - public static IEnumerable ValueSeparators - { - get { return valueSeparatorList; } - set { valueSeparatorList = new List(value); } - } - - private static Regex RegexTokenize - { - get { return new Regex(TokenizePattern, RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace); } - } - - private static string TokenizePattern - { - get - { - return string.Format( - TokenizeExpressionFormat, GetCaseSensitiveOption(), string.Join(string.Empty, CommandSeparators), - string.Join(string.Empty, ValueSeparators)); - } - } - - #endregion - - #region Public Methods - - public static List GetParameters(List tokens) - { - return tokens == null ? null : tokens.FindAll(arg => arg.IsParameter()); - } - - public static List GetSwitches(List tokens) - { - return tokens == null ? null : tokens.FindAll(arg => arg.IsCommand()); - } - - public static T Parse() where T : class, new() - { - var argument = InitializeNewArgument(); - - var tokens = Tokenize(); - - foreach (var commandArgument in tokens) - { - ApplyCommandArgument(commandArgument, argument); - } - - // Some commands signify a request for command line help - if (parameters.Values.Any(p => p.Attribute.IsHelp && p.ArgumentSupplied)) - { - throw new CommandLineHelpException(new CommandArgumentHelp(typeof(T))); - } - - parameters.VerifyRequiredArguments(); - - return argument; - } - - public static void Pause(string text = null, ConsoleColor color = ConsoleColor.Yellow) - { - text = text ?? Strings.PressAnyKey; - WriteLineColor(color, text); - Console.ReadKey(true); - } - - public static char PromptKey(string prompt, params char[] allowedKeys) - { - if (allowedKeys == null) - { - throw new ArgumentNullException("allowedKeys"); - } - - char keyChar; - bool validKey; - var allowedString = ToDelimitedList(allowedKeys); - do - { - Console.Write("{0} ({1}) ", prompt, allowedString); - keyChar = ToLower(Console.ReadKey(false).KeyChar); - validKey = allowedKeys.Contains(keyChar); - if (!validKey) - { - Console.WriteLine(); - Console.WriteLine(Strings.InvalidKey(keyChar, allowedString)); - } - else - { - Console.WriteLine(); - } - } - while (!validKey); - - return keyChar; - } - - public static List Tokenize() - { - var tokenList = new List(); - - if (string.IsNullOrWhiteSpace(Text)) - { - return tokenList; - } - - var nextPosition = 1; - - tokenList.AddRange( - from arg in Args - let matches = RegexTokenize.Matches(arg) - select matches.Count == 1 - ? new CommandArgument(matches[0]) // Command argument - : new CommandArgument(arg, nextPosition++)); - - return tokenList; - } - - public static void WriteLineColor(ConsoleColor color, string format, params object[] formatArgs) - { - WriteLineColor(Console.WriteLine, Console.WriteLine, color, format, formatArgs); - } - - public static void WriteLineColor( - Action outputNoParams, Action outputParams, - ConsoleColor color, string format, params object[] formatArgs) - { - var saveColor = Console.ForegroundColor; - Console.ForegroundColor = color; - if (formatArgs.Length > 0) - { - outputParams(format, formatArgs); - } - else - { - outputNoParams(format); - } - Console.ForegroundColor = saveColor; - } - - #endregion - - #region Methods - - private static void ApplyCommandArgument(CommandArgument cmd, object argument) - { - var parameter = parameters.Get(cmd); - - // No command parameter matching this command switch or position - if (parameter == null) - { - throw new CommandLineArgumentInvalidException(argument.GetType(), cmd); - } - - parameter.SetValue(argument, cmd); - } - - // - // Returns a string with the case sensitive option - // - // null when case sensitive is on, "-" when it is off - private static string GetCaseSensitiveOption() - { - return CaseSensitive ? null : "-"; - } - - private static IEnumerable InferCommandLineParameterAttribute( - PropertyInfo property) - { - return new[] - { - new CommandLineParameterAttribute - { - Name = property.Name, - Command = property.Name - } - }; - } - - private static T InitializeNewArgument() where T : new() - { - parameters = new CommandLineParametersCollection(typeof(T)); - - var argument = new T(); - - foreach (var parameter in parameters.Values) - { - parameter.SetDefaultValue(argument); - } - - return argument; - } - - private static string ToDelimitedList(char[] allowedKeys) - { - var sb = new StringBuilder(); - for (var index = 0; index < allowedKeys.Length; index++) - { - var allowedKey = allowedKeys[index]; - sb.Append(allowedKey); - if (index + 1 - < allowedKeys.Length) - { - sb.Append(','); - } - } - return sb.ToString(); - } - - private static char ToLower(char keyChar) - { - return keyChar.ToString().ToLowerInvariant()[0]; - } - - #endregion - - private class CommandLineParametersCollection - { - #region Constructors and Destructors - - internal CommandLineParametersCollection(Type argumentType) - { - Parameters = new Dictionary(); - ArgumentType = argumentType; - Load(); - } - - #endregion - - #region Properties - - public IEnumerable Values - { - get { return Parameters.Values; } - } - - private Type ArgumentType { get; set; } - - private Dictionary Parameters { get; set; } - - #endregion - - #region Public Methods - - public CommandLineParameter Get(CommandArgument cmd) - { - CommandLineParameter parameter; - - Parameters.TryGetValue(cmd.Key, out parameter); - - return parameter; - } - - public void VerifyRequiredArguments() - { - foreach (var parameter in Values.Where(parameter => !parameter.RequiredArgumentSupplied)) - { - throw new CommandLineRequiredArgumentMissingException( - ArgumentType, parameter.Attribute.NameOrCommand, parameter.Attribute.ParameterIndex); - } - } - - #endregion - - #region Methods - - private static bool IsParameter(CommandLineParameter parameter) - { - return parameter.IsParameter(); - } - - private static int ParameterIndex(CommandLineParameter parameter) - { - return parameter.Attribute.ParameterIndex; - } - - private void Add(CommandLineParameter parameter) - { - // Each attribute is uniquely keyed - try - { - Parameters.Add(parameter.Key, parameter); - } - catch (ArgumentException exception) - { - throw new CommandLineException( - new CommandArgumentHelp( - parameter.Property.DeclaringType, - parameter.IsCommand() - ? Strings.DuplicateCommand(parameter.Command) - : Strings.DuplicateParameterIndex(parameter.Attribute.ParameterIndex, parameter.Property.Name)), - exception); - } - } - - private void Load() - { - // Select all the CommandLineParameterAttribute attributes from all the properties on the type and create a command line parameter for it - CommandLineParameterAttribute.ForEach(ArgumentType, Add); - - VerifyPositionalArgumentsInSequence(); - - // If there are no attributed properties - if (Parameters.Count == 0) - { - // infer them based on the property names - CommandLineParameterAttribute.ForEach(ArgumentType, InferCommandLineParameterAttribute, Add); - } - } - - private void VerifyPositionalArgumentsInSequence() - { - // Get the positional arguments ordered by position - var parameters = Parameters.Values.Where(IsParameter).OrderBy(ParameterIndex); - - for (var i = 0; i < parameters.Count(); i++) - { - var arg = parameters.ElementAt(i); - - // Parameter Indexes are 1 based so add 1 to i - var expectedIndex = i + 1; - if (arg.Attribute.ParameterIndex != expectedIndex) - { - throw new CommandLineException( - new CommandArgumentHelp( - arg.Property.DeclaringType, - Strings.ParameterOutOfOrder( - arg.Attribute.Name, - expectedIndex, - arg.Attribute.ParameterIndex))); - } - } - } - - #endregion - } - } -} diff --git a/src/Migrate/CmdLine/CommandLineArgumentInvalidException.cs b/src/Migrate/CmdLine/CommandLineArgumentInvalidException.cs deleted file mode 100644 index cbc907d4c0..0000000000 --- a/src/Migrate/CmdLine/CommandLineArgumentInvalidException.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace CmdLine -{ - using System; - using System.Data.Entity.Migrations.Console.Resources; - - [Serializable] - internal class CommandLineArgumentInvalidException : CommandLineException - { - public CommandLineArgumentInvalidException(Type argumentType, CommandArgument argument) - : base(GetInvalidArgumentString(argumentType, argument)) - { - } - - private static CommandArgumentHelp GetInvalidArgumentString(Type argumentType, CommandArgument argument) - { - var cmdLine = string.Join(" ", CommandLine.Args); - var message = argument.IsParameter() - ? Strings.InvalidCommandLineArgument(argument.Token, argument.ParameterIndex, cmdLine) - : Strings.InvalidCommandLineCommand( - argument.Token, cmdLine.IndexOf(argument.Token, StringComparison.InvariantCulture), cmdLine); - - return new CommandArgumentHelp(argumentType, message); - } - } -} diff --git a/src/Migrate/CmdLine/CommandLineArgumentsAttribute.cs b/src/Migrate/CmdLine/CommandLineArgumentsAttribute.cs deleted file mode 100644 index 78514bc72b..0000000000 --- a/src/Migrate/CmdLine/CommandLineArgumentsAttribute.cs +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace CmdLine -{ - using System; - using System.Data.Entity.Migrations.Console.Resources; - using System.Linq; - using System.Reflection; - - [AttributeUsage(AttributeTargets.Class)] - internal class CommandLineArgumentsAttribute : Attribute - { - private string title; - - public string Title - { - get - { - if (TitleResourceId != null) - { - return EntityRes.GetString(TitleResourceId); - } - return title; - } - set - { - if (TitleResourceId != null) - { - throw Error.AmbiguousAttributeValues("Title", "TitleResourceId"); - } - title = value; - } - } - - private string titleResourceId; - - public string TitleResourceId - { - get { return titleResourceId; } - set - { - if (Title != null) - { - throw Error.AmbiguousAttributeValues("Title", "TitleResourceId"); - } - titleResourceId = value; - } - } - - private string description; - - public string Description - { - get - { - if (DescriptionResourceId != null) - { - return EntityRes.GetString(DescriptionResourceId); - } - return description; - } - set - { - if (DescriptionResourceId != null) - { - throw Error.AmbiguousAttributeValues("Description", "DescriptionResourceId"); - } - description = value; - } - } - - private string descriptionResourceId; - - public string DescriptionResourceId - { - get { return descriptionResourceId; } - set - { - if (Description != null) - { - throw Error.AmbiguousAttributeValues("Description", "DescriptionResourceId"); - } - descriptionResourceId = value; - } - } - - public string Program { get; set; } - - // - // Returns a CommandLineArgumentsAttribute - // - public static CommandLineArgumentsAttribute Get(MemberInfo member) - { - return - GetCustomAttributes(member, typeof(CommandLineArgumentsAttribute)).Cast() - .FirstOrDefault(); - } - } -} diff --git a/src/Migrate/CmdLine/CommandLineException.cs b/src/Migrate/CmdLine/CommandLineException.cs deleted file mode 100644 index b33d9c1cce..0000000000 --- a/src/Migrate/CmdLine/CommandLineException.cs +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace CmdLine -{ - using System; - using System.Diagnostics.CodeAnalysis; - using System.Runtime.Serialization; - - [SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors", - Justification = "SerializeObjectState used instead")] - [Serializable] - internal class CommandLineException : Exception - { - [NonSerialized] - private CommandLineExceptionState _state; - - public CommandLineException(string message) - : base(message) - { - SubscribeToSerializeObjectState(); - } - - public CommandLineException(CommandArgumentHelp argumentHelp) - : base(CheckNotNull(argumentHelp).Message) - { - ArgumentHelp = argumentHelp; - - SubscribeToSerializeObjectState(); - } - - public CommandLineException(CommandArgumentHelp argumentHelp, Exception inner) - : base(CheckNotNull(argumentHelp).Message, inner) - { - ArgumentHelp = argumentHelp; - - SubscribeToSerializeObjectState(); - } - - public CommandArgumentHelp ArgumentHelp - { - get { return _state.ArgumentHelp; } - set { _state.ArgumentHelp = value; } - } - - private static CommandArgumentHelp CheckNotNull(CommandArgumentHelp argumentHelp) - { - if (argumentHelp == null) - { - throw new ArgumentNullException("argumentHelp"); - } - return argumentHelp; - } - - private void SubscribeToSerializeObjectState() - { - SerializeObjectState += (_, a) => a.AddSerializedState(_state); - } - - [Serializable] - private struct CommandLineExceptionState : ISafeSerializationData - { - public CommandArgumentHelp ArgumentHelp { get; set; } - - public void CompleteDeserialization(object deserialized) - { - var commandLineException = (CommandLineException)deserialized; - - commandLineException._state = this; - commandLineException.SubscribeToSerializeObjectState(); - } - } - } -} diff --git a/src/Migrate/CmdLine/CommandLineHelpException.cs b/src/Migrate/CmdLine/CommandLineHelpException.cs deleted file mode 100644 index c2c676dde4..0000000000 --- a/src/Migrate/CmdLine/CommandLineHelpException.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace CmdLine -{ - using System; - - internal class CommandLineHelpException : CommandLineException - { - #region Constructors and Destructors - - public CommandLineHelpException(string message) - : base(message) - { - } - - public CommandLineHelpException(CommandArgumentHelp argumentHelp) - : base(argumentHelp.Message) - { - ArgumentHelp = argumentHelp; - } - - public CommandLineHelpException(CommandArgumentHelp argumentHelp, Exception inner) - : base(argumentHelp, inner) - { - ArgumentHelp = argumentHelp; - } - - #endregion - } -} diff --git a/src/Migrate/CmdLine/CommandLineParameter.cs b/src/Migrate/CmdLine/CommandLineParameter.cs deleted file mode 100644 index 44c9af5995..0000000000 --- a/src/Migrate/CmdLine/CommandLineParameter.cs +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace CmdLine -{ - using System; - using System.Collections.Generic; - using System.Data.Entity.Migrations.Console.Resources; - using System.Reflection; - - internal class CommandLineParameter - { - internal CommandLineParameter(PropertyInfo property, CommandLineParameterAttribute attribute) - { - Property = property; - Attribute = attribute; - Command = Attribute.Command; - - // Set the defaults - if (property.PropertyType - == typeof(bool)) - { - // If no switch is specified for bool properties then the name is the switch - if (string.IsNullOrWhiteSpace(Command)) - { - Command = property.Name; - } - } - } - - internal string Command { get; set; } - - internal PropertyInfo Property { get; set; } - - internal CommandArgument Argument { get; set; } - - internal CommandLineParameterAttribute Attribute { get; private set; } - - internal bool ArgumentSupplied { get; set; } - - internal bool RequiredArgumentSupplied - { - get { return !Attribute.Required || ArgumentSupplied; } - } - - public string Key - { - get - { - return IsCommand() - ? CommandLine.CaseSensitive - ? Command - : Command.ToLowerInvariant() - : CommandLineParameterAttribute.GetParameterKey(Attribute.ParameterIndex); - } - } - - internal bool IsParameter() - { - return !IsCommand(); - } - - internal bool IsCommand() - { - return !string.IsNullOrWhiteSpace(Command); - } - - public void SetDefaultValue(object argument) - { - if (Attribute == null - || Attribute.Default == null) - { - return; - } - - var property = argument.GetType().GetProperty(Property.Name); - property.SetValue(argument, Attribute.Default, null); - } - - public void SetValue(object argument, CommandArgument cmd) - { - // Argument already supplied - if (!IsCollection() && ArgumentSupplied) - { - throw new CommandLineArgumentInvalidException(argument.GetType(), cmd); - } - - Argument = cmd; - - if (Property.PropertyType - == typeof(bool)) - { - Property.SetValue(argument, GetBoolValue(cmd), null); - } - else if (Property.PropertyType - == typeof(int)) - { - Property.SetValue(argument, Convert.ToInt32(cmd.Value), null); - } - else if (Property.PropertyType - == typeof(DateTime)) - { - Property.SetValue(argument, Convert.ToDateTime(cmd.Value), null); - } - else if (Property.PropertyType - == typeof(string)) - { - Property.SetValue(argument, cmd.Value, null); - } - else if (Property.PropertyType - == typeof(List)) - { - var list = (List)Property.GetValue(argument, null) ?? new List(); - list.Add(cmd.Value); - Property.SetValue(argument, list, null); - } - else - { - throw new CommandLineException( - new CommandArgumentHelp( - argument.GetType(), Strings.UnsupportedPropertyType(Property.PropertyType))); - } - - ArgumentSupplied = true; - } - - private bool IsCollection() - { - return Property.PropertyType == typeof(List); - } - - // - // Returns a boolean value from a command switch - // - // The command switch - // A boolean value based on the switch and value - private static bool GetBoolValue(CommandArgument cmd) - { - return string.IsNullOrWhiteSpace(cmd.SwitchOption) || cmd.SwitchOption.Trim() == "+"; - } - } -} diff --git a/src/Migrate/CmdLine/CommandLineParameterAttribute.cs b/src/Migrate/CmdLine/CommandLineParameterAttribute.cs deleted file mode 100644 index e6af79e592..0000000000 --- a/src/Migrate/CmdLine/CommandLineParameterAttribute.cs +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace CmdLine -{ - using System; - using System.Collections.Generic; - using System.Data.Entity.Migrations.Console.Resources; - using System.Linq; - using System.Reflection; - - [AttributeUsage(AttributeTargets.Property)] - [Serializable] - internal class CommandLineParameterAttribute : Attribute - { - private int parameterIndex = -1; - - public CommandLineParameterAttribute() - { - } - - public CommandLineParameterAttribute(string command) - { - Command = command; - } - - private string name; - - public string Name - { - get - { - if (NameResourceId != null) - { - return EntityRes.GetString(NameResourceId); - } - return name; - } - set - { - if (NameResourceId != null) - { - throw Error.AmbiguousAttributeValues("Name", "NameResourceId"); - } - name = value; - } - } - - private string nameResourceId; - - public string NameResourceId - { - get { return nameResourceId; } - set - { - if (Name != null) - { - throw Error.AmbiguousAttributeValues("Name", "NameResourceId"); - } - nameResourceId = value; - } - } - - private string description; - - // - // The description of the command - // - public string Description - { - get - { - if (DescriptionResourceId != null) - { - return EntityRes.GetString(DescriptionResourceId); - } - return description; - } - set - { - if (DescriptionResourceId != null) - { - throw Error.AmbiguousAttributeValues("Description", "DescriptionResourceId"); - } - description = value; - } - } - - private string descriptionResourceId; - - // - // The resource id of the command description - // - public string DescriptionResourceId - { - get { return descriptionResourceId; } - set - { - if (Description != null) - { - throw Error.AmbiguousAttributeValues("Description", "DescriptionResourceId"); - } - descriptionResourceId = value; - } - } - - public object Default { get; set; } - - public bool Required { get; set; } - - public string ValueExample { get; set; } - - public int ParameterIndex - { - get { return parameterIndex; } - set - { - if (value < 1) - { - throw Error.InvalidParameterIndexValue(); - } - - parameterIndex = value; - } - } - - public object Value { get; set; } - - public string Command { get; set; } - - public string NameOrCommand - { - get - { - return string.IsNullOrWhiteSpace(Name) - ? Command - : Name; - } - } - - public bool IsHelp { get; set; } - - public static CommandLineParameterAttribute Get(MemberInfo member) - { - return - GetCustomAttributes(member, typeof(CommandLineParameterAttribute)).Cast() - .FirstOrDefault(); - } - - public static IEnumerable GetAll(MemberInfo member) - { - return - GetCustomAttributes(member, typeof(CommandLineParameterAttribute)).Cast(); - } - - public static IEnumerable GetAllPropertyParameters(Type argumentClassType) - { - return - argumentClassType.GetProperties().SelectMany( - property => - property.GetCustomAttributes(typeof(CommandLineParameterAttribute), true).Cast - ()); - } - - public bool IsCommand() - { - return !string.IsNullOrWhiteSpace(Command); - } - - internal static string GetParameterKey(int position) - { - return string.Format("Parameter[{0}]", position); - } - - internal void Validate(CommandLineParameter parameter) - { - if (ParameterIndex < 1) - { - throw new CommandLineException( - new CommandArgumentHelp(parameter.Property, Strings.InvalidPropertyParameterIndexValue(parameter.Property.Name))); - } - } - - // - // Searches a type for all properties with the CommandLineParameterAttribute and does action - // - // The argument type - // The action to apply - internal static void ForEach(Type argumentType, Action action) - { - ForEach(argumentType, GetAll, action); - } - - // - // Searches a type for all properties with the CommandLineParameterAttribute and does action - // - // The argument type - // The action to apply - internal static void ForEach( - Type argumentType, Func> selector, - Action action) - { - foreach (var parameter in argumentType.GetProperties().SelectMany( - property => selector(property).Select(cmdAttribute => new CommandLineParameter(property, cmdAttribute))) - ) - { - action(parameter); - } - } - - public bool IsParameter() - { - return !IsCommand(); - } - } -} diff --git a/src/Migrate/CmdLine/CommandLineRequiredArgumentMissingException.cs b/src/Migrate/CmdLine/CommandLineRequiredArgumentMissingException.cs deleted file mode 100644 index 64af30aca4..0000000000 --- a/src/Migrate/CmdLine/CommandLineRequiredArgumentMissingException.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace CmdLine -{ - using System; - using System.Data.Entity.Migrations.Console.Resources; - - [Serializable] - internal class CommandLineRequiredArgumentMissingException : CommandLineException - { - public CommandLineRequiredArgumentMissingException(Type argumentType, string argumentName, int parameterIndex) - : base(new CommandArgumentHelp(argumentType, FormatMessage(argumentName, parameterIndex))) - { - } - - private static string FormatMessage(string argumentName, int parameterIndex) - { - return parameterIndex == -1 - ? Strings.MissingCommandLineParameter("", argumentName, CommandLine.Text) - : Strings.MissingCommandLineParameter(parameterIndex, argumentName, string.Join(" ", CommandLine.Args)); - } - } -} diff --git a/src/Migrate/CmdLine/ICommandEnvironment.cs b/src/Migrate/CmdLine/ICommandEnvironment.cs deleted file mode 100644 index 57b1fe61f2..0000000000 --- a/src/Migrate/CmdLine/ICommandEnvironment.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace CmdLine -{ - internal interface ICommandEnvironment - { - string CommandLine { get; } - - string[] GetCommandLineArgs(); - - string Program { get; } - } -} diff --git a/src/Migrate/Migrate.csproj b/src/Migrate/Migrate.csproj deleted file mode 100644 index 083034dd80..0000000000 --- a/src/Migrate/Migrate.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - Exe - System.Data.Entity.Migrations.Console - migrate - True - net45 - migrate.exe - 6.0.0.0 - - - - - Properties\Resources.cs - - - Properties\Resources.Migrate.cs - - - Properties\SharedAssemblyInfo.cs - - - Properties\SharedAssemblyVersionInfo.cs - - - - - - - - diff --git a/src/Migrate/Program.cs b/src/Migrate/Program.cs deleted file mode 100644 index 167303a80a..0000000000 --- a/src/Migrate/Program.cs +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations.Console -{ - using System.Data.Entity.Infrastructure; - using System.Data.Entity.Migrations.Console.Resources; - using System.Data.Entity.Migrations.Design; - using System.Diagnostics; - using System.IO; - using System.Reflection; - using System.Text; - using CmdLine; - using Console = System.Console; - - internal class Program - { - private const int ExitCodeSuccess = 0; - private const int ExitCodeError = 1; - - private readonly Arguments _arguments; - - public Program(Arguments arguments) - { - _arguments = arguments; - } - - public static int Main(string[] args) - { - Arguments arguments = null; - - try - { - arguments = CommandLine.Parse(); - arguments.Validate(); - arguments.Standardize(); - - AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; - - new Program(arguments).Run(); - } - catch (CommandLineHelpException ex) - { - WriteLine(ex.ArgumentHelp.GetHelpText(Console.BufferWidth)); - - return ExitCodeSuccess; - } - catch (CommandLineException ex) - { - if (ex.ArgumentHelp != null) - { - WriteError(ex.ArgumentHelp.Message); - WriteLine(ex.ArgumentHelp.GetHelpText(Console.BufferWidth)); - } - else - { - WriteError(ex.Message); - } - - return ExitCodeError; - } - catch (Exception ex) - { - if (arguments != null - && arguments.Verbose) - { - WriteVerbose(ex.ToString()); - } - - WriteError(ex.Message); - - return ExitCodeError; - } - - return ExitCodeSuccess; - } - - public void Run() - { - using (var facade = CreateFacade()) - { - if (!String.IsNullOrEmpty(_arguments.ScriptFile)) - { - ScriptUpdate(facade, _arguments); - } - else - { - facade.Update(_arguments.TargetMigration, _arguments.Force); - } - } - } - - private static void ScriptUpdate(ToolingFacade facade, Arguments arguments) - { - string scriptContents = facade.ScriptUpdate(arguments.SourceMigration, arguments.TargetMigration, arguments.Force); - - File.WriteAllText(arguments.ScriptFile, scriptContents, Encoding.UTF8); - } - - private static Assembly ResolveAssembly(object sender, ResolveEventArgs args) - { - if (new AssemblyName(args.Name).Name == "EntityFramework") - { - var assemblyPath = Path.Combine( - AppDomain.CurrentDomain.BaseDirectory, @"..\lib\net45\EntityFramework.dll"); - - if (File.Exists(assemblyPath)) - { - return Assembly.LoadFrom(assemblyPath); - } - } - - return null; - } - - private static void WriteLine(string message) - { - Console.WriteLine(message); - } - - private static void WriteError(string message) - { - CommandLine.WriteLineColor(ConsoleColor.Red, Strings.ErrorMessage(message)); - } - - private static void WriteWarning(string message) - { - CommandLine.WriteLineColor(ConsoleColor.Yellow, Strings.WarningMessage(message)); - } - - private static void WriteVerbose(string message) - { - CommandLine.WriteLineColor(ConsoleColor.DarkGray, message); - } - - private ToolingFacade CreateFacade() - { - DbConnectionInfo connectionStringInfo = null; - - if (!string.IsNullOrWhiteSpace(_arguments.ConnectionStringName)) - { - Debug.Assert(string.IsNullOrWhiteSpace(_arguments.ConnectionString)); - Debug.Assert(string.IsNullOrWhiteSpace(_arguments.ConnectionProviderName)); - - connectionStringInfo = new DbConnectionInfo(_arguments.ConnectionStringName); - } - else if (!string.IsNullOrWhiteSpace(_arguments.ConnectionString)) - { - Debug.Assert(string.IsNullOrWhiteSpace(_arguments.ConnectionStringName)); - Debug.Assert(!string.IsNullOrWhiteSpace(_arguments.ConnectionProviderName)); - - connectionStringInfo = new DbConnectionInfo( - _arguments.ConnectionString, _arguments.ConnectionProviderName); - } - - var facade - = new ToolingFacade( - _arguments.AssemblyName, - string.IsNullOrWhiteSpace(_arguments.ContextAssemblyName) ? _arguments.AssemblyName : _arguments.ContextAssemblyName, - _arguments.ConfigurationTypeName, - _arguments.WorkingDirectory, - _arguments.ConfigurationFile, - _arguments.DataDirectory, - connectionStringInfo); - - facade.LogInfoDelegate = WriteLine; - facade.LogWarningDelegate = WriteWarning; - - if (_arguments.Verbose) - { - facade.LogVerboseDelegate = sql => WriteVerbose(Strings.VerboseMessage(sql)); - } - - return facade; - } - } -} diff --git a/src/Migrate/Properties/AssemblyInfo.cs b/src/Migrate/Properties/AssemblyInfo.cs deleted file mode 100644 index 8f7201af8d..0000000000 --- a/src/Migrate/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System.Reflection; - -[assembly: AssemblyDefaultAlias("migrate.exe")] diff --git a/src/Migrate/Properties/InternalsVisibleTo.cs b/src/Migrate/Properties/InternalsVisibleTo.cs deleted file mode 100644 index 41a999455a..0000000000 --- a/src/Migrate/Properties/InternalsVisibleTo.cs +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -using System.Runtime.CompilerServices; - -[assembly: - InternalsVisibleTo( - "EntityFramework.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007D1FA57C4AED9F0A32E84AA0FAEFD0DE9E8FD6AEC8F87FB03766C834C99921EB23BE79AD9D5DCC1DD9AD236132102900B723CF980957FC4E177108FC607774F29E8320E92EA05ECE4E821C0A5EFE8F1645C4C0C93C1AB99285D622CAA652C1DFAD63D745D6F2DE5F17E5EAF0FC4963D261C8A12436518206DC093344D5AD293" - )] diff --git a/src/NuGet/EntityFramework/EntityFramework.NuGet.csproj b/src/NuGet/EntityFramework/EntityFramework.NuGet.csproj index 27a2c6f5eb..110ef02ea9 100644 --- a/src/NuGet/EntityFramework/EntityFramework.NuGet.csproj +++ b/src/NuGet/EntityFramework/EntityFramework.NuGet.csproj @@ -22,11 +22,6 @@ - - - - - diff --git a/src/NuGet/EntityFramework/EntityFramework.NuGet.nuspec b/src/NuGet/EntityFramework/EntityFramework.NuGet.nuspec index c247bcda70..b4fdec0065 100644 --- a/src/NuGet/EntityFramework/EntityFramework.NuGet.nuspec +++ b/src/NuGet/EntityFramework/EntityFramework.NuGet.nuspec @@ -23,8 +23,6 @@ - - @@ -43,7 +41,6 @@ - diff --git a/src/NuGet/EntityFramework/tools/EntityFramework6.psm1 b/src/NuGet/EntityFramework/tools/EntityFramework6.psm1 index 5a039ea81b..b4aaa4f0e6 100644 --- a/src/NuGet/EntityFramework/tools/EntityFramework6.psm1 +++ b/src/NuGet/EntityFramework/tools/EntityFramework6.psm1 @@ -3,14 +3,6 @@ $ErrorActionPreference = 'Stop' $InitialDatabase = '0' -$knownExceptions = @( - 'System.Data.Entity.Migrations.Infrastructure.MigrationsException', - 'System.Data.Entity.Migrations.Infrastructure.AutomaticMigrationsDisabledException', - 'System.Data.Entity.Migrations.Infrastructure.AutomaticDataLossException', - 'System.Data.Entity.Migrations.Infrastructure.MigrationsPendingException', - 'System.Data.Entity.Migrations.ProjectTypeNotSupportedException' -) - <# .SYNOPSIS Adds or updates an Entity Framework provider entry in the project config @@ -282,16 +274,7 @@ function Enable-Migrations $params += '--migrations-dir', $MigrationsDirectory } - if ($ConnectionStringName) - { - $params += '--connection-string-name', $ConnectionStringName - } - - if ($ConnectionString) - { - $params += '--connection-string', $ConnectionString, - '--connection-provider', $ConnectionProviderName - } + $params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName if ($Force) { @@ -380,10 +363,9 @@ function Enable-Migrations #> function Add-Migration { - [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')] - param ( - [parameter(Position = 0, - Mandatory = $true)] + [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)] + param( + [parameter(Position = 0, Mandatory = $true)] [string] $Name, [switch] $Force, [string] $ProjectName, @@ -391,42 +373,44 @@ function Add-Migration [string] $ConfigurationTypeName, [parameter(ParameterSetName = 'ConnectionStringName')] [string] $ConnectionStringName, - [parameter(ParameterSetName = 'ConnectionStringAndProviderName', - Mandatory = $true)] + [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)] [string] $ConnectionString, - [parameter(ParameterSetName = 'ConnectionStringAndProviderName', - Mandatory = $true)] + [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)] [string] $ConnectionProviderName, [switch] $IgnoreChanges, [string] $AppDomainBaseDirectory) - Hint-Downgrade $MyInvocation.MyCommand - $runner = New-MigrationsRunner $ProjectName $StartUpProjectName $null $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName $null $AppDomainBaseDirectory + WarnIfOtherEFs 'Add-Migration' - try - { - Invoke-RunnerCommand $runner System.Data.Entity.Migrations.AddMigrationCommand @( $Name, $Force.IsPresent, $IgnoreChanges.IsPresent ) - $error = Get-RunnerError $runner + $project = GetProject $ProjectName + $startupProject = GetStartupProject $StartUpProjectName $project - if ($error) - { - if ($knownExceptions -notcontains $error.TypeName) - { - Write-Host $error.StackTrace - } - else - { - Write-Verbose $error.StackTrace - } + $params = 'migrations', 'add', $Name, '--json' - throw $error.Message - } - $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow]).Show() + if ($Force) + { + $params += '--force' } - finally + + if ($ConfigurationTypeName) + { + $params += '--migrations-config', $ConfigurationTypeName + } + + if ($IgnoreChanges) { - Remove-Runner $runner + $params += '--ignore-changes' } + + $params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName + + # NB: -join is here to support ConvertFrom-Json on PowerShell 3.0 + $result = (EF6 $project $startupProject $AppDomainBaseDirectory $params) -join "`n" | ConvertFrom-Json + + $project.ProjectItems.AddFromFile($result.migration) | Out-Null + $DTE.ItemOperations.OpenFile($result.migration) | Out-Null + $project.ProjectItems.AddFromFile($result.migrationResources) | Out-Null + $project.ProjectItems.AddFromFile($result.migrationDesigner) | Out-Null } <# @@ -518,8 +502,8 @@ function Add-Migration #> function Update-Database { - [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')] - param ( + [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)] + param( [string] $SourceMigration, [string] $TargetMigration, [switch] $Script, @@ -529,40 +513,69 @@ function Update-Database [string] $ConfigurationTypeName, [parameter(ParameterSetName = 'ConnectionStringName')] [string] $ConnectionStringName, - [parameter(ParameterSetName = 'ConnectionStringAndProviderName', - Mandatory = $true)] + [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)] [string] $ConnectionString, - [parameter(ParameterSetName = 'ConnectionStringAndProviderName', - Mandatory = $true)] + [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)] [string] $ConnectionProviderName, [string] $AppDomainBaseDirectory) - Hint-Downgrade $MyInvocation.MyCommand - $runner = New-MigrationsRunner $ProjectName $StartUpProjectName $null $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName $null $AppDomainBaseDirectory + WarnIfOtherEFs 'Update-Database' - try + $project = GetProject $ProjectName + $startupProject = GetStartupProject $StartUpProjectName $project + + $params = 'database', 'update' + + if ($SourceMigration) + { + $params += '--source', $SourceMigration + } + + if ($TargetMigration) + { + $params += '--target', $TargetMigration + } + + if ($Script) { - Invoke-RunnerCommand $runner System.Data.Entity.Migrations.UpdateDatabaseCommand @( $SourceMigration, $TargetMigration, $Script.IsPresent, $Force.IsPresent, $Verbose.IsPresent ) - $error = Get-RunnerError $runner + $params += '--script' + } + + if ($Force) + { + $params += '--force' + } - if ($error) + $params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName + + $result = EF6 $project $startupProject $AppDomainBaseDirectory $params + if ($result) + { + try { - if ($knownExceptions -notcontains $error.TypeName) - { - Write-Host $error.StackTrace - } - else + $window = $DTE.ItemOperations.NewFile('General\Sql File') + $textDocument = $window.Document.Object('TextDocument') + $editPoint = $textDocument.StartPoint.CreateEditPoint() + $editPoint.Insert($result) + } + catch + { + $intermediatePath = GetIntermediatePath $project + if (![IO.Path]::IsPathRooted($intermediatePath)) { - Write-Verbose $error.StackTrace + $projectDir = GetProperty $project.Properties 'FullPath' + $intermediatePath = Join-Path $projectDir $intermediatePath -Resolve | Convert-Path } - throw $error.Message + $fileName = [IO.Path]::ChangeExtension([IO.Path]::GetRandomFileName(), '.sql') + $sqlFile = Join-Path $intermediatePath $fileName + + [IO.File]::WriteAllText($sqlFile, $result) + + $DTE.ItemOperations.OpenFile($sqlFile) | Out-Null } - $(Get-VSComponentModel).GetService([NuGetConsole.IPowerConsoleWindow]).Show() - } - finally - { - Remove-Runner $runner + + ShowConsole } } @@ -608,342 +621,34 @@ function Update-Database #> function Get-Migrations { - [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')] - param ( + [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)] + param( [string] $ProjectName, [string] $StartUpProjectName, [string] $ConfigurationTypeName, [parameter(ParameterSetName = 'ConnectionStringName')] [string] $ConnectionStringName, - [parameter(ParameterSetName = 'ConnectionStringAndProviderName', - Mandatory = $true)] + [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)] [string] $ConnectionString, - [parameter(ParameterSetName = 'ConnectionStringAndProviderName', - Mandatory = $true)] + [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)] [string] $ConnectionProviderName, [string] $AppDomainBaseDirectory) - $runner = New-MigrationsRunner $ProjectName $StartUpProjectName $null $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName $null $AppDomainBaseDirectory - - try - { - Invoke-RunnerCommand $runner System.Data.Entity.Migrations.GetMigrationsCommand - $error = Get-RunnerError $runner - - if ($error) - { - if ($knownExceptions -notcontains $error.TypeName) - { - Write-Host $error.StackTrace - } - else - { - Write-Verbose $error.StackTrace - } - - throw $error.Message - } - } - finally - { - Remove-Runner $runner - } -} - -function New-MigrationsRunner($ProjectName, $StartUpProjectName, $ContextProjectName, $ConfigurationTypeName, $ConnectionStringName, $ConnectionString, $ConnectionProviderName, $ContextAssemblyName, $AppDomainBaseDirectory) -{ - $startUpProject = Get-MigrationsStartUpProject $StartUpProjectName $ProjectName - Build-Project $startUpProject - - $project = Get-MigrationsProject $ProjectName - Build-Project $project - - $contextProject = $project - if ($ContextProjectName) - { - $contextProject = Get-SingleProject $ContextProjectName - Build-Project $contextProject - } - - $installPath = Get-EntityFrameworkInstallPath $project - $toolsPath = Join-Path $installPath tools - - $info = New-AppDomainSetup $project $installPath + WarnIfOtherEFs 'Get-Migrations' - $domain = [AppDomain]::CreateDomain('Migrations', $null, $info) - $domain.SetData('project', $project) - $domain.SetData('contextProject', $contextProject) - $domain.SetData('startUpProject', $startUpProject) - $domain.SetData('configurationTypeName', $ConfigurationTypeName) - $domain.SetData('connectionStringName', $ConnectionStringName) - $domain.SetData('connectionString', $ConnectionString) - $domain.SetData('connectionProviderName', $ConnectionProviderName) - $domain.SetData('contextAssemblyName', $ContextAssemblyName) - $domain.SetData('appDomainBaseDirectory', $AppDomainBaseDirectory) - - $dispatcher = New-DomainDispatcher $toolsPath - $domain.SetData('efDispatcher', $dispatcher) - - return @{ - Domain = $domain; - ToolsPath = $toolsPath - } -} - -function New-AppDomainSetup($Project, $InstallPath) -{ - $info = New-Object System.AppDomainSetup -Property @{ - ShadowCopyFiles = 'true'; - ApplicationBase = $InstallPath; - PrivateBinPath = 'tools'; - ConfigurationFile = ([AppDomain]::CurrentDomain.SetupInformation.ConfigurationFile) - } - - $targetFrameworkVersion = (New-Object System.Runtime.Versioning.FrameworkName ($Project.Properties.Item('TargetFrameworkMoniker').Value)).Version - - if ($targetFrameworkVersion -lt (New-Object Version @( 4, 5 ))) - { - $info.PrivateBinPath += ';lib\net40' - } - else - { - $info.PrivateBinPath += ';lib\net45' - } - - return $info -} - -function New-DomainDispatcher($ToolsPath) -{ - $utilityAssembly = [System.Reflection.Assembly]::LoadFrom((Join-Path $ToolsPath EntityFramework.PowerShell.Utility.dll)) - $dispatcher = $utilityAssembly.CreateInstance( - 'System.Data.Entity.Migrations.Utilities.DomainDispatcher', - $false, - [System.Reflection.BindingFlags]::Instance -bor [System.Reflection.BindingFlags]::Public, - $null, - $PSCmdlet, - $null, - $null) - - return $dispatcher -} - -function Remove-Runner($runner) -{ - [AppDomain]::Unload($runner.Domain) -} - -function Invoke-RunnerCommand($runner, $command, $parameters, $anonymousArguments) -{ - $domain = $runner.Domain - - if ($anonymousArguments) - { - $anonymousArguments.GetEnumerator() | %{ - $domain.SetData($_.Name, $_.Value) - } - } - - $domain.CreateInstanceFrom( - (Join-Path $runner.ToolsPath EntityFramework.PowerShell.dll), - $command, - $false, - 0, - $null, - $parameters, - $null, - $null) | Out-Null -} - -function Get-RunnerError($runner) -{ - $domain = $runner.Domain - - if (!$domain.GetData('wasError')) - { - return $null - } - - return @{ - Message = $domain.GetData('error.Message'); - TypeName = $domain.GetData('error.TypeName'); - StackTrace = $domain.GetData('error.StackTrace') - } -} - -function Get-MigrationsProject($name, $hideMessage) -{ - if ($name) - { - return Get-SingleProject $name - } - - $project = Get-Project - $projectName = $project.Name - - if (!$hideMessage) - { - Write-Verbose "Using NuGet project '$projectName'." - } - - return $project -} - -function Get-MigrationsStartUpProject($name, $fallbackName) -{ - $startUpProject = $null - - if ($name) - { - $startUpProject = Get-SingleProject $name - } - else - { - $startupProjectPaths = $DTE.Solution.SolutionBuild.StartupProjects - - if ($startupProjectPaths) - { - if ($startupProjectPaths.Length -eq 1) - { - $startupProjectPath = $startupProjectPaths[0] - - if (!(Split-Path -IsAbsolute $startupProjectPath)) - { - $solutionPath = Split-Path $DTE.Solution.Properties.Item('Path').Value - $startupProjectPath = Join-Path $solutionPath $startupProjectPath -Resolve - } - - $startupProject = Get-SolutionProjects | ?{ - try - { - $fullName = $_.FullName - } - catch [NotImplementedException] - { - return $false - } - - if ($fullName -and $fullName.EndsWith('\')) - { - $fullName = $fullName.Substring(0, $fullName.Length - 1) - } - - return $fullName -eq $startupProjectPath - } - } - else - { - Write-Verbose 'More than one start-up project found.' - } - } - else - { - Write-Verbose 'No start-up project found.' - } - } - - if (!($startUpProject -and (Test-StartUpProject $startUpProject))) - { - $startUpProject = Get-MigrationsProject $fallbackName $true - $startUpProjectName = $startUpProject.Name - - Write-Warning "Cannot determine a valid start-up project. Using project '$startUpProjectName' instead. Your configuration file and working directory may not be set as expected. Use the -StartUpProjectName parameter to set one explicitly. Use the -Verbose switch for more information." - } - else - { - $startUpProjectName = $startUpProject.Name - - Write-Verbose "Using StartUp project '$startUpProjectName'." - } - - return $startUpProject -} - -function Get-SolutionProjects() -{ - $projects = New-Object System.Collections.Stack - - $DTE.Solution.Projects | %{ - $projects.Push($_) - } - - while ($projects.Count -ne 0) - { - $project = $projects.Pop(); - - # NOTE: This line is similar to doing a "yield return" in C# - $project - - if ($project.ProjectItems) - { - $project.ProjectItems | ?{ $_.SubProject } | %{ - $projects.Push($_.SubProject) - } - } - } -} - -function Get-SingleProject($name) -{ - $project = Get-Project $name - - if ($project -is [array]) - { - throw "More than one project '$name' was found. Specify the full name of the one to use." - } - - return $project -} - -function Test-StartUpProject($project) -{ - if ($project.Kind -eq '{cc5fd16d-436d-48ad-a40c-5a424c6e3e79}') - { - $projectName = $project.Name - Write-Verbose "Cannot use start-up project '$projectName'. The Windows Azure Project type isn't supported." - - return $false - } - - return $true -} - -function Build-Project($project) -{ - $configuration = $DTE.Solution.SolutionBuild.ActiveConfiguration.Name - - $DTE.Solution.SolutionBuild.BuildProject($configuration, $project.UniqueName, $true) - - if ($DTE.Solution.SolutionBuild.LastBuildInfo) - { - $projectName = $project.Name - - throw "The project '$projectName' failed to build." - } -} + $project = GetProject $ProjectName + $startupProject = GetStartupProject $StartUpProjectName $project -function Get-EntityFrameworkInstallPath($project) -{ - $package = Get-Package -ProjectName $project.FullName | ?{ $_.Id -eq 'EntityFramework' } + $params = 'migrations', 'list' - if (!$package) + if ($ConfigurationTypeName) { - $projectName = $project.Name - - throw "The EntityFramework package is not installed on project '$projectName'." + $params += '--migrations-config', $ConfigurationTypeName } - return Get-PackageInstallPath $package -} - -function Get-PackageInstallPath($package) -{ - $componentModel = Get-VsComponentModel - $packageInstallerServices = $componentModel.GetService([NuGet.VisualStudio.IVsPackageInstallerServices]) - - $vsPackage = $packageInstallerServices.GetInstalledPackages() | ?{ $_.Id -eq $package.Id -and $_.Version -eq $package.Version } + $params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName - return $vsPackage.InstallPath + return EF6 $project $startupProject $AppDomainBaseDirectory $params } function WarnIfOtherEFs($cmdlet) @@ -1050,6 +755,24 @@ function GetSolutionProjects() } } +function GetParams($connectionStringName, $connectionString, $connectionProviderName) +{ + $params = @() + + if ($connectionStringName) + { + $params += '--connection-string-name', $connectionStringName + } + + if ($connectionString) + { + $params += '--connection-string', $connectionString, + '--connection-provider', $connectionProviderName + } + + return $params +} + function ShowConsole { $componentModel = Get-VSComponentModel @@ -1298,6 +1021,17 @@ function IsWeb($project) return $false; } +function GetIntermediatePath($project) +{ + $intermediatePath = GetProperty $project.ConfigurationManager.ActiveConfiguration.Properties 'IntermediatePath' + if ($intermediatePath) + { + return $intermediatePath + } + + return GetMSBuildProperty $project 'IntermediateOutputPath' +} + function GetPlatformTarget($project) { if (IsCpsProject $project) @@ -1310,7 +1044,7 @@ function GetPlatformTarget($project) return GetCpsProperty $project 'Platform' } - + $platformTarget = GetProperty $project.ConfigurationManager.ActiveConfiguration.Properties 'PlatformTarget' if ($platformTarget) { diff --git a/src/ef6/Commands/DatabaseCommand.cs b/src/ef6/Commands/DatabaseCommand.cs index 4340bdb9b8..525c8617a7 100644 --- a/src/ef6/Commands/DatabaseCommand.cs +++ b/src/ef6/Commands/DatabaseCommand.cs @@ -11,8 +11,7 @@ public override void Configure(CommandLineApplication command) { command.Description = MyResources.DatabaseDescription; - // TODO - //command.Command("update", new DatabaseUpdateCommand().Configure); + command.Command("update", new DatabaseUpdateCommand().Configure); base.Configure(command); } diff --git a/src/ef6/Commands/DatabaseUpdateCommand.cs b/src/ef6/Commands/DatabaseUpdateCommand.cs new file mode 100644 index 0000000000..fd681a8cab --- /dev/null +++ b/src/ef6/Commands/DatabaseUpdateCommand.cs @@ -0,0 +1,76 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using Microsoft.DotNet.Cli.CommandLine; +using MyResources = System.Data.Entity.Tools.Properties.Resources; + +namespace System.Data.Entity.Tools.Commands +{ + internal class DatabaseUpdateCommand : MigrationsCommandBase + { + private CommandOption _sourceMigration; + private CommandOption _targetMigration; + private CommandOption _script; + private CommandOption _force; + + public override void Configure(CommandLineApplication command) + { + command.Description = MyResources.DatabaseUpdateDescription; + + _sourceMigration = command.Option("--source ", MyResources.DatabaseUpdateSourceDescription); + _targetMigration = command.Option("--target ", MyResources.DatabaseUpdateTargetDescription); + _script = command.Option("--script", MyResources.DatabaseUpdateScriptDescription); + _force = command.Option("-f|--force", MyResources.DatabaseUpdateForceDescription); + + base.Configure(command); + } + + protected override int Execute() + { + if (_script.HasValue()) + { + var sql = CreateExecutor().ScriptUpdate( + _sourceMigration.Value(), + _targetMigration.Value(), + _force.HasValue(), + ConnectionStringName.Value(), + ConnectionString.Value(), + ConnectionProvider.Value(), + MigrationsConfig.Value()); + + Reporter.WriteData(sql); + } + else + { + if (!Reporter.IsVerbose) + { + Reporter.WriteInformation(MyResources.UpdateDatabaseCommand_VerboseInstructions); + } + + try + { + CreateExecutor().Update( + _targetMigration.Value(), + _force.HasValue(), + ConnectionStringName.Value(), + ConnectionString.Value(), + ConnectionProvider.Value(), + MigrationsConfig.Value()); + } + catch (WrappedException ex) + { + if (ex.Type == "System.Data.Entity.Migrations.Infrastructure.AutomaticMigrationsDisabledException") + { + Reporter.WriteWarning(ex.Message); + Reporter.WriteWarning(MyResources.AutomaticMigrationDisabledInfo); + } + else + { + throw; + } + } + } + + return base.Execute(); + } + } +} diff --git a/src/ef6/Commands/MigrationsAddCommand.cs b/src/ef6/Commands/MigrationsAddCommand.cs new file mode 100644 index 0000000000..2dcd1fdd10 --- /dev/null +++ b/src/ef6/Commands/MigrationsAddCommand.cs @@ -0,0 +1,119 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System.IO; +using System.Linq; +using Microsoft.DotNet.Cli.CommandLine; + +using MyResources = System.Data.Entity.Tools.Properties.Resources; + +namespace System.Data.Entity.Tools.Commands +{ + internal class MigrationsAddCommand : MigrationsCommandBase + { + private CommandArgument _name; + private CommandOption _force; + private CommandOption _ignoreChanges; + private CommandOption _json; + + public override void Configure(CommandLineApplication command) + { + command.Description = MyResources.MigrationsAddDescription; + + _name = command.Argument("", MyResources.MigrationNameDescription); + _force = command.Option("-f|--force", MyResources.MigrationsAddForceDescription); + _ignoreChanges = command.Option("--ignore-changes", MyResources.IgnoreChangesDescription); + _json = Json.ConfigureOption(command); + + base.Configure(command); + } + + protected override void Validate() + { + base.Validate(); + + if (string.IsNullOrEmpty(_name.Value)) + { + throw new CommandException(string.Format(MyResources.MissingArgument, _name.Name)); + } + } + + protected override int Execute() + { + var scaffoldedMigration = CreateExecutor().Scaffold( + _name.Value, + ConnectionStringName.Value(), + ConnectionString.Value(), + ConnectionProvider.Value(), + MigrationsConfig.Value(), + _ignoreChanges.HasValue()); + + Reporter.WriteInformation( + string.Format( + !scaffoldedMigration.IsRescaffold + ? MyResources.ScaffoldingMigration + : MyResources.RescaffoldingMigration, + _name.Value)); + + var userCodePath + = WriteMigration(scaffoldedMigration, scaffoldedMigration.IsRescaffold, _force.HasValue(), _name.Value); + + if (!scaffoldedMigration.IsRescaffold) + { + Reporter.WriteWarning(string.Format(MyResources.SnapshotBehindWarning, _name.Value)); + + var databaseMigrations + = CreateExecutor().GetDatabaseMigrations( + ConnectionStringName.Value(), + ConnectionString.Value(), + ConnectionProvider.Value(), + MigrationsConfig.Value()) + .Take(2).ToList(); + + var lastDatabaseMigration = databaseMigrations.FirstOrDefault(); + + if ((lastDatabaseMigration != null) + && string.Equals(lastDatabaseMigration.MigrationName(), _name.Value, StringComparison.Ordinal)) + { + var revertTargetMigration + = databaseMigrations.ElementAtOrDefault(1); + + Reporter.WriteWarning( + string.Format( + MyResources.DidYouMeanToRescaffold, + _name.Value, + revertTargetMigration ?? "$InitialDatabase", + Path.GetFileName(userCodePath))); + } + } + + if (_json.HasValue()) + { + string migrationPath = null; + string migrationDesignerPath = null; + string migrationResourcesPath = null; + if (scaffoldedMigration != null) + { + var absoluteMigrationsDirectory = Path.Combine(ProjectDir.Value(), scaffoldedMigration.Directory); + + migrationPath = Path.Combine( + absoluteMigrationsDirectory, + scaffoldedMigration.MigrationId + "." + scaffoldedMigration.Language); + migrationDesignerPath = Path.Combine( + absoluteMigrationsDirectory, + scaffoldedMigration.MigrationId + ".resx"); + migrationResourcesPath = Path.Combine( + absoluteMigrationsDirectory, + scaffoldedMigration.MigrationId + ".Designer." + scaffoldedMigration.Language); + } + + Reporter.WriteData("{"); + Reporter.WriteData(" \"migration\": " + Json.Literal(migrationPath) + ","); + Reporter.WriteData(" \"migrationResources\": " + Json.Literal(migrationDesignerPath) + ","); + Reporter.WriteData(" \"migrationDesigner\": " + Json.Literal(migrationResourcesPath)); + Reporter.WriteData("}"); + } + + return base.Execute(); + } + } +} diff --git a/src/ef6/Commands/MigrationsCommand.cs b/src/ef6/Commands/MigrationsCommand.cs index 6c7f582f1d..425529ef50 100644 --- a/src/ef6/Commands/MigrationsCommand.cs +++ b/src/ef6/Commands/MigrationsCommand.cs @@ -12,10 +12,9 @@ public override void Configure(CommandLineApplication command) { command.Description = MyResources.MigrationsDescription; - // TODO - //command.Command("add", new MigrationsAddCommand().Configure); + command.Command("add", new MigrationsAddCommand().Configure); command.Command("enable", new MigrationsEnableCommand().Configure); - //command.Command("list", new MigrationsListCommand().Configure); + command.Command("list", new MigrationsListCommand().Configure); base.Configure(command); } diff --git a/src/ef6/Commands/MigrationsCommandBase.cs b/src/ef6/Commands/MigrationsCommandBase.cs new file mode 100644 index 0000000000..9b974f3353 --- /dev/null +++ b/src/ef6/Commands/MigrationsCommandBase.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using Microsoft.DotNet.Cli.CommandLine; + +using MyResources = System.Data.Entity.Tools.Properties.Resources; + +namespace System.Data.Entity.Tools.Commands +{ + internal abstract class MigrationsCommandBase : ProjectCommandBase + { + protected CommandOption MigrationsConfig { get; private set; } + + public override void Configure(CommandLineApplication command) + { + MigrationsConfig = command.Option("--migrations-config ", MyResources.MigrationsConfigDescription); + + base.Configure(command); + } + } +} diff --git a/src/ef6/Commands/MigrationsEnableCommand.cs b/src/ef6/Commands/MigrationsEnableCommand.cs index ada74f4bab..0e601e48bd 100644 --- a/src/ef6/Commands/MigrationsEnableCommand.cs +++ b/src/ef6/Commands/MigrationsEnableCommand.cs @@ -1,12 +1,9 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. using System.Collections.Generic; -using System.Data.Entity.Tools.Migrations.Design; using System.Data.Entity.Tools.Utilities; using System.Diagnostics; using System.IO; -using System.Reflection; -using System.Resources; using System.Text; using Microsoft.DotNet.Cli.CommandLine; @@ -14,84 +11,36 @@ namespace System.Data.Entity.Tools.Commands { - internal class MigrationsEnableCommand : EFCommandBase + internal class MigrationsEnableCommand : ProjectCommandBase { - private CommandOption _assembly; private CommandOption _force; private CommandOption _auto; - private CommandOption _language; - private CommandOption _projectDir; private CommandOption _migrationsDir; - private CommandOption _rootNamespace; private CommandOption _context; private CommandOption _contextAssembly; private CommandOption _json; - private CommandOption _connectionStringName; - private CommandOption _connectionString; - private CommandOption _connectionProvider; - private CommandOption _dataDir; - private CommandOption _config; public override void Configure(CommandLineApplication command) { command.Description = MyResources.MigrationsEnableDescription; - _assembly = command.Option("-a|--assembly ", MyResources.AssemblyDescription); - _projectDir = command.Option("--project-dir ", MyResources.ProjectDirDescription); - _language = command.Option("--language ", MyResources.LanguageDescription); - _rootNamespace = command.Option("--root-namespace ", MyResources.RootNamespaceDescription); _auto = command.Option("--auto", MyResources.MigrationsEnableAutoDescription); _force = command.Option("-f|--force", MyResources.MigrationsEnableForceDescription); _migrationsDir = command.Option("--migrations-dir ", MyResources.MigrationsDirDescription); _context = command.Option("-c|--context ", MyResources.ContextDescription); _contextAssembly = command.Option("--context-assembly ", MyResources.ContextAssemblyDescription); _json = Json.ConfigureOption(command); - _connectionStringName = command.Option("--connection-string-name ", MyResources.ConnectionStringNameDescription); - _connectionString = command.Option("--connection-string ", MyResources.ConnectionStringDescription); - _connectionProvider = command.Option("--connection-provider ", MyResources.ConnectionProviderDescription); - _dataDir = command.Option("--data-dir ", MyResources.DataDirDescription); - _config = command.Option("--config ", MyResources.ConfigDescription); base.Configure(command); } - protected override void Validate() - { - base.Validate(); - - if (!_assembly.HasValue()) - { - throw new CommandException(string.Format(MyResources.MissingOption, _assembly.LongName)); - } - - if (_connectionString.HasValue() || _connectionProvider.HasValue()) - { - if (!_connectionString.HasValue()) - { - throw new CommandException(string.Format(MyResources.MissingOption, _connectionString.LongName)); - } - if (!_connectionProvider.HasValue()) - { - throw new CommandException(string.Format(MyResources.MissingOption, _connectionProvider.LongName)); - } - if (_connectionStringName.HasValue()) - { - throw new CommandException( - string.Format( - MyResources.MutuallyExclusiveOptions, - _connectionStringName.LongName, - _connectionString.LongName)); - } - } - } - protected override int Execute() { var migrationsDirectory = _migrationsDir.Value(); var qualifiedContextTypeName = CreateExecutor().GetContextType( _context.Value(), _contextAssembly.Value()); - var isVb = string.Equals(_language.Value(), "VB", StringComparison.OrdinalIgnoreCase); + var isVb = string.Equals(Language.Value(), "VB", StringComparison.OrdinalIgnoreCase); var fileName = isVb ? "Configuration.vb" : "Configuration.cs"; var templateStream = typeof(MigrationsEnableCommand).Assembly.GetManifestResourceStream("System.Data.Entity.Tools.Templates." + fileName); Debug.Assert(templateStream != null); @@ -122,7 +71,7 @@ protected override int Execute() ? (isVb ? "True" : "true") : (isVb ? "False" : "false"); - var rootNamespace = _rootNamespace.Value(); + var rootNamespace = RootNamespace.Value(); var migrationsNamespace = migrationsDirectory.Replace("\\", "."); tokens["namespace"] @@ -145,13 +94,13 @@ protected override int Execute() throw new CommandException(string.Format(MyResources.MigrationsDirectoryParamIsRooted, migrationsDirectory)); } - var absoluteMigrationsDirectory = Path.Combine(_projectDir.Value(), migrationsDirectory); + var absoluteMigrationsDirectory = Path.Combine(ProjectDir.Value(), migrationsDirectory); var absolutePath = Path.Combine(absoluteMigrationsDirectory, fileName); if (!_force.HasValue() && File.Exists(absolutePath)) { - throw new CommandException(string.Format(MyResources.MigrationsAlreadyEnabled, _assembly.Value())); + throw new CommandException(string.Format(MyResources.MigrationsAlreadyEnabled, Assembly.Value())); } var fullMigrationsNamespace = rootNamespace + "." + migrationsNamespace; @@ -159,9 +108,9 @@ protected override int Execute() Reporter.WriteInformation(MyResources.EnableMigrations_BeginInitialScaffold); var scaffoldedMigration = CreateExecutor().ScaffoldInitialCreate( - _connectionStringName.Value(), - _connectionString.Value(), - _connectionProvider.Value(), + ConnectionStringName.Value(), + ConnectionString.Value(), + ConnectionProvider.Value(), qualifiedContextTypeName, _contextAssembly.Value(), fullMigrationsNamespace, @@ -218,70 +167,5 @@ protected override int Execute() return base.Execute(); } - - private ExecutorBase CreateExecutor() - { - try - { -#if NET40 || NET45 - return new AppDomainExecutor( - _assembly.Value(), - _dataDir.Value(), - _config.Value(), - _rootNamespace.Value(), - _language.Value()); -#elif NETCOREAPP3_0 - return new ReflectionExecutor( - _assembly.Value(), - _dataDir.Value(), - _config.Value(), - _rootNamespace.Value(), - _language.Value()); -#else -#error Unexpected target framework -#endif - } - catch (FileNotFoundException ex) - when (new AssemblyName(ex.FileName).Name == "EntityFramework") - { - throw new CommandException( - string.Format( - MyResources.EntityFrameworkNotFound, - Path.GetFileNameWithoutExtension(_assembly.Value())), - ex); - } - } - - private string WriteMigration(ScaffoldedMigration scaffoldedMigration) - { - DebugCheck.NotNull(scaffoldedMigration); - - var userCodeFileName = scaffoldedMigration.MigrationId + "." + scaffoldedMigration.Language; - var userCodePath = Path.Combine(scaffoldedMigration.Directory, userCodeFileName); - var absoluteUserCodePath = Path.Combine(_projectDir.Value(), userCodePath); - var designerCodeFileName = scaffoldedMigration.MigrationId + ".Designer." + scaffoldedMigration.Language; - var designerCodePath = Path.Combine(scaffoldedMigration.Directory, designerCodeFileName); - var absoluteDesignerCodePath = Path.Combine(_projectDir.Value(), designerCodePath); - var resourcesFileName = scaffoldedMigration.MigrationId + ".resx"; - var resourcesPath = Path.Combine(scaffoldedMigration.Directory, resourcesFileName); - - Directory.CreateDirectory(Path.GetDirectoryName(absoluteUserCodePath)); - File.WriteAllText(absoluteUserCodePath, scaffoldedMigration.UserCode, Encoding.UTF8); - - var absoluteResourcesPath = Path.Combine(_projectDir.Value(), resourcesPath); - - using (var writer = new ResXResourceWriter(absoluteResourcesPath)) - { - foreach (var i in scaffoldedMigration.Resources) - { - writer.AddResource(i.Key, i.Value); - } - } - - Directory.CreateDirectory(Path.GetDirectoryName(absoluteDesignerCodePath)); - File.WriteAllText(absoluteDesignerCodePath, scaffoldedMigration.DesignerCode, Encoding.UTF8); - - return userCodePath; - } } } diff --git a/src/ef6/Commands/MigrationsListCommand.cs b/src/ef6/Commands/MigrationsListCommand.cs new file mode 100644 index 0000000000..d3b6bb9bab --- /dev/null +++ b/src/ef6/Commands/MigrationsListCommand.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System.Linq; +using Microsoft.DotNet.Cli.CommandLine; + +using MyResources = System.Data.Entity.Tools.Properties.Resources; + +namespace System.Data.Entity.Tools.Commands +{ + internal class MigrationsListCommand : MigrationsCommandBase + { + public override void Configure(CommandLineApplication command) + { + command.Description = MyResources.MigrationsListDescription; + + base.Configure(command); + } + + protected override int Execute() + { + Reporter.WriteInformation(MyResources.GetMigrationsCommand_Intro); + + var migrations = CreateExecutor().GetDatabaseMigrations( + ConnectionStringName.Value(), + ConnectionString.Value(), + ConnectionProvider.Value(), + MigrationsConfig.Value()); + + if (migrations.Any()) + { + foreach (var migration in migrations) + { + Reporter.WriteData(migration); + } + } + else + { + Reporter.WriteInformation(MyResources.GetMigrationsCommand_NoHistory); + } + + return base.Execute(); + } + } +} diff --git a/src/ef6/Commands/ProjectCommandBase.cs b/src/ef6/Commands/ProjectCommandBase.cs new file mode 100644 index 0000000000..878e6fe411 --- /dev/null +++ b/src/ef6/Commands/ProjectCommandBase.cs @@ -0,0 +1,154 @@ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +using System.Data.Entity.Tools.Migrations.Design; +using System.Data.Entity.Tools.Utilities; +using System.Diagnostics; +using System.IO; +using System.Reflection; +using System.Resources; +using System.Text; +using Microsoft.DotNet.Cli.CommandLine; + +using MyResources = System.Data.Entity.Tools.Properties.Resources; + +namespace System.Data.Entity.Tools.Commands +{ + internal abstract class ProjectCommandBase : EFCommandBase + { + protected CommandOption Assembly { get; private set; } + protected CommandOption Config { get; private set; } + protected CommandOption ConnectionProvider { get; private set; } + protected CommandOption ConnectionString { get; private set; } + protected CommandOption ConnectionStringName { get; private set; } + protected CommandOption DataDir { get; private set; } + protected CommandOption Language { get; private set; } + protected CommandOption ProjectDir { get; private set; } + protected CommandOption RootNamespace { get; private set; } + + public override void Configure(CommandLineApplication command) + { + Assembly = command.Option("-a|--assembly ", MyResources.AssemblyDescription); + ProjectDir = command.Option("--project-dir ", MyResources.ProjectDirDescription); + Language = command.Option("--language ", MyResources.LanguageDescription); + RootNamespace = command.Option("--root-namespace ", MyResources.RootNamespaceDescription); + DataDir = command.Option("--data-dir ", MyResources.DataDirDescription); + Config = command.Option("--config ", MyResources.ConfigDescription); + ConnectionStringName = command.Option("--connection-string-name ", MyResources.ConnectionStringNameDescription); + ConnectionString = command.Option("--connection-string ", MyResources.ConnectionStringDescription); + ConnectionProvider = command.Option("--connection-provider ", MyResources.ConnectionProviderDescription); + + base.Configure(command); + } + + protected override void Validate() + { + base.Validate(); + + if (!Assembly.HasValue()) + { + throw new CommandException(string.Format(MyResources.MissingOption, Assembly.LongName)); + } + + if (ConnectionString.HasValue() || ConnectionProvider.HasValue()) + { + if (!ConnectionString.HasValue()) + { + throw new CommandException(string.Format(MyResources.MissingOption, ConnectionString.LongName)); + } + if (!ConnectionProvider.HasValue()) + { + throw new CommandException(string.Format(MyResources.MissingOption, ConnectionProvider.LongName)); + } + if (ConnectionStringName.HasValue()) + { + throw new CommandException( + string.Format( + MyResources.MutuallyExclusiveOptions, + ConnectionStringName.LongName, + ConnectionString.LongName)); + } + } + } + + protected ExecutorBase CreateExecutor() + { + try + { +#if NET40 || NET45 + return new AppDomainExecutor( + Assembly.Value(), + DataDir.Value(), + Config.Value(), + RootNamespace.Value(), + Language.Value()); +#elif NETCOREAPP3_0 + return new ReflectionExecutor( + Assembly.Value(), + DataDir.Value(), + Config.Value(), + RootNamespace.Value(), + Language.Value()); +#else +#error Unexpected target framework +#endif + } + catch (FileNotFoundException ex) + when (new AssemblyName(ex.FileName).Name == "EntityFramework") + { + throw new CommandException( + string.Format( + MyResources.EntityFrameworkNotFound, + Path.GetFileNameWithoutExtension(Assembly.Value())), + ex); + } + } + + protected string WriteMigration( + ScaffoldedMigration scaffoldedMigration, + bool rescaffolding = false, + bool force = false, + string name = null) + { + DebugCheck.NotNull(scaffoldedMigration); + + var userCodeFileName = scaffoldedMigration.MigrationId + "." + scaffoldedMigration.Language; + var userCodePath = Path.Combine(scaffoldedMigration.Directory, userCodeFileName); + var absoluteUserCodePath = Path.Combine(ProjectDir.Value(), userCodePath); + var designerCodeFileName = scaffoldedMigration.MigrationId + ".Designer." + scaffoldedMigration.Language; + var designerCodePath = Path.Combine(scaffoldedMigration.Directory, designerCodeFileName); + var absoluteDesignerCodePath = Path.Combine(ProjectDir.Value(), designerCodePath); + var resourcesFileName = scaffoldedMigration.MigrationId + ".resx"; + var resourcesPath = Path.Combine(scaffoldedMigration.Directory, resourcesFileName); + + if (rescaffolding && !force) + { + if (!string.Equals(scaffoldedMigration.UserCode, File.ReadAllText(absoluteUserCodePath))) + { + Debug.Assert(!string.IsNullOrWhiteSpace(name)); + + Reporter.WriteWarning(string.Format(MyResources.RescaffoldNoForce, name)); + } + } + else + { + Directory.CreateDirectory(Path.GetDirectoryName(absoluteUserCodePath)); + File.WriteAllText(absoluteUserCodePath, scaffoldedMigration.UserCode, Encoding.UTF8); + } + + var absoluteResourcesPath = Path.Combine(ProjectDir.Value(), resourcesPath); + + using (var writer = new ResXResourceWriter(absoluteResourcesPath)) + { + foreach (var i in scaffoldedMigration.Resources) + { + writer.AddResource(i.Key, i.Value); + } + } + + Directory.CreateDirectory(Path.GetDirectoryName(absoluteDesignerCodePath)); + File.WriteAllText(absoluteDesignerCodePath, scaffoldedMigration.DesignerCode, Encoding.UTF8); + + return userCodePath; + } + } +} diff --git a/src/ef6/ExecutorBase.cs b/src/ef6/ExecutorBase.cs index dd6e51a3ba..f39c47c827 100644 --- a/src/ef6/ExecutorBase.cs +++ b/src/ef6/ExecutorBase.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. using System.Collections; +using System.Collections.Generic; using System.Data.Entity.Tools.Migrations.Design; namespace System.Data.Entity.Tools @@ -41,6 +42,12 @@ public ScaffoldedMigration ScaffoldInitialCreate( ["auto"] = auto, ["migrationsDir"] = migrationsDir }); + + return ToScaffoldedMigration(result); + } + + private static ScaffoldedMigration ToScaffoldedMigration(IDictionary result) + { if (result == null) { return null; @@ -64,6 +71,84 @@ public ScaffoldedMigration ScaffoldInitialCreate( return scaffoldedMigration; } + public ScaffoldedMigration Scaffold( + string name, + string connectionStringName, + string connectionString, + string connectionProviderName, + string migrationsConfigurationName, + bool ignoreChanges) + { + var result = Invoke( + "Scaffold", + new Hashtable + { + ["name"] = name, + ["connectionStringName"] = connectionStringName, + ["connectionString"] = connectionString, + ["connectionProviderName"] = connectionProviderName, + ["migrationsConfigurationName"] = migrationsConfigurationName, + ["ignoreChanges"] = ignoreChanges + }); + + return ToScaffoldedMigration(result); + } + + public IEnumerable GetDatabaseMigrations( + string connectionStringName, + string connectionString, + string connectionProviderName, + string migrationsConfigurationName) + => Invoke>( + "GetDatabaseMigrations", + new Hashtable + { + ["connectionStringName"] = connectionStringName, + ["connectionString"] = connectionString, + ["connectionProviderName"] = connectionProviderName, + ["migrationsConfigurationName"] = migrationsConfigurationName + }); + + public string ScriptUpdate( + string sourceMigration, + string targetMigration, + bool force, + string connectionStringName, + string connectionString, + string connectionProviderName, + string migrationsConfigurationName) + => Invoke( + "ScriptUpdate", + new Hashtable + { + ["sourceMigration"] = sourceMigration, + ["targetMigration"] = targetMigration, + ["force"] = force, + ["connectionStringName"] = connectionStringName, + ["connectionString"] = connectionString, + ["connectionProviderName"] = connectionProviderName, + ["migrationsConfigurationName"] = migrationsConfigurationName + }); + + public void Update( + string targetMigration, + bool force, + string connectionStringName, + string connectionString, + string connectionProviderName, + string migrationsConfigurationName) + => Invoke( + "Update", + new Hashtable + { + ["targetMigration"] = targetMigration, + ["force"] = force, + ["connectionStringName"] = connectionStringName, + ["connectionString"] = connectionString, + ["connectionProviderName"] = connectionProviderName, + ["migrationsConfigurationName"] = migrationsConfigurationName + }); + protected abstract dynamic CreateResultHandler(); protected abstract void Execute(string operation, object resultHandler, IDictionary args); diff --git a/src/EntityFramework.PowerShell/Migrations/Utilities/StringExtensions.cs b/src/ef6/Extensions/StringExtensions.cs similarity index 87% rename from src/EntityFramework.PowerShell/Migrations/Utilities/StringExtensions.cs rename to src/ef6/Extensions/StringExtensions.cs index 61efb758c1..602e6c1046 100644 --- a/src/EntityFramework.PowerShell/Migrations/Utilities/StringExtensions.cs +++ b/src/ef6/Extensions/StringExtensions.cs @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. -namespace System.Data.Entity.Migrations.Utilities +namespace System { - using System.Data.Entity.Utilities; + using System.Data.Entity.Tools.Utilities; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Text.RegularExpressions; @@ -11,6 +11,7 @@ namespace System.Data.Entity.Migrations.Utilities Justification = "Due to a bug in code contracts IsNullOrWhiteSpace isn't recognized as pure.")] internal static class StringExtensions { + private const string InitialDatabase = "0"; private static readonly Regex _migrationIdPattern = new Regex(@"\d{15}_.+"); public static bool EqualsIgnoreCase(this string s1, string s2) @@ -31,7 +32,7 @@ public static bool IsValidMigrationId(this string migrationId) DebugCheck.NotEmpty(migrationId); return _migrationIdPattern.IsMatch(migrationId) - || migrationId == DbMigrator.InitialDatabase; + || migrationId == InitialDatabase; } } } diff --git a/src/ef6/Properties/Resources.Designer.cs b/src/ef6/Properties/Resources.Designer.cs index f7adb6a65e..b4ff9f0688 100644 --- a/src/ef6/Properties/Resources.Designer.cs +++ b/src/ef6/Properties/Resources.Designer.cs @@ -69,6 +69,15 @@ internal static string AssemblyDescription { } } + /// + /// Looks up a localized string similar to You can use the Add-Migration command to write the pending model changes to a code-based migration.. + /// + internal static string AutomaticMigrationDisabledInfo { + get { + return ResourceManager.GetString("AutomaticMigrationDisabledInfo", resourceCulture); + } + } + /// /// Looks up a localized string similar to Specifies the configuration file to use for named connection strings.. /// @@ -132,6 +141,51 @@ internal static string DatabaseDescription { } } + /// + /// Looks up a localized string similar to Applies any pending migrations to the database.. + /// + internal static string DatabaseUpdateDescription { + get { + return ResourceManager.GetString("DatabaseUpdateDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Specifies that data loss is acceptable during automatic migration of the database.. + /// + internal static string DatabaseUpdateForceDescription { + get { + return ResourceManager.GetString("DatabaseUpdateForceDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Generate a SQL script rather than executing the pending changes directly.. + /// + internal static string DatabaseUpdateScriptDescription { + get { + return ResourceManager.GetString("DatabaseUpdateScriptDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Only valid with --script. Specifies the name of a particular migration to use as the update's starting point. If omitted, the last applied migration in the database will be used.. + /// + internal static string DatabaseUpdateSourceDescription { + get { + return ResourceManager.GetString("DatabaseUpdateSourceDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Specifies the name of a particular migration to update the database to. If omitted, the current model will be used.. + /// + internal static string DatabaseUpdateTargetDescription { + get { + return ResourceManager.GetString("DatabaseUpdateTargetDescription", resourceCulture); + } + } + /// /// Looks up a localized string similar to The data directory.. /// @@ -141,6 +195,15 @@ internal static string DataDirDescription { } } + /// + /// Looks up a localized string similar to A previous migration called '{0}' was already applied to the target database. If you meant to re-scaffold '{0}', revert it by running 'Update-Database -TargetMigration {1}', then delete '{2}' and run 'Add-Migration {0}' again.. + /// + internal static string DidYouMeanToRescaffold { + get { + return ResourceManager.GetString("DidYouMeanToRescaffold", resourceCulture); + } + } + /// /// Looks up a localized string similar to Entity Framework Command-line Tools. /// @@ -186,6 +249,33 @@ internal static string EntityFrameworkNotFound { } } + /// + /// Looks up a localized string similar to Retrieving migrations that have been applied to the target database.. + /// + internal static string GetMigrationsCommand_Intro { + get { + return ResourceManager.GetString("GetMigrationsCommand_Intro", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to No migrations have been applied to the target database.. + /// + internal static string GetMigrationsCommand_NoHistory { + get { + return ResourceManager.GetString("GetMigrationsCommand_NoHistory", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Scaffolds an empty migration ignoring any pending changes detected in the current model. This can be used to create an initial, empty migration to enable Migrations for an existing database. N.B. Doing this assumes that the target database schema is compatible with the current model.. + /// + internal static string IgnoreChangesDescription { + get { + return ResourceManager.GetString("IgnoreChangesDescription", resourceCulture); + } + } + /// /// Looks up a localized string similar to Show JSON output.. /// @@ -204,6 +294,33 @@ internal static string LanguageDescription { } } + /// + /// Looks up a localized string similar to Specifies the name of the custom script.. + /// + internal static string MigrationNameDescription { + get { + return ResourceManager.GetString("MigrationNameDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Scaffolds a migration script for any pending model changes.. + /// + internal static string MigrationsAddDescription { + get { + return ResourceManager.GetString("MigrationsAddDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Specifies that the migration user code be overwritten when re-scaffolding an existing migration.. + /// + internal static string MigrationsAddForceDescription { + get { + return ResourceManager.GetString("MigrationsAddForceDescription", resourceCulture); + } + } + /// /// Looks up a localized string similar to Migrations have already been enabled in project '{0}'. To overwrite the existing migrations configuration, use the -Force parameter.. /// @@ -213,6 +330,15 @@ internal static string MigrationsAlreadyEnabled { } } + /// + /// Looks up a localized string similar to Specifies the migrations configuration to use. If omitted, migrations will attempt to locate a single migrations configuration type in the target project.. + /// + internal static string MigrationsConfigDescription { + get { + return ResourceManager.GetString("MigrationsConfigDescription", resourceCulture); + } + } + /// /// Looks up a localized string similar to Commands to manage migrations.. /// @@ -267,6 +393,24 @@ internal static string MigrationsEnableForceDescription { } } + /// + /// Looks up a localized string similar to Displays the migrations that have been applied to the target database.. + /// + internal static string MigrationsListDescription { + get { + return ResourceManager.GetString("MigrationsListDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Missing required argument '{0}'.. + /// + internal static string MissingArgument { + get { + return ResourceManager.GetString("MissingArgument", resourceCulture); + } + } + /// /// Looks up a localized string similar to Missing required option '--{0}'.. /// @@ -312,6 +456,24 @@ internal static string ProjectDirDescription { } } + /// + /// Looks up a localized string similar to Re-scaffolding migration '{0}'.. + /// + internal static string RescaffoldingMigration { + get { + return ResourceManager.GetString("RescaffoldingMigration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Only the Designer Code for migration '{0}' was re-scaffolded. To re-scaffold the entire migration, use the -Force parameter.. + /// + internal static string RescaffoldNoForce { + get { + return ResourceManager.GetString("RescaffoldNoForce", resourceCulture); + } + } + /// /// Looks up a localized string similar to The root namespace. Defaults to the target assembly name.. /// @@ -321,6 +483,33 @@ internal static string RootNamespaceDescription { } } + /// + /// Looks up a localized string similar to Scaffolding migration '{0}'.. + /// + internal static string ScaffoldingMigration { + get { + return ResourceManager.GetString("ScaffoldingMigration", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration {0}' again.. + /// + internal static string SnapshotBehindWarning { + get { + return ResourceManager.GetString("SnapshotBehindWarning", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Specify the '-Verbose' flag to view the SQL statements being applied to the target database.. + /// + internal static string UpdateDatabaseCommand_VerboseInstructions { + get { + return ResourceManager.GetString("UpdateDatabaseCommand_VerboseInstructions", resourceCulture); + } + } + /// /// Looks up a localized string similar to Show verbose output.. /// diff --git a/src/ef6/Properties/Resources.resx b/src/ef6/Properties/Resources.resx index f14e9e55d9..bc60b49a74 100644 --- a/src/ef6/Properties/Resources.resx +++ b/src/ef6/Properties/Resources.resx @@ -120,6 +120,9 @@ The assembly to use. + + You can use the Add-Migration command to write the pending model changes to a code-based migration. + Specifies the configuration file to use for named connection strings. @@ -141,9 +144,27 @@ Commands to manage the database. + + Applies any pending migrations to the database. + + + Specifies that data loss is acceptable during automatic migration of the database. + + + Generate a SQL script rather than executing the pending changes directly. + + + Only valid with --script. Specifies the name of a particular migration to use as the update's starting point. If omitted, the last applied migration in the database will be used. + + + Specifies the name of a particular migration to update the database to. If omitted, the current model will be used. + The data directory. + + A previous migration called '{0}' was already applied to the target database. If you meant to re-scaffold '{0}', revert it by running 'Update-Database -TargetMigration {1}', then delete '{2}' and run 'Add-Migration {0}' again. + Entity Framework Command-line Tools @@ -159,15 +180,36 @@ Your target project '{0}' doesn't reference EntityFramework. This package is required for the Entity Framework Core Tools to work. Ensure your target project is correct, install the package, and try again. + + Retrieving migrations that have been applied to the target database. + + + No migrations have been applied to the target database. + + + Scaffolds an empty migration ignoring any pending changes detected in the current model. This can be used to create an initial, empty migration to enable Migrations for an existing database. N.B. Doing this assumes that the target database schema is compatible with the current model. + Show JSON output. The language. Defaults to 'C#'. + + Specifies the name of the custom script. + + + Scaffolds a migration script for any pending model changes. + + + Specifies that the migration user code be overwritten when re-scaffolding an existing migration. + Migrations have already been enabled in project '{0}'. To overwrite the existing migrations configuration, use the -Force parameter. + + Specifies the migrations configuration to use. If omitted, migrations will attempt to locate a single migrations configuration type in the target project. + Commands to manage migrations. @@ -186,6 +228,12 @@ Specifies that the migrations configuration be overwritten when running more than once for a given project. + + Displays the migrations that have been applied to the target database. + + + Missing required argument '{0}'. + Missing required option '--{0}'. @@ -201,9 +249,24 @@ The project directory. Defaults to the current directory. + + Re-scaffolding migration '{0}'. + + + Only the Designer Code for migration '{0}' was re-scaffolded. To re-scaffold the entire migration, use the -Force parameter. + The root namespace. Defaults to the target assembly name. + + Scaffolding migration '{0}'. + + + The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration {0}' again. + + + Specify the '-Verbose' flag to view the SQL statements being applied to the target database. + Show verbose output. diff --git a/test/EntityFramework/FunctionalTests/Migrations/ToolingScenarios.cs b/test/EntityFramework/FunctionalTests/Migrations/ToolingScenarios.cs deleted file mode 100644 index 5bffa84a82..0000000000 --- a/test/EntityFramework/FunctionalTests/Migrations/ToolingScenarios.cs +++ /dev/null @@ -1,507 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace System.Data.Entity.Migrations -{ - using System.CodeDom.Compiler; - using System.Collections.Generic; - using System.Data.Entity.Functionals.Utilities; - using System.Data.Entity.Migrations.Design; - using System.Data.Entity.Migrations.Infrastructure; - using System.Data.Entity.SqlServer; - using System.IO; - using System.Linq; - using System.Text; - using Microsoft.CSharp; - using Xunit; - - [Variant(DatabaseProvider.SqlClient, ProgrammingLanguage.CSharp)] - public class ToolingScenarios : DbTestCase, IClassFixture - { - private string _projectDir; - private string _contextDir; - - [MigrationsTheory(SlowGroup = TestGroup.MigrationsTests, Skip = "Fails when delay signed")] - public void Can_update() - { - ResetDatabase(); - - var logBuilder = new StringBuilder(); - - using (var facade = new ToolingFacade( - "ClassLibrary1", - "ContextLibrary1", - "ClassLibrary1.Configuration", - _projectDir, - Path.Combine(_projectDir, "App.config"), - null, - null)) - { - facade.LogInfoDelegate = m => logBuilder.AppendLine("INFO: " + m); - facade.LogVerboseDelegate = s => logBuilder.AppendLine("SQL: " + s); - - facade.Update(null, false); - } - - var log = logBuilder.ToString(); - Assert.True(log.Contains("INFO: Applying automatic migration")); - Assert.True(log.Contains("SQL: CREATE TABLE [dbo].[Entities]")); - - Assert.True(DatabaseExists()); - Assert.True(TableExists("Entities")); - } - - [MigrationsTheory(SlowGroup = TestGroup.MigrationsTests, Skip = "Fails when delay signed")] - public void Can_script_update() - { - ResetDatabase(); - - var logBuilder = new StringBuilder(); - string sql; - - using (var facade = new ToolingFacade( - "ClassLibrary1", - "ContextLibrary1", - "ClassLibrary1.Configuration", - _projectDir, - Path.Combine(_projectDir, "App.config"), - null, - null)) - { - facade.LogInfoDelegate = m => logBuilder.AppendLine("INFO: " + m); - - sql = facade.ScriptUpdate(null, null, false); - } - - Assert.True(sql.Contains("CREATE TABLE [dbo].[Entities]")); - - var log = logBuilder.ToString(); - Assert.True(log.Contains("INFO: Applying automatic migration")); - } - - [MigrationsTheory(Skip = "Fails when delay signed")] - public void Can_get_context_types() - { - ResetDatabase(); - - using (var facade = new ToolingFacade( - "ClassLibrary1", - "ContextLibrary1", - configurationTypeName: null, - workingDirectory: _contextDir, - configurationFilePath: null, - dataDirectory: null, - connectionStringInfo: null)) - { - var result = facade.GetContextTypes(); - - Assert.Equal(1, result.Count()); - Assert.Equal("ContextLibrary1.Context", result.First()); - } - } - - [MigrationsTheory(Skip = "Fails when delay signed")] - public void Can_get_context_type() - { - ResetDatabase(); - - using (var facade = new ToolingFacade( - "ClassLibrary1", - "ContextLibrary1", - configurationTypeName: null, - workingDirectory: _contextDir, - configurationFilePath: null, - dataDirectory: null, - connectionStringInfo: null)) - { - var result = facade.GetContextType(null); - - Assert.Equal("ContextLibrary1.Context", result); - } - } - - [MigrationsTheory(Skip = "Fails when delay signed")] - public void Can_get_context_type_by_name() - { - ResetDatabase(); - - using (var facade = new ToolingFacade( - "ClassLibrary1", - "ContextLibrary1", - configurationTypeName: null, - workingDirectory: _contextDir, - configurationFilePath: null, - dataDirectory: null, - connectionStringInfo: null)) - { - var result = facade.GetContextType("Context"); - - Assert.Equal("ContextLibrary1.Context", result); - } - } - - [MigrationsTheory(Skip = "Fails when delay signed")] - public void Can_get_context_type_by_qualified_name() - { - ResetDatabase(); - - using (var facade = new ToolingFacade( - "ClassLibrary1", - "ContextLibrary1", - configurationTypeName: null, - workingDirectory: _contextDir, - configurationFilePath: null, - dataDirectory: null, - connectionStringInfo: null)) - { - var result = facade.GetContextType("ContextLibrary1.Context"); - - Assert.Equal("ContextLibrary1.Context", result); - } - } - - [MigrationsTheory(Skip = "Fails when delay signed")] - public void Throws_when_context_type_not_found() - { - ResetDatabase(); - - using (var facade = new ToolingFacade( - "ClassLibrary1", - "ContextLibrary1", - configurationTypeName: null, - workingDirectory: _contextDir, - configurationFilePath: null, - dataDirectory: null, - connectionStringInfo: null)) - { - Assert.Throws(() => facade.GetContextType("MissingContext")); - } - } - - [MigrationsTheory(Skip = "Fails when delay signed")] - public void Can_still_scaffold_generic_context_by_specifying_name_directly() - { - ResetDatabase(); - - using (var facade = new ToolingFacade( - "ClassLibrary1", - "ContextLibrary1", - configurationTypeName: null, - workingDirectory: _contextDir, - configurationFilePath: null, - dataDirectory: null, - connectionStringInfo: null)) - { - var result = facade.GetContextType("GenericContext`1"); - Assert.Equal("ContextLibrary1.GenericContext`1", result); - } - } - - [MigrationsTheory(Skip = "Fails when delay signed")] - public void Can_still_scaffold_abstract_context_by_specifying_name_directly() - { - ResetDatabase(); - - using (var facade = new ToolingFacade( - "ClassLibrary1", - "ContextLibrary1", - configurationTypeName: null, - workingDirectory: _contextDir, - configurationFilePath: null, - dataDirectory: null, - connectionStringInfo: null)) - { - var result = facade.GetContextType("AbstractContext"); - Assert.Equal("ContextLibrary1.AbstractContext", result); - } - } - - [MigrationsTheory(SlowGroup = TestGroup.MigrationsTests, Skip = "Fails when delay signed")] - public void Can_scaffold_initial_create() - { - ResetDatabase(); - - var migrator = CreateMigrator(); - - var initialCreate = new MigrationScaffolder(migrator.Configuration).Scaffold("InitialCreate"); - - migrator = CreateMigrator(scaffoldedMigrations: initialCreate, contextKey: "ContextLibrary1.Context"); - - migrator.Update(); - - using (var facade = new ToolingFacade( - "ClassLibrary1", - "ContextLibrary1", - "ClassLibrary1.Configuration", - _projectDir, - Path.Combine(_projectDir, "App.config"), - null, - null)) - { - var scaffoldedMigration = facade.ScaffoldInitialCreate("cs", "ClassLibrary1"); - - Assert.True(scaffoldedMigration.DesignerCode.Length > 500); - Assert.Equal("cs", scaffoldedMigration.Language); - Assert.True(scaffoldedMigration.MigrationId.EndsWith("_InitialCreate")); - Assert.True(scaffoldedMigration.UserCode.Length > 500); - } - } - - [MigrationsTheory(SlowGroup = TestGroup.MigrationsTests, Skip = "Fails when delay signed")] - public void Can_scaffold_empty() - { - using (var facade = new ToolingFacade( - "ClassLibrary1", - "ContextLibrary1", - "ClassLibrary1.Configuration", - _projectDir, - Path.Combine(_projectDir, "App.config"), - null, - null)) - { - var scaffoldedMigration = facade.Scaffold("Create", "cs", "ClassLibrary1", ignoreChanges: true); - - Assert.True(scaffoldedMigration.DesignerCode.Length > 500); - Assert.Equal("cs", scaffoldedMigration.Language); - Assert.True(scaffoldedMigration.MigrationId.EndsWith("_Create")); - Assert.True(scaffoldedMigration.UserCode.Length < 300); - } - } - - [MigrationsTheory(Skip = "Fails when delay signed")] - public void Can_scaffold() - { - ResetDatabase(); - - using (var facade = new ToolingFacade( - "ClassLibrary1", - "ContextLibrary1", - "ClassLibrary1.Configuration", - _projectDir, - Path.Combine(_projectDir, "App.config"), - null, - null)) - { - var scaffoldedMigration = facade.Scaffold("Create", "cs", "ClassLibrary1", ignoreChanges: false); - - Assert.True(scaffoldedMigration.DesignerCode.Length > 500); - Assert.Equal("cs", scaffoldedMigration.Language); - Assert.True(scaffoldedMigration.MigrationId.EndsWith("_Create")); - Assert.True(scaffoldedMigration.UserCode.Length > 500); - } - } - - [MigrationsTheory(SlowGroup = TestGroup.MigrationsTests, Skip = "Fails when delay signed")] - public void Can_scaffold_vb() - { - ResetDatabase(); - - using (var facade = new ToolingFacade( - "ClassLibrary1", - "ContextLibrary1", - "ClassLibrary1.Configuration", - _projectDir, - Path.Combine(_projectDir, "App.config"), - null, - null)) - { - var scaffoldedMigration = facade.Scaffold("Create", "vb", "ClassLibrary1", ignoreChanges: false); - - Assert.True(scaffoldedMigration.DesignerCode.Length > 500); - Assert.Equal("vb", scaffoldedMigration.Language); - Assert.True(scaffoldedMigration.MigrationId.EndsWith("_Create")); - Assert.True(scaffoldedMigration.UserCode.Length > 500); - } - } - - [MigrationsTheory(Skip = "Fails when delay signed")] - public void Wraps_assembly_not_found_exceptions() - { - const string unknownAssemblyName = "UnknownAssembly"; - - using (var facade = new ToolingFacade( - unknownAssemblyName, - unknownAssemblyName, - "ClassLibrary1.Configuration", - _projectDir, - Path.Combine(_projectDir, "App.config"), - null, - null)) - { - Assert.Throws(() => facade.GetDatabaseMigrations()) - .ValidateMessage("ToolingFacade_AssemblyNotFound", unknownAssemblyName); - } - } - - public ToolingScenarios(DatabaseProviderFixture databaseProviderFixture, ToolingFixture data) - : base(databaseProviderFixture) - { - _projectDir = data.ProjectDir; - _contextDir = data.ContextDir; - } - } - - public class ToolingFixture : IDisposable - { - public string ProjectDir { get; private set; } - public string ContextDir { get; private set; } - - public ToolingFixture() - { - var contextDir = IOHelpers.GetTempDirName(); - CreateContextProject(contextDir); - - var targetDir = IOHelpers.GetTempDirName(); - CreateMigrationsProject(targetDir, contextDir); - AddAppConfig(targetDir); - - ProjectDir = targetDir; - ContextDir = contextDir; - } - - private static void AddAppConfig(string targetDir) - { - var configurationFile = Path.Combine(targetDir, "App.config"); - - File.WriteAllText( - configurationFile, - @" - - - - -"); - } - - private static void CreateContextProject(string targetDir) - { - CreateProject( - targetDir, "ContextLibrary1", new List(), - @"namespace ContextLibrary1 -{ - using System.Data.Entity; - - public class Context : DbContext - { - public Context() - : base(""Name=ClassLibrary1"") - { - } - - public DbSet Entities { get; set; } - } - - public class GenericContext : DbContext where TEntity : class - { - public GenericContext() - : base(""Name=ClassLibrary1"") - { - } - - public DbSet Entities { get; set; } - } - - public abstract class AbstractContext : DbContext - { - public AbstractContext() - : base(""Name=ClassLibrary1"") - { - } - - public DbSet Entities { get; set; } - } - - public class Entity - { - public int Id { get; set; } - public string Name { get; set; } - } -}"); - } - - private static void CreateMigrationsProject(string targetDir, string contextDir) - { - var contextPath = Path.Combine(contextDir, "ContextLibrary1.dll"); - IOHelpers.CopyToDir(contextPath, targetDir); - - CreateProject( - targetDir, "ClassLibrary1", new List { contextPath }, - @"namespace ClassLibrary1 -{ - using System.Data.Common; - using System.Data.Entity; - using System.Data.Entity.Migrations; - using System.Data.Entity.Migrations.History; - - public class Configuration : DbMigrationsConfiguration - { - public Configuration() - { - AutomaticMigrationsEnabled = true; - } - } - - public class CustomHistoryContext : HistoryContext - { - public CustomHistoryContext(DbConnection existingConnection, string defaultSchema) - : base(existingConnection, defaultSchema) - { - } - } -}"); - } - - private static void CreateProject(string targetDir, string targetName, List additionalAssemblies, string code) - { - var targetFileName = targetName + ".dll"; - var targetPath = Path.Combine(targetDir, targetFileName); - - var entityFrameworkPath = new Uri(typeof(DbContext).Assembly().CodeBase).LocalPath; - IOHelpers.CopyToDir(entityFrameworkPath, targetDir); - - var entityFrameworkSqlServerPath = new Uri(typeof(SqlProviderServices).Assembly().CodeBase).LocalPath; - IOHelpers.CopyToDir(entityFrameworkSqlServerPath, targetDir); - - using (var compiler = new CSharpCodeProvider()) - { - additionalAssemblies.AddRange( - new List - { - "System.dll", - "System.Data.dll", - "System.Core.dll", - "System.Data.Entity.dll", - entityFrameworkPath - }); - - var results = compiler.CompileAssemblyFromSource(new CompilerParameters(additionalAssemblies.ToArray(), targetPath), code); - - if (results.Errors.HasErrors) - { - throw new InvalidOperationException(results.Errors.Cast().First(e => !e.IsWarning).ToString()); - } - } - } - - public void Dispose() - { - if (ProjectDir != null - && Directory.Exists(ProjectDir)) - { - Directory.Delete(ProjectDir, true); - } - - if (ContextDir != null - && Directory.Exists(ContextDir)) - { - Directory.Delete(ContextDir, true); - } - } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/CommandLineArgumentInvalidExceptionTests.cs b/test/EntityFramework/UnitTests/CommandLine/CommandLineArgumentInvalidExceptionTests.cs deleted file mode 100644 index f14b03cb40..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/CommandLineArgumentInvalidExceptionTests.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine -{ - extern alias migrate; - using System.Data.Entity; - using Xunit; - - public class CommandLineArgumentInvalidExceptionTests - { - [Fact] // CodePlex 1107 - public void Deserialized_exception_can_be_serialized_and_deserialized_again() - { - var commandArg = new migrate::CmdLine.CommandArgument("/N:345", 7); - commandArg.Command = "N"; - - var ex = new migrate::CmdLine.CommandLineArgumentInvalidException( - typeof(CommandLineExceptionTests.SomeCommandLineClass), commandArg); - - Assert.Contains("/N:345", ex.Message); - - Assert.Contains( - "/N:345", - ExceptionHelpers.SerializeAndDeserialize(ExceptionHelpers.SerializeAndDeserialize(ex)).Message); - } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/CommandLineArgumentsAttributeTest.cs b/test/EntityFramework/UnitTests/CommandLine/CommandLineArgumentsAttributeTest.cs deleted file mode 100644 index 7184edd7f1..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/CommandLineArgumentsAttributeTest.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine.Tests -{ - extern alias migrate; - using System; - using Xunit; - - public class CommandLineArgumentsAttributeTest - { - [Fact] - public void GetShouldReturnCommandLineArgumentsAttribute() - { - var attribute = migrate::CmdLine.CommandLineArgumentsAttribute.Get(typeof(XCopyCommandArgs)); - Assert.NotNull(attribute); - Assert.Equal(XCopyCommandArgs.Title, attribute.Title); - Assert.Equal(XCopyCommandArgs.Description, attribute.Description); - } - - [Fact] - public void GetReturnsNullWhenNoAttribute() - { - var attribute = migrate::CmdLine.CommandLineArgumentsAttribute.Get(typeof(string)); - Assert.Null(attribute); - } - - [Fact] - public void GetThrowsArgumentNullWhenNull() - { - Assert.Equal( - "element", Assert.Throws(() => migrate::CmdLine.CommandLineArgumentsAttribute.Get(null)).ParamName); - } - - [Fact] - public void SettingTitleAndTitleResourceIdThrows() - { - var attribute = new migrate::CmdLine.CommandLineArgumentsAttribute - { - Title = "foo" - }; - - Assert.Equal( - migrate::System.Data.Entity.Migrations.Console.Resources.Strings.AmbiguousAttributeValues("Title", "TitleResourceId"), - Assert.Throws(() => attribute.TitleResourceId = "bar").Message); - } - - [Fact] - public void SettingTitleResourceIdAndTitleThrows() - { - var attribute = new migrate::CmdLine.CommandLineArgumentsAttribute - { - TitleResourceId = "foo" - }; - - Assert.Equal( - migrate::System.Data.Entity.Migrations.Console.Resources.Strings.AmbiguousAttributeValues("Title", "TitleResourceId"), - Assert.Throws(() => attribute.Title = "bar").Message); - } - - [Fact] - public void SettingDescriptionAndDescriptionResourceIdThrows() - { - var attribute = new migrate::CmdLine.CommandLineArgumentsAttribute - { - Description = "foo" - }; - - Assert.Equal( - migrate::System.Data.Entity.Migrations.Console.Resources.Strings.AmbiguousAttributeValues( - "Description", "DescriptionResourceId"), - Assert.Throws(() => attribute.DescriptionResourceId = "bar").Message); - } - - [Fact] - public void SettingDescriptionResourceIdAndDescriptionThrows() - { - var attribute = new migrate::CmdLine.CommandLineArgumentsAttribute - { - DescriptionResourceId = "foo" - }; - - Assert.Equal( - migrate::System.Data.Entity.Migrations.Console.Resources.Strings.AmbiguousAttributeValues( - "Description", "DescriptionResourceId"), - Assert.Throws(() => attribute.Description = "bar").Message); - } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/CommandLineExceptionTests.cs b/test/EntityFramework/UnitTests/CommandLine/CommandLineExceptionTests.cs deleted file mode 100644 index df8379c0bd..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/CommandLineExceptionTests.cs +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine -{ - extern alias migrate; - using System; - using System.Data.Entity; - using Xunit; - - public class CommandLineExceptionTests - { - [Fact] - public void Constructors_allow_for_nulls_message_and_inner_exception() - { - Assert.Contains("CmdLine.CommandLineException", new migrate::CmdLine.CommandLineException((string)null).Message); - Assert.Null( - new migrate::CmdLine.CommandLineException( - new migrate::CmdLine.CommandArgumentHelp(typeof(SomeCommandLineClass)), null).InnerException); - } - - [Fact] - public void Constructors_throw_when_given_null_CommandArgumentHelp() - { - Assert.Equal( - "argumentHelp", - Assert.Throws( - () => new migrate::CmdLine.CommandLineException((migrate::CmdLine.CommandArgumentHelp)null)).ParamName); - - Assert.Equal( - "argumentHelp", - Assert.Throws( - () => new migrate::CmdLine.CommandLineException(null, new Exception())).ParamName); - } - - [Fact] - public void Constructor_uses_given_message_and_sets_up_serialization() - { - var exception = new migrate::CmdLine.CommandLineException("I'm a DOS prompt."); - - Assert.Equal("I'm a DOS prompt.", exception.Message); - Assert.Null(exception.ArgumentHelp); - - exception = ExceptionHelpers.SerializeAndDeserialize(exception); - - Assert.Equal("I'm a DOS prompt.", exception.Message); - Assert.Null(exception.ArgumentHelp); - } - - [Fact] - public void Constructor_uses_given_ArgumentHelp_and_sets_up_serialization() - { - var exception = - new migrate::CmdLine.CommandLineException( - new migrate::CmdLine.CommandArgumentHelp(typeof(SomeCommandLineClass), "CLI")); - - Assert.Equal("CLI", exception.Message); - Assert.Equal("Code First Migrations Command Line Utility", exception.ArgumentHelp.Title); - - exception = ExceptionHelpers.SerializeAndDeserialize(exception); - - Assert.Equal("CLI", exception.Message); - Assert.Equal("Code First Migrations Command Line Utility", exception.ArgumentHelp.Title); - } - - [Fact] - public void Constructor_uses_given_ArgumentHelp_and_inner_exception_and_sets_up_serialization() - { - var innerException = new Exception("You are so exceptional!"); - var exception = - new migrate::CmdLine.CommandLineException( - new migrate::CmdLine.CommandArgumentHelp(typeof(SomeCommandLineClass), "Look inside."), innerException); - - Assert.Equal("Look inside.", exception.Message); - Assert.Same(innerException, exception.InnerException); - Assert.Equal("Code First Migrations Command Line Utility", exception.ArgumentHelp.Title); - - exception = ExceptionHelpers.SerializeAndDeserialize(exception); - - Assert.Equal("Look inside.", exception.Message); - Assert.Equal(innerException.Message, exception.InnerException.Message); - Assert.Equal("Code First Migrations Command Line Utility", exception.ArgumentHelp.Title); - } - - [Fact] // CodePlex 1107 - public void Deserialized_exception_can_be_serialized_and_deserialized_again() - { - var innerException = new Exception("You are so exceptional!"); - var exception = - new migrate::CmdLine.CommandLineException( - new migrate::CmdLine.CommandArgumentHelp(typeof(SomeCommandLineClass), "Look inside."), innerException); - - exception = ExceptionHelpers.SerializeAndDeserialize(ExceptionHelpers.SerializeAndDeserialize(exception)); - - Assert.Equal("Look inside.", exception.Message); - Assert.Equal(innerException.Message, exception.InnerException.Message); - Assert.Equal("Code First Migrations Command Line Utility", exception.ArgumentHelp.Title); - } - - [Fact] - public void ArgumentHelp_can_be_read_and_set() - { - var argHelp = new migrate::CmdLine.CommandArgumentHelp(typeof(SomeCommandLineClass)); - Assert.Same( - argHelp, new migrate::CmdLine.CommandLineException("") - { - ArgumentHelp = argHelp - }.ArgumentHelp); - } - - [migrate::CmdLine.CommandLineArgumentsAttribute( - Program = "migrate", - TitleResourceId = migrate::System.Data.Entity.Migrations.Console.Resources.EntityRes.MigrateTitle, - DescriptionResourceId = migrate::System.Data.Entity.Migrations.Console.Resources.EntityRes.MigrateDescription)] - public class SomeCommandLineClass - { - } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/CommandLineParameterAttributeTests.cs b/test/EntityFramework/UnitTests/CommandLine/CommandLineParameterAttributeTests.cs deleted file mode 100644 index b9e7357807..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/CommandLineParameterAttributeTests.cs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine.Tests -{ - extern alias migrate; - using System; - using Xunit; - - public class CommandLineParameterAttributeTests - { - [Fact] - public void SettingNameAndNameResourceIdThrows() - { - var attribute = new migrate::CmdLine.CommandLineParameterAttribute - { - Name = "foo" - }; - - Assert.Equal( - migrate::System.Data.Entity.Migrations.Console.Resources.Strings.AmbiguousAttributeValues("Name", "NameResourceId"), - Assert.Throws(() => attribute.NameResourceId = "bar").Message); - } - - [Fact] - public void SettingNameResourceIdAndNameThrows() - { - var attribute = new migrate::CmdLine.CommandLineParameterAttribute - { - NameResourceId = "foo" - }; - - Assert.Equal( - migrate::System.Data.Entity.Migrations.Console.Resources.Strings.AmbiguousAttributeValues("Name", "NameResourceId"), - Assert.Throws(() => attribute.Name = "bar").Message); - } - - [Fact] - public void SettingDescriptionAndDescriptionResourceIdThrows() - { - var attribute = new migrate::CmdLine.CommandLineParameterAttribute - { - Description = "foo" - }; - - Assert.Equal( - migrate::System.Data.Entity.Migrations.Console.Resources.Strings.AmbiguousAttributeValues( - "Description", "DescriptionResourceId"), - Assert.Throws(() => attribute.DescriptionResourceId = "bar").Message); - } - - [Fact] - public void SettingDescriptionResourceIdAndDescriptionThrows() - { - var attribute = new migrate::CmdLine.CommandLineParameterAttribute - { - DescriptionResourceId = "foo" - }; - - Assert.Equal( - migrate::System.Data.Entity.Migrations.Console.Resources.Strings.AmbiguousAttributeValues( - "Description", "DescriptionResourceId"), - Assert.Throws(() => attribute.Description = "bar").Message); - } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/CommandLineRequiredArgumentMissingExceptionTests.cs b/test/EntityFramework/UnitTests/CommandLine/CommandLineRequiredArgumentMissingExceptionTests.cs deleted file mode 100644 index fe39305e6e..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/CommandLineRequiredArgumentMissingExceptionTests.cs +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine -{ - extern alias migrate; - using System.Data.Entity; - using Xunit; - - public class CommandLineRequiredArgumentMissingExceptionTests - { - [Fact] // CodePlex 1107 - public void Deserialized_exception_can_be_serialized_and_deserialized_again() - { - var commandArg = new migrate::CmdLine.CommandArgument("/N:345", 7); - commandArg.Command = "N"; - - var ex = new migrate::CmdLine.CommandLineRequiredArgumentMissingException( - typeof(CommandLineExceptionTests.SomeCommandLineClass), "/N:345", 7); - - Assert.Contains("/N:345", ex.Message); - - Assert.Contains( - "/N:345", - ExceptionHelpers.SerializeAndDeserialize(ExceptionHelpers.SerializeAndDeserialize(ex)).Message); - } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/CommandLineTest.cs b/test/EntityFramework/UnitTests/CommandLine/CommandLineTest.cs deleted file mode 100644 index eb295eaa7f..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/CommandLineTest.cs +++ /dev/null @@ -1,399 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine.Tests -{ - extern alias migrate; - using System; - using System.Collections.Generic; - using System.Data.Entity.TestHelpers; - using System.Linq; - using System.Reflection; - using Xunit; - - public class CommandLineTest - { - [Fact] - public void CommandLineTokenizesQuestionMarkSwitches() - { - var args = new[] { "/?" }; - - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args); - - var tokens = migrate::CmdLine.CommandLine.Tokenize(); - - Assert.Equal(1, migrate::CmdLine.CommandLine.Args.Length); - Assert.Equal(1, migrate::CmdLine.CommandLine.GetSwitches(tokens).Count); - Assert.Equal(0, migrate::CmdLine.CommandLine.GetParameters(tokens).Count); - Assert.True(tokens[0].IsCommand()); - Assert.Equal("?", tokens[0].Command); - } - - [Fact] - public void CommandLineTokenizesSwitchesAndParameters() - { - var args = new[] - { - "C:\\Foo And Bar\\Some Long File.txt", "/1:Test", "-2:Some Quoted Arg", "/3=Arg with in it", "/Y-", - "And another", - "Another", "One", "Word", "Args" - }; - - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args); - - var tokens = migrate::CmdLine.CommandLine.Tokenize(); - - Assert.Equal(10, migrate::CmdLine.CommandLine.Args.Length); - Assert.Equal(4, migrate::CmdLine.CommandLine.GetSwitches(tokens).Count); - Assert.Equal(6, migrate::CmdLine.CommandLine.GetParameters(tokens).Count); - Assert.True(tokens[0].IsParameter()); - Assert.True(tokens[1].IsCommand()); - Assert.True(tokens[2].IsCommand()); - Assert.True(tokens[3].IsCommand()); - Assert.True(tokens[4].IsCommand()); - Assert.True(tokens[5].IsParameter()); - Assert.True(tokens[6].IsParameter()); - Assert.True(tokens[7].IsParameter()); - Assert.True(tokens[8].IsParameter()); - Assert.True(tokens[9].IsParameter()); - - for (var i = 0; i < args.Length; i++) - { - Assert.Equal(args[i], tokens[i].Token); - } - } - - [Fact] - public void ParseDoesNotThrowWhenNullCommandLine() - { - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(); - migrate::CmdLine.CommandLine.Parse(); - } - - [Fact] - public void MissingRequiredSwitchArgShouldThrow() - { - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(); - Assert.Equal( - new migrate::CmdLine.CommandLineRequiredArgumentMissingException(typeof(string), "N", -1).Message, - Assert.Throws( - () => migrate::CmdLine.CommandLine.Parse()).Message); - } - - [Fact] - public void AttributeWithNoCommandNameShouldUsePropertyName() - { - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment("/b1-"); - var actual = migrate::CmdLine.CommandLine.Parse(); - Assert.False(actual.b1); - } - - [Fact] - public void MissingRequiredPositionArgShouldThrow() - { - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(); - Assert.Equal( - new migrate::CmdLine.CommandLineRequiredArgumentMissingException(typeof(string), "String 1", 1).Message, - Assert.Throws( - () => migrate::CmdLine.CommandLine.Parse()).Message); - } - - [Fact] - public void DuplicateArgsShouldThrow() - { - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment("/N:123 /N:345"); - - var commandArg = new migrate::CmdLine.CommandArgument("/N:345", 7); - commandArg.Command = "N"; - Assert.Equal( - new migrate::CmdLine.CommandLineArgumentInvalidException(typeof(string), commandArg).Message, - Assert.Throws(() => migrate::CmdLine.CommandLine.Parse()). - Message); - } - - [Fact] - public void DuplicateArgsWithListShouldNotThrow() - { - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment("/N:123 /N:345"); - var actual = migrate::CmdLine.CommandLine.Parse(); - Assert.Equal(2, actual.NList.Count); - Assert.Equal("123", actual.NList[0]); - Assert.Equal("345", actual.NList[1]); - } - - [Fact] - public void DefaultArgsAreApplied() - { - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment("/n:123"); - var target = migrate::CmdLine.CommandLine.Parse(); - - Assert.True(target.BoolT); - Assert.False(target.BoolY); - Assert.Equal(TestArgs.StringArgDefault, target.StringArg); - } - - /// - /// Verifies that you can use alternate seperators - /// - [Fact] - public void CommandLineTokenizesWithAlternateSwitchChars() - { - var args = new[] - { - "C:\\Foo And Bar\\Some Long File.txt", "~1|Test", "~2|Some Quoted Arg", "~3|Arg with in it", "_Y-", - "And another", - "Another", "One", "Word", "Args" - }; - - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args); - - // Save the seperators since they are static members - var oldSep = migrate::CmdLine.CommandLine.CommandSeparators; - var oldValueSep = migrate::CmdLine.CommandLine.ValueSeparators; - - migrate::CmdLine.CommandLine.CommandSeparators = new List - { - "~", - "_" - }; - migrate::CmdLine.CommandLine.ValueSeparators = new List - { - "|" - }; - - var tokens = migrate::CmdLine.CommandLine.Tokenize(); - - // Restore the seperators - migrate::CmdLine.CommandLine.CommandSeparators = oldSep; - migrate::CmdLine.CommandLine.ValueSeparators = oldValueSep; - - Assert.Equal(10, migrate::CmdLine.CommandLine.Args.Length); - Assert.Equal(4, migrate::CmdLine.CommandLine.GetSwitches(tokens).Count); - Assert.Equal(6, migrate::CmdLine.CommandLine.GetParameters(tokens).Count); - Assert.True(tokens[0].IsParameter()); - Assert.True(tokens[1].IsCommand()); - Assert.True(tokens[2].IsCommand()); - Assert.True(tokens[3].IsCommand()); - Assert.True(tokens[4].IsCommand()); - Assert.True(tokens[5].IsParameter()); - Assert.True(tokens[6].IsParameter()); - Assert.True(tokens[7].IsParameter()); - Assert.True(tokens[8].IsParameter()); - Assert.True(tokens[9].IsParameter()); - - for (var i = 0; i < args.Length; i++) - { - Assert.Equal(args[i], tokens[i].Token); - } - } - - /// - /// Verifies positional args work - /// - [Fact] - public void PositionalArgsAreApplied() - { - var args = new[] - { - @"D:\Documents and Settings\MY.USERNAME\My Documents\*", @"E:\MYBACKUP\My Documents\", "/A", - @"/EXCLUDE:SomeQuoted String" - , "/I", "/D:7-8-2011" - }; - - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args); - var xcopyCommand = migrate::CmdLine.CommandLine.Parse(); - - Assert.NotNull(xcopyCommand); - Assert.Equal(args[0], xcopyCommand.Source); - Assert.Equal(args[1], xcopyCommand.Destination); - Assert.Equal("SomeQuoted String", xcopyCommand.ExcludeFiles); - Assert.True(xcopyCommand.ArchivedBit); - Assert.True(xcopyCommand.InferDirectory); - Assert.Equal(DateTime.Parse("7-8-2011"), xcopyCommand.ChangedAfterDate); - } - - [Fact] - public void EmbeddedSeparatorsDoNotCountAsSwitch() - { - var args = new[] { "/S:Value/With:Separators", "/Y-", "/t", "/N:123" }; - - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args); - - var actual = migrate::CmdLine.CommandLine.Parse(); - - Assert.Equal("Value/With:Separators", actual.StringArg); - Assert.True(actual.BoolT); - Assert.False(actual.BoolY); - } - - [Fact] - public void CaseSensitiveAllowsUpperAndLowerWithSameSwitch() - { - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment("/t:lower /T:UPPER /y /Y-"); - var oldValue = migrate::CmdLine.CommandLine.CaseSensitive; - migrate::CmdLine.CommandLine.CaseSensitive = true; - - var actual = migrate::CmdLine.CommandLine.Parse(); - - migrate::CmdLine.CommandLine.CaseSensitive = oldValue; - - Assert.Equal("lower", actual.Lower); - Assert.Equal("UPPER", actual.Upper); - Assert.True(actual.YLower); - Assert.False(actual.YUpper); - } - - [Fact] - public void NoMatchingPropertyShouldThrow() - { - var args = new[] { "/?" }; - - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args); - - try - { - migrate::CmdLine.CommandLine.Parse(); - Assert.True(false, "Parse did not throw an exception"); - } - catch (migrate::CmdLine.CommandLineArgumentInvalidException exception) - { - Assert.NotNull(exception.ArgumentHelp); - Assert.Equal(4, exception.ArgumentHelp.ValidArguments.Count()); - } - } - - [Fact] - public void NoMatchingPropertyWithInferredShouldThrow() - { - var args = new[] { "/NoMatch" }; - - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args); - - var commandArg = new migrate::CmdLine.CommandArgument("/NoMatch", 0); - commandArg.Command = "NoMatch"; - Assert.Equal( - new migrate::CmdLine.CommandLineArgumentInvalidException(typeof(string), commandArg).Message, - Assert.Throws( - () => migrate::CmdLine.CommandLine.Parse()).Message); - } - - [Fact] - public void TwoPropsWithSameSwitchShouldThrow() - { - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(); - Assert.Equal( - new migrate::CmdLine.CommandLineException("Duplicate Command \"B\"").Message, - Assert.Throws(() => migrate::CmdLine.CommandLine.Parse()). - Message); - } - - [Fact] - public void WhenNoAttributesParseWillUsePropertyNames() - { - var args = new[] { "/StringArg:Value/With:Separators", "/BoolY-", "/BoolT", "/Date:12-1-2011", "/Number:23" }; - - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(args); - - var actual = migrate::CmdLine.CommandLine.Parse(); - - Assert.Equal("Value/With:Separators", actual.StringArg); - Assert.True(actual.BoolT); - Assert.False(actual.BoolY); - Assert.Equal(DateTime.Parse("12-1-2011"), actual.Date); - Assert.Equal(23, actual.Number); - } - - [Fact] - public void WhenNoPositionOneShouldThrow() - { - if (LocalizationTestHelpers.IsEnglishLocale()) - { - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(); - Assert.Equal( - new migrate::CmdLine.CommandLineException( - "Out of order parameter \"source\" should have be at parameter index 1 but was found at 2").Message, - Assert.Throws(() => migrate::CmdLine.CommandLine.Parse()). - Message); - } - } - - [Fact] - public void WhenNoPositionTwoShouldThrow() - { - if (LocalizationTestHelpers.IsEnglishLocale()) - { - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(); - Assert.Equal( - new migrate::CmdLine.CommandLineException( - "Out of order parameter \"destination\" should have be at parameter index 2 but was found at 3"). - Message, - Assert.Throws(() => migrate::CmdLine.CommandLine.Parse()). - Message); - } - } - - [Fact] - public void WhenDuplicatePositionShouldThrow() - { - if (LocalizationTestHelpers.IsEnglishLocale()) - { - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(); - Assert.Equal( - new migrate::CmdLine.CommandLineException("Duplicate Parameter Index [1] on Property \"S2\"").Message, - Assert.Throws( - () => migrate::CmdLine.CommandLine.Parse()).Message); - } - } - - [Fact] - public void WhenBadParameterIndexShouldThrow() - { - if (LocalizationTestHelpers.IsEnglishLocale()) - { - migrate::CmdLine.CommandLine.CommandEnvironment = new TestCommandEnvironment(); - Assert.Equal( - new CustomAttributeFormatException("'ParameterIndex' property specified was not found.").Message, - Assert.Throws(() => migrate::CmdLine.CommandLine.Parse()).Message); - } - } - } - - public class TestArgsWithList - { - [migrate::CmdLine.CommandLineParameterAttribute(Command = "N")] - public List NList { get; set; } - } - - public class TypeWithUpperAndLower - { - [migrate::CmdLine.CommandLineParameterAttribute("t")] - public string Lower { get; set; } - - [migrate::CmdLine.CommandLineParameterAttribute("T")] - public string Upper { get; set; } - - [migrate::CmdLine.CommandLineParameterAttribute("y")] - public bool YLower { get; set; } - - [migrate::CmdLine.CommandLineParameterAttribute("Y")] - public bool YUpper { get; set; } - } - - public class TypeWithBadParamIndex - { - [migrate::CmdLine.CommandLineParameterAttribute(ParameterIndex = -1)] - public string S1 { get; set; } - } - - public class TypeWithDuplicateParamIndex - { - [migrate::CmdLine.CommandLineParameterAttribute(ParameterIndex = 1)] - public string S1 { get; set; } - - [migrate::CmdLine.CommandLineParameterAttribute(ParameterIndex = 1)] - public string S2 { get; set; } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/CommandLineWriteLineColorTests.cs b/test/EntityFramework/UnitTests/CommandLine/CommandLineWriteLineColorTests.cs deleted file mode 100644 index adb82a3ad3..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/CommandLineWriteLineColorTests.cs +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace System.Data.Entity.CommandLine -{ - extern alias migrate; - using Xunit; - - public class CommandLineWriteLineColorTests - { - [Fact] // CodePlex 1950 - public void WriteLineColor_can_write_text_with_replacement_tokens() - { - var noParamsText = ""; - var paramsText = ""; - - migrate::CmdLine.CommandLine.WriteLineColor( - s => noParamsText = s, - (s, p) => paramsText = s + p[0], - ConsoleColor.Cyan, - "Some Text "); - - Assert.Equal("Some Text ", noParamsText); - Assert.Equal("", paramsText); - } - - [Fact] // CodePlex 1950 - public void WriteLineColor_can_write_text_with_replacement_tokens_when_replacement_args_exist() - { - var noParamsText = ""; - var paramsText = ""; - - migrate::CmdLine.CommandLine.WriteLineColor( - s => noParamsText = s, - (s, p) => paramsText = s + p[0], - ConsoleColor.Cyan, - "SomeText ", - "Hey!"); - - Assert.Equal("", noParamsText); - Assert.Equal("SomeText Hey!", paramsText); - } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/BadPositionArgMissingTwo.cs b/test/EntityFramework/UnitTests/CommandLine/TestHelpers/BadPositionArgMissingTwo.cs deleted file mode 100644 index c2fff7d9a1..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/BadPositionArgMissingTwo.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine.Tests -{ - extern alias migrate; - - public class BadPositionArgMissingTwo - { - [migrate::CmdLine.CommandLineParameterAttribute(Name = "source", ParameterIndex = 1, Required = true, - Description = "Specifies the file(s) to copy.")] - public string Source { get; set; } - - // Note: There is no position 2 - - [migrate::CmdLine.CommandLineParameterAttribute(Name = "destination", ParameterIndex = 3, - Description = "Specifies the file(s) to copy.")] - public string Destination { get; set; } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/BadPositionArgNoOne.cs b/test/EntityFramework/UnitTests/CommandLine/TestHelpers/BadPositionArgNoOne.cs deleted file mode 100644 index c14d692209..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/BadPositionArgNoOne.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine.Tests -{ - extern alias migrate; - - public class BadPositionArgNoOne - { - // Note: There is no position 1 - [migrate::CmdLine.CommandLineParameterAttribute(Name = "source", ParameterIndex = 2, Required = true, - Description = "Specifies the file(s) to copy.")] - public string Source { get; set; } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/InferredTestArgs.cs b/test/EntityFramework/UnitTests/CommandLine/TestHelpers/InferredTestArgs.cs deleted file mode 100644 index 5672979fb8..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/InferredTestArgs.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace CmdLine.Tests -{ - using System; - - /// - /// An argument class that uses inferred attributes - /// - public class InferredTestArgs - { - public string StringArg { get; set; } - - public bool BoolT { get; set; } - - public bool BoolY { get; set; } - - public DateTime Date { get; set; } - - public int Number { get; set; } - } -} diff --git a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/PropWithNoCommandName.cs b/test/EntityFramework/UnitTests/CommandLine/TestHelpers/PropWithNoCommandName.cs deleted file mode 100644 index 6333cf66f5..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/PropWithNoCommandName.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine.Tests -{ - extern alias migrate; - - public class PropWithNoCommandName - { - [migrate::CmdLine.CommandLineParameterAttribute(Default = true)] - public bool b1 { get; set; } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/TestArgs.cs b/test/EntityFramework/UnitTests/CommandLine/TestHelpers/TestArgs.cs deleted file mode 100644 index 956dc90040..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/TestArgs.cs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine.Tests -{ - extern alias migrate; - - [migrate::CmdLine.CommandLineArgumentsAttribute(Title = TestArgsTitle, Description = TestArgsDescription)] - public class TestArgs - { - private const string SArgDescription = "This is a string argument"; - - public const string TestArgsTitle = "My Test Program"; - - public const string TestArgsDescription = "Verifies that the command parsing works"; - - public const string YArgDescription = "The Y Arg is optional"; - - public const string TArgDescription = "The T value is required"; - - public const string StringArgDefault = "Default S Value"; - - public const bool BoolYDefault = false; - - public const bool BoolTDefault = true; - - [migrate::CmdLine.CommandLineParameterAttribute(Command = "Y", Name = "The Y Value", Description = YArgDescription)] - public bool BoolY { get; set; } - - [migrate::CmdLine.CommandLineParameterAttribute(Command = "T", Default = true, Description = TArgDescription)] - public bool BoolT { get; set; } - - [migrate::CmdLine.CommandLineParameterAttribute(Command = "S", Description = SArgDescription, Default = StringArgDefault)] - public string StringArg { get; set; } - - [migrate::CmdLine.CommandLineParameterAttribute(Command = "N", Description = "An Int32 Number", Required = true, ValueExample = "13" - )] - public int Number { get; set; } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/TestCommandEnvironment.cs b/test/EntityFramework/UnitTests/CommandLine/TestHelpers/TestCommandEnvironment.cs deleted file mode 100644 index cc06856c34..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/TestCommandEnvironment.cs +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine.Tests -{ - extern alias migrate; - using System; - using System.Collections.Generic; - - public class TestCommandEnvironment : migrate::CmdLine.ICommandEnvironment - { - private string[] args; - - public TestCommandEnvironment() - { - } - - public TestCommandEnvironment(string cmdLine) - { - CommandLine = cmdLine; - Args = cmdLine.Split(' '); - } - - public TestCommandEnvironment(string[] args) - { - Args = args; - CommandLine = string.Join(" ", args); - } - - public string[] Args - { - get - { - if (args == null) - { - SetArgs(null); - } - return args; - } - private set { SetArgs(value); } - } - - #region ICommandEnvironment Members - - public string CommandLine { get; private set; } - - public string[] GetCommandLineArgs() - { - return Args; - } - - public string Program - { - get { return Environment.GetCommandLineArgs()[0]; } - } - - #endregion - - private void SetArgs(IEnumerable values) - { - var argList = new List - { - Program - }; - - if (values != null) - { - argList.AddRange(values); - } - - args = argList.ToArray(); - } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/ThreeRequiredPositionArgs.cs b/test/EntityFramework/UnitTests/CommandLine/TestHelpers/ThreeRequiredPositionArgs.cs deleted file mode 100644 index 521f271994..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/ThreeRequiredPositionArgs.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine.Tests -{ - extern alias migrate; - - public class ThreeRequiredPositionArgs - { - [migrate::CmdLine.CommandLineParameterAttribute(Name = "String 1", ParameterIndex = 1, Required = true)] - public string S1 { get; set; } - - [migrate::CmdLine.CommandLineParameterAttribute(Name = "String 2", ParameterIndex = 2, Required = true)] - public string S2 { get; set; } - - [migrate::CmdLine.CommandLineParameterAttribute(Name = "String 3", ParameterIndex = 3, Required = true)] - public string S3 { get; set; } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/TwoPropsWithSameSwitch.cs b/test/EntityFramework/UnitTests/CommandLine/TestHelpers/TwoPropsWithSameSwitch.cs deleted file mode 100644 index 0bec013f0f..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/TwoPropsWithSameSwitch.cs +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine.Tests -{ - extern alias migrate; - - public class TwoPropsWithSameSwitch - { - [migrate::CmdLine.CommandLineParameterAttribute("B")] - public bool B1 { get; set; } - - [migrate::CmdLine.CommandLineParameterAttribute("B")] - public bool B2 { get; set; } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/XCopyCommandArgs.cs b/test/EntityFramework/UnitTests/CommandLine/TestHelpers/XCopyCommandArgs.cs deleted file mode 100644 index b0399687f3..0000000000 --- a/test/EntityFramework/UnitTests/CommandLine/TestHelpers/XCopyCommandArgs.cs +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace CmdLine.Tests -{ - extern alias migrate; - using System; - - /// - /// Test class to see if we can simulate processing of XCopy command lines - /// - /// - /// XCOPY source [destination] [/A | /M] [/D[:date]] [/P] [/S [/E]] [/V] [/W] - /// [/C] [/I] [/Q] [/F] [/L] [/G] [/H] [/R] [/T] [/U] - /// [/K] [/N] [/O] [/X] [/Y] [/-Y] [/Z] [/B] - /// [/EXCLUDE:file1[+file2][+file3]...] - /// - /// source Specifies the file(s) to copy. - /// destination Specifies the location and/or name of new files. - /// /A Copies only files with the archive attribute set, - /// doesn't change the attribute. - /// /M Copies only files with the archive attribute set, - /// turns off the archive attribute. - /// /D:m-d-y Copies files changed on or after the specified date. - /// If no date is given, copies only those files whose - /// source time is newer than the destination time. - /// /EXCLUDE:file1[+file2][+file3]... - /// Specifies a list of files containing strings. Each string - /// should be in a separate line in the files. When any of the - /// strings match any part of the absolute path of the file to be - /// copied, that file will be excluded from being copied. For - /// example, specifying a string like \obj\ or .obj will exclude - /// all files underneath the directory obj or all files with the - /// .obj extension respectively. - /// /P Prompts you before creating each destination file. - /// /S Copies directories and subdirectories except empty ones. - /// /E Copies directories and subdirectories, including empty ones. - /// Same as /S /E. May be used to modify /T. - /// /V Verifies the size of each new file. - /// /W Prompts you to press a key before copying. - /// /C Continues copying even if errors occur. - /// /I If destination does not exist and copying more than one file, - /// assumes that destination must be a directory. - /// /Q Does not display file names while copying. - /// /F Displays full source and destination file names while copying. - /// /L Displays files that would be copied. - /// /G Allows the copying of encrypted files to destination that does - /// not support encryption. - /// /H Copies hidden and system files also. - /// /R Overwrites read-only files. - /// /T Creates directory structure, but does not copy files. Does not - /// include empty directories or subdirectories. /T /E includes - /// empty directories and subdirectories. - /// /U Copies only files that already exist in destination. - /// /K Copies attributes. Normal Xcopy will reset read-only attributes. - /// /N Copies using the generated short names. - /// /O Copies file ownership and ACL information. - /// /X Copies file audit settings (implies /O). - /// /Y Suppresses prompting to confirm you want to overwrite an - /// existing destination file. - /// /-Y Causes prompting to confirm you want to overwrite an - /// existing destination file. - /// /Z Copies networked files in restartable mode. - /// /B Copies the Symbolic Link itself versus the target of the link. - /// /J Copies using unbuffered I/O. Recommended for very large files. - /// - /// The switch /Y may be preset in the COPYCMD environment variable. - /// This may be overridden with /-Y on the command line. - /// - [migrate::CmdLine.CommandLineArgumentsAttribute(Title = Title, Description = Description)] - public class XCopyCommandArgs - { - public const string Title = "XCopy Example"; - - public const string Description = "A possible implementation of XCopy as a command args class"; - - /// source Specifies the file(s) to copy. - [migrate::CmdLine.CommandLineParameterAttribute(Name = "source", ParameterIndex = 1, Required = true, - Description = "Specifies the file(s) to copy.")] - public string Source { get; set; } - - /// destination Specifies the location and/or name of new files. - [migrate::CmdLine.CommandLineParameterAttribute(Name = "destination", ParameterIndex = 2, - Description = "Specifies the file(s) to copy.")] - public string Destination { get; set; } - - // /A Copies only files with the archive attribute set, - [migrate::CmdLine.CommandLineParameterAttribute(Command = "A", Description = "Copies only files with the archive attribute set")] - public bool ArchivedBit { get; set; } - - /// /I If destination does not exist and copying more than one file, - /// assumes that destination must be a directory. - [migrate::CmdLine.CommandLineParameterAttribute(Command = "I", - Description = "If destination does not exist and copying more than one file,assumes that destination must be a directory.")] - public bool InferDirectory { get; set; } - - /// /D:m-d-y Copies files changed on or after the specified date. - [migrate::CmdLine.CommandLineParameterAttribute(Command = "D", ValueExample = "m-d-y", - Description = "Copies files changed on or after the specified date.")] - public DateTime ChangedAfterDate { get; set; } - - /// /EXCLUDE:file1[+file2][+file3]... - [migrate::CmdLine.CommandLineParameterAttribute(Command = "EXCLUDE", ValueExample = "file1[+file2][+file3]...", - DescriptionResourceId = "ExcludeDescription")] - public string ExcludeFiles { get; set; } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/Migrations/AddMigrationCommandTests.cs b/test/EntityFramework/UnitTests/Migrations/AddMigrationCommandTests.cs deleted file mode 100644 index cd0083942d..0000000000 --- a/test/EntityFramework/UnitTests/Migrations/AddMigrationCommandTests.cs +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace System.Data.Entity.Migrations -{ - using System.Collections.Generic; - using System.Data.Entity.Migrations.Design; - using System.Data.Entity.Migrations.Resources; - using System.Data.Entity.Migrations.Utilities; - using System.Linq; - using EnvDTE; - using Moq; - using Xunit; - - public class AddMigrationCommandTests - { - [Fact] - public void Writes_scaffolding_message_when_new_migration() - { - var command = new TestableAddMigrationCommand(); - - command.Execute("M", false, false); - - Assert.Equal(Strings.ScaffoldingMigration("M"), command.Messages.Single()); - } - - [Fact] - public void Opens_migration_file_when_no_error() - { - var command = new TestableAddMigrationCommand(); - - command.Execute("M", false, false); - - command.MockDispatcher.Verify(p => p.OpenFile(@".\M")); - } - - [Fact] - public void Writes_rescaffolding_message_when_rescaffolding() - { - var command = new TestableAddMigrationCommand(); - - command.MockToolingFacade - .Setup(f => f.Scaffold("M", It.IsAny(), It.IsAny(), It.IsAny())) - .Returns( - new ScaffoldedMigration - { - IsRescaffold = true - }); - - command.Execute("M", false, false); - - Assert.Equal(Strings.RescaffoldingMigration("M"), command.Messages.Single()); - } - - [Fact] - public void Writes_code_behind_warning_when_new_migration() - { - var command = new TestableAddMigrationCommand(); - - command.MockToolingFacade - .Setup(f => f.Scaffold("M", It.IsAny(), It.IsAny(), It.IsAny())) - .Returns( - new ScaffoldedMigration - { - MigrationId = "Foo" - }); - - command.Execute("M", false, false); - - Assert.Equal(Strings.SnapshotBehindWarning("M"), command.Warnings.Single()); - } - - [Fact] - public void Writes_rescaffold_warning_when_new_migration_name_matches_only_applied_migration() - { - var command = new TestableAddMigrationCommand(); - - command.MockToolingFacade - .Setup(f => f.GetDatabaseMigrations()).Returns(new[] { "201301040020540_M" }); - - command.Execute("M", false, false); - - Assert.Equal( - Strings.DidYouMeanToRescaffold("M", "$InitialDatabase", "M"), - command.Warnings.Last().Trim()); - } - - [Fact] - public void Writes_rescaffold_warning_when_new_migration_name_matches_last_applied_migration() - { - var command = new TestableAddMigrationCommand(); - - command.MockToolingFacade - .Setup(f => f.GetDatabaseMigrations()) - .Returns(new[] { "201301040020540_M2", "201301040020540_M1" }); - - command.Execute("M2", false, false); - - Assert.Equal( - Strings.DidYouMeanToRescaffold("M2", "201301040020540_M1", "M2"), - command.Warnings.Last().Trim()); - } - - internal class TestableAddMigrationCommand : AddMigrationCommand - { - public readonly Mock MockToolingFacade - = new Mock - { - DefaultValue = DefaultValue.Mock - }; - - public readonly Mock MockProject - = new Mock - { - DefaultValue = DefaultValue.Mock - }; - - public readonly Mock MockDispatcher = new Mock(); - - public readonly List Messages = new List(); - public readonly List Warnings = new List(); - - public TestableAddMigrationCommand() - { - AppDomain.CurrentDomain.SetData("efDispatcher", MockDispatcher.Object); - - var mockFullPathProperty = new Mock(); - mockFullPathProperty.SetupGet(p => p.Value).Returns("."); - - MockProject.Setup(p => p.Properties.Item("FullPath")).Returns(mockFullPathProperty.Object); - - var mockRootNamespaceProperty = new Mock(); - mockRootNamespaceProperty.SetupGet(p => p.Value).Returns("N"); - - MockProject.Setup(p => p.Properties.Item("RootNamespace")).Returns(mockRootNamespaceProperty.Object); - } - - public override ToolingFacade GetFacade(string configurationTypeName = null, bool useContextWorkingDirectory = false) - { - return MockToolingFacade.Object; - } - - public override Project Project - { - get { return MockProject.Object; } - } - - public override void WriteLine(string message) - { - Messages.Add(message); - } - - public override void WriteWarning(string message) - { - Warnings.Add(message); - } - - protected override string WriteMigration(string name, bool force, ScaffoldedMigration scaffoldedMigration, bool rescaffolding) - { - return name; - } - } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/Migrations/Design/ToolingExceptionTests.cs b/test/EntityFramework/UnitTests/Migrations/Design/ToolingExceptionTests.cs deleted file mode 100644 index d903ab6e35..0000000000 --- a/test/EntityFramework/UnitTests/Migrations/Design/ToolingExceptionTests.cs +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -namespace System.Data.Entity.Migrations.Design -{ - using Xunit; - - public class ToolingExceptionTests - { - [Fact] - public void Constructors_allow_for_nulls() - { - Assert.True(new ToolingException(null).Message.Contains("'System.Data.Entity.Migrations.Design.ToolingException'")); - Assert.True(new ToolingException(null, null).Message.Contains("'System.Data.Entity.Migrations.Design.ToolingException'")); - Assert.Null(new ToolingException(null, null).InnerException); - Assert.Null(new ToolingException(null, null, null).InnerType); - Assert.Null(new ToolingException(null, null, null).InnerStackTrace); - Assert.True(new ToolingException(null, null, null).Message.Contains("'System.Data.Entity.Migrations.Design.ToolingException'")); - } - - [Fact] - public void Parameterless_constructor_uses_default_message_and_sets_up_serialization() - { - var exception = new ToolingException(); - - Assert.True(exception.Message.Contains("'System.Data.Entity.Migrations.Design.ToolingException'")); - Assert.Null(exception.InnerType); - Assert.Null(exception.InnerStackTrace); - - exception = ExceptionHelpers.SerializeAndDeserialize(exception); - - Assert.True(exception.Message.Contains("'System.Data.Entity.Migrations.Design.ToolingException'")); - Assert.Null(exception.InnerType); - Assert.Null(exception.InnerStackTrace); - } - - [Fact] - public void Constructor_uses_given_message_and_sets_up_serialization() - { - var exception = new ToolingException("It's Tool Time!"); - - Assert.Equal("It's Tool Time!", exception.Message); - Assert.Null(exception.InnerType); - Assert.Null(exception.InnerStackTrace); - - exception = ExceptionHelpers.SerializeAndDeserialize(exception); - - Assert.Equal("It's Tool Time!", exception.Message); - Assert.Null(exception.InnerType); - Assert.Null(exception.InnerStackTrace); - } - - [Fact] - public void Constructor_uses_given_message_and_inner_exception_and_sets_up_serialization() - { - var innerException = new Exception("Hello? Hello?"); - var exception = new ToolingException("Can somebody let me out?", innerException); - - Assert.Equal("Can somebody let me out?", exception.Message); - Assert.Same(innerException, exception.InnerException); - Assert.Null(exception.InnerType); - Assert.Null(exception.InnerStackTrace); - - exception = ExceptionHelpers.SerializeAndDeserialize(exception); - - Assert.Equal("Can somebody let me out?", exception.Message); - Assert.Equal(innerException.Message, exception.InnerException.Message); - Assert.Null(exception.InnerType); - Assert.Null(exception.InnerStackTrace); - } - - [Fact] - public void Constructor_uses_given_detailed_information_and_sets_up_serialization() - { - var exception = new ToolingException("Really?", "INTP", "Where's my tracing paper?"); - - Assert.Equal("Really?", exception.Message); - Assert.Equal("INTP", exception.InnerType); - Assert.Equal("Where's my tracing paper?", exception.InnerStackTrace); - - exception = ExceptionHelpers.SerializeAndDeserialize(exception); - - Assert.Equal("Really?", exception.Message); - Assert.Equal("INTP", exception.InnerType); - Assert.Equal("Where's my tracing paper?", exception.InnerStackTrace); - } - } -} diff --git a/test/EntityFramework/UnitTests/Migrations/Utilities/MigrationWriterTests.cs b/test/EntityFramework/UnitTests/Migrations/Utilities/MigrationWriterTests.cs deleted file mode 100644 index d5fca37d11..0000000000 --- a/test/EntityFramework/UnitTests/Migrations/Utilities/MigrationWriterTests.cs +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. - -#if NET452 - -namespace System.Data.Entity.Migrations.Utilities -{ - using System.Collections; - using System.Data.Entity.Migrations.Design; - using System.IO; - using System.Linq; - using System.Resources; - using EnvDTE; - using Moq; - using Xunit; - - public class MigrationWriterTests : IDisposable - { - private const string MigrationName = "InitialCreate"; - private const string MigrationId = "201206072128312_" + MigrationName; - private const string Language = "cs"; - private const string MigrationsDirectory = "Migrations"; - private const string UserCodeFileName = MigrationId + "." + Language; - private const string DesignerCodeFileName = MigrationId + ".Designer." + Language; - private const string ResourcesFileName = MigrationId + ".resx"; - private const string UserCodePath = MigrationsDirectory + @"\" + UserCodeFileName; - private const string DesignerCodePath = MigrationsDirectory + @"\" + DesignerCodeFileName; - private const string ResourcesPath = MigrationsDirectory + @"\" + ResourcesFileName; - private const string ResourceName = "MyResource"; - - private readonly string _projectDir = IOHelpers.GetTempDirName(); - - [Fact] - public void Write_writes_artifacts() - { - TestWrite( - (writer, scaffoldedMigration) => - writer.Write(scaffoldedMigration)); - } - - [Fact] - public void Write_overwrites_designerCode_and_resources_when_rescaffolding() - { - CreateProject( - "The user code.", - "The old designer code.", - "The old resource."); - - TestWrite( - (writer, scaffoldedMigration) => - writer.Write(scaffoldedMigration, rescaffolding: true)); - } - - [Fact] - public void Write_doesnt_overwrite_userCode_when_rescaffolding() - { - CreateProject( - "The edited user code.", - "The old designer code.", - "The old resource."); - - TestWrite( - (writer, scaffoldedMigration) => - writer.Write(scaffoldedMigration, rescaffolding: true, name: MigrationName), - skipUserCodeVerification: true); - - var userCodePath = Path.Combine(_projectDir, UserCodePath); - Assert.Equal("The edited user code.", File.ReadAllText(userCodePath)); - } - - [Fact] - public void Write_overwrites_artifacts_when_rescaffolding_with_force() - { - CreateProject( - "The edited user code.", - "The old designer code.", - "The old resource."); - - TestWrite( - (writer, scaffoldedMigration) => - writer.Write(scaffoldedMigration, rescaffolding: true, force: true)); - } - - public void Dispose() - { - Directory.Delete(_projectDir, recursive: true); - } - - private void CreateProject(string userCode, string designerCode, string resource) - { - Directory.CreateDirectory(Path.Combine(_projectDir, MigrationsDirectory)); - - var userCodePath = Path.Combine(_projectDir, UserCodePath); - File.WriteAllText(userCodePath, userCode); - - var designerCodePath = Path.Combine(_projectDir, DesignerCodePath); - File.WriteAllText(designerCodePath, designerCode); - - var resourcesPath = Path.Combine(_projectDir, ResourcesPath); - - using (var resourceWriter = new ResXResourceWriter(resourcesPath)) - { - resourceWriter.AddResource(ResourceName, resource); - } - } - - private void TestWrite( - Func action, - bool skipUserCodeVerification = false) - { - var command = CreateCommand(_projectDir); - var writer = new System.Data.Entity.Migrations.Utilities.MigrationWriter(command); - var scaffoldedMigration = new ScaffoldedMigration - { - MigrationId = MigrationId, - Language = Language, - Directory = MigrationsDirectory, - UserCode = "The user code.", - DesignerCode = "The designer code.", - Resources = - { - { ResourceName, "The resource." } - } - }; - - var relativeUserCodePath = action(writer, scaffoldedMigration); - - Assert.Equal(UserCodePath, relativeUserCodePath); - - if (!skipUserCodeVerification) - { - var userCodePath = Path.Combine(_projectDir, UserCodePath); - Assert.Equal("The user code.", File.ReadAllText(userCodePath)); - } - - var designerCodePath = Path.Combine(_projectDir, DesignerCodePath); - Assert.Equal("The designer code.", File.ReadAllText(designerCodePath)); - - var resourcesPath = Path.Combine(_projectDir, ResourcesPath); - - using (var reader = new ResXResourceReader(resourcesPath)) - { - var resources = reader.Cast(); - - Assert.Equal(1, resources.Count()); - Assert.Contains(new DictionaryEntry(ResourceName, "The resource."), resources); - } - } - - private static System.Data.Entity.Migrations.MigrationsDomainCommand CreateCommand(string projectDir) - { - var fullPathProperty = new Mock(); - fullPathProperty.SetupGet(p => p.Value).Returns(projectDir); - - var properties = new Mock(); - properties.Setup(p => p.Item("FullPath")).Returns(fullPathProperty.Object); - - var dte = new Mock(); - - var projectItems = new Mock(); - projectItems.SetupGet(pi => pi.Kind).Returns( - System.Data.Entity.Migrations.Extensions.ProjectExtensions.VsProjectItemKindPhysicalFolder); - projectItems.Setup(pi => pi.AddFromDirectory(It.IsAny())).Returns( - () => - { - var dirProjectItems = new Mock(); - - var dirProjectItem = new Mock(); - dirProjectItem.SetupGet(pi => pi.ProjectItems).Returns(dirProjectItems.Object); - - return dirProjectItem.Object; - }); - - var project = new Mock(); - projectItems.SetupGet(pi => pi.Parent).Returns(() => project.Object); - project.SetupGet(p => p.Properties).Returns(properties.Object); - project.SetupGet(p => p.DTE).Returns(dte.Object); - project.SetupGet(p => p.ProjectItems).Returns(projectItems.Object); - - var command = new Mock(); - command.SetupGet(c => c.Project).Returns(project.Object); - command.Setup(c => c.WriteWarning(It.IsAny())).Callback(() => { }); - - return command.Object; - } - } -} - -#endif diff --git a/test/EntityFramework/UnitTests/UnitTests.csproj b/test/EntityFramework/UnitTests/UnitTests.csproj index 1f645d0c5b..747fc1a98c 100644 --- a/test/EntityFramework/UnitTests/UnitTests.csproj +++ b/test/EntityFramework/UnitTests/UnitTests.csproj @@ -90,13 +90,6 @@ - - - - migrate - - -