From 52a8bb30f6e1a7d162c49a709116c14e0ca7a8f7 Mon Sep 17 00:00:00 2001 From: Rikard Pavelic Date: Fri, 2 Nov 2018 16:23:42 +0100 Subject: [PATCH] Initial support for new .NET tooling POCO and Revenj Postgres support new tooling (and build to source also) Support for Typescript --- VisualStudioPlugin/Compiler.cs | 24 ++++++---- VisualStudioPlugin/DDDLanguage.csproj | 7 +++ VisualStudioPlugin/DDDLanguagePackage.cs | 18 ++++++++ VisualStudioPlugin/Gui/CompileTargets.cs | 44 ++++++++++++++----- VisualStudioPlugin/Gui/LibraryInfo.cs | 28 +++++++++--- VisualStudioPlugin/Gui/ToolPresenter.cs | 4 ++ .../Gui/View/ConfigurationPocoControl.xaml | 8 ++++ .../View/ConfigurationPostgresControl.xaml | 12 ++++- .../View/ConfigurationTypescriptControl.xaml | 33 ++++++++++++++ .../ConfigurationTypescriptControl.xaml.cs | 14 ++++++ .../Gui/View/StatusControl.xaml | 34 ++++++++------ 11 files changed, 186 insertions(+), 40 deletions(-) create mode 100644 VisualStudioPlugin/Gui/View/ConfigurationTypescriptControl.xaml create mode 100644 VisualStudioPlugin/Gui/View/ConfigurationTypescriptControl.xaml.cs diff --git a/VisualStudioPlugin/Compiler.cs b/VisualStudioPlugin/Compiler.cs index bd688cf..1401592 100644 --- a/VisualStudioPlugin/Compiler.cs +++ b/VisualStudioPlugin/Compiler.cs @@ -115,11 +115,11 @@ public static string TempPath } } - private static readonly char[] InvalidFileChars = Path.GetInvalidFileNameChars(); + private static readonly char[] InvalidFileChars = Path.GetInvalidFileNameChars().Except(new[] { '/' }).ToArray(); - public static string BuildDotnet(string project, string output, Dictionary dependencies, Dictionary files) + public static string BuildDotnet(LibraryInfo library, string[] customDlls, Dictionary files) { - var folder = Path.Combine(TempPath, project); + var folder = Path.Combine(TempPath, library.Type); if (!Directory.Exists(folder)) Directory.CreateDirectory(folder); else @@ -127,7 +127,7 @@ public static string BuildDotnet(string project, string output, Dictionary netstandard2.0 @@ -137,14 +137,22 @@ public static string BuildDotnet(string project, string output, Dictionary false "); - if (dependencies.Count != 0) + if (library.Nugets.Count != 0 || customDlls.Length != 0) { csproj.Append(@" "); - foreach (var kv in dependencies) + foreach (var n in library.Nugets) { csproj.AppendFormat(@" - ", kv.Key, kv.Value); + ", n.Project, n.Version); + } + foreach (var dll in customDlls) + { + var fullPath = Path.Combine(LibraryInfo.BasePath, dll); + csproj.AppendFormat(@" + + {1} + ", Path.GetFileNameWithoutExtension(dll), fullPath); } csproj.Append(@" @@ -152,7 +160,7 @@ public static string BuildDotnet(string project, string output, Dictionary"); - File.WriteAllText(Path.Combine(folder, project + ".csproj"), csproj.ToString()); + File.WriteAllText(Path.Combine(folder, library.Type + ".csproj"), csproj.ToString()); foreach (var kv in files) { var name = kv.Key; diff --git a/VisualStudioPlugin/DDDLanguage.csproj b/VisualStudioPlugin/DDDLanguage.csproj index 1f80d2a..45ba268 100644 --- a/VisualStudioPlugin/DDDLanguage.csproj +++ b/VisualStudioPlugin/DDDLanguage.csproj @@ -145,6 +145,9 @@ ConfigurationPostgresControl.xaml + + ConfigurationTypescriptControl.xaml + DiffControl.xaml @@ -272,6 +275,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + Designer MSBuild:Compile diff --git a/VisualStudioPlugin/DDDLanguagePackage.cs b/VisualStudioPlugin/DDDLanguagePackage.cs index 80881c6..dcd8b79 100644 --- a/VisualStudioPlugin/DDDLanguagePackage.cs +++ b/VisualStudioPlugin/DDDLanguagePackage.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel.Design; +using System.Linq; using System.Runtime.InteropServices; using System.Windows; using EnvDTE; @@ -188,6 +189,16 @@ private void ReadInfo(LibraryInfo info, IPropertyBag pBag) info.Name = TryReadString(info.Type + ".Name", pBag) ?? info.Name; info.Target = TryReadString(info.Type + ".Target", pBag) ?? info.Target; info.Dependencies = TryReadString(info.Type + ".Dependencies", pBag) ?? info.Dependencies; + var nugets = TryReadString(info.Type + ".Nugets", pBag); + if (!string.IsNullOrWhiteSpace(nugets)) + { + var values = nugets.Split(';'); + info.Nugets = values.Select(it => + { + var parts = it.Split(':'); + return new LibraryInfo.Nuget { Project = parts[0], Version = parts[parts.Length - 1] }; + }).ToList(); + } info.Namespace = TryReadString(info.Type + ".Namespace", pBag) ?? info.Namespace; info.WithActiveRecord = TryReadBool(info.Type + ".ActiveRecord", pBag, info.WithActiveRecord); info.WithHelperMethods = TryReadBool(info.Type + ".HelperMethods", pBag, info.WithHelperMethods); @@ -209,6 +220,7 @@ public int ReadSolutionProps(IVsHierarchy pHierarchy, string pszProjectName, str ReadInfo(Presenter.ClientLibrary, pPropBag); ReadInfo(Presenter.PortableLibrary, pPropBag); ReadInfo(Presenter.PhpLibrary, pPropBag); + ReadInfo(Presenter.TypescriptLibrary, pPropBag); ReadInfo(Presenter.WpfLibrary, pPropBag); ReadInfo(Presenter.PostgresLibrary, pPropBag); ReadInfo(Presenter.OracleLibrary, pPropBag); @@ -320,6 +332,11 @@ private void WriteInfo(LibraryInfo info, LibraryInfo reference, IPropertyBag pBa val = info.Dependencies; pBag.Write(info.Type + ".Dependencies", ref val); } + if (!LibraryInfo.Nuget.Equal(info.Nugets, reference.Nugets)) + { + val = string.Join(";", info.Nugets.Select(it => it.Project + ":" + it.Version)); + pBag.Write(info.Type + ".Nugets", ref val); + } if (reference.Namespace != info.Namespace) { val = info.Namespace; @@ -381,6 +398,7 @@ public int WriteSolutionProps(IVsHierarchy pHierarchy, string pszKey, IPropertyB WriteInfo(Presenter.ClientLibrary, CompileTargets.ClientLibraryDefault, pPropBag); WriteInfo(Presenter.PortableLibrary, CompileTargets.PortableLibraryDefault, pPropBag); WriteInfo(Presenter.PhpLibrary, CompileTargets.PhpSourceDefault, pPropBag); + WriteInfo(Presenter.TypescriptLibrary, CompileTargets.TypescriptSourceDefault, pPropBag); WriteInfo(Presenter.WpfLibrary, CompileTargets.WpfLibraryDefault, pPropBag); WriteInfo(Presenter.PostgresLibrary, CompileTargets.PostgresLibraryDefault, pPropBag); WriteInfo(Presenter.OracleLibrary, CompileTargets.OracleLibraryDefault, pPropBag); diff --git a/VisualStudioPlugin/Gui/CompileTargets.cs b/VisualStudioPlugin/Gui/CompileTargets.cs index ebedb41..67187fc 100644 --- a/VisualStudioPlugin/Gui/CompileTargets.cs +++ b/VisualStudioPlugin/Gui/CompileTargets.cs @@ -8,8 +8,14 @@ namespace DDDLanguage { internal class CompileTargets { - private static readonly Dictionary NoDependencies = new Dictionary(); - private static readonly Dictionary RevenjStandard = new Dictionary() { { "revenj", "1.4.2" } }; + private static List NoDependencies() + { + return new List(); + } + private static List RevenjStandard() + { + return new List(new[] { new LibraryInfo.Nuget { Project = "revenj", Version = "1.4.2" } }); + } private static readonly string[] PocoDependencies = new[] { typeof(string).Assembly.Location, @@ -67,32 +73,35 @@ public string CompilerPath } private LibraryInfo oldPocoLibrary; - public static readonly LibraryInfo PocoLibraryDefault = new LibraryInfo("Poco", "dotnet_poco", false, PocoDependencies, NoDependencies, BuildTypes.LegacyDotNet, ".cs", BuildTypes.LegacyDotNet, BuildTypes.DotNetStandard); + public static readonly LibraryInfo PocoLibraryDefault = new LibraryInfo("Poco", "dotnet_poco", false, PocoDependencies, NoDependencies(), BuildTypes.LegacyDotNet, ".cs", BuildTypes.LegacyDotNet, BuildTypes.DotNetStandard, BuildTypes.Source); public readonly LibraryInfo PocoLibrary = PocoLibraryDefault.Clone(); private LibraryInfo oldClientLibrary; - public static readonly LibraryInfo ClientLibraryDefault = new LibraryInfo("Client", "dotnet_client", true, PocoDependencies, NoDependencies, BuildTypes.LegacyDotNet, ".cs"); + public static readonly LibraryInfo ClientLibraryDefault = new LibraryInfo("Client", "dotnet_client", true, PocoDependencies, NoDependencies(), BuildTypes.LegacyDotNet, ".cs"); public readonly LibraryInfo ClientLibrary = ClientLibraryDefault.Clone(); private LibraryInfo oldPortableLibrary; - public static readonly LibraryInfo PortableLibraryDefault = new LibraryInfo("Portable", "dotnet_portable", true, new string[0], NoDependencies, BuildTypes.LegacyDotNet, ".cs"); + public static readonly LibraryInfo PortableLibraryDefault = new LibraryInfo("Portable", "dotnet_portable", true, new string[0], NoDependencies(), BuildTypes.LegacyDotNet, ".cs"); public readonly LibraryInfo PortableLibrary = PortableLibraryDefault.Clone(); private LibraryInfo oldPhpSource; - public static readonly LibraryInfo PhpSourceDefault = new LibraryInfo("Php", "php_client", false, new string[0], NoDependencies, BuildTypes.Source, ".php"); + public static readonly LibraryInfo PhpSourceDefault = new LibraryInfo("Php", "php_client", false, new string[0], NoDependencies(), BuildTypes.Source, ".php"); public readonly LibraryInfo PhpSource = PhpSourceDefault.Clone(); + private LibraryInfo oldTypescriptSource; + public static readonly LibraryInfo TypescriptSourceDefault = new LibraryInfo("Typescript", "typescript", false, new string[0], NoDependencies(), BuildTypes.Source, string.Empty); + public readonly LibraryInfo TypescriptSource = TypescriptSourceDefault.Clone(); private LibraryInfo oldWpfLibrary; - public static readonly LibraryInfo WpfLibraryDefault = new LibraryInfo("Wpf", "wpf", true, WpfDependencies, NoDependencies, BuildTypes.LegacyDotNet, ".cs"); + public static readonly LibraryInfo WpfLibraryDefault = new LibraryInfo("Wpf", "wpf", true, WpfDependencies, NoDependencies(), BuildTypes.LegacyDotNet, ".cs"); public readonly LibraryInfo WpfLibrary = WpfLibraryDefault.Clone(); private LibraryInfo oldPostgresLibrary; - public static readonly LibraryInfo PostgresLibraryDefault = new LibraryInfo("Postgres", "dotnet_server_postgres", true, RevenjDependencies, RevenjStandard, BuildTypes.LegacyDotNet, ".cs", BuildTypes.LegacyDotNet, BuildTypes.DotNetStandard); + public static readonly LibraryInfo PostgresLibraryDefault = new LibraryInfo("Postgres", "dotnet_server_postgres", true, RevenjDependencies, RevenjStandard(), BuildTypes.LegacyDotNet, ".cs", BuildTypes.LegacyDotNet, BuildTypes.DotNetStandard, BuildTypes.Source); public readonly LibraryInfo PostgresLibrary = PostgresLibraryDefault.Clone(); private LibraryInfo oldOracleLibrary; - public static readonly LibraryInfo OracleLibraryDefault = new LibraryInfo("Oracle", "dotnet_server_oracle", true, RevenjDependencies, NoDependencies, BuildTypes.LegacyDotNet, ".cs"); + public static readonly LibraryInfo OracleLibraryDefault = new LibraryInfo("Oracle", "dotnet_server_oracle", true, RevenjDependencies, NoDependencies(), BuildTypes.LegacyDotNet, ".cs"); public readonly LibraryInfo OracleLibrary = OracleLibraryDefault.Clone(); private readonly LibraryInfo[] Targets; public CompileTargets() { - Targets = new[] { PocoLibrary, ClientLibrary, PortableLibrary, PhpSource, WpfLibrary, PostgresLibrary, OracleLibrary }; + Targets = new[] { PocoLibrary, ClientLibrary, PortableLibrary, PhpSource, TypescriptSource, WpfLibrary, PostgresLibrary, OracleLibrary }; } public bool HasChanges() @@ -101,6 +110,7 @@ public bool HasChanges() || !ClientLibrary.Equals(oldClientLibrary) || !PortableLibrary.Equals(oldPortableLibrary) || !PhpSource.Equals(oldPhpSource) + || !TypescriptSource.Equals(oldTypescriptSource) || !WpfLibrary.Equals(oldWpfLibrary) || !PostgresLibrary.Equals(oldPostgresLibrary) || !OracleLibrary.Equals(oldOracleLibrary); @@ -113,6 +123,7 @@ public void Reset(string compilerPath) oldClientLibrary = ClientLibrary.Clone(); oldPortableLibrary = PortableLibrary.Clone(); oldPhpSource = PhpSource.Clone(); + oldTypescriptSource = TypescriptSource.Clone(); oldWpfLibrary = WpfLibrary.Clone(); oldPostgresLibrary = PostgresLibrary.Clone(); oldOracleLibrary = OracleLibrary.Clone(); @@ -146,6 +157,10 @@ private Either> RunCompiler(string dslCompiler, Libra sb.Append(" settings=legacy"); if (target.MutableSnowflake) sb.Append(" settings=mutable-snowflake"); + if (!string.IsNullOrWhiteSpace(target.Namespace)) + sb.Append(" namespace=").Append(target.Namespace); + if (string.IsNullOrEmpty(target.Extension)) + sb.Append(" file-extension"); sb.Append(" format=xml"); var result = Compiler.CompileDsl(sb, dsls, null, cms => XElement.Load(cms)); if (result.Success) @@ -190,6 +205,7 @@ public void CompileAll(Dictionary files) ProcessResult(PortableLibrary, files, true); ProcessResult(WpfLibrary, files, true); ProcessResult(PhpSource, files, true); + ProcessResult(TypescriptSource, files, true); ProcessResult(PostgresLibrary, files, true); ProcessResult(OracleLibrary, files, true); } @@ -205,7 +221,7 @@ private void CopySource(LibraryInfo info, Dictionary files, bool DumpToDisk(info.TargetPath, sources, info.Extension, 3); } - private static readonly char[] InvalidFileChars = Path.GetInvalidFileNameChars(); + private static readonly char[] InvalidFileChars = Path.GetInvalidFileNameChars().Except(new[] { '/' }).ToArray(); private static void DumpToDisk(string folder, Dictionary files, string extension, int retries) { @@ -259,7 +275,11 @@ private void ProcessResult(LibraryInfo info, Dictionary files, b } else { - var file = Compiler.BuildDotnet(info.Type, info.Name, info.ReferencesNew, files); + var depLen = info.DependenciesPath.Length - info.Dependencies.Length; + var references = + (info.DependenciesExists ? Directory.GetFiles(info.DependenciesPath, "*.dll").Select(it => it.Substring(depLen)) : new string[0]) + .Except(info.DependenciesExists ? new[] { Path.Combine(info.Dependencies, info.Name + ".dll") } : new string[0]); + var file = Compiler.BuildDotnet(info, references.ToArray(), files); File.Copy(file, target, true); } } diff --git a/VisualStudioPlugin/Gui/LibraryInfo.cs b/VisualStudioPlugin/Gui/LibraryInfo.cs index f08b2e1..47cfbb6 100644 --- a/VisualStudioPlugin/Gui/LibraryInfo.cs +++ b/VisualStudioPlugin/Gui/LibraryInfo.cs @@ -50,7 +50,23 @@ public string Dependencies public readonly bool RequireDependenciesLegacy; public string Extension { get; private set; } public string[] ReferencesLegacy { get; private set; } - public Dictionary ReferencesNew { get; private set; } + public List Nugets { get; set; } + + public class Nuget + { + public string Project { get; set; } + public string Version { get; set; } + public Nuget Clone() + { + return new Nuget { Project = Project, Version = Version }; + } + + public static bool Equal(List left, List right) + { + if (left.Count != right.Count) return false; + return left.Zip(right, (l, r) => new { l, r }).All(kv => kv.l.Project == kv.r.Project && kv.l.Version == kv.r.Version); + } + } public static string BasePath { get; set; } public readonly BuildTypes[] SupportedBuilds; @@ -60,7 +76,7 @@ public LibraryInfo( string compilerName, bool requireDependenciesLegacy, string[] referencesLegacy, - Dictionary referencesNew, + List nugets, BuildTypes buildType, string extension, params BuildTypes[] supportedBuilds) @@ -80,7 +96,7 @@ public LibraryInfo( } CompilerName = compilerName; ReferencesLegacy = referencesLegacy; - ReferencesNew = referencesNew; + Nugets = nugets; Extension = extension; this.BuildType = buildType; Dependencies = Path.Combine("dependencies", type); @@ -92,6 +108,7 @@ public LibraryInfo( public Visibility BuildVisibility { get { return SupportedBuilds != null && SupportedBuilds.Length > 1 ? Visibility.Visible : Visibility.Collapsed; } } public Visibility DllVisibility { get { return BuildType != BuildTypes.Source ? Visibility.Visible : Visibility.Collapsed; } } public Visibility LegacyVisibility { get { return BuildType == BuildTypes.LegacyDotNet ? Visibility.Visible : Visibility.Collapsed; } } + public Visibility NetStandardVisibility { get { return BuildType == BuildTypes.DotNetStandard ? Visibility.Visible : Visibility.Collapsed; } } public string DependenciesPath { get { return Path.Combine(BasePath, Dependencies); } } public bool TargetExists { get { return PathExists(Target); } } public bool DependenciesExists { get { return PathExists(Dependencies); } } @@ -174,7 +191,7 @@ public bool CanCompile public LibraryInfo Clone() { - return new LibraryInfo(Type, CompilerName, RequireDependenciesLegacy, ReferencesLegacy, ReferencesNew, BuildType, Extension, SupportedBuilds) + return new LibraryInfo(Type, CompilerName, RequireDependenciesLegacy, ReferencesLegacy, Nugets.Select(it => it.Clone()).ToList(), BuildType, Extension, SupportedBuilds) { CompileOption = CompileOption, Name = Name, @@ -208,7 +225,8 @@ public bool Equals(LibraryInfo other) && other.NoPrepareExecute == this.NoPrepareExecute && other.Legacy == this.Legacy && other.Namespace == this.Namespace - && other.BuildType == this.BuildType; + && other.BuildType == this.BuildType + && Nuget.Equal(other.Nugets, this.Nugets); } } } diff --git a/VisualStudioPlugin/Gui/ToolPresenter.cs b/VisualStudioPlugin/Gui/ToolPresenter.cs index 2336f56..0b2eb78 100644 --- a/VisualStudioPlugin/Gui/ToolPresenter.cs +++ b/VisualStudioPlugin/Gui/ToolPresenter.cs @@ -33,6 +33,7 @@ public string DslCompiler public LibraryInfo OracleLibrary { get { return Targets.OracleLibrary; } } public LibraryInfo PostgresLibrary { get { return Targets.PostgresLibrary; } } public LibraryInfo PhpLibrary { get { return Targets.PhpSource; } } + public LibraryInfo TypescriptLibrary { get { return Targets.TypescriptSource; } } public DatabaseInfo PostgresDb { get; private set; } public DatabaseInfo OracleDb { get; private set; } @@ -55,6 +56,7 @@ public string DslCompiler public ICommand ConfigureClient { get; private set; } public ICommand ConfigurePortable { get; private set; } public ICommand ConfigurePhp { get; private set; } + public ICommand ConfigureTypescript { get; private set; } public ICommand ConfigureWpf { get; private set; } public ICommand ConfigurePostgres { get; private set; } public ICommand ConfigureOracle { get; private set; } @@ -136,6 +138,7 @@ public ToolPresenter() ConfigureClient = new RelayCommand(() => OpenConfigurationAction(new ConfigurationClientControl())); ConfigurePortable = new RelayCommand(() => OpenConfigurationAction(new ConfigurationPortableControl())); ConfigurePhp = new RelayCommand(() => OpenConfigurationAction(new ConfigurationPhpControl())); + ConfigureTypescript = new RelayCommand(() => OpenConfigurationAction(new ConfigurationTypescriptControl())); ConfigureWpf = new RelayCommand(() => OpenConfigurationAction(new ConfigurationWpfControl())); ConfigurePostgres = new RelayCommand(() => OpenConfigurationAction(new ConfigurationPostgresControl())); ConfigureOracle = new RelayCommand(() => OpenConfigurationAction(new ConfigurationOracleControl())); @@ -379,6 +382,7 @@ public bool CanCompile() || ClientLibrary.Compile || PortableLibrary.Compile || WpfLibrary.Compile || PhpLibrary.Compile + || TypescriptLibrary.Compile || PostgresLibrary.Compile || OracleLibrary.Compile || PostgresDb.CompileMigration || OracleDb.CompileMigration); } diff --git a/VisualStudioPlugin/Gui/View/ConfigurationPocoControl.xaml b/VisualStudioPlugin/Gui/View/ConfigurationPocoControl.xaml index 45926f2..9d78247 100644 --- a/VisualStudioPlugin/Gui/View/ConfigurationPocoControl.xaml +++ b/VisualStudioPlugin/Gui/View/ConfigurationPocoControl.xaml @@ -40,6 +40,14 @@ Build C# classes based on DSL definition ToolTip="Dependencies for specialized library are used during compilation process." Foreground="{Binding Path=PocoLibrary.DependenciesColor}" /> + + + + + + - + - -