diff --git a/.travis.yml b/.travis.yml index db3e43a..5827688 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,49 +5,29 @@ matrix: - os: linux dist: trusty sudo: required - mono: 5.4.1 - env: build_config=Release - env: netmoniker=net461 - - os: linux - dist: precise - sudo: required - mono: 5.4.1 + mono: 5.16.0 + dotnet: 2.0 env: build_config=Release env: netmoniker=net461 - os: linux dist: trusty sudo: required - mono: 5.4.1 - env: build_config=Debug - env: netmoniker=net461 - - os: linux - dist: precise - sudo: required - mono: 5.4.1 + mono: 5.16.0 + dotnet: 2.0 env: build_config=Debug env: netmoniker=net461 - os: osx - osx_image: xcode8.2 + osx_image: xcode9.4 sudo: required - mono: 5.4.1 + mono: 5.16.0 + dotnet: 2.0 env: build_config=Release env: netmoniker=net461 - os: osx - osx_image: xcode6.4 - sudo: required - mono: 5.4.1 - env: build_config=Release - env: netmoniker=net461 - - os: osx - osx_image: xcode8.2 - sudo: required - mono: 5.4.1 - env: build_config=Debug - env: netmoniker=net461 - - os: osx - osx_image: xcode6.4 + osx_image: xcode9.4 sudo: required - mono: 5.4.1 + mono: 5.16.0 + dotnet: 2.0 env: build_config=Debug env: netmoniker=net461 @@ -57,11 +37,11 @@ matrix: before_script: - chmod +x build.sh - - ./build.sh --target Restore + - ./build.sh --target=Restore script: - - ./build.sh --target Build + - ./build.sh --target=Build after_script: - - travis_wait 60 ./build.sh --target AllTests - - if [ "$TRAVIS_OS_NAME" == "linux" ]; then travis_wait 60 ./build.sh --target Upload-Coverage; fi \ No newline at end of file + - travis_wait 60 ./build.sh --target=AllTests + - if [ "$TRAVIS_OS_NAME" != "linux" && "$TRAVIS_OS_NAME" != "osx" ]; then travis_wait 60 ./build.sh --target=Upload-Coverage; fi \ No newline at end of file diff --git a/Computator.NET.Charting/Computator.NET.Charting.csproj b/Computator.NET.Charting/Computator.NET.Charting.csproj index 4d3ee74..a7be90b 100644 --- a/Computator.NET.Charting/Computator.NET.Charting.csproj +++ b/Computator.NET.Charting/Computator.NET.Charting.csproj @@ -50,7 +50,7 @@ - + diff --git a/Computator.NET.Charting/RealCharting/Chart2D.cs b/Computator.NET.Charting/RealCharting/Chart2D.cs index e3ddeca..21f73a0 100644 --- a/Computator.NET.Charting/RealCharting/Chart2D.cs +++ b/Computator.NET.Charting/RealCharting/Chart2D.cs @@ -213,6 +213,13 @@ public void ShowSeries(string series) #endregion + + + public void Redraw() + { + Invalidate(); + } + public double XMin { get { return ChartAreas[0].AxisX.Minimum; } @@ -235,11 +242,6 @@ public double XMin } } - public void Redraw() - { - Invalidate(); - } - public double XMax { get { return ChartAreas[0].AxisX.Maximum; } diff --git a/Computator.NET.Core.IntegrationTests/Computator.NET.Core.IntegrationTests.csproj b/Computator.NET.Core.IntegrationTests/Computator.NET.Core.IntegrationTests.csproj index 5b0016c..a74c18f 100644 --- a/Computator.NET.Core.IntegrationTests/Computator.NET.Core.IntegrationTests.csproj +++ b/Computator.NET.Core.IntegrationTests/Computator.NET.Core.IntegrationTests.csproj @@ -31,8 +31,8 @@ false - - + + @@ -44,4 +44,7 @@ + + + \ No newline at end of file diff --git a/Computator.NET.Core.Tests/Computator.NET.Core.Tests.csproj b/Computator.NET.Core.Tests/Computator.NET.Core.Tests.csproj index 3b77b1b..3490556 100644 --- a/Computator.NET.Core.Tests/Computator.NET.Core.Tests.csproj +++ b/Computator.NET.Core.Tests/Computator.NET.Core.Tests.csproj @@ -31,10 +31,10 @@ false - - + + - + @@ -45,4 +45,7 @@ + + + \ No newline at end of file diff --git a/Computator.NET.Core/Bootstrapping/CoreBootstrapper.cs b/Computator.NET.Core/Bootstrapping/CoreBootstrapper.cs index 0728ec6..51fd860 100644 --- a/Computator.NET.Core/Bootstrapping/CoreBootstrapper.cs +++ b/Computator.NET.Core/Bootstrapping/CoreBootstrapper.cs @@ -7,9 +7,23 @@ using Computator.NET.Core.Services.ErrorHandling; using Unity; using Unity.Lifetime; +using Unity.Registration; namespace Computator.NET.Core.Bootstrapping { + public static class ContainerExtensions + { + public static void RegisterTypeLegacy(this IUnityContainer container, params InjectionMember[] injectionMembers) where TTo : TFrom + { + container.RegisterTypeLegacy(null, injectionMembers); + } + + public static void RegisterTypeLegacy(this IUnityContainer container, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers) where TTo : TFrom + { + container.RegisterType(lifetimeManager); + container.RegisterType(); + } + } public class CoreBootstrapper { public IUnityContainer Container { get; } @@ -39,30 +53,30 @@ public void RegisterInstance(TInterface instance) private void RegisterModel() { //models and business objects - Container.RegisterType(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); } private void RegisterHandlers() { //singleton handlers - Container.RegisterType(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); } private void RegisterSharedObjects() { //shared singletons - Container.RegisterType(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); } } } \ No newline at end of file diff --git a/Computator.NET.Core/Bootstrapping/FuzzyMatchingParameterOverrideWithFallback.cs b/Computator.NET.Core/Bootstrapping/FuzzyMatchingParameterOverrideWithFallback.cs index b60a4aa..1cdf9eb 100644 --- a/Computator.NET.Core/Bootstrapping/FuzzyMatchingParameterOverrideWithFallback.cs +++ b/Computator.NET.Core/Bootstrapping/FuzzyMatchingParameterOverrideWithFallback.cs @@ -33,7 +33,7 @@ public FuzzyMatchingParameterOverrideWithFallback(Dictionary parameter } } - public override IDependencyResolverPolicy GetResolver(IBuilderContext context, Type dependencyType) + public override IResolverPolicy GetResolver(IBuilderContext context, Type dependencyType) { Guard.ArgumentNotNull(context, nameof(context)); diff --git a/Computator.NET.Core/Compilation/NativeCompiler.cs b/Computator.NET.Core/Compilation/NativeCompiler.cs index b79dd7b..41b5d51 100644 --- a/Computator.NET.Core/Compilation/NativeCompiler.cs +++ b/Computator.NET.Core/Compilation/NativeCompiler.cs @@ -88,15 +88,8 @@ private CompilationErrorPlace GetPlaceForLine(int line) public Assembly Compile(string input) { - if (RuntimeInformation.IsUnix) - { - if (!Directory.Exists(AppInformation.TempDirectory)) - { - Directory.CreateDirectory(AppInformation.TempDirectory); - } - //fix for #39 - otherwise in Mono CSharpCodeProvider will always return the same assembly - _parameters.OutputAssembly = Path.Combine(AppInformation.TempDirectory, Guid.NewGuid().ToString()); - } + FixForMonoAndNetCore(); + var results = CompileAssemblyFromSource(_parameters, input); if (results.Errors.HasErrors) @@ -152,6 +145,18 @@ public Assembly Compile(string input) return results.CompiledAssembly; } + private void FixForMonoAndNetCore() + { + //fix for #39 - otherwise in Mono CSharpCodeProvider will always return the same assembly + //this also happens on .NET Core + if (!Directory.Exists(AppInformation.TempDirectory)) + { + Directory.CreateDirectory(AppInformation.TempDirectory); + } + + _parameters.OutputAssembly = Path.Combine(AppInformation.TempDirectory, Guid.NewGuid().ToString()); + } + private CompilationException CreateCompilationExceptionFromCompilerResults(CompilerResults results) { var compilationException = new CompilationException(); diff --git a/Computator.NET.Core/Computator.NET.Core.csproj b/Computator.NET.Core/Computator.NET.Core.csproj index 612f3af..f5f4f04 100644 --- a/Computator.NET.Core/Computator.NET.Core.csproj +++ b/Computator.NET.Core/Computator.NET.Core.csproj @@ -77,12 +77,6 @@ PreserveNewest - - Always - - - Always - PreserveNewest @@ -92,10 +86,10 @@ - - + + - + diff --git a/Computator.NET.Core/Static/fonts/cambria.ttc b/Computator.NET.Core/Static/fonts/cambria.ttc deleted file mode 100644 index e0e8a21..0000000 Binary files a/Computator.NET.Core/Static/fonts/cambria.ttc and /dev/null differ diff --git a/Computator.NET.Core/Static/fonts/consola.ttf b/Computator.NET.Core/Static/fonts/consola.ttf deleted file mode 100644 index 4439f79..0000000 Binary files a/Computator.NET.Core/Static/fonts/consola.ttf and /dev/null differ diff --git a/Computator.NET.Core/TSL Examples/_Scripts/Example08_SolvingEquations.tsl b/Computator.NET.Core/TSL Examples/_Scripts/Example08_SolvingEquations.tsl index 0d27c97..a57a526 100644 --- a/Computator.NET.Core/TSL Examples/_Scripts/Example08_SolvingEquations.tsl +++ b/Computator.NET.Core/TSL Examples/_Scripts/Example08_SolvingEquations.tsl @@ -21,7 +21,7 @@ var results = solve(eq); writeln(results); //alternatively we could call it on all it's elements -writeln("x = "); write(results[0]); -writeln("y = "); write(results[1]); -writeln("z = "); write(results[2]); +write("x = "); writeln(results[0]); +write("y = "); writeln(results[1]); +write("z = "); writeln(results[2]); //of course that would be not very useful for bigger sets of equations \ No newline at end of file diff --git a/Computator.NET.DataTypes/Computator.NET.DataTypes.csproj b/Computator.NET.DataTypes/Computator.NET.DataTypes.csproj index 8e1f9e8..22f61bb 100644 --- a/Computator.NET.DataTypes/Computator.NET.DataTypes.csproj +++ b/Computator.NET.DataTypes/Computator.NET.DataTypes.csproj @@ -45,7 +45,7 @@ - + diff --git a/Computator.NET.DataTypes/Configuration/AppInformation.cs b/Computator.NET.DataTypes/Configuration/AppInformation.cs index 1d74049..b4d146c 100644 --- a/Computator.NET.DataTypes/Configuration/AppInformation.cs +++ b/Computator.NET.DataTypes/Configuration/AppInformation.cs @@ -15,7 +15,6 @@ public static class AppInformation public static readonly string DataDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments,Environment.SpecialFolderOption.Create), AppInformation.Name); public static readonly string LogsDirectory = Path.Combine(DataDirectory, "Logs"); public static readonly string SettingsPath = Path.Combine(DataDirectory, "settings.dat"); - public static readonly string FontsDirectory = Path.Combine(Directory, "Static","fonts"); public static readonly string TempDirectory = Path.Combine(Path.GetTempPath(), $"{An.Name}.{An.ProcessorArchitecture}.{An.Version}"); diff --git a/Computator.NET.DataTypes/Text/CustomFonts.cs b/Computator.NET.DataTypes/Text/CustomFonts.cs index 109b1e4..491cfba 100644 --- a/Computator.NET.DataTypes/Text/CustomFonts.cs +++ b/Computator.NET.DataTypes/Text/CustomFonts.cs @@ -11,15 +11,6 @@ namespace Computator.NET.DataTypes.Text { public static class CustomFonts { - [DllImport("gdi32.dll")] - private static extern IntPtr AddFontMemResourceEx(IntPtr pbFont, uint cbFont, IntPtr pdv, [In] ref uint pcFonts); - - private static readonly ILogger Logger = LogManager.GetCurrentClassLogger(); - - private static PrivateFontCollection mathFontCollection; - - private static PrivateFontCollection scriptingFontCollection; - public static Font GetFontFromFont(Font value) { if (value.FontFamily.Name.ToLowerInvariant().Contains("cambria")) @@ -35,68 +26,12 @@ public static Font GetFontFromFont(Font value) public static Font GetMathFont(float fontSize) { - if (mathFontCollection == null) GetCustomFonts(); - return new Font(mathFontCollection.Families[0], fontSize, GraphicsUnit.Point); + return new Font("Cambria", fontSize, GraphicsUnit.Point); } public static Font GetScriptingFont(float fontSize) { - if (scriptingFontCollection == null) GetCustomFonts(); - return new Font(scriptingFontCollection.Families[0], fontSize, GraphicsUnit.Point); - } - - - private static void GetCustomFonts() - { - mathFontCollection = new PrivateFontCollection(); - scriptingFontCollection = new PrivateFontCollection(); - - var pathToMathFont = Path.Combine(AppInformation.FontsDirectory, "cambria.ttc"); - var pathToScriptFont = Path.Combine(AppInformation.FontsDirectory, "consola.ttf"); - try - { - if (RuntimeInformation.IsUnix) - { - mathFontCollection.AddFontFile(pathToMathFont); - scriptingFontCollection.AddFontFile(pathToScriptFont); - } - else - { - RegisterFont(mathFontCollection,pathToMathFont); - RegisterFont(scriptingFontCollection, pathToScriptFont); - } - } - catch (Exception ex) - { - var nex = - new Exception( - "Probably missing " + pathToMathFont + " or " + pathToScriptFont + " file\nDetails:" + ex.Message, ex); - - Logger.Error(ex, "Probably missing " + pathToMathFont + " file\nDetails:" + ex.Message); - throw nex; - } - } - - private static void RegisterFont(PrivateFontCollection pfc, string path) - { - var fontData = File.ReadAllBytes(path); - - //create an unsafe memory block for the data - System.IntPtr data = Marshal.AllocCoTaskMem((int)fontData.Length); - - - //copy the bytes to the unsafe memory block - Marshal.Copy(fontData, 0, data, (int)fontData.Length); - - // We HAVE to do this to register the font to the system (Weird .NET bug !) - uint pcFonts = 0; - AddFontMemResourceEx(data, (uint)fontData.Length, IntPtr.Zero, ref pcFonts); - - //pass the font to the font collection - pfc.AddMemoryFont(data, (int)fontData.Length); - - //free the unsafe memory - Marshal.FreeCoTaskMem(data); + return new Font("Consolas", fontSize, GraphicsUnit.Point); } } } \ No newline at end of file diff --git a/Computator.NET.Desktop.UITests/Computator.NET.Desktop.UITests.csproj b/Computator.NET.Desktop.UITests/Computator.NET.Desktop.UITests.csproj index 3b9ee25..5919acf 100644 --- a/Computator.NET.Desktop.UITests/Computator.NET.Desktop.UITests.csproj +++ b/Computator.NET.Desktop.UITests/Computator.NET.Desktop.UITests.csproj @@ -30,9 +30,9 @@ - + - + diff --git a/Computator.NET.Desktop/Bootstrapping/WinFormsBootstrapper.cs b/Computator.NET.Desktop/Bootstrapping/WinFormsBootstrapper.cs index 5fc3313..c9103e0 100644 --- a/Computator.NET.Desktop/Bootstrapping/WinFormsBootstrapper.cs +++ b/Computator.NET.Desktop/Bootstrapping/WinFormsBootstrapper.cs @@ -33,7 +33,7 @@ public WinFormsBootstrapper() : this(new UnityContainer()) public WinFormsBootstrapper(IUnityContainer coreContainer) : base(coreContainer) { - Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); RegisterWinFormsServices(); RegisterViews(); RegisterControls(); @@ -41,9 +41,9 @@ public WinFormsBootstrapper(IUnityContainer coreContainer) : base(coreContainer) private void RegisterWinFormsServices() { - Container.RegisterType(); - Container.RegisterType(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); } public override T Create() @@ -70,40 +70,40 @@ private void CreatePresenters() private void RegisterViews() { //views - Container.RegisterType(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); - // container.RegisterType(new ContainerControlledLifetimeManager()); - // container.RegisterType(new ContainerControlledLifetimeManager()); + // container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + // container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); - Container.RegisterType( + Container.RegisterTypeLegacy( new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); - Container.RegisterType(); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(); - Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); } private void RegisterControls() { //components and controls //charts - Container.RegisterType(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); - Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); //ExpressionTextBox - Container.RegisterType(new ContainerControlledLifetimeManager()); + Container.RegisterTypeLegacy(new ContainerControlledLifetimeManager()); Container.RegisterType(new InjectionFactory(c => Container.Resolve())); - Container.RegisterType(); - Container.RegisterType(); + Container.RegisterTypeLegacy(); + Container.RegisterTypeLegacy(); //Scripting and CustomFunctions Container.RegisterType("scripting"); @@ -117,19 +117,19 @@ private void RegisterControls() //container.RegisterType();//check Container.RegisterType( - new InjectionFactory(c => Container.Resolve(_resolver))); + new InjectionFactory(c => c.Resolve(_resolver))); Container.RegisterType( - new InjectionFactory(c => Container.Resolve(_resolver))); + new InjectionFactory(c => c.Resolve(_resolver))); Container.RegisterType( - new InjectionFactory(c => Container.Resolve(_resolver))); + new InjectionFactory(c => c.Resolve(_resolver))); Container.RegisterType( - new InjectionFactory(c => Container.Resolve(_resolver))); + new InjectionFactory(c => c.Resolve(_resolver))); Container.RegisterType( - new InjectionFactory(c => Container.Resolve(_resolver))); + new InjectionFactory(c => c.Resolve(_resolver))); Container.RegisterType( - new InjectionFactory(c => Container.Resolve(_resolver))); + new InjectionFactory(c => c.Resolve(_resolver))); Container.RegisterType( - new InjectionFactory(c => Container.Resolve(_resolver))); + new InjectionFactory(c => c.Resolve(_resolver))); } } } \ No newline at end of file diff --git a/Computator.NET.Desktop/Computator.NET.Desktop.csproj b/Computator.NET.Desktop/Computator.NET.Desktop.csproj index 126ac65..6d6df9a 100644 --- a/Computator.NET.Desktop/Computator.NET.Desktop.csproj +++ b/Computator.NET.Desktop/Computator.NET.Desktop.csproj @@ -35,8 +35,8 @@ - - + + diff --git a/Computator.NET.Desktop/Startup.cs b/Computator.NET.Desktop/Startup.cs index fddf455..e16b4b5 100644 --- a/Computator.NET.Desktop/Startup.cs +++ b/Computator.NET.Desktop/Startup.cs @@ -40,18 +40,9 @@ private static void CurrentDomain_UnhandledException(object sender, UnhandledExc if (ex.Message.ToLowerInvariant().Contains("font")) { - //e.IsTerminating = false; - if (MessageBox.Show(Strings.Program_CurrentDomain_UnhandledException_Try_installing_font_, Strings.Warning_, MessageBoxButtons.OKCancel) == DialogResult.OK) - { - var fonts = Directory.EnumerateFiles(AppInformation.FontsDirectory, "*.*", SearchOption.AllDirectories) - .Where(s => s.EndsWith(".ttc", StringComparison.OrdinalIgnoreCase) || - s.EndsWith(".ttf", StringComparison.OrdinalIgnoreCase) || - s.EndsWith(".otf", StringComparison.OrdinalIgnoreCase)); - foreach (var font in fonts) - { - Process.Start(font);//ttc/ttf/otf - } - } + MessageBox.Show( + Strings.Program_CurrentDomain_UnhandledException_Try_installing_font_ + " Cambria, Consolas", + Strings.Warning_, MessageBoxButtons.OKCancel); } Logger.Error(ex, Strings.Unhandled_UI_Exception + $"is terminting: {e.IsTerminating}, {e?.ExceptionObject}"); diff --git a/Computator.NET.Installer/Computator.NET.Installer.csproj b/Computator.NET.Installer/Computator.NET.Installer.csproj index f9bb9ea..96b02c4 100644 --- a/Computator.NET.Installer/Computator.NET.Installer.csproj +++ b/Computator.NET.Installer/Computator.NET.Installer.csproj @@ -33,8 +33,8 @@ - - + + \ No newline at end of file diff --git a/Computator.NET.Installer/Dependencies/NetFx40WebInstaller.cs b/Computator.NET.Installer/Dependencies/NetFx40WebInstaller.cs index c1faaee..c9d8f24 100644 --- a/Computator.NET.Installer/Dependencies/NetFx40WebInstaller.cs +++ b/Computator.NET.Installer/Dependencies/NetFx40WebInstaller.cs @@ -1,5 +1,4 @@ -using Microsoft.Win32; -using WixSharp; +using WixSharp; using WixSharp.Bootstrapper; namespace Computator.NET.Installer diff --git a/Computator.NET.Installer/Dependencies/NetFx461WebInstaller.cs b/Computator.NET.Installer/Dependencies/NetFx461WebInstaller.cs index 750d795..aa0d716 100644 --- a/Computator.NET.Installer/Dependencies/NetFx461WebInstaller.cs +++ b/Computator.NET.Installer/Dependencies/NetFx461WebInstaller.cs @@ -1,5 +1,4 @@ -using Microsoft.Win32; -using WixSharp; +using WixSharp; using WixSharp.Bootstrapper; namespace Computator.NET.Installer diff --git a/Computator.NET.Installer/Dependencies/PatchKB2468871.cs b/Computator.NET.Installer/Dependencies/PatchKB2468871.cs index ced2377..81bd722 100644 --- a/Computator.NET.Installer/Dependencies/PatchKB2468871.cs +++ b/Computator.NET.Installer/Dependencies/PatchKB2468871.cs @@ -1,6 +1,5 @@ using System.Linq; using Microsoft.Deployment.WindowsInstaller; -using Microsoft.Win32; using WixSharp; using WixSharp.Bootstrapper; diff --git a/Computator.NET.Installer/Fonts.cs b/Computator.NET.Installer/Fonts.cs deleted file mode 100644 index 98d24d6..0000000 --- a/Computator.NET.Installer/Fonts.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Xml; -using System.Xml.Linq; -using WixSharp; - -namespace Computator.NET.Installer -{ - class Fonts - { - public static WixEntity[] GetFontFiles() - { - var consolaFont = new FontFile(@"..\Computator.NET.Core\Static\fonts\consola.ttf") - { - NeverOverwrite = false, - TrueType = true, - }; - var cambriaFont = new FontFile(@"..\Computator.NET.Core\Static\fonts\cambria.ttc") - { - NeverOverwrite = false, - TrueType = true, - }; - - return new WixEntity[] {consolaFont, cambriaFont}; - } - - public static void InjectFonts(System.Xml.Linq.XDocument document) - { - var fontsDirectoryDocument = new XmlDocument(); - fontsDirectoryDocument.LoadXml(@" - - - - - - "); - - document.Root.Select("Product/Directory").AddElement(XmlElementToXelement(fontsDirectoryDocument.DocumentElement)); - - - var fontsFolderComponent = new XmlDocument(); - fontsFolderComponent.LoadXml(@""); - document.Root.Select("Product/Feature").AddElement(XmlElementToXelement(fontsFolderComponent.DocumentElement)); - } - - private static XElement XmlElementToXelement(XmlElement e) - { - return XElement.Parse(e.OuterXml); - } - } -} diff --git a/Computator.NET.Installer/ProjectBuilder.cs b/Computator.NET.Installer/ProjectBuilder.cs index a0f024f..8d90001 100644 --- a/Computator.NET.Installer/ProjectBuilder.cs +++ b/Computator.NET.Installer/ProjectBuilder.cs @@ -39,7 +39,6 @@ public string BuildMsi() var project = new Project("Computator.NET", new Dir(@"%ProgramFiles%\Computator.NET", new Files(binariesPath), new File(new Id(nameof(SharedProperties.TslIcon)), SharedProperties.TslIcon)) - ,new Dir("%Fonts%", Fonts.GetFontFiles()) ) { Version = SharedProperties.Version, diff --git a/Computator.NET.WebApi.IntegrationTests/Computator.NET.WebApi.IntegrationTests.csproj b/Computator.NET.WebApi.IntegrationTests/Computator.NET.WebApi.IntegrationTests.csproj index 5b67442..f131739 100644 --- a/Computator.NET.WebApi.IntegrationTests/Computator.NET.WebApi.IntegrationTests.csproj +++ b/Computator.NET.WebApi.IntegrationTests/Computator.NET.WebApi.IntegrationTests.csproj @@ -16,10 +16,10 @@ - - - - + + + + diff --git a/Computator.NET.WebApi/Computator.NET.WebApi.csproj b/Computator.NET.WebApi/Computator.NET.WebApi.csproj index ff1b429..4f7120f 100644 --- a/Computator.NET.WebApi/Computator.NET.WebApi.csproj +++ b/Computator.NET.WebApi/Computator.NET.WebApi.csproj @@ -5,7 +5,6 @@ true net461 AnyCPU - win-x64 false false false @@ -37,15 +36,15 @@ - - - - - - + + + + + + - - + + diff --git a/Computator.NET.WebClient/ClientApp/boot-client.tsx b/Computator.NET.WebClient/ClientApp/boot-client.tsx deleted file mode 100644 index cc4ce3e..0000000 --- a/Computator.NET.WebClient/ClientApp/boot-client.tsx +++ /dev/null @@ -1,43 +0,0 @@ -import './css/site.css'; -import 'bootstrap'; -import * as React from 'react'; -import * as ReactDOM from 'react-dom'; -import { AppContainer } from 'react-hot-loader'; -import { Provider } from 'react-redux'; -import { ConnectedRouter } from 'react-router-redux'; -import { createBrowserHistory } from 'history'; -import configureStore from './configureStore'; -import { ApplicationState } from './store'; -import * as RoutesModule from './routes'; -let routes = RoutesModule.routes; - -// Create browser history to use in the Redux store -const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href')!; -const history = createBrowserHistory({ basename: baseUrl }); - -// Get the application-wide store instance, prepopulating with state from the server where available. -const initialState = (window as any).initialReduxState as ApplicationState; -const store = configureStore(history, initialState); - -function renderApp() { - // This code starts up the React app when it runs in a browser. It sets up the routing configuration - // and injects the app into a DOM element. - ReactDOM.render( - - - - - , - document.getElementById('react-app') - ); -} - -renderApp(); - -// Allow Hot Module Replacement -if (module.hot) { - module.hot.accept('./routes', () => { - routes = require('./routes').routes; - renderApp(); - }); -} diff --git a/Computator.NET.WebClient/ClientApp/boot-server.tsx b/Computator.NET.WebClient/ClientApp/boot-server.tsx deleted file mode 100644 index 7b622c0..0000000 --- a/Computator.NET.WebClient/ClientApp/boot-server.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import * as React from 'react'; -import { Provider } from 'react-redux'; -import { renderToString } from 'react-dom/server'; -import { StaticRouter } from 'react-router-dom'; -import { replace } from 'react-router-redux'; -import { createMemoryHistory } from 'history'; -import { createServerRenderer, RenderResult } from 'aspnet-prerendering'; -import { routes } from './routes'; -import configureStore from './configureStore'; - -export default createServerRenderer(params => { - return new Promise((resolve, reject) => { - // Prepare Redux store with in-memory history, and dispatch a navigation event - // corresponding to the incoming URL - const basename = params.baseUrl.substring(0, params.baseUrl.length - 1); // Remove trailing slash - const urlAfterBasename = params.url.substring(basename.length); - const store = configureStore(createMemoryHistory()); - store.dispatch(replace(urlAfterBasename)); - - // Prepare an instance of the application and perform an inital render that will - // cause any async tasks (e.g., data access) to begin - const routerContext: any = {}; - const app = ( - - - - ); - renderToString(app); - - // If there's a redirection, just send this information back to the host application - if (routerContext.url) { - resolve({ redirectUrl: routerContext.url }); - return; - } - - // Once any async tasks are done, we can perform the final render - // We also send the redux store state, so the client can continue execution where the server left off - params.domainTasks.then(() => { - resolve({ - html: renderToString(app), - globals: { initialReduxState: store.getState() } - }); - }, reject); // Also propagate any errors back into the host application - }); -}); diff --git a/Computator.NET.WebClient/ClientApp/boot.tsx b/Computator.NET.WebClient/ClientApp/boot.tsx new file mode 100644 index 0000000..f1081ff --- /dev/null +++ b/Computator.NET.WebClient/ClientApp/boot.tsx @@ -0,0 +1,30 @@ +import './css/site.css'; +import 'bootstrap'; +import * as React from 'react'; +import * as ReactDOM from 'react-dom'; +import { AppContainer } from 'react-hot-loader'; +import { BrowserRouter } from 'react-router-dom'; +import * as RoutesModule from './routes'; +let routes = RoutesModule.routes; + +function renderApp() { + // This code starts up the React app when it runs in a browser. It sets up the routing + // configuration and injects the app into a DOM element. + const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href')!; + ReactDOM.render( + + + , + document.getElementById('react-app') + ); +} + +renderApp(); + +// Allow Hot Module Replacement +if (module.hot) { + module.hot.accept('./routes', () => { + routes = require('./routes').routes; + renderApp(); + }); +} diff --git a/Computator.NET.WebClient/ClientApp/components/Counter.tsx b/Computator.NET.WebClient/ClientApp/components/Counter.tsx deleted file mode 100644 index da275fb..0000000 --- a/Computator.NET.WebClient/ClientApp/components/Counter.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import * as React from 'react'; -import { Link, RouteComponentProps } from 'react-router-dom'; -import { connect } from 'react-redux'; -import { ApplicationState } from '../store'; -import * as CounterStore from '../store/Counter'; -import * as WeatherForecasts from '../store/WeatherForecasts'; - -type CounterProps = - CounterStore.CounterState - & typeof CounterStore.actionCreators - & RouteComponentProps<{}>; - -class Counter extends React.Component { - public render() { - return
-

Counter

- -

This is a simple example of a React component.

- -

Current count: { this.props.count }

- - -
; - } -} - -// Wire up the React component to the Redux store -export default connect( - (state: ApplicationState) => state.counter, // Selects which state properties are merged into the component's props - CounterStore.actionCreators // Selects which action creators are merged into the component's props -)(Counter) as typeof Counter; \ No newline at end of file diff --git a/Computator.NET.WebClient/ClientApp/components/FetchData.tsx b/Computator.NET.WebClient/ClientApp/components/FetchData.tsx index e4e2ebc..ce191bd 100644 --- a/Computator.NET.WebClient/ClientApp/components/FetchData.tsx +++ b/Computator.NET.WebClient/ClientApp/components/FetchData.tsx @@ -1,38 +1,37 @@ import * as React from 'react'; -import { Link, RouteComponentProps } from 'react-router-dom'; -import { connect } from 'react-redux'; -import { ApplicationState } from '../store'; -import * as WeatherForecastsState from '../store/WeatherForecasts'; +import { RouteComponentProps } from 'react-router'; +import 'isomorphic-fetch'; -// At runtime, Redux will merge together... -type WeatherForecastProps = - WeatherForecastsState.WeatherForecastsState // ... state we've requested from the Redux store - & typeof WeatherForecastsState.actionCreators // ... plus action creators we've requested - & RouteComponentProps<{ startDateIndex: string }>; // ... plus incoming routing parameters +interface FetchDataExampleState { + forecasts: WeatherForecast[]; + loading: boolean; +} -export class FetchData extends React.Component { - componentWillMount() { - // This method runs when the component is first added to the page - let startDateIndex = parseInt(this.props.match.params.startDateIndex) || 0; - this.props.requestWeatherForecasts(startDateIndex); - } +export class FetchData extends React.Component, FetchDataExampleState> { + constructor() { + super(); + this.state = { forecasts: [], loading: true }; - componentWillReceiveProps(nextProps: WeatherForecastProps) { - // This method runs when incoming props (e.g., route params) change - let startDateIndex = parseInt(nextProps.match.params.startDateIndex) || 0; - this.props.requestWeatherForecasts(startDateIndex); + fetch('api/SampleData/WeatherForecasts') + .then(response => response.json() as Promise) + .then(data => { + this.setState({ forecasts: data, loading: false }); + }); } public render() { + let contents = this.state.loading + ?

Loading...

+ : FetchData.renderForecastsTable(this.state.forecasts); + return

Weather forecast

-

This component demonstrates fetching data from the server and working with URL parameters.

- { this.renderForecastsTable() } - { this.renderPagination() } +

This component demonstrates fetching data from the server.

+ { contents }
; } - private renderForecastsTable() { + private static renderForecastsTable(forecasts: WeatherForecast[]) { return @@ -43,7 +42,7 @@ export class FetchData extends React.Component { - {this.props.forecasts.map(forecast => + {forecasts.map(forecast => @@ -54,20 +53,11 @@ export class FetchData extends React.Component {
{ forecast.dateFormatted } { forecast.temperatureC }
; } - - private renderPagination() { - let prevStartDateIndex = (this.props.startDateIndex || 0) - 5; - let nextStartDateIndex = (this.props.startDateIndex || 0) + 5; - - return

- Previous - Next - { this.props.isLoading ? Loading... : [] } -

; - } } -export default connect( - (state: ApplicationState) => state.weatherForecasts, // Selects which state properties are merged into the component's props - WeatherForecastsState.actionCreators // Selects which action creators are merged into the component's props -)(FetchData) as typeof FetchData; +interface WeatherForecast { + dateFormatted: string; + temperatureC: number; + temperatureF: number; + summary: string; +} diff --git a/Computator.NET.WebClient/ClientApp/components/Layout.tsx b/Computator.NET.WebClient/ClientApp/components/Layout.tsx index db3f646..8c8870e 100644 --- a/Computator.NET.WebClient/ClientApp/components/Layout.tsx +++ b/Computator.NET.WebClient/ClientApp/components/Layout.tsx @@ -1,7 +1,11 @@ import * as React from 'react'; import { NavMenu } from './NavMenu'; -export class Layout extends React.Component<{}, {}> { +export interface LayoutProps { + children?: React.ReactNode; +} + +export class Layout extends React.Component { public render() { return
diff --git a/Computator.NET.WebClient/ClientApp/configureStore.ts b/Computator.NET.WebClient/ClientApp/configureStore.ts deleted file mode 100644 index 79c22ab..0000000 --- a/Computator.NET.WebClient/ClientApp/configureStore.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { createStore, applyMiddleware, compose, combineReducers, GenericStoreEnhancer, Store, StoreEnhancerStoreCreator, ReducersMapObject } from 'redux'; -import thunk from 'redux-thunk'; -import { routerReducer, routerMiddleware } from 'react-router-redux'; -import * as StoreModule from './store'; -import { ApplicationState, reducers } from './store'; -import { History } from 'history'; - -export default function configureStore(history: History, initialState?: ApplicationState) { - // Build middleware. These are functions that can process the actions before they reach the store. - const windowIfDefined = typeof window === 'undefined' ? null : window as any; - // If devTools is installed, connect to it - const devToolsExtension = windowIfDefined && windowIfDefined.devToolsExtension as () => GenericStoreEnhancer; - const createStoreWithMiddleware = compose( - applyMiddleware(thunk, routerMiddleware(history)), - devToolsExtension ? devToolsExtension() : (next: StoreEnhancerStoreCreator) => next - )(createStore); - - // Combine all reducers and instantiate the app-wide store instance - const allReducers = buildRootReducer(reducers); - const store = createStoreWithMiddleware(allReducers, initialState) as Store; - - // Enable Webpack hot module replacement for reducers - if (module.hot) { - module.hot.accept('./store', () => { - const nextRootReducer = require('./store'); - store.replaceReducer(buildRootReducer(nextRootReducer.reducers)); - }); - } - - return store; -} - -function buildRootReducer(allReducers: ReducersMapObject) { - return combineReducers(Object.assign({}, allReducers, { routing: routerReducer })); -} diff --git a/Computator.NET.WebClient/ClientApp/routes.tsx b/Computator.NET.WebClient/ClientApp/routes.tsx index a713d61..78ab517 100644 --- a/Computator.NET.WebClient/ClientApp/routes.tsx +++ b/Computator.NET.WebClient/ClientApp/routes.tsx @@ -8,9 +8,9 @@ import { Scripting } from './components/Scripting'; import { NumericalCalculations } from './components/NumericalCalculations'; export const routes = - + - + ; diff --git a/Computator.NET.WebClient/ClientApp/store/Counter.ts b/Computator.NET.WebClient/ClientApp/store/Counter.ts deleted file mode 100644 index baa3206..0000000 --- a/Computator.NET.WebClient/ClientApp/store/Counter.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { Action, Reducer } from 'redux'; - -// ----------------- -// STATE - This defines the type of data maintained in the Redux store. - -export interface CounterState { - count: number; -} - -// ----------------- -// ACTIONS - These are serializable (hence replayable) descriptions of state transitions. -// They do not themselves have any side-effects; they just describe something that is going to happen. -// Use @typeName and isActionType for type detection that works even after serialization/deserialization. - -interface IncrementCountAction { type: 'INCREMENT_COUNT' } -interface DecrementCountAction { type: 'DECREMENT_COUNT' } - -// Declare a 'discriminated union' type. This guarantees that all references to 'type' properties contain one of the -// declared type strings (and not any other arbitrary string). -type KnownAction = IncrementCountAction | DecrementCountAction; - -// ---------------- -// ACTION CREATORS - These are functions exposed to UI components that will trigger a state transition. -// They don't directly mutate state, but they can have external side-effects (such as loading data). - -export const actionCreators = { - increment: () => { type: 'INCREMENT_COUNT' }, - decrement: () => { type: 'DECREMENT_COUNT' } -}; - -// ---------------- -// REDUCER - For a given state and action, returns the new state. To support time travel, this must not mutate the old state. - -export const reducer: Reducer = (state: CounterState, action: KnownAction) => { - switch (action.type) { - case 'INCREMENT_COUNT': - return { count: state.count + 1 }; - case 'DECREMENT_COUNT': - return { count: state.count - 1 }; - default: - // The following line guarantees that every action in the KnownAction union has been covered by a case above - const exhaustiveCheck: never = action; - } - - // For unrecognized actions (or in cases where actions have no effect), must return the existing state - // (or default initial state if none was supplied) - return state || { count: 0 }; -}; diff --git a/Computator.NET.WebClient/ClientApp/store/WeatherForecasts.ts b/Computator.NET.WebClient/ClientApp/store/WeatherForecasts.ts deleted file mode 100644 index ea79d9f..0000000 --- a/Computator.NET.WebClient/ClientApp/store/WeatherForecasts.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { fetch, addTask } from 'domain-task'; -import { Action, Reducer, ActionCreator } from 'redux'; -import { AppThunkAction } from './'; - -// ----------------- -// STATE - This defines the type of data maintained in the Redux store. - -export interface WeatherForecastsState { - isLoading: boolean; - startDateIndex?: number; - forecasts: WeatherForecast[]; -} - -export interface WeatherForecast { - dateFormatted: string; - temperatureC: number; - temperatureF: number; - summary: string; -} - -// ----------------- -// ACTIONS - These are serializable (hence replayable) descriptions of state transitions. -// They do not themselves have any side-effects; they just describe something that is going to happen. - -interface RequestWeatherForecastsAction { - type: 'REQUEST_WEATHER_FORECASTS'; - startDateIndex: number; -} - -interface ReceiveWeatherForecastsAction { - type: 'RECEIVE_WEATHER_FORECASTS'; - startDateIndex: number; - forecasts: WeatherForecast[]; -} - -// Declare a 'discriminated union' type. This guarantees that all references to 'type' properties contain one of the -// declared type strings (and not any other arbitrary string). -type KnownAction = RequestWeatherForecastsAction | ReceiveWeatherForecastsAction; - -// ---------------- -// ACTION CREATORS - These are functions exposed to UI components that will trigger a state transition. -// They don't directly mutate state, but they can have external side-effects (such as loading data). - -export const actionCreators = { - requestWeatherForecasts: (startDateIndex: number): AppThunkAction => (dispatch, getState) => { - // Only load data if it's something we don't already have (and are not already loading) - if (startDateIndex !== getState().weatherForecasts.startDateIndex) { - let fetchTask = fetch(`api/SampleData/WeatherForecasts?startDateIndex=${ startDateIndex }`) - .then(response => response.json() as Promise) - .then(data => { - dispatch({ type: 'RECEIVE_WEATHER_FORECASTS', startDateIndex: startDateIndex, forecasts: data }); - }); - - addTask(fetchTask); // Ensure server-side prerendering waits for this to complete - dispatch({ type: 'REQUEST_WEATHER_FORECASTS', startDateIndex: startDateIndex }); - } - } -}; - -// ---------------- -// REDUCER - For a given state and action, returns the new state. To support time travel, this must not mutate the old state. - -const unloadedState: WeatherForecastsState = { forecasts: [], isLoading: false }; - -export const reducer: Reducer = (state: WeatherForecastsState, incomingAction: Action) => { - const action = incomingAction as KnownAction; - switch (action.type) { - case 'REQUEST_WEATHER_FORECASTS': - return { - startDateIndex: action.startDateIndex, - forecasts: state.forecasts, - isLoading: true - }; - case 'RECEIVE_WEATHER_FORECASTS': - // Only accept the incoming data if it matches the most recent request. This ensures we correctly - // handle out-of-order responses. - if (action.startDateIndex === state.startDateIndex) { - return { - startDateIndex: action.startDateIndex, - forecasts: action.forecasts, - isLoading: false - }; - } - break; - default: - // The following line guarantees that every action in the KnownAction union has been covered by a case above - const exhaustiveCheck: never = action; - } - - return state || unloadedState; -}; diff --git a/Computator.NET.WebClient/ClientApp/store/index.ts b/Computator.NET.WebClient/ClientApp/store/index.ts deleted file mode 100644 index 0b5b3c1..0000000 --- a/Computator.NET.WebClient/ClientApp/store/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -import * as WeatherForecasts from './WeatherForecasts'; -import * as Counter from './Counter'; - -// The top-level state object -export interface ApplicationState { - counter: Counter.CounterState; - weatherForecasts: WeatherForecasts.WeatherForecastsState; -} - -// Whenever an action is dispatched, Redux will update each top-level application state property using -// the reducer with the matching name. It's important that the names match exactly, and that the reducer -// acts on the corresponding ApplicationState property type. -export const reducers = { - counter: Counter.reducer, - weatherForecasts: WeatherForecasts.reducer -}; - -// This type can be used as a hint on action creators so that its 'dispatch' and 'getState' params are -// correctly typed to match your store. -export interface AppThunkAction { - (dispatch: (action: TAction) => void, getState: () => ApplicationState): void; -} diff --git a/Computator.NET.WebClient/Computator.NET.WebClient.csproj b/Computator.NET.WebClient/Computator.NET.WebClient.csproj index 1282e0a..1e4b6ec 100644 --- a/Computator.NET.WebClient/Computator.NET.WebClient.csproj +++ b/Computator.NET.WebClient/Computator.NET.WebClient.csproj @@ -3,7 +3,7 @@ PackageReference true true - netcoreapp2.0 + netcoreapp2.1 true false AnyCPU @@ -32,24 +32,19 @@ false false - - - - - - - - - - + + + + + + - - + @@ -65,6 +60,7 @@ + @@ -73,7 +69,7 @@ - + %(DistFiles.Identity) PreserveNewest diff --git a/Computator.NET.WebClient/Controllers/SampleDataController.cs b/Computator.NET.WebClient/Controllers/SampleDataController.cs index b2039ee..04153e2 100644 --- a/Computator.NET.WebClient/Controllers/SampleDataController.cs +++ b/Computator.NET.WebClient/Controllers/SampleDataController.cs @@ -15,12 +15,12 @@ public class SampleDataController : Controller }; [HttpGet("[action]")] - public IEnumerable WeatherForecasts(int startDateIndex) + public IEnumerable WeatherForecasts() { var rng = new Random(); return Enumerable.Range(1, 5).Select(index => new WeatherForecast { - DateFormatted = DateTime.Now.AddDays(index + startDateIndex).ToString("d"), + DateFormatted = DateTime.Now.AddDays(index).ToString("d"), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }); diff --git a/Computator.NET.WebClient/Views/Home/Index.cshtml b/Computator.NET.WebClient/Views/Home/Index.cshtml index a53a97e..139ed8a 100644 --- a/Computator.NET.WebClient/Views/Home/Index.cshtml +++ b/Computator.NET.WebClient/Views/Home/Index.cshtml @@ -2,8 +2,8 @@ ViewData["Title"] = "Home Page"; } -
Loading...
+
Loading...
@section scripts { - + } diff --git a/Computator.NET.WebClient/Views/Shared/_Layout.cshtml b/Computator.NET.WebClient/Views/Shared/_Layout.cshtml index 723e9bd..ae27f0b 100644 --- a/Computator.NET.WebClient/Views/Shared/_Layout.cshtml +++ b/Computator.NET.WebClient/Views/Shared/_Layout.cshtml @@ -7,7 +7,9 @@ - + + + @RenderBody() diff --git a/Computator.NET.WebClient/package.json b/Computator.NET.WebClient/package.json index fb8f92e..30d7a35 100644 --- a/Computator.NET.WebClient/package.json +++ b/Computator.NET.WebClient/package.json @@ -35,7 +35,7 @@ "author": "TROKA Software", "license": "GPL-3.0", "description": "Computator.NET is a unique open numerical software that is fast and easy to use and stands up to other feature-wise software.", - "dependencies": { + "devDependencies": { "@types/ace": "0.0.35", "@types/history": "4.6.0", "@types/isomorphic-fetch": "0.0.34", @@ -43,42 +43,31 @@ "@types/react": "16.0.2", "@types/react-dom": "15.5.2", "@types/react-hot-loader": "3.0.3", - "@types/react-redux": "4.4.45", "@types/react-router": "4.0.14", "@types/react-router-dom": "4.0.5", - "@types/react-router-redux": "5.0.3", "@types/webpack": "3.0.8", "@types/webpack-env": "1.13.0", - "aspnet-prerendering": "^3.0.1", "aspnet-webpack": "^2.0.1", "aspnet-webpack-react": "^3.0.0", "awesome-typescript-loader": "3.2.3", "brace": "0.10.0", - "bootstrap": "3.3.7", - "css-loader": "0.28.5", - "domain-task": "^3.0.3", + "bootstrap": "3.4.1", + "css-loader": "0.28.4", "event-source-polyfill": "0.0.9", "extract-text-webpack-plugin": "3.0.0", "file-loader": "0.11.2", "isomorphic-fetch": "2.2.1", - "history": "4.6.3", - "jquery": "3.2.1", + "jquery": "3.5.0", "json-loader": "0.5.7", - "node-noop": "1.0.0", "react": "15.6.1", "react-dom": "15.6.1", "react-hot-loader": "3.0.0-beta.7", - "react-redux": "5.0.6", "react-router-dom": "4.1.2", "react-ace": "5.1.2", - "react-router-redux": "5.0.0-alpha.6", - "redux": "3.7.2", - "redux-thunk": "2.2.0", "style-loader": "0.18.2", "typescript": "2.4.2", "url-loader": "0.5.9", - "webpack": "3.5.5", - "webpack-hot-middleware": "2.18.2", - "webpack-merge": "4.1.0" + "webpack": "3.5.4", + "webpack-hot-middleware": "2.18.2" } } diff --git a/Computator.NET.WebClient/tsconfig.json b/Computator.NET.WebClient/tsconfig.json index 7909f2d..ed53101 100644 --- a/Computator.NET.WebClient/tsconfig.json +++ b/Computator.NET.WebClient/tsconfig.json @@ -5,11 +5,9 @@ "moduleResolution": "node", "target": "es5", "jsx": "react", - "experimentalDecorators": true, "sourceMap": true, "skipDefaultLibCheck": true, "strict": true, - "lib": ["es6", "dom"], "types": ["webpack-env"] }, "exclude": [ diff --git a/Computator.NET.WebClient/webpack.config.js b/Computator.NET.WebClient/webpack.config.js index 59a5739..01e45ea 100644 --- a/Computator.NET.WebClient/webpack.config.js +++ b/Computator.NET.WebClient/webpack.config.js @@ -2,40 +2,28 @@ const path = require('path'); const webpack = require('webpack'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin; -const merge = require('webpack-merge'); +const bundleOutputDir = './wwwroot/dist'; module.exports = (env) => { const isDevBuild = !(env && env.prod); - - // Configuration in common to both client-side and server-side bundles - const sharedConfig = () => ({ + return [{ stats: { modules: false }, + entry: { 'main': './ClientApp/boot.tsx' }, resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx'] }, output: { + path: path.join(__dirname, bundleOutputDir), filename: '[name].js', - publicPath: 'dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix + publicPath: 'dist/' }, module: { rules: [ { test: /\.tsx?$/, include: /ClientApp/, use: 'awesome-typescript-loader?silent=true' }, + { test: /\.css$/, use: isDevBuild ? ['style-loader', 'css-loader'] : ExtractTextPlugin.extract({ use: 'css-loader?minimize' }) }, { test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' } ] }, - plugins: [new CheckerPlugin()] - }); - - // Configuration for client-side bundle suitable for running in browsers - const clientBundleOutputDir = './wwwroot/dist'; - const clientBundleConfig = merge(sharedConfig(), { - entry: { 'main-client': './ClientApp/boot-client.tsx' }, - module: { - rules: [ - { test: /\.css$/, use: ExtractTextPlugin.extract({ use: isDevBuild ? 'css-loader' : 'css-loader?minimize' }) } - ] - }, - output: { path: path.join(__dirname, clientBundleOutputDir) }, plugins: [ - new ExtractTextPlugin('site.css'), + new CheckerPlugin(), new webpack.DllReferencePlugin({ context: __dirname, manifest: require('./wwwroot/dist/vendor-manifest.json') @@ -44,33 +32,12 @@ module.exports = (env) => { // Plugins that apply in development builds only new webpack.SourceMapDevToolPlugin({ filename: '[file].map', // Remove this line if you prefer inline source maps - moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk + moduleFilenameTemplate: path.relative(bundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk }) ] : [ // Plugins that apply in production builds only - new webpack.optimize.UglifyJsPlugin() + new webpack.optimize.UglifyJsPlugin(), + new ExtractTextPlugin('site.css') ]) - }); - - // Configuration for server-side (prerendering) bundle suitable for running in Node - const serverBundleConfig = merge(sharedConfig(), { - resolve: { mainFields: ['main'] }, - entry: { 'main-server': './ClientApp/boot-server.tsx' }, - plugins: [ - new webpack.DllReferencePlugin({ - context: __dirname, - manifest: require('./ClientApp/dist/vendor-manifest.json'), - sourceType: 'commonjs2', - name: './vendor' - }) - ], - output: { - libraryTarget: 'commonjs', - path: path.join(__dirname, './ClientApp/dist') - }, - target: 'node', - devtool: 'inline-source-map' - }); - - return [clientBundleConfig, serverBundleConfig]; + }]; }; \ No newline at end of file diff --git a/Computator.NET.WebClient/webpack.config.vendor.js b/Computator.NET.WebClient/webpack.config.vendor.js index eaaa647..d23ac4f 100644 --- a/Computator.NET.WebClient/webpack.config.vendor.js +++ b/Computator.NET.WebClient/webpack.config.vendor.js @@ -1,87 +1,42 @@ const path = require('path'); const webpack = require('webpack'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); -const merge = require('webpack-merge'); module.exports = (env) => { - const isDevBuild = !(env && env.prod); const extractCSS = new ExtractTextPlugin('vendor.css'); - - const sharedConfig = { + const isDevBuild = !(env && env.prod); + return [{ stats: { modules: false }, - resolve: { extensions: [ '.js' ] }, + resolve: { + extensions: [ '.js' ] + }, module: { rules: [ - { test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, use: 'url-loader?limit=100000' } + { test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, use: 'url-loader?limit=100000' }, + { test: /\.css(\?|$)/, use: extractCSS.extract([ isDevBuild ? 'css-loader' : 'css-loader?minimize' ]) } ] }, entry: { - vendor: [ - 'bootstrap', - 'bootstrap/dist/css/bootstrap.css', - 'domain-task', - 'event-source-polyfill', - 'history', - 'react', - 'react-dom', - 'react-router-dom', - 'react-redux', - 'redux', - 'redux-thunk', - 'react-router-redux', - 'jquery' - ], + vendor: ['bootstrap', 'bootstrap/dist/css/bootstrap.css', 'event-source-polyfill', 'isomorphic-fetch', 'react', 'react-dom', 'react-router-dom', 'jquery'], }, output: { + path: path.join(__dirname, 'wwwroot', 'dist'), publicPath: 'dist/', filename: '[name].js', library: '[name]_[hash]', }, - plugins: [ - new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable) - new webpack.NormalModuleReplacementPlugin(/\/iconv-loader$/, require.resolve('node-noop')), // Workaround for https://github.com/andris9/encoding/issues/16 - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': isDevBuild ? '"development"' : '"production"' - }) - ] - }; - - const clientBundleConfig = merge(sharedConfig, { - output: { path: path.join(__dirname, 'wwwroot', 'dist') }, - module: { - rules: [ - { test: /\.css(\?|$)/, use: extractCSS.extract({ use: isDevBuild ? 'css-loader' : 'css-loader?minimize' }) } - ] - }, plugins: [ extractCSS, + new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable) new webpack.DllPlugin({ path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'), name: '[name]_[hash]' + }), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': isDevBuild ? '"development"' : '"production"' }) ].concat(isDevBuild ? [] : [ new webpack.optimize.UglifyJsPlugin() ]) - }); - - const serverBundleConfig = merge(sharedConfig, { - target: 'node', - resolve: { mainFields: ['main'] }, - output: { - path: path.join(__dirname, 'ClientApp', 'dist'), - libraryTarget: 'commonjs2', - }, - module: { - rules: [ { test: /\.css(\?|$)/, use: isDevBuild ? 'css-loader' : 'css-loader?minimize' } ] - }, - entry: { vendor: ['aspnet-prerendering', 'react-dom/server'] }, - plugins: [ - new webpack.DllPlugin({ - path: path.join(__dirname, 'ClientApp', 'dist', '[name]-manifest.json'), - name: '[name]_[hash]' - }) - ] - }); - - return [clientBundleConfig, serverBundleConfig]; + }]; }; diff --git a/Computator.NET.sln b/Computator.NET.sln index fc5a2bf..e3d29c7 100644 --- a/Computator.NET.sln +++ b/Computator.NET.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 -VisualStudioVersion = 15.0.27004.2008 +VisualStudioVersion = 15.0.27130.2026 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Computator.NET", "Computator.NET\Computator.NET.csproj", "{5731ED79-DFC9-41D5-8A2E-82C578AD1D96}" ProjectSection(ProjectDependencies) = postProject diff --git a/README.md b/README.md index 41d166f..65110db 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ Alternatively, you can always solve equations graphically, simply by looking at * [**.NET Framework** **4.0 Full**](https://www.microsoft.com/en-US/download/details.aspx?id=17718) * [.NET 4.0 **KB2468871**](https://www.microsoft.com/en-us/download/details.aspx?id=3556) update * Linux / Mac OS X (non-official support) - * [**Mono** **5.4.1**](http://www.mono-project.com/docs/about-mono/releases/) or newer + * [**Mono** **5.14.0**](http://www.mono-project.com/docs/about-mono/releases/) or newer * Operating system **Windows XP SP3** or later (**Windows Vista** or later is recommended, **Windows 10** is the best option because of continous testing on it) * Processor **1 GHz** or faster * Memory **512 MB** or more diff --git a/appveyor.yml b/appveyor.yml index 547ca6e..4f633dd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -6,6 +6,7 @@ environment: image: - Visual Studio 2017 +- Ubuntu configuration: - Debug @@ -19,19 +20,23 @@ assembly_info: assembly_informational_version: "{version}β" before_build: - - build.cmd -Target Restore + - cmd: build.cmd -Target Restore + - sh: ./build.sh --target=Restore build_script: - - build.cmd -Target Build + - cmd: build.cmd -Target Build + - sh: ./build.sh --target=Build -#test_script: -# - build.cmd -Target AllTests +test_script: + - cmd: build.cmd -Target AllTests + - sh: ./build.sh --target=AllTests after_test: - - build.cmd -Target Upload-Coverage + - cmd: build.cmd -Target Upload-Coverage after_build: - - build.cmd -Target Publish + - cmd: build.cmd -Target Publish + - sh: ./build.sh --target=Publish notifications: - provider: GitHubPullRequest diff --git a/build-mono/generateTravisBuildEnvironments.csx b/build-mono/generateTravisBuildEnvironments.csx index 36791b2..aca6b5f 100644 --- a/build-mono/generateTravisBuildEnvironments.csx +++ b/build-mono/generateTravisBuildEnvironments.csx @@ -4,7 +4,7 @@ var monos = new[]{ //"alpha", //"beta", //"latest", - "5.4.1", + "5.14.0", //"5.4.0", //"5.2.0", //"5.0.1", @@ -32,7 +32,10 @@ var sudos = new[] { //"false" }; -var dists = new[] { "trusty", "precise" }; +var dists = new[] { + "trusty", + //"precise" + }; var dotnets = new string[] { ////"1.0.0-preview2-003121", @@ -40,12 +43,13 @@ var dotnets = new string[] { }; var osx_images = new[] { - "xcode8.2",//OS X 10.12 + "xcode9.4",//OS X 10.13 + //"xcode8.2",//OS X 10.12 //"xcode8.1",//OS X 10.12 //"xcode8",//OS X 10.11 ////"xcode7.3",//OS X 10.11 //"xcode7.2",//OS X 10.11 - "xcode6.4"//OS X 10.10 + //"xcode6.4"//OS X 10.10 }; var buildConfigs = new[] { "Release", "Debug" }; diff --git a/build-uwp/AppxManifest.xml b/build-uwp/AppxManifest.xml index 7cedd94..667aa39 100644 --- a/build-uwp/AppxManifest.xml +++ b/build-uwp/AppxManifest.xml @@ -36,12 +36,6 @@ - - - - - - Troka Scripting Language diff --git a/build-uwp/build.bat b/build-uwp/build.bat index 681b04a..8a91baf 100644 --- a/build-uwp/build.bat +++ b/build-uwp/build.bat @@ -10,7 +10,6 @@ xcopy build-uwp\Registry.dat AppPackages\PackageFiles\* xcopy /s Computator.NET.Core\Special\windows-x64 AppPackages\PackageFiles\* xcopy /s Graphics\Assets AppPackages\PackageFiles\Assets\* xcopy /s "Computator.NET.Core\TSL Examples" "AppPackages\PackageFiles\VFS\Users\ContainerAdministrator\Documents\Computator.NET\TSL Examples\*" -xcopy /s Computator.NET.Core\Static\fonts AppPackages\PackageFiles\VFS\Windows\Fonts\* makepri createconfig /cf AppPackages\PackageFiles\priconfig.xml /dq en-US makepri new /pr AppPackages\PackageFiles /cf AppPackages\PackageFiles\priconfig.xml move /y .\*.pri AppPackages\PackageFiles diff --git a/build.cake b/build.cake index fb7ce92..ac8faba 100644 --- a/build.cake +++ b/build.cake @@ -1,10 +1,11 @@ -#addin Cake.Coveralls +// Pinned Coveralls version to older one because 1.0.0 has Error: One or more errors occurred. Package 'coveralls.net 1.0.0' has a package type 'DotnetTool' that is not supported by project 'C:/Projects/Computator.NET/tools'. +#addin nuget:?package=Cake.Coveralls&version=0.7.0 #addin nuget:?package=Cake.Codecov #addin nuget:?package=Cake.AppPackager #addin nuget:?package=Cake.VersionReader -#addin "Cake.FileHelpers" +#addin nuget:?package=Cake.FileHelpers -#tool coveralls.net +#tool nuget:?package=coveralls.net&version=0.7.0 #tool nuget:?package=OpenCover #tool nuget:?package=NUnit.ConsoleRunner #tool nuget:?package=Codecov @@ -32,7 +33,7 @@ if (type != null) } } -var isMonoButSupportsMsBuild = monoVersion!=null && System.Text.RegularExpressions.Regex.IsMatch(monoVersion,@"([5-9]|\d{2,})\.\d+\.\d+(\.\d+)?"); +var isMonoButSupportsMsBuild = monoVersion!=null && System.Text.RegularExpressions.Regex.IsMatch(monoVersion,@"^\s*([5-9]|\d{2,})\.\d+\.\d+(\.\d+)?"); var normalNUnit3Settings = new NUnit3Settings() @@ -86,7 +87,7 @@ var msBuildSettings = new MSBuildSettings { { if(travisOsName == "osx" || System.Environment.OSVersion.Platform == System.PlatformID.MacOSX) { - var msBuildVersions = new [] {"15.5","15.4","15.3","15.2","15.1","15.0"}; + var msBuildVersions = new [] {"15.9","15.8","15.7","15.6","15.5","15.4","15.3","15.2","15.1","15.0"}; var monoVersions = new [] {"Current", monoVersionShort}; var msBuildExecutableNames = new [] {"MSBuild.exe", "MSBuild.dll", "msBuild.exe", "msbuild.exe", "msBuild.dll", "msbuild.dll"}; @@ -336,7 +337,6 @@ Task("Build-Uwp") CopyDirectory(@"Graphics/Assets",packageFiles+@"/Assets"); CopyDirectory(@"Computator.NET.Core/TSL Examples",packageFiles+@"/VFS/Users/ContainerAdministrator/Documents/Computator.NET/TSL Examples"); - CopyDirectory(@"Computator.NET.Core/Static/fonts",packageFiles+@"/VFS/Windows/Fonts"); var programFilesPath = System.Environment.Is64BitOperatingSystem ? Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) : Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); var makePriPaths = GetFiles(programFilesPath + @"\Windows Kits\10\bin\x86\makepri.exe"); diff --git a/build.ps1 b/build.ps1 index 9b84bb9..b233d3c 100644 --- a/build.ps1 +++ b/build.ps1 @@ -21,13 +21,14 @@ The build script target to run. The build configuration to use. .PARAMETER Verbosity Specifies the amount of information to be displayed. +.PARAMETER ShowDescription +Shows description about tasks. +.PARAMETER DryRun +Performs a dry run. .PARAMETER Experimental -Tells Cake to use the latest Roslyn release. -.PARAMETER WhatIf -Performs a dry run of the build script. -No tasks will be executed. +Uses the nightly builds of the Roslyn script engine. .PARAMETER Mono -Tells Cake to use the Mono scripting engine. +Uses the Mono Compiler rather than the Roslyn script engine. .PARAMETER SkipToolPackageRestore Skips restoring of packages. .PARAMETER ScriptArgs @@ -41,14 +42,14 @@ https://cakebuild.net [CmdletBinding()] Param( [string]$Script = "build.cake", - [string]$Target = "Default", - [ValidateSet("Release", "Debug")] - [string]$Configuration = "Release", + [string]$Target, + [string]$Configuration, [ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")] - [string]$Verbosity = "Verbose", + [string]$Verbosity, + [switch]$ShowDescription, + [Alias("WhatIf", "Noop")] + [switch]$DryRun, [switch]$Experimental, - [Alias("DryRun","Noop")] - [switch]$WhatIf, [switch]$Mono, [switch]$SkipToolPackageRestore, [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] @@ -80,6 +81,15 @@ function MD5HashFile([string] $filePath) } } +function GetProxyEnabledWebClient +{ + $wc = New-Object System.Net.WebClient + $proxy = [System.Net.WebRequest]::GetSystemWebProxy() + $proxy.Credentials = [System.Net.CredentialCache]::DefaultCredentials + $wc.Proxy = $proxy + return $wc +} + Write-Host "Preparing to run build script..." if(!$PSScriptRoot){ @@ -87,31 +97,15 @@ if(!$PSScriptRoot){ } $TOOLS_DIR = Join-Path $PSScriptRoot "tools" +$ADDINS_DIR = Join-Path $TOOLS_DIR "Addins" +$MODULES_DIR = Join-Path $TOOLS_DIR "Modules" $NUGET_EXE = Join-Path $TOOLS_DIR "nuget.exe" $CAKE_EXE = Join-Path $TOOLS_DIR "Cake/Cake.exe" $NUGET_URL = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe" $PACKAGES_CONFIG = Join-Path $TOOLS_DIR "packages.config" $PACKAGES_CONFIG_MD5 = Join-Path $TOOLS_DIR "packages.config.md5sum" - -# Should we use mono? -$UseMono = ""; -if($Mono.IsPresent) { - Write-Verbose -Message "Using the Mono based scripting engine." - $UseMono = "-mono" -} - -# Should we use the new Roslyn? -$UseExperimental = ""; -if($Experimental.IsPresent -and !($Mono.IsPresent)) { - Write-Verbose -Message "Using experimental version of Roslyn." - $UseExperimental = "-experimental" -} - -# Is this a dry run? -$UseDryRun = ""; -if($WhatIf.IsPresent) { - $UseDryRun = "-dryrun" -} +$ADDINS_PACKAGES_CONFIG = Join-Path $ADDINS_DIR "packages.config" +$MODULES_PACKAGES_CONFIG = Join-Path $MODULES_DIR "packages.config" # Make sure tools folder exists if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { @@ -122,7 +116,10 @@ if ((Test-Path $PSScriptRoot) -and !(Test-Path $TOOLS_DIR)) { # Make sure that packages.config exist. if (!(Test-Path $PACKAGES_CONFIG)) { Write-Verbose -Message "Downloading packages.config..." - try { (New-Object System.Net.WebClient).DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) } catch { + try { + $wc = GetProxyEnabledWebClient + $wc.DownloadFile("https://cakebuild.net/download/bootstrapper/packages", $PACKAGES_CONFIG) + } catch { Throw "Could not download packages.config." } } @@ -142,7 +139,8 @@ if (!(Test-Path $NUGET_EXE)) { if (!(Test-Path $NUGET_EXE)) { Write-Verbose -Message "Downloading NuGet.exe..." try { - (New-Object System.Net.WebClient).DownloadFile($NUGET_URL, $NUGET_EXE) + $wc = GetProxyEnabledWebClient + $wc.DownloadFile($NUGET_URL, $NUGET_EXE) } catch { Throw "Could not download NuGet.exe." } @@ -161,32 +159,81 @@ if(-Not $SkipToolPackageRestore.IsPresent) { if((!(Test-Path $PACKAGES_CONFIG_MD5)) -Or ($md5Hash -ne (Get-Content $PACKAGES_CONFIG_MD5 ))) { Write-Verbose -Message "Missing or changed package.config hash..." - Remove-Item * -Recurse -Exclude packages.config,nuget.exe + Get-ChildItem -Exclude packages.config,nuget.exe,Cake.Bakery | + Remove-Item -Recurse } Write-Verbose -Message "Restoring tools from NuGet..." $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$TOOLS_DIR`"" if ($LASTEXITCODE -ne 0) { - Throw "An error occured while restoring NuGet tools." + Throw "An error occurred while restoring NuGet tools." } else { $md5Hash | Out-File $PACKAGES_CONFIG_MD5 -Encoding "ASCII" } Write-Verbose -Message ($NuGetOutput | out-string) + Pop-Location } # Temporarily skip assemblies verification $ENV:CAKE_SETTINGS_SKIPVERIFICATION='true' +# Restore addins from NuGet +if (Test-Path $ADDINS_PACKAGES_CONFIG) { + Push-Location + Set-Location $ADDINS_DIR + + Write-Verbose -Message "Restoring addins from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$ADDINS_DIR`"" + + if ($LASTEXITCODE -ne 0) { + Throw "An error occurred while restoring NuGet addins." + } + + Write-Verbose -Message ($NuGetOutput | out-string) + + Pop-Location +} + +# Restore modules from NuGet +if (Test-Path $MODULES_PACKAGES_CONFIG) { + Push-Location + Set-Location $MODULES_DIR + + Write-Verbose -Message "Restoring modules from NuGet..." + $NuGetOutput = Invoke-Expression "&`"$NUGET_EXE`" install -ExcludeVersion -OutputDirectory `"$MODULES_DIR`"" + + if ($LASTEXITCODE -ne 0) { + Throw "An error occurred while restoring NuGet modules." + } + + Write-Verbose -Message ($NuGetOutput | out-string) + + Pop-Location +} + # Make sure that Cake has been installed. if (!(Test-Path $CAKE_EXE)) { Throw "Could not find Cake.exe at $CAKE_EXE" } + + +# Build Cake arguments +$cakeArguments = @("$Script"); +if ($Target) { $cakeArguments += "-target=$Target" } +if ($Configuration) { $cakeArguments += "-configuration=$Configuration" } +if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" } +if ($ShowDescription) { $cakeArguments += "-showdescription" } +if ($DryRun) { $cakeArguments += "-dryrun" } +if ($Experimental) { $cakeArguments += "-experimental" } +if ($Mono) { $cakeArguments += "-mono" } +$cakeArguments += $ScriptArgs + # Start Cake Write-Host "Running build script..." -Invoke-Expression "& `"$CAKE_EXE`" `"$Script`" -target=`"$Target`" -configuration=`"$Configuration`" -verbosity=`"$Verbosity`" $UseMono $UseDryRun $UseExperimental $ScriptArgs" +&$CAKE_EXE $cakeArguments exit $LASTEXITCODE \ No newline at end of file diff --git a/build.sh b/build.sh index 4be81a4..d44b9a0 100755 --- a/build.sh +++ b/build.sh @@ -9,10 +9,14 @@ # Define directories. SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ) TOOLS_DIR=$SCRIPT_DIR/tools +ADDINS_DIR=$TOOLS_DIR/Addins +MODULES_DIR=$TOOLS_DIR/Modules NUGET_EXE=$TOOLS_DIR/nuget.exe CAKE_EXE=$TOOLS_DIR/Cake/Cake.exe PACKAGES_CONFIG=$TOOLS_DIR/packages.config PACKAGES_CONFIG_MD5=$TOOLS_DIR/packages.config.md5sum +ADDINS_PACKAGES_CONFIG=$ADDINS_DIR/packages.config +MODULES_PACKAGES_CONFIG=$MODULES_DIR/packages.config # Define md5sum or md5 depending on Linux/OSX MD5_EXE= @@ -24,24 +28,14 @@ fi # Define default arguments. SCRIPT="build.cake" -TARGET="Default" -CONFIGURATION="Release" -VERBOSITY="verbose" -DRYRUN= -SHOW_VERSION=false -SCRIPT_ARGUMENTS=() +CAKE_ARGUMENTS=() # Parse arguments. for i in "$@"; do case $1 in -s|--script) SCRIPT="$2"; shift ;; - -t|--target) TARGET="$2"; shift ;; - -c|--configuration) CONFIGURATION="$2"; shift ;; - -v|--verbosity) VERBOSITY="$2"; shift ;; - -d|--dryrun) DRYRUN="-dryrun" ;; - --version) SHOW_VERSION=true ;; - --) shift; SCRIPT_ARGUMENTS+=("$@"); break ;; - *) SCRIPT_ARGUMENTS+=("$1") ;; + --) shift; CAKE_ARGUMENTS+=("$@"); break ;; + *) CAKE_ARGUMENTS+=("$1") ;; esac shift done @@ -56,7 +50,7 @@ if [ ! -f "$TOOLS_DIR/packages.config" ]; then echo "Downloading packages.config..." curl -Lsfo "$TOOLS_DIR/packages.config" https://cakebuild.net/download/bootstrapper/packages if [ $? -ne 0 ]; then - echo "An error occured while downloading packages.config." + echo "An error occurred while downloading packages.config." exit 1 fi fi @@ -66,27 +60,53 @@ if [ ! -f "$NUGET_EXE" ]; then echo "Downloading NuGet..." curl -Lsfo "$NUGET_EXE" https://dist.nuget.org/win-x86-commandline/latest/nuget.exe if [ $? -ne 0 ]; then - echo "An error occured while downloading nuget.exe." + echo "An error occurred while downloading nuget.exe." exit 1 fi fi # Restore tools from NuGet. pushd "$TOOLS_DIR" >/dev/null -if [ ! -f $PACKAGES_CONFIG_MD5 ] || [ "$( cat $PACKAGES_CONFIG_MD5 | sed 's/\r$//' )" != "$( $MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' )" ]; then - find . -type d ! -name . | xargs rm -rf +if [ ! -f "$PACKAGES_CONFIG_MD5" ] || [ "$( cat "$PACKAGES_CONFIG_MD5" | sed 's/\r$//' )" != "$( $MD5_EXE "$PACKAGES_CONFIG" | awk '{ print $1 }' )" ]; then + find . -type d ! -name . ! -name 'Cake.Bakery' | xargs rm -rf fi mono "$NUGET_EXE" install -ExcludeVersion if [ $? -ne 0 ]; then - echo "Could not restore NuGet packages." + echo "Could not restore NuGet tools." exit 1 fi -$MD5_EXE $PACKAGES_CONFIG | awk '{ print $1 }' >| $PACKAGES_CONFIG_MD5 +$MD5_EXE "$PACKAGES_CONFIG" | awk '{ print $1 }' >| "$PACKAGES_CONFIG_MD5" popd >/dev/null +# Restore addins from NuGet. +if [ -f "$ADDINS_PACKAGES_CONFIG" ]; then + pushd "$ADDINS_DIR" >/dev/null + + mono "$NUGET_EXE" install -ExcludeVersion + if [ $? -ne 0 ]; then + echo "Could not restore NuGet addins." + exit 1 + fi + + popd >/dev/null +fi + +# Restore modules from NuGet. +if [ -f "$MODULES_PACKAGES_CONFIG" ]; then + pushd "$MODULES_DIR" >/dev/null + + mono "$NUGET_EXE" install -ExcludeVersion + if [ $? -ne 0 ]; then + echo "Could not restore NuGet modules." + exit 1 + fi + + popd >/dev/null +fi + # Temporarily skip assemblies verification export CAKE_SETTINGS_SKIPVERIFICATION=true @@ -97,8 +117,4 @@ if [ ! -f "$CAKE_EXE" ]; then fi # Start Cake -if $SHOW_VERSION; then - exec mono "$CAKE_EXE" -version -else - exec mono "$CAKE_EXE" $SCRIPT -verbosity=$VERBOSITY -configuration=$CONFIGURATION -target=$TARGET $DRYRUN "${SCRIPT_ARGUMENTS[@]}" -fi \ No newline at end of file +exec mono "$CAKE_EXE" $SCRIPT "${CAKE_ARGUMENTS[@]}" \ No newline at end of file diff --git a/tools/packages.config b/tools/packages.config index 747e13e..0501888 100644 --- a/tools/packages.config +++ b/tools/packages.config @@ -1,4 +1,4 @@ - +