From 3e50a74878c08d0bad07443e38a72f691cb7dd51 Mon Sep 17 00:00:00 2001 From: Josh Hiles Date: Thu, 22 Jul 2021 19:21:53 +0100 Subject: [PATCH 01/26] Create SECURITY.md --- SECURITY.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..c22fe3e --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,17 @@ +# Security Policy + +## Supported Versions + +| Version | Supported | +| ------- | ------------------ | +| 2.0.0 | :white_check_mark: | +| < 2.0 | :x: | + +## Reporting a Vulnerability + +Security issues and bugs should be reported privately. + +> The best approach at the moment is to message one of the contributors on https://gitter.im/scientistproject/community privately +> If you dont receive a reply within a couple of days please send the message onto another member + +Please do not open issues for anything you think might have a security implication. From ba87e7db8885dc1c742ed8ee5cd8ed6f1a2f8e65 Mon Sep 17 00:00:00 2001 From: Joshua Hiles Date: Thu, 22 Jul 2021 20:14:23 +0100 Subject: [PATCH 02/26] Initialised 3 --- .gitignore | 2 + Scientist.Test/Scientist.Test.csproj | 22 ++ Scientist.Test/Scientist.cs | 15 + Scientist.net.sln | 44 +-- Scientist/IScientist.cs | 7 + Scientist/Scientist.cs | 198 ++++++++++ Scientist/Scientist.csproj | 8 + .gitattributes => old/.gitattributes | 0 old/.gitignore | 128 +++++++ old/CODE_OF_CONDUCT.md | 74 ++++ old/LICENSE.txt | 19 + NuGet.config => old/NuGet.config | 0 old/README.md | 349 ++++++++++++++++++ ReleaseNotes.md => old/ReleaseNotes.md | 0 old/Scientist.net.sln | 49 +++ appveyor.yml => old/appveyor.yml | 0 old/assets/Scientist_Final-01.svg | 38 ++ old/assets/scientist-logo-64x64.png | Bin 0 -> 1272 bytes build.cmd => old/build.cmd | 0 build.fsx => old/build.fsx | 0 .../Extensions/LinqExtensionMethods.cs | 0 .../Scientist/FireAndForgetResultPublisher.cs | 0 {src => old/src}/Scientist/FodyWeavers.xml | 0 {src => old/src}/Scientist/IExperiment.cs | 0 .../src}/Scientist/IResultPublisher.cs | 0 {src => old/src}/Scientist/IScientist.cs | 0 .../src}/Scientist/Internals/ConcurrentSet.cs | 0 .../src}/Scientist/Internals/Experiment.cs | 0 .../Scientist/Internals/ExperimentInstance.cs | 0 .../Scientist/Internals/ExperimentSettings.cs | 0 .../Internals/InMemoryResultPublisher.cs | 0 .../src}/Scientist/MismatchException.cs | 0 {src => old/src}/Scientist/Observation.cs | 0 {src => old/src}/Scientist/Operation.cs | 0 .../src}/Scientist/OperationException.cs | 0 .../src}/Scientist/Properties/AssemblyInfo.cs | 0 {src => old/src}/Scientist/Result.cs | 0 {src => old/src}/Scientist/Scientist.cs | 0 {src => old/src}/Scientist/Scientist.csproj | 0 .../src}/Scientist/ScientistExtensions.cs | 0 {src => old/src}/Scientist/packages.config | 0 .../test}/Scientist.Benchmark/Program.cs | 0 .../Scientist.Benchmark.csproj | 0 .../ScientistBenchmarks.cs | 0 .../test}/Scientist.Test/ComplexResult.cs | 0 .../FireAndForgetResultPublisherTests.cs | 0 .../test}/Scientist.Test/IControlCandidate.cs | 0 .../Scientist.Test/IScientistSettings.cs | 0 .../Scientist.Test/Properties/AssemblyInfo.cs | 0 .../Scientist.Test/Scientist.Test.csproj | 0 .../test}/Scientist.Test/ScientistTests.cs | 0 {test => old/test}/Scientist.Test/Swap.cs | 0 .../test}/Scientist.Test/TestHelper.cs | 0 .../test}/Scientist.Test/ThrownTests.cs | 0 {tools => old/tools}/nuget/NuGet.exe | Bin 55 files changed, 922 insertions(+), 31 deletions(-) create mode 100644 Scientist.Test/Scientist.Test.csproj create mode 100644 Scientist.Test/Scientist.cs create mode 100644 Scientist/IScientist.cs create mode 100644 Scientist/Scientist.cs create mode 100644 Scientist/Scientist.csproj rename .gitattributes => old/.gitattributes (100%) create mode 100644 old/.gitignore create mode 100644 old/CODE_OF_CONDUCT.md create mode 100644 old/LICENSE.txt rename NuGet.config => old/NuGet.config (100%) create mode 100644 old/README.md rename ReleaseNotes.md => old/ReleaseNotes.md (100%) create mode 100644 old/Scientist.net.sln rename appveyor.yml => old/appveyor.yml (100%) create mode 100644 old/assets/Scientist_Final-01.svg create mode 100644 old/assets/scientist-logo-64x64.png rename build.cmd => old/build.cmd (100%) rename build.fsx => old/build.fsx (100%) rename {src => old/src}/Scientist/Extensions/LinqExtensionMethods.cs (100%) rename {src => old/src}/Scientist/FireAndForgetResultPublisher.cs (100%) rename {src => old/src}/Scientist/FodyWeavers.xml (100%) rename {src => old/src}/Scientist/IExperiment.cs (100%) rename {src => old/src}/Scientist/IResultPublisher.cs (100%) rename {src => old/src}/Scientist/IScientist.cs (100%) rename {src => old/src}/Scientist/Internals/ConcurrentSet.cs (100%) rename {src => old/src}/Scientist/Internals/Experiment.cs (100%) rename {src => old/src}/Scientist/Internals/ExperimentInstance.cs (100%) rename {src => old/src}/Scientist/Internals/ExperimentSettings.cs (100%) rename {src => old/src}/Scientist/Internals/InMemoryResultPublisher.cs (100%) rename {src => old/src}/Scientist/MismatchException.cs (100%) rename {src => old/src}/Scientist/Observation.cs (100%) rename {src => old/src}/Scientist/Operation.cs (100%) rename {src => old/src}/Scientist/OperationException.cs (100%) rename {src => old/src}/Scientist/Properties/AssemblyInfo.cs (100%) rename {src => old/src}/Scientist/Result.cs (100%) rename {src => old/src}/Scientist/Scientist.cs (100%) rename {src => old/src}/Scientist/Scientist.csproj (100%) rename {src => old/src}/Scientist/ScientistExtensions.cs (100%) rename {src => old/src}/Scientist/packages.config (100%) rename {test => old/test}/Scientist.Benchmark/Program.cs (100%) rename {test => old/test}/Scientist.Benchmark/Scientist.Benchmark.csproj (100%) rename {test => old/test}/Scientist.Benchmark/ScientistBenchmarks.cs (100%) rename {test => old/test}/Scientist.Test/ComplexResult.cs (100%) rename {test => old/test}/Scientist.Test/FireAndForgetResultPublisherTests.cs (100%) rename {test => old/test}/Scientist.Test/IControlCandidate.cs (100%) rename {test => old/test}/Scientist.Test/IScientistSettings.cs (100%) rename {test => old/test}/Scientist.Test/Properties/AssemblyInfo.cs (100%) rename {test => old/test}/Scientist.Test/Scientist.Test.csproj (100%) rename {test => old/test}/Scientist.Test/ScientistTests.cs (100%) rename {test => old/test}/Scientist.Test/Swap.cs (100%) rename {test => old/test}/Scientist.Test/TestHelper.cs (100%) rename {test => old/test}/Scientist.Test/ThrownTests.cs (100%) rename {tools => old/tools}/nuget/NuGet.exe (100%) diff --git a/.gitignore b/.gitignore index 2a2ef7b..9f83e16 100644 --- a/.gitignore +++ b/.gitignore @@ -126,3 +126,5 @@ artifacts/ *.scc BenchmarkDotNet.Artifacts + +**/.vs \ No newline at end of file diff --git a/Scientist.Test/Scientist.Test.csproj b/Scientist.Test/Scientist.Test.csproj new file mode 100644 index 0000000..14db845 --- /dev/null +++ b/Scientist.Test/Scientist.Test.csproj @@ -0,0 +1,22 @@ + + + + net6.0 + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + diff --git a/Scientist.Test/Scientist.cs b/Scientist.Test/Scientist.cs new file mode 100644 index 0000000..199f4a9 --- /dev/null +++ b/Scientist.Test/Scientist.cs @@ -0,0 +1,15 @@ +using System; +using Xunit; + +namespace Scientist.Test +{ + public class Scientist + { + [Fact] + public void DoesntRunCandidate() + { + const int expectedResult = 42; + + } + } +} diff --git a/Scientist.net.sln b/Scientist.net.sln index 02c1cb7..6edb64a 100644 --- a/Scientist.net.sln +++ b/Scientist.net.sln @@ -1,25 +1,11 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26730.16 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31512.422 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Meta", "Meta", "{0FF544BE-E75C-4EF7-AEB3-A534ED5D7BB5}" - ProjectSection(SolutionItems) = preProject - .gitattributes = .gitattributes - .gitignore = .gitignore - appveyor.yml = appveyor.yml - build.cmd = build.cmd - build.fsx = build.fsx - LICENSE.txt = LICENSE.txt - README.md = README.md - ReleaseNotes.md = ReleaseNotes.md - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scientist", "Scientist\Scientist.csproj", "{8794D5E1-EC60-48CD-A834-63B3531D90B3}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scientist", "src\Scientist\Scientist.csproj", "{AF3E98CD-DA8C-43B2-8217-76B6AE8BCA20}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scientist.Test", "test\Scientist.Test\Scientist.Test.csproj", "{0686E0A8-FB25-4B20-9BC0-CD05E916E5AD}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scientist.Benchmark", "test\Scientist.Benchmark\Scientist.Benchmark.csproj", "{243420EF-8A98-4D0F-9E2E-86F4E70C3128}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Scientist.Test", "Scientist.Test\Scientist.Test.csproj", "{8087793F-0EC4-4085-9C18-91D991FFE3DF}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -27,23 +13,19 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {AF3E98CD-DA8C-43B2-8217-76B6AE8BCA20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AF3E98CD-DA8C-43B2-8217-76B6AE8BCA20}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AF3E98CD-DA8C-43B2-8217-76B6AE8BCA20}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AF3E98CD-DA8C-43B2-8217-76B6AE8BCA20}.Release|Any CPU.Build.0 = Release|Any CPU - {0686E0A8-FB25-4B20-9BC0-CD05E916E5AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {0686E0A8-FB25-4B20-9BC0-CD05E916E5AD}.Debug|Any CPU.Build.0 = Debug|Any CPU - {0686E0A8-FB25-4B20-9BC0-CD05E916E5AD}.Release|Any CPU.ActiveCfg = Release|Any CPU - {0686E0A8-FB25-4B20-9BC0-CD05E916E5AD}.Release|Any CPU.Build.0 = Release|Any CPU - {243420EF-8A98-4D0F-9E2E-86F4E70C3128}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {243420EF-8A98-4D0F-9E2E-86F4E70C3128}.Debug|Any CPU.Build.0 = Debug|Any CPU - {243420EF-8A98-4D0F-9E2E-86F4E70C3128}.Release|Any CPU.ActiveCfg = Release|Any CPU - {243420EF-8A98-4D0F-9E2E-86F4E70C3128}.Release|Any CPU.Build.0 = Release|Any CPU + {8794D5E1-EC60-48CD-A834-63B3531D90B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8794D5E1-EC60-48CD-A834-63B3531D90B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8794D5E1-EC60-48CD-A834-63B3531D90B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8794D5E1-EC60-48CD-A834-63B3531D90B3}.Release|Any CPU.Build.0 = Release|Any CPU + {8087793F-0EC4-4085-9C18-91D991FFE3DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8087793F-0EC4-4085-9C18-91D991FFE3DF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8087793F-0EC4-4085-9C18-91D991FFE3DF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8087793F-0EC4-4085-9C18-91D991FFE3DF}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {8CFF3922-3285-4B9E-9E64-7FC7D5332E56} + SolutionGuid = {9285881B-56A7-4C56-8189-DC9C8C2D8F2E} EndGlobalSection EndGlobal diff --git a/Scientist/IScientist.cs b/Scientist/IScientist.cs new file mode 100644 index 0000000..9316d5e --- /dev/null +++ b/Scientist/IScientist.cs @@ -0,0 +1,7 @@ + +namespace Scientist +{ + public interface IScientist + { + } +} diff --git a/Scientist/Scientist.cs b/Scientist/Scientist.cs new file mode 100644 index 0000000..75cdf22 --- /dev/null +++ b/Scientist/Scientist.cs @@ -0,0 +1,198 @@ +using System; +using System.Threading.Tasks; + +namespace Scientist +{ + public class Scientist : IScientist + { + static readonly Task EnabledTask = Task.FromResult(true); + static readonly Lazy _sharedScientist = new Lazy(CreateSharedInstance); + static Func> _enabled = () => EnabledTask; + static IResultPublisher _sharedPublisher = new InMemoryResultPublisher(); + readonly IResultPublisher _resultPublisher; + + /// + /// Initializes a new instance of the class + /// using the specified + /// + public Scientist(IResultPublisher resultPublisher) + { + _resultPublisher = resultPublisher + ?? throw new ArgumentNullException(nameof(resultPublisher), "A result publisher must be specified"); + } + + // TODO: How can we guide the developer to the pit of success + + /// + /// Gets or sets the result publisher to use. + /// This should be configured once before starting observations. + /// + /// + /// An attempt to set the value was made after the first experiment has been run. + /// + public static IResultPublisher ResultPublisher + { + get + { + return _sharedPublisher; + } + + set + { + if (_sharedScientist.IsValueCreated) + { + throw new InvalidOperationException($"The value of the {nameof(ResultPublisher)} property cannot be changed once an experiment has been run."); + } + + _sharedPublisher = value; + } + } + + static Scientist CreateSharedInstance() => new SharedScientist(ResultPublisher); + + Experiment Build(string name, int concurrentTasks, Action> experiment) + { + // TODO: Maybe we could automatically generate the name if none is provided using the calling method name. We'd have to + // make sure we don't inline this method though. + var experimentBuilder = new Experiment(name, IsEnabledAsync, concurrentTasks, _resultPublisher); + + experiment(experimentBuilder); + + return experimentBuilder; + } + + Experiment Build(string name, int concurrentTasks, Action> experiment) + { + var builder = new Experiment(name, IsEnabledAsync, concurrentTasks, _resultPublisher); + + experiment(builder); + + return builder; + } + + /// + /// Determines if an experiment should be enabled. + /// + /// A delegate returning if an experiment should run. + public static void Enabled(Func enabled) => Enabled(() => Task.FromResult(enabled())); + + /// + /// Determines if an experiment should be enabled. + /// + /// A delegate returning an asynchronous task determining if an experiment should run. + public static void Enabled(Func> enabled) => _enabled = enabled; + + /// + /// Conduct a synchronous experiment + /// + /// The return type of the experiment + /// Name of the experiment + /// Experiment callback used to configure the experiment + /// The value of the experiment's control function. + public static T Science(string name, Action> experiment) => + _sharedScientist.Value.Experiment(name, experiment); + + /// + /// Conduct a synchronous experiment + /// + /// The return type of the experiment + /// The clean type for publishing. + /// Name of the experiment + /// Experiment callback used to configure the experiment + /// The value of the experiment's control function. + public static T Science(string name, Action> experiment) => + _sharedScientist.Value.Experiment(name, experiment); + + /// + /// Conduct an asynchronous experiment + /// + /// The return type of the experiment + /// Name of the experiment + /// Experiment callback used to configure the experiment + /// The value of the experiment's control function. + public static Task ScienceAsync(string name, Action> experiment) => + _sharedScientist.Value.ExperimentAsync(name, experiment); + + /// + /// Conduct an asynchronous experiment + /// + /// The return type of the experiment + /// Name of the experiment + /// Number of tasks to run concurrently + /// Experiment callback used to configure the experiment + /// The value of the experiment's control function. + public static Task ScienceAsync(string name, int concurrentTasks, Action> experiment) => + _sharedScientist.Value.ExperimentAsync(name, concurrentTasks, experiment); + + /// + /// Conduct an asynchronous experiment + /// + /// The return type of the experiment + /// The clean type for publishing. + /// Name of the experiment + /// Experiment callback used to configure the experiment + /// The value of the experiment's control function. + public static Task ScienceAsync(string name, Action> experiment) => + _sharedScientist.Value.ExperimentAsync(name, experiment); + + /// + /// Conduct an asynchronous experiment + /// + /// The return type of the experiment + /// The clean type for publishing. + /// Name of the experiment + /// Number of tasks to run concurrently + /// Experiment callback used to configure the experiment + /// The value of the experiment's control function. + public static Task ScienceAsync(string name, int concurrentTasks, Action> experiment) => + _sharedScientist.Value.ExperimentAsync(name, concurrentTasks, experiment); + + /// + /// Conduct a synchronous experiment + /// + /// The return type of the experiment + /// The clean type for publishing. + /// Name of the experiment + /// Experiment callback used to configure the experiment + /// The value of the experiment's control function. + public T Experiment(string name, Action> experiment) => + Build(name, 1, experiment).Build().Run().Result; + + /// + /// Conduct an asynchronous experiment + /// + /// The return type of the experiment + /// The clean type for publishing. + /// Name of the experiment + /// Number of tasks to run concurrently + /// Experiment callback used to configure the experiment + /// The value of the experiment's control function. + public Task ExperimentAsync(string name, int concurrentTasks, Action> experiment) => + Build(name, concurrentTasks, experiment).Build().Run(); + + /// + /// Returns whether the experiment is enabled as an asynchronous operation + /// + /// + /// A which returns whether the experiment is enabled. + /// + /// + /// Override this method to change the default implementation which always returns . + /// + protected virtual Task IsEnabledAsync() => EnabledTask; + + // This class acts as a proxy to allow the static methods to set the state on an instance of Scientist. + private sealed class SharedScientist : Scientist + { + internal SharedScientist(IResultPublisher resultPublisher) + : base(resultPublisher) + { + } + + protected override async Task IsEnabledAsync() + { + return await _enabled().ConfigureAwait(false); + } + } + } +} diff --git a/Scientist/Scientist.csproj b/Scientist/Scientist.csproj new file mode 100644 index 0000000..4de8048 --- /dev/null +++ b/Scientist/Scientist.csproj @@ -0,0 +1,8 @@ + + + + net6.0 + enable + + + diff --git a/.gitattributes b/old/.gitattributes similarity index 100% rename from .gitattributes rename to old/.gitattributes diff --git a/old/.gitignore b/old/.gitignore new file mode 100644 index 0000000..2a2ef7b --- /dev/null +++ b/old/.gitignore @@ -0,0 +1,128 @@ +# Windows image file caches +Thumbs.db + +# Folder config file +Desktop.ini + +# Files left over from merge conflicts +*.orig + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user + +# Build results +bin/[Dd]ebug/ +bin/[Rr]elease/ +*_i.c +*_p.c +*.ilk +*.log +*.meta +*.obj +*.pch +bin/**/*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.vspscc +.builds + +# Roslyn cache directories +*.ide/ +*.vs/ + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf + +# Visual Studio profiler +*.psess +*.vsp + +# ReSharper is a .NET coding add-in +_ReSharper* + +# Click-Once directory +publish + +# Others +[Bb]in +[Oo]bj +sql +TestResults +*.Cache +ClientBin +stylecop.* +~$* +*.dbmdl +Generated_Code #added for RIA/Silverlight projects +*.results.xml +nunit-*.xml +*.userprefs +packaging/ +tools/FAKE.Core +tools/SourceLink.Fake +tools/xunit.runner.console +tools/Octokit.CodeFormatter +tools/dotnet +*.ncrunch* +*.GhostDoc.xml + +# FAKE temporary files +.fake/ + +# New VS Test Runner creates arbitrary folders with PDBs +*.pdb +pingme.txt + +# ReadTheDocs build output +docs/_build + +# it's 2015, no need to keep this around when migrating projects +Backup/ + +# Let's not commit the NuGet packages +packages/ + +# DNX +project.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +BenchmarkDotNet.Artifacts diff --git a/old/CODE_OF_CONDUCT.md b/old/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..87e7d92 --- /dev/null +++ b/old/CODE_OF_CONDUCT.md @@ -0,0 +1,74 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or +advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at haacked@gmail.com. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ diff --git a/old/LICENSE.txt b/old/LICENSE.txt new file mode 100644 index 0000000..b5910ee --- /dev/null +++ b/old/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2016 GitHub, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/NuGet.config b/old/NuGet.config similarity index 100% rename from NuGet.config rename to old/NuGet.config diff --git a/old/README.md b/old/README.md new file mode 100644 index 0000000..8a8aa43 --- /dev/null +++ b/old/README.md @@ -0,0 +1,349 @@ +# Scientist.NET + +A .NET Port of the [Scientist](https://github.com/github/scientist) library for carefully refactoring critical paths. + +[![Build status](https://ci.appveyor.com/api/projects/status/b548cd5okkel3h4x/branch/master?svg=true)](https://ci.appveyor.com/project/shiftkey/scientist-net/branch/master) +[![Gitter](https://badges.gitter.im/scientistproject/community.svg)](https://gitter.im/scientistproject/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) + +To give it a twirl, use NuGet to install: `Install-Package Scientist` + +## How do I science? + +Let's pretend you're changing the way you handle permissions in a large web app. Tests can help guide your refactoring, but you really want to compare the current and refactored behaviors under load. + +```csharp +using GitHub; + +... + +public bool CanAccess(IUser user) +{ + return Scientist.Science("widget-permissions", experiment => + { + experiment.Use(() => IsCollaborator(user)); // old way + experiment.Try(() => HasAccess(user)); // new way + }); // returns the control value +} +``` + +Wrap a `Use` block around the code's original behavior, and wrap `Try` around the new behavior. Invoking `Scientist.Science` will always return whatever the `Use` block returns, but it does a bunch of stuff behind the scenes: + +* It decides whether or not to run the `Try` block, +* Randomizes the order in which `Use` and `Try` blocks are run, +* Measures the durations of all behaviors, +* Compares the result of `Try` to the result of `Use`, +* Swallows (but records) any exceptions raised in the `Try` block, and +* Publishes all this information. + +The `Use` block is called the **control**. The `Try` block is called the **candidate**. + +If you don't declare any `Try` blocks, none of the Scientist machinery is invoked and the control value is always returned. + +## Making science useful + +### Publishing results + +What good is science if you can't publish your results? + +By default results are published in an in-memory publisher. To override this behavior, create your own implementation of `IResultPublisher`: + +```csharp +public class MyResultPublisher : IResultPublisher +{ + public Task Publish(Result result) + { + Logger.Debug($"Publishing results for experiment '{result.ExperimentName}'"); + Logger.Debug($"Result: {(result.Matched ? "MATCH" : "MISMATCH")}"); + Logger.Debug($"Control value: {result.Control.Value}"); + Logger.Debug($"Control duration: {result.Control.Duration}"); + foreach (var observation in result.Candidates) + { + Logger.Debug($"Candidate name: {observation.Name}"); + Logger.Debug($"Candidate value: {observation.Value}"); + Logger.Debug($"Candidate duration: {observation.Duration}"); + } + + if (result.Mismatched) + { + // saved mismatched experiments to DB + DbHelpers.SaveExperimentResults(result); + } + + return Task.FromResult(0); + } +} +``` + +Then set Scientist to use it before running the experiments: + +```csharp +Scientist.ResultPublisher = new MyResultPublisher(); +``` + +As of v1.0.2, A `IResultPublisher` can also be wrapped in `FireAndForgetResultPublisher` so that result publishing avoids any delays in running experiments and is delegated to another thread: + +```csharp +Scientist.ResultPublisher = new FireAndForgetResultPublisher(new MyResultPublisher(onPublisherException)); +``` + +### Controlling comparison + +Scientist compares control and candidate values using `==`. To override this behavior, use `Compare` to define how to compare observed values instead: + +```csharp +public IUser GetCurrentUser(string hash) +{ + return Scientist.Science("get-current-user", experiment => + { + experiment.Compare((x, y) => x.Name == y.Name); + + experiment.Use(() => LookupUser(hash)); + experiment.Try(() => RetrieveUser(hash)); + }); +} +``` + +### Adding context + + +Results aren't very useful without some way to identify them. Use the `AddContext` method to add to the context for an experiment: + +```csharp +public IUser GetUserByName(string userName) +{ + return Scientist.Science("get-user-by-name", experiment => + { + experiment.AddContext("username", userName); + + experiment.Use(() => FindUser(userName)); + experiment.Try(() => GetUser(userName)); + }); +} +``` + +`AddContext` takes a string identifier and an object value, and adds them to an internal `Dictionary`. When you publish the results, you can access the context by using the ```Contexts``` property: + +```csharp +public class MyResultPublisher : IResultPublisher +{ + public Task Publish(Result result) + { + foreach (var kvp in result.Contexts) + { + Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}"); + } + return Task.FromResult(0); + } +} +``` + +### Expensive setup + +If an experiment requires expensive setup that should only occur when the experiment is going to be run, define it with the `BeforeRun` method: + +```csharp +public int DoSomethingExpensive() +{ + return Scientist.Science("expensive-but-worthwile", experiment => + { + experiment.BeforeRun(() => ExpensiveSetup()); + + experiment.Use(() => TheOldWay()); + experiment.Try(() => TheNewWay()); + }); +} +``` + +### Keeping it clean + +Sometimes you don't want to store the full value for later analysis. For example, an experiment may return `IUser` instances, but when researching a mismatch, all you care about is the logins. You can define how to clean these values in an experiment: + +```csharp +public IUser GetUserByEmail(string emailAddress) +{ + return Scientist.Science("get-user-by-email", experiment => + { + experiment.Use(() => OldApi.FindUserByEmail(emailAddress)); + experiment.Try(() => NewApi.GetUserByEmail(emailAddress)); + + experiment.Clean(user => user.Login); + }); +} +``` + +And this cleaned value is available in the final published result: + +```csharp +public class MyResultPublisher : IResultPublisher +{ + public Task Publish(Result result) + { + // result.Control.Value = + IUser user = (IUser)result.Control.Value; + Console.WriteLine($"Login from raw object: {user.Login}"); + + // result.Control.CleanedValue = "user name" + Console.WriteLine($"Login from cleaned object: {result.Control.CleanedValue}"); + + return Task.FromResult(0); + } +} +``` + +### Ignoring mismatches + +During the early stages of an experiment, it's possible that some of your code will always generate a mismatch for reasons you know and understand but haven't yet fixed. Instead of these known cases always showing up as mismatches in your metrics or analysis, you can tell an experiment whether or not to ignore a mismatch using the `Ignore` method. You may include more than one block if needed: + +```csharp +public bool CanAccess(IUser user) +{ + return Scientist.Science("widget-permissions", experiment => + { + experiment.Use(() => IsCollaborator(user)); + experiment.Try(() => HasAccess(user)); + + // user is staff, always an admin in the new system + experiment.Ignore((control, candidate) => user.IsStaff); + // new system doesn't handle unconfirmed users yet + experiment.Ignore((control, candidate) => control && !candidate && !user.ConfirmedEmail); + }); +} +``` + +The ignore blocks are only called if the *values* don't match. If one observation raises an exception and the other doesn't, it's always considered a mismatch. If both observations raise different exceptions, that is also considered a mismatch. + +### Enabling/disabling experiments + +Sometimes you don't want an experiment to run. Say, disabling a new codepath for anyone who isn't staff. You can disable an experiment by setting a `RunIf` block. If this returns `false`, the experiment will merely return the control value. Otherwise, it defers to the global `Scientist.Enabled` method. + +```csharp +public decimal GetUserStatistic(IUser user) +{ + return Scientist.Science("new-statistic-calculation", experiment => + { + experiment.RunIf(() => user.IsTestSubject); + + experiment.Use(() => CalculateStatistic(user)); + experiment.Try(() => NewCalculateStatistic(user)); + }); +} +``` + +### Ramping up experiments + +As a scientist, you know it's always important to be able to turn your experiment off, lest it run amok and result in villagers with pitchforks on your doorstep. You can set a global switch to control whether or not experiments is enabled by using the `Scientist.Enabled` method. + +```csharp +int percentEnabled = 10; +Random rand = new Random(); +Scientist.Enabled(() => +{ + return rand.Next(100) < percentEnabled; +}); +``` + +This code will be invoked for every method with an experiment every time, so be sensitive about its performance. For example, you can store an experiment in the database but wrap it in various levels of caching. + +### Running candidates in parallel (asynchronous) + +Scientist runs tasks synchronously by default. This can end up doubling (more or less) the time it takes the original method call to complete, depending on how many candidates are added and how long they take to run. + +In cases where Scientist is used for production refactoring, for example, this ends up causing the calling method to return slower than before which may affect the performance of your original code. However, if the candidates can be run at the same time as the control method without affecting each other, then they can be run in parallel so the Scientist call will only take as long as the slowest task (plus a tiny bit of overhead): + +```csharp +await Scientist.ScienceAsync( + "ExperimentName", + 3, // number of tasks to run concurrently + experiment => { + experiment.Use(async () => await StartRunningSomething(myData)); + experiment.Try(async () => await RunAtTheSameTimeAsTheControlMethod(myData)); + experiment.Try(async () => await AlsoRunThisConcurrently(myData)); + }); +``` + +As always when using async/await, don't forget to call `.ConfigureAwait(false)` where appropriate. + +### Testing + +When running your test suite, it's helpful to know that the experimental results always match. To help with testing, Scientist has a `ThrowOnMismatches` property that can be set to `true`. Only do this in your test suite! + +To throw on mismatches: + +```csharp +Scientist.Science("ExperimentN", experiment => +{ + experiment.ThrowOnMismatches = true; + // ... +}); +``` + +Scientist will throw a `MismatchException` exception if any observations don't match. + +### Handling errors + +If an exception is thrown in any of Scientist's internal helpers like `Compare`, `Enabled`, or `Ignore`, the default behavior of Scientist is to re-throw that exception. Since this halts the experiment entirely, it's often a better idea to handle this error and continue so the experiment as a whole isn't canceled entirely: + +```csharp +Scientist.Science("ExperimentCatch", experiment => +{ + experiment.Thrown((operation, exception) => InternalTracker.Track($"Science failure in ExperimentCatch: {operation}.", exception)) + // ... +}); +``` + +The operations that may be handled here are: + +* `Operation.Compare` - an exception is raised in a `Compare` block +* `Operation.Enabled` - an exception is raised in the `Enabled` block +* `Operation.Ignore` - an exception is raised in an `Ignore` block +* `Operation.Publish` - an exception is raised while publishing results +* `Operation.RunIf` - an exception is raised in a `RunIf` block + +### Designing an experiment + +Because `Enabled` and `RunIf` determine when a candidate runs, it's impossible to guarantee that it will run every time. For this reason, Scientist is only safe for wrapping methods that aren't changing data. + +When using Scientist, we've found it most useful to modify both the existing and new systems simultaneously anywhere writes happen, and verify the results at read time with `Science`. `ThrowOnMismatches` has also been useful to ensure that the correct data was written during tests, and reviewing published mismatches has helped us find any situations we overlooked with our production data at runtime. When writing to and reading from two systems, it's also useful to write some data reconciliation scripts to verify and clean up production data alongside any running experiments. + +### Finishing an experiment + +As your candidate behavior converges on the controls, you'll start thinking about removing an experiment and using the new behavior. + +* If there are any ignore blocks, the candidate behavior is *guaranteed* to be different. If this is unacceptable, you'll need to remove the ignore blocks and resolve any ongoing mismatches in behavior until the observations match perfectly every time. +* When removing a read-behavior experiment, it's a good idea to keep any write-side duplication between an old and new system in place until well after the new behavior has been in production, in case you need to roll back. + +## Breaking the rules + +Sometimes scientists just gotta do weird stuff. We understand. + + +### Ignoring results entirely + +Science is useful even when all you care about is the timing data or even whether or not a new code path blew up. If you have the ability to incrementally control how often an experiment runs via your `Enabled` method, you can use it to silently and carefully test new code paths and ignore the results altogether. You can do this by setting `Ignore((x, y) => true)`, or for greater efficiency, `Compare((x, y) => true)`. + +This will still log mismatches if any exceptions are raised, but will disregard the values entirely. + +### Trying more than one thing + +It's not usually a good idea to try more than one alternative simultaneously. Behavior isn't guaranteed to be isolated and reporting + visualization get quite a bit harder. Still, it's sometimes useful. + +To try more than one alternative at once, add names to some `Try` blocks: + +```csharp +public bool CanAccess(IUser user) +{ + return Scientist.Science("widget-permissions", experiment => + { + experiment.Use(() => IsCollaborator(user)); + experiment.Try("api", () => HasAccess(user)); + experiment.Try("raw-sql", () => HasAccessSql(user)); + }); +} +``` + +## Alternatives + +Here are other implementations of Scientist available in different languages. + +- [github/scientist](https://github.com/github/scientist) the original implementation of Scientist, in [Ruby](https://www.ruby-lang.org/). +- [daylerees/scientist](https://github.com/daylerees/scientist) for [PHP](http://php.net/) by [Dayle Rees](https://github.com/daylerees). diff --git a/ReleaseNotes.md b/old/ReleaseNotes.md similarity index 100% rename from ReleaseNotes.md rename to old/ReleaseNotes.md diff --git a/old/Scientist.net.sln b/old/Scientist.net.sln new file mode 100644 index 0000000..02c1cb7 --- /dev/null +++ b/old/Scientist.net.sln @@ -0,0 +1,49 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26730.16 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Meta", "Meta", "{0FF544BE-E75C-4EF7-AEB3-A534ED5D7BB5}" + ProjectSection(SolutionItems) = preProject + .gitattributes = .gitattributes + .gitignore = .gitignore + appveyor.yml = appveyor.yml + build.cmd = build.cmd + build.fsx = build.fsx + LICENSE.txt = LICENSE.txt + README.md = README.md + ReleaseNotes.md = ReleaseNotes.md + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scientist", "src\Scientist\Scientist.csproj", "{AF3E98CD-DA8C-43B2-8217-76B6AE8BCA20}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scientist.Test", "test\Scientist.Test\Scientist.Test.csproj", "{0686E0A8-FB25-4B20-9BC0-CD05E916E5AD}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Scientist.Benchmark", "test\Scientist.Benchmark\Scientist.Benchmark.csproj", "{243420EF-8A98-4D0F-9E2E-86F4E70C3128}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AF3E98CD-DA8C-43B2-8217-76B6AE8BCA20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AF3E98CD-DA8C-43B2-8217-76B6AE8BCA20}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AF3E98CD-DA8C-43B2-8217-76B6AE8BCA20}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AF3E98CD-DA8C-43B2-8217-76B6AE8BCA20}.Release|Any CPU.Build.0 = Release|Any CPU + {0686E0A8-FB25-4B20-9BC0-CD05E916E5AD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0686E0A8-FB25-4B20-9BC0-CD05E916E5AD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0686E0A8-FB25-4B20-9BC0-CD05E916E5AD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0686E0A8-FB25-4B20-9BC0-CD05E916E5AD}.Release|Any CPU.Build.0 = Release|Any CPU + {243420EF-8A98-4D0F-9E2E-86F4E70C3128}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {243420EF-8A98-4D0F-9E2E-86F4E70C3128}.Debug|Any CPU.Build.0 = Debug|Any CPU + {243420EF-8A98-4D0F-9E2E-86F4E70C3128}.Release|Any CPU.ActiveCfg = Release|Any CPU + {243420EF-8A98-4D0F-9E2E-86F4E70C3128}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {8CFF3922-3285-4B9E-9E64-7FC7D5332E56} + EndGlobalSection +EndGlobal diff --git a/appveyor.yml b/old/appveyor.yml similarity index 100% rename from appveyor.yml rename to old/appveyor.yml diff --git a/old/assets/Scientist_Final-01.svg b/old/assets/Scientist_Final-01.svg new file mode 100644 index 0000000..862c131 --- /dev/null +++ b/old/assets/Scientist_Final-01.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/old/assets/scientist-logo-64x64.png b/old/assets/scientist-logo-64x64.png new file mode 100644 index 0000000000000000000000000000000000000000..70ab606c2b1042e199713e20bb76501234f92729 GIT binary patch literal 1272 zcmVPNDOp{>- z3|=6iTlcVKWH#!9GfWmA*wzQlQj+7vmW>za%`C{7G}=mRdp4QJABC1ncAQmwew0vZ` zl>h*2x)^@i7bWHti9x8K^w=|C#73-N0k}4;!9m%yD_${&r)3 zVM3^&^ib680RY4UPc}7IYjYFtCdLbdh}Q>q=O8rQuj6m$gVN0%;(;d!*lvgklu$&( z9Mmc$XalvjM-MS@dA!99fi_UM{mrE{`|sYnPsEFh<{-4)VIyWVF*&vVVB;&m-ujj6 z*=fM>tMDP1db?r${4|u?x36T2kLK~tM<1{4J0cA5+t0e))<` zyQgPh9vDhmIh0+a}WPD6MrDUEqwZ!0`=cv)V_3y49B6&J49(RJi70AO_7nNz}*R|s>- z7oz1V=oL!%q6{Pw368330f5NCi_ae*w)}a4;PVG?_uhT9HaFqh>Q`6w=Tavqia24= zV$JBS?ca@NKU3IZ5%UQyj~53z`f%o?88tdB0N~olP1r|n7JLjs)G_+}0hqJY3Ew_) zICbizPr?F#GbhbyTVF85VMB~>gmGHm#Xl~ z19#T3x5k|tjz>1^6LPihd?s4E>4U|cN*AO#xIA8%Klu#rC6CdzT7wp=Ft*5|51T~@ iA_NhF2tkBUMEVD{O`v?(oQy#L0000 Date: Fri, 23 Jul 2021 00:16:53 +0100 Subject: [PATCH 03/26] added boilerplate to test github action --- Scientist.Test/Scientist.Test.csproj | 13 +- Scientist.Test/Scientist.cs | 9 +- Scientist/Scientist.cs | 190 +-------------------------- 3 files changed, 17 insertions(+), 195 deletions(-) diff --git a/Scientist.Test/Scientist.Test.csproj b/Scientist.Test/Scientist.Test.csproj index 14db845..6f332ca 100644 --- a/Scientist.Test/Scientist.Test.csproj +++ b/Scientist.Test/Scientist.Test.csproj @@ -1,22 +1,29 @@ - + net6.0 false + + cb167bc0-e4e4-4cb9-97fd-7f8528c2683b - + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + runtime; build; native; contentfiles; analyzers; buildtransitive all + + + + diff --git a/Scientist.Test/Scientist.cs b/Scientist.Test/Scientist.cs index 199f4a9..05e25b3 100644 --- a/Scientist.Test/Scientist.cs +++ b/Scientist.Test/Scientist.cs @@ -3,13 +3,16 @@ namespace Scientist.Test { - public class Scientist + public class ScientistTest { [Fact] - public void DoesntRunCandidate() + public void IsEven_EvenNumber_ExpectTrue() { - const int expectedResult = 42; + const int testData = 42; + var isEven = Scientist.IsEven(testData); + + Assert.True(isEven); } } } diff --git a/Scientist/Scientist.cs b/Scientist/Scientist.cs index 75cdf22..e493986 100644 --- a/Scientist/Scientist.cs +++ b/Scientist/Scientist.cs @@ -5,194 +5,6 @@ namespace Scientist { public class Scientist : IScientist { - static readonly Task EnabledTask = Task.FromResult(true); - static readonly Lazy _sharedScientist = new Lazy(CreateSharedInstance); - static Func> _enabled = () => EnabledTask; - static IResultPublisher _sharedPublisher = new InMemoryResultPublisher(); - readonly IResultPublisher _resultPublisher; - - /// - /// Initializes a new instance of the class - /// using the specified - /// - public Scientist(IResultPublisher resultPublisher) - { - _resultPublisher = resultPublisher - ?? throw new ArgumentNullException(nameof(resultPublisher), "A result publisher must be specified"); - } - - // TODO: How can we guide the developer to the pit of success - - /// - /// Gets or sets the result publisher to use. - /// This should be configured once before starting observations. - /// - /// - /// An attempt to set the value was made after the first experiment has been run. - /// - public static IResultPublisher ResultPublisher - { - get - { - return _sharedPublisher; - } - - set - { - if (_sharedScientist.IsValueCreated) - { - throw new InvalidOperationException($"The value of the {nameof(ResultPublisher)} property cannot be changed once an experiment has been run."); - } - - _sharedPublisher = value; - } - } - - static Scientist CreateSharedInstance() => new SharedScientist(ResultPublisher); - - Experiment Build(string name, int concurrentTasks, Action> experiment) - { - // TODO: Maybe we could automatically generate the name if none is provided using the calling method name. We'd have to - // make sure we don't inline this method though. - var experimentBuilder = new Experiment(name, IsEnabledAsync, concurrentTasks, _resultPublisher); - - experiment(experimentBuilder); - - return experimentBuilder; - } - - Experiment Build(string name, int concurrentTasks, Action> experiment) - { - var builder = new Experiment(name, IsEnabledAsync, concurrentTasks, _resultPublisher); - - experiment(builder); - - return builder; - } - - /// - /// Determines if an experiment should be enabled. - /// - /// A delegate returning if an experiment should run. - public static void Enabled(Func enabled) => Enabled(() => Task.FromResult(enabled())); - - /// - /// Determines if an experiment should be enabled. - /// - /// A delegate returning an asynchronous task determining if an experiment should run. - public static void Enabled(Func> enabled) => _enabled = enabled; - - /// - /// Conduct a synchronous experiment - /// - /// The return type of the experiment - /// Name of the experiment - /// Experiment callback used to configure the experiment - /// The value of the experiment's control function. - public static T Science(string name, Action> experiment) => - _sharedScientist.Value.Experiment(name, experiment); - - /// - /// Conduct a synchronous experiment - /// - /// The return type of the experiment - /// The clean type for publishing. - /// Name of the experiment - /// Experiment callback used to configure the experiment - /// The value of the experiment's control function. - public static T Science(string name, Action> experiment) => - _sharedScientist.Value.Experiment(name, experiment); - - /// - /// Conduct an asynchronous experiment - /// - /// The return type of the experiment - /// Name of the experiment - /// Experiment callback used to configure the experiment - /// The value of the experiment's control function. - public static Task ScienceAsync(string name, Action> experiment) => - _sharedScientist.Value.ExperimentAsync(name, experiment); - - /// - /// Conduct an asynchronous experiment - /// - /// The return type of the experiment - /// Name of the experiment - /// Number of tasks to run concurrently - /// Experiment callback used to configure the experiment - /// The value of the experiment's control function. - public static Task ScienceAsync(string name, int concurrentTasks, Action> experiment) => - _sharedScientist.Value.ExperimentAsync(name, concurrentTasks, experiment); - - /// - /// Conduct an asynchronous experiment - /// - /// The return type of the experiment - /// The clean type for publishing. - /// Name of the experiment - /// Experiment callback used to configure the experiment - /// The value of the experiment's control function. - public static Task ScienceAsync(string name, Action> experiment) => - _sharedScientist.Value.ExperimentAsync(name, experiment); - - /// - /// Conduct an asynchronous experiment - /// - /// The return type of the experiment - /// The clean type for publishing. - /// Name of the experiment - /// Number of tasks to run concurrently - /// Experiment callback used to configure the experiment - /// The value of the experiment's control function. - public static Task ScienceAsync(string name, int concurrentTasks, Action> experiment) => - _sharedScientist.Value.ExperimentAsync(name, concurrentTasks, experiment); - - /// - /// Conduct a synchronous experiment - /// - /// The return type of the experiment - /// The clean type for publishing. - /// Name of the experiment - /// Experiment callback used to configure the experiment - /// The value of the experiment's control function. - public T Experiment(string name, Action> experiment) => - Build(name, 1, experiment).Build().Run().Result; - - /// - /// Conduct an asynchronous experiment - /// - /// The return type of the experiment - /// The clean type for publishing. - /// Name of the experiment - /// Number of tasks to run concurrently - /// Experiment callback used to configure the experiment - /// The value of the experiment's control function. - public Task ExperimentAsync(string name, int concurrentTasks, Action> experiment) => - Build(name, concurrentTasks, experiment).Build().Run(); - - /// - /// Returns whether the experiment is enabled as an asynchronous operation - /// - /// - /// A which returns whether the experiment is enabled. - /// - /// - /// Override this method to change the default implementation which always returns . - /// - protected virtual Task IsEnabledAsync() => EnabledTask; - - // This class acts as a proxy to allow the static methods to set the state on an instance of Scientist. - private sealed class SharedScientist : Scientist - { - internal SharedScientist(IResultPublisher resultPublisher) - : base(resultPublisher) - { - } - - protected override async Task IsEnabledAsync() - { - return await _enabled().ConfigureAwait(false); - } - } + public static bool IsEven(int num) => num % 2 == 0; } } From 5c3081ecb16c48531fe5e50fa46a9d672e8ce63f Mon Sep 17 00:00:00 2001 From: Daniel Loudon Date: Fri, 23 Jul 2021 21:25:10 +0100 Subject: [PATCH 04/26] Create build.yml --- .github/workflows/build.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..401dea1 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,25 @@ +name: .NET Build + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 6.0.x + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore + - name: Test + run: dotnet test --no-build --verbosity normal From dd217781a7d87ebae37f0f694f82a6dca86b6e25 Mon Sep 17 00:00:00 2001 From: Daniel Loudon Date: Fri, 23 Jul 2021 21:33:48 +0100 Subject: [PATCH 05/26] Update and rename build.yml to ver3build.yml --- .github/workflows/{build.yml => ver3build.yml} | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) rename .github/workflows/{build.yml => ver3build.yml} (82%) diff --git a/.github/workflows/build.yml b/.github/workflows/ver3build.yml similarity index 82% rename from .github/workflows/build.yml rename to .github/workflows/ver3build.yml index 401dea1..c4433c0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/ver3build.yml @@ -1,10 +1,11 @@ -name: .NET Build +name: 3.0.0 Build on: + workflow_dispatch: push: - branches: [ master ] + branches: [ 3.0.0 ] pull_request: - branches: [ master ] + branches: [ 3.0.0 ] jobs: build: From 91971a51ab5547809923cf9c89f37e72c0b36619 Mon Sep 17 00:00:00 2001 From: Daniel Loudon Date: Fri, 23 Jul 2021 21:36:20 +0100 Subject: [PATCH 06/26] Update ver3build.yml --- .github/workflows/ver3build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ver3build.yml b/.github/workflows/ver3build.yml index c4433c0..a2c30bd 100644 --- a/.github/workflows/ver3build.yml +++ b/.github/workflows/ver3build.yml @@ -18,6 +18,7 @@ jobs: uses: actions/setup-dotnet@v1 with: dotnet-version: 6.0.x + include-prerelease: true - name: Restore dependencies run: dotnet restore - name: Build From 26dc09bb038aa0060c476340773ff5f7157013a2 Mon Sep 17 00:00:00 2001 From: Daniel Loudon Date: Fri, 23 Jul 2021 21:39:55 +0100 Subject: [PATCH 07/26] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8a8aa43..5ac3d41 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A .NET Port of the [Scientist](https://github.com/github/scientist) library for carefully refactoring critical paths. -[![Build status](https://ci.appveyor.com/api/projects/status/b548cd5okkel3h4x/branch/master?svg=true)](https://ci.appveyor.com/project/shiftkey/scientist-net/branch/master) +[![3.0.0 Build](https://github.com/marblekirby/Scientist.net/actions/workflows/ver3build.yml/badge.svg?branch=3.0.0)](https://github.com/marblekirby/Scientist.net/actions/workflows/ver3build.yml) [![Gitter](https://badges.gitter.im/scientistproject/community.svg)](https://gitter.im/scientistproject/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) To give it a twirl, use NuGet to install: `Install-Package Scientist` From 39dbf4734feeeedb76cb6625cb87d07fdb15df05 Mon Sep 17 00:00:00 2001 From: Daniel Loudon Date: Fri, 23 Jul 2021 21:41:58 +0100 Subject: [PATCH 08/26] Update ver3build.yml --- .github/workflows/ver3build.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ver3build.yml b/.github/workflows/ver3build.yml index a2c30bd..44a2cfc 100644 --- a/.github/workflows/ver3build.yml +++ b/.github/workflows/ver3build.yml @@ -23,5 +23,7 @@ jobs: run: dotnet restore - name: Build run: dotnet build --no-restore + working-directory: ./src - name: Test run: dotnet test --no-build --verbosity normal + working-directory: ./src From 77cab03e836e229c7f5bf3722f60cbfbc3d1db00 Mon Sep 17 00:00:00 2001 From: Daniel Loudon Date: Fri, 23 Jul 2021 21:43:49 +0100 Subject: [PATCH 09/26] Update ver3build.yml --- .github/workflows/ver3build.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/ver3build.yml b/.github/workflows/ver3build.yml index 44a2cfc..a2c30bd 100644 --- a/.github/workflows/ver3build.yml +++ b/.github/workflows/ver3build.yml @@ -23,7 +23,5 @@ jobs: run: dotnet restore - name: Build run: dotnet build --no-restore - working-directory: ./src - name: Test run: dotnet test --no-build --verbosity normal - working-directory: ./src From d2b72d9ddc1ce14ff3269d7a37de45044f02a463 Mon Sep 17 00:00:00 2001 From: Daniel Loudon Date: Fri, 23 Jul 2021 21:51:55 +0100 Subject: [PATCH 10/26] Update ver3build.yml --- .github/workflows/ver3build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ver3build.yml b/.github/workflows/ver3build.yml index a2c30bd..96674c3 100644 --- a/.github/workflows/ver3build.yml +++ b/.github/workflows/ver3build.yml @@ -24,4 +24,4 @@ jobs: - name: Build run: dotnet build --no-restore - name: Test - run: dotnet test --no-build --verbosity normal + run: dotnet test --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover From 2687a3498e6bb070afb6cb7fcd873eb15fdc9678 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 23 Jul 2021 22:01:24 +0100 Subject: [PATCH 11/26] updated project settings --- .gitignore | 3 ++- Scientist.Test/Scientist.Test.csproj | 4 ++++ Scientist/Scientist.csproj | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 9f83e16..21957d8 100644 --- a/.gitignore +++ b/.gitignore @@ -127,4 +127,5 @@ artifacts/ BenchmarkDotNet.Artifacts -**/.vs \ No newline at end of file +**/.vs +/Scientist.Test/coverage.json diff --git a/Scientist.Test/Scientist.Test.csproj b/Scientist.Test/Scientist.Test.csproj index 6f332ca..ba2d143 100644 --- a/Scientist.Test/Scientist.Test.csproj +++ b/Scientist.Test/Scientist.Test.csproj @@ -9,6 +9,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Scientist/Scientist.csproj b/Scientist/Scientist.csproj index 4de8048..d15ac72 100644 --- a/Scientist/Scientist.csproj +++ b/Scientist/Scientist.csproj @@ -1,4 +1,4 @@ - + net6.0 From b10057865f8d87268ee83d3d3070d41ef050da42 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 23 Jul 2021 22:04:42 +0100 Subject: [PATCH 12/26] Reverted changes and commented code out for github action to pass --- Scientist.Test/Scientist.cs | 8 +- Scientist/Scientist.cs | 190 +++++++++++++++++++++++++++++++++++- 2 files changed, 191 insertions(+), 7 deletions(-) diff --git a/Scientist.Test/Scientist.cs b/Scientist.Test/Scientist.cs index 05e25b3..00bf97f 100644 --- a/Scientist.Test/Scientist.cs +++ b/Scientist.Test/Scientist.cs @@ -6,13 +6,9 @@ namespace Scientist.Test public class ScientistTest { [Fact] - public void IsEven_EvenNumber_ExpectTrue() + public void Test_Method() { - const int testData = 42; - - var isEven = Scientist.IsEven(testData); - - Assert.True(isEven); + } } } diff --git a/Scientist/Scientist.cs b/Scientist/Scientist.cs index e493986..51131a5 100644 --- a/Scientist/Scientist.cs +++ b/Scientist/Scientist.cs @@ -5,6 +5,194 @@ namespace Scientist { public class Scientist : IScientist { - public static bool IsEven(int num) => num % 2 == 0; + //static readonly Task EnabledTask = Task.FromResult(true); + //static readonly Lazy _sharedScientist = new Lazy(CreateSharedInstance); + //static Func> _enabled = () => EnabledTask; + //static IResultPublisher _sharedPublisher = new InMemoryResultPublisher(); + //readonly IResultPublisher _resultPublisher; + + ///// + ///// Initializes a new instance of the class + ///// using the specified + ///// + //public Scientist(IResultPublisher resultPublisher) + //{ + // _resultPublisher = resultPublisher + // ?? throw new ArgumentNullException(nameof(resultPublisher), "A result publisher must be specified"); + //} + + //// TODO: How can we guide the developer to the pit of success + + ///// + ///// Gets or sets the result publisher to use. + ///// This should be configured once before starting observations. + ///// + ///// + ///// An attempt to set the value was made after the first experiment has been run. + ///// + //public static IResultPublisher ResultPublisher + //{ + // get + // { + // return _sharedPublisher; + // } + + // set + // { + // if (_sharedScientist.IsValueCreated) + // { + // throw new InvalidOperationException($"The value of the {nameof(ResultPublisher)} property cannot be changed once an experiment has been run."); + // } + + // _sharedPublisher = value; + // } + //} + + //static Scientist CreateSharedInstance() => new SharedScientist(ResultPublisher); + + //Experiment Build(string name, int concurrentTasks, Action> experiment) + //{ + // // TODO: Maybe we could automatically generate the name if none is provided using the calling method name. We'd have to + // // make sure we don't inline this method though. + // var experimentBuilder = new Experiment(name, IsEnabledAsync, concurrentTasks, _resultPublisher); + + // experiment(experimentBuilder); + + // return experimentBuilder; + //} + + //Experiment Build(string name, int concurrentTasks, Action> experiment) + //{ + // var builder = new Experiment(name, IsEnabledAsync, concurrentTasks, _resultPublisher); + + // experiment(builder); + + // return builder; + //} + + ///// + ///// Determines if an experiment should be enabled. + ///// + ///// A delegate returning if an experiment should run. + //public static void Enabled(Func enabled) => Enabled(() => Task.FromResult(enabled())); + + ///// + ///// Determines if an experiment should be enabled. + ///// + ///// A delegate returning an asynchronous task determining if an experiment should run. + //public static void Enabled(Func> enabled) => _enabled = enabled; + + ///// + ///// Conduct a synchronous experiment + ///// + ///// The return type of the experiment + ///// Name of the experiment + ///// Experiment callback used to configure the experiment + ///// The value of the experiment's control function. + //public static T Science(string name, Action> experiment) => + // _sharedScientist.Value.Experiment(name, experiment); + + ///// + ///// Conduct a synchronous experiment + ///// + ///// The return type of the experiment + ///// The clean type for publishing. + ///// Name of the experiment + ///// Experiment callback used to configure the experiment + ///// The value of the experiment's control function. + //public static T Science(string name, Action> experiment) => + // _sharedScientist.Value.Experiment(name, experiment); + + ///// + ///// Conduct an asynchronous experiment + ///// + ///// The return type of the experiment + ///// Name of the experiment + ///// Experiment callback used to configure the experiment + ///// The value of the experiment's control function. + //public static Task ScienceAsync(string name, Action> experiment) => + // _sharedScientist.Value.ExperimentAsync(name, experiment); + + ///// + ///// Conduct an asynchronous experiment + ///// + ///// The return type of the experiment + ///// Name of the experiment + ///// Number of tasks to run concurrently + ///// Experiment callback used to configure the experiment + ///// The value of the experiment's control function. + //public static Task ScienceAsync(string name, int concurrentTasks, Action> experiment) => + // _sharedScientist.Value.ExperimentAsync(name, concurrentTasks, experiment); + + ///// + ///// Conduct an asynchronous experiment + ///// + ///// The return type of the experiment + ///// The clean type for publishing. + ///// Name of the experiment + ///// Experiment callback used to configure the experiment + ///// The value of the experiment's control function. + //public static Task ScienceAsync(string name, Action> experiment) => + // _sharedScientist.Value.ExperimentAsync(name, experiment); + + ///// + ///// Conduct an asynchronous experiment + ///// + ///// The return type of the experiment + ///// The clean type for publishing. + ///// Name of the experiment + ///// Number of tasks to run concurrently + ///// Experiment callback used to configure the experiment + ///// The value of the experiment's control function. + //public static Task ScienceAsync(string name, int concurrentTasks, Action> experiment) => + // _sharedScientist.Value.ExperimentAsync(name, concurrentTasks, experiment); + + ///// + ///// Conduct a synchronous experiment + ///// + ///// The return type of the experiment + ///// The clean type for publishing. + ///// Name of the experiment + ///// Experiment callback used to configure the experiment + ///// The value of the experiment's control function. + //public T Experiment(string name, Action> experiment) => + // Build(name, 1, experiment).Build().Run().Result; + + ///// + ///// Conduct an asynchronous experiment + ///// + ///// The return type of the experiment + ///// The clean type for publishing. + ///// Name of the experiment + ///// Number of tasks to run concurrently + ///// Experiment callback used to configure the experiment + ///// The value of the experiment's control function. + //public Task ExperimentAsync(string name, int concurrentTasks, Action> experiment) => + // Build(name, concurrentTasks, experiment).Build().Run(); + + ///// + ///// Returns whether the experiment is enabled as an asynchronous operation + ///// + ///// + ///// A which returns whether the experiment is enabled. + ///// + ///// + ///// Override this method to change the default implementation which always returns . + ///// + //protected virtual Task IsEnabledAsync() => EnabledTask; + + //// This class acts as a proxy to allow the static methods to set the state on an instance of Scientist. + //private sealed class SharedScientist : Scientist + //{ + // internal SharedScientist(IResultPublisher resultPublisher) + // : base(resultPublisher) + // { + // } + + // protected override async Task IsEnabledAsync() + // { + // return await _enabled().ConfigureAwait(false); + // } + //} } } From 3faf72a59dd5fbc2c332f4b26f979b5bbc120934 Mon Sep 17 00:00:00 2001 From: Daniel Loudon Date: Fri, 23 Jul 2021 22:05:54 +0100 Subject: [PATCH 13/26] Update and rename ver3build.yml to ver3-unit-test.yml --- .github/workflows/{ver3build.yml => ver3-unit-test.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename .github/workflows/{ver3build.yml => ver3-unit-test.yml} (96%) diff --git a/.github/workflows/ver3build.yml b/.github/workflows/ver3-unit-test.yml similarity index 96% rename from .github/workflows/ver3build.yml rename to .github/workflows/ver3-unit-test.yml index 96674c3..e776a0c 100644 --- a/.github/workflows/ver3build.yml +++ b/.github/workflows/ver3-unit-test.yml @@ -1,4 +1,4 @@ -name: 3.0.0 Build +name: 3.0.0 Unit Test on: workflow_dispatch: From f532c1d2a2435d6b6530af35cae88a15071756dc Mon Sep 17 00:00:00 2001 From: Daniel Loudon Date: Fri, 23 Jul 2021 22:06:28 +0100 Subject: [PATCH 14/26] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ac3d41..d5c5448 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A .NET Port of the [Scientist](https://github.com/github/scientist) library for carefully refactoring critical paths. -[![3.0.0 Build](https://github.com/marblekirby/Scientist.net/actions/workflows/ver3build.yml/badge.svg?branch=3.0.0)](https://github.com/marblekirby/Scientist.net/actions/workflows/ver3build.yml) +[![3.0.0 Unit Test](https://github.com/marblekirby/Scientist.net/actions/workflows/ver3-unit-test.yml/badge.svg?branch=3.0.0)](https://github.com/marblekirby/Scientist.net/actions/workflows/ver3build.yml) [![Gitter](https://badges.gitter.im/scientistproject/community.svg)](https://gitter.im/scientistproject/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) To give it a twirl, use NuGet to install: `Install-Package Scientist` From 14956097830c33ccad6af92eebb0f08a026a2803 Mon Sep 17 00:00:00 2001 From: Daniel Loudon Date: Fri, 23 Jul 2021 22:09:33 +0100 Subject: [PATCH 15/26] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5c5448..cbdf891 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A .NET Port of the [Scientist](https://github.com/github/scientist) library for carefully refactoring critical paths. -[![3.0.0 Unit Test](https://github.com/marblekirby/Scientist.net/actions/workflows/ver3-unit-test.yml/badge.svg?branch=3.0.0)](https://github.com/marblekirby/Scientist.net/actions/workflows/ver3build.yml) +[![3.0.0 Unit Test](https://github.com/marblekirby/Scientist.net/actions/workflows/ver3-unit-test.yml/badge.svg?branch=3.0.0)](https://github.com/marblekirby/Scientist.net/actions/workflows/ver3-unit-test.yml) [![Gitter](https://badges.gitter.im/scientistproject/community.svg)](https://gitter.im/scientistproject/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) To give it a twirl, use NuGet to install: `Install-Package Scientist` From 7e89d29e6642016fc4e76cdc14543eba6d2605b3 Mon Sep 17 00:00:00 2001 From: Josh Hiles Date: Wed, 28 Jul 2021 19:39:56 +0100 Subject: [PATCH 16/26] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 56 +++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..4e40696 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,56 @@ +name: "CodeQL" + +on: + push: + branches: [ 3.0.0 ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ 3.0.0 ] + schedule: + - cron: '0 0 * * 1' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'csharp' ] + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 8a01737f467dc3a7b7a4e83b1b93c7392c92a0b7 Mon Sep 17 00:00:00 2001 From: Daniel Loudon Date: Fri, 30 Jul 2021 16:44:31 +0100 Subject: [PATCH 17/26] Update README.md Co-authored-by: Mordechai Zuber --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cbdf891..bc38372 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A .NET Port of the [Scientist](https://github.com/github/scientist) library for carefully refactoring critical paths. -[![3.0.0 Unit Test](https://github.com/marblekirby/Scientist.net/actions/workflows/ver3-unit-test.yml/badge.svg?branch=3.0.0)](https://github.com/marblekirby/Scientist.net/actions/workflows/ver3-unit-test.yml) +[![Build status](https://ci.appveyor.com/api/projects/status/b548cd5okkel3h4x/branch/3.0.0?svg=true)](https://ci.appveyor.com/project/shiftkey/scientist-net/branch/3.0.0) [![Gitter](https://badges.gitter.im/scientistproject/community.svg)](https://gitter.im/scientistproject/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) To give it a twirl, use NuGet to install: `Install-Package Scientist` From edacdc44f69f96a06130107729ca28d12c7c515f Mon Sep 17 00:00:00 2001 From: Joshua Hiles Date: Sun, 8 Aug 2021 12:15:23 +0100 Subject: [PATCH 18/26] chore(codeql): Use dotnet build instead of autobuild for .net 6 --- .github/workflows/codeql-analysis.yml | 59 ++++++++++++--------------- 1 file changed, 25 insertions(+), 34 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 4e40696..e604060 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,12 +2,12 @@ name: "CodeQL" on: push: - branches: [ 3.0.0 ] + branches: [3.0.0] pull_request: # The branches below must be a subset of the branches above - branches: [ 3.0.0 ] + branches: [3.0.0] schedule: - - cron: '0 0 * * 1' + - cron: "0 0 * * 1" jobs: analyze: @@ -21,36 +21,27 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'csharp' ] + language: ["csharp"] steps: - - name: Checkout repository - uses: actions/checkout@v2 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + + # Autobuild doesnt support .net 6 + # - name: Autobuild + # uses: github/codeql-action/autobuild@v1 + + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: "6.0.x" + include-prerelease: true + - run: | + dotnet build /p:UseSharedCompilation=false + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 1069664eee4b5046b29578456a20e76dd57eda9a Mon Sep 17 00:00:00 2001 From: Josh Hiles Date: Mon, 30 Aug 2021 16:45:33 +0100 Subject: [PATCH 19/26] docs: Issue templates for 3.0.0 branch (#147) * Adding issue templates * Update to bug report which is more specific to this repo * docs: Adding pull request template * docs: Remove old CoC & add new CoC * docs: Add new contributing doc * docs(CodeOfConduct): Adding link to gitter in CoC --- .github/ISSUE_TEMPLATE/bug_report.md | 36 ++++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 +++ .../pull_request_template.md | 31 +++++ CODE_OF_CONDUCT.md | 74 ----------- CodeOfConduct.md | 120 ++++++++++++++++++ Contributing.md | 87 +++++++++++++ 6 files changed, 294 insertions(+), 74 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template.md delete mode 100644 CODE_OF_CONDUCT.md create mode 100644 CodeOfConduct.md create mode 100644 Contributing.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..e5c0393 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,36 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "[Bug] Lorem Ipsum" +labels: bug +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Please point us to a minimalistic repro project hosted in a GitHub repo. +For a repo project, create a new project using the template of your your choice, apply the minimum required code to result in the issue you're observing. + +We will close this issue if: +- the repro project you share with us is complex +- if we will not be able to reproduce the behavior you're reporting + +**Expected behavior** +A clear and concise description of what you expected to happen. + +### Exceptions (if any) +Include the exception you get when facing this issue + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +### Further technical details +- Scientist.net version +- Include the output of `dotnet --info` +- The IDE (VS / VS Code/ VS4Mac) you're running on, and its version + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..c250b1d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[Feature] Lorem Ipsum" +labels: feature +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 0000000..80aef02 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,31 @@ + + +## Description + + +## Related Issue + + + + + +## Motivation and Context + + +## Types of changes + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) +- [ ] Documentation + +## Checklist: + + +- [ ] I have read the **[CONTRIBUTING](../../Contributing.md)** document. +- [ ] I have checked to ensure there aren't other open **[PULL REQUESTS](../../../pulls)** for the same update/change. +- [ ] My code follows the code style of this project. +- [ ] I have updated the documentation accordingly where applicable. +- [ ] I have added tests to cover my changes. +- [ ] All new and existing tests passed. +- [ ] Coverage is 100% for new code. \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 87e7d92..0000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,74 +0,0 @@ -# Contributor Covenant Code of Conduct - -## Our Pledge - -In the interest of fostering an open and welcoming environment, we as -contributors and maintainers pledge to making participation in our project and -our community a harassment-free experience for everyone, regardless of age, body -size, disability, ethnicity, gender identity and expression, level of experience, -nationality, personal appearance, race, religion, or sexual identity and -orientation. - -## Our Standards - -Examples of behavior that contributes to creating a positive environment -include: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery and unwelcome sexual attention or -advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others' private information, such as a physical or electronic - address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a - professional setting - -## Our Responsibilities - -Project maintainers are responsible for clarifying the standards of acceptable -behavior and are expected to take appropriate and fair corrective action in -response to any instances of unacceptable behavior. - -Project maintainers have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other contributions -that are not aligned to this Code of Conduct, or to ban temporarily or -permanently any contributor for other behaviors that they deem inappropriate, -threatening, offensive, or harmful. - -## Scope - -This Code of Conduct applies both within project spaces and in public spaces -when an individual is representing the project or its community. Examples of -representing a project or community include using an official project e-mail -address, posting via an official social media account, or acting as an appointed -representative at an online or offline event. Representation of a project may be -further defined and clarified by project maintainers. - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported by contacting the project team at haacked@gmail.com. All -complaints will be reviewed and investigated and will result in a response that -is deemed necessary and appropriate to the circumstances. The project team is -obligated to maintain confidentiality with regard to the reporter of an incident. -Further details of specific enforcement policies may be posted separately. - -Project maintainers who do not follow or enforce the Code of Conduct in good -faith may face temporary or permanent repercussions as determined by other -members of the project's leadership. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, -available at [http://contributor-covenant.org/version/1/4][version] - -[homepage]: http://contributor-covenant.org -[version]: http://contributor-covenant.org/version/1/4/ diff --git a/CodeOfConduct.md b/CodeOfConduct.md new file mode 100644 index 0000000..16c7c4c --- /dev/null +++ b/CodeOfConduct.md @@ -0,0 +1,120 @@ + +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement on [Gitter](https://gitter.im/scientistproject/community). + +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0]. diff --git a/Contributing.md b/Contributing.md new file mode 100644 index 0000000..f601e36 --- /dev/null +++ b/Contributing.md @@ -0,0 +1,87 @@ +# Contributing to Scientist.NET + +## Table of Contents: +- [Code of Conduct](#code-of-conduct) +- [I just have a question](#i-just-have-a-question) +- [How can i contribute?](#how-can-i-contribute) + - [Reporting bugs](#reporting-bugs) + - [Suggesting enhancements](#suggesting-enhancements) + - [Your first code contribution](#your-first-code-contribution) + - [Pull Requests](#pull-requests) +- [Styleguides](#styleguides) + - [Git Commit Messages](#git-commit-messages) +- [Labels](#labels) + - [Issue labels](#issue-labels) + - [Topic category labels](#topic-category-labels) + - [Pull request labels](#pull-request-labels) + +## Code of conduct + +This project and everyone participating in it is governed by the [Code of Conduct](CodeOfConduct.md). By participating, you are expected to uphold this code. + +Please report unacceptable behavior on [Gitter](https://gitter.im/scientistproject/community) to a maintainer. + +## I just have a question + +> Please don't file an issue to ask a question. + +> TODO + + +## How can i contribute? + +### Reporting bugs + +> TODO + + +### Suggesting enhancements + +> TODO + +### Your first code contribution +- [good first issue](https://github.com/scientistproject/Scientist.net/issues?q=is:issue+is:open+label:good+first+issue) + +### Pull Requests + +Please follow these steps to have your contribution considered by the maintainers: + +- Follow all instructions in [the template](.github/PULL_REQUEST_TEMPLATE/pull_request_template.md) +- Follow the [styleguides](#styleguides) +- After you submit your pull request, verify that all [status checks](https://help.github.com/articles/about-status-checks/) are passing
What if the status checks are failing?If a status check is failing, and you believe that the failure is unrelated to your change, please leave a comment on the pull request explaining why you believe the failure is unrelated. A maintainer will re-run the status check for you. If we conclude that the failure was a false positive, then we will open an issue to track that problem with our status check suite.
+ +While the prerequisites above must be satisfied prior to having your pull request reviewed, the reviewer(s) may ask you to complete additional design work, tests, or other changes before your pull request can be ultimately accepted. + +## Styleguides +### Git commit messages +Please refer to [Conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) + +| Type | Usage | Version increment | +| --- | --- | --- | +| fix(): | A commit which fixes or patches a bug | x.x.1| +| feat(): | A commit which introduces a new feature | x.1.x| +| BREAKING CHANGE: | A commit which has BREAKING CHANGE: in the footer | 1.x.x | + +## Labels + +### Issue labels +| Label name | Search | Description | +| --- | --- | --- | +| `good first issue` | [search](https://github.com/scientistproject/Scientist.net/issues?q=is:issue+is:open+label:good+first+issue) | Less complex issues which would be good first issues to work on for users who want to contribute. | +| `help wanted` | [search](https://github.com/scientistproject/Scientist.net/issues?q=is:issue+is:open+label:help+wanted) | The would appreciate help from the community in resolving these issues. | + +### Topic category labels +| Label name | Search | Description | +| --- | --- | --- | +| `documentation` | [search](https://github.com/scientistproject/Scientist.net/issues?q=is:issue+is:open+label:) | Related to any type of documentation. | +| `performance` | [search](https://github.com/scientistproject/Scientist.net/issues?q=is:issue+is:open+label:performance) | Related to performance. | +| `security` | [search](https://github.com/scientistproject/Scientist.net/issues?q=is:issue+is:open+label:security) | Related to security. | + +### Pull request labels +| Label name | Search | Description | +| --- | --- | --- | +| `work-in-progress` | [search](https://github.com/scientistproject/Scientist.net/issues?q=is:issue+is:open+label:work-in-progress) | Pull requests which are still being worked on, more changes will follow. | +| `needs-review` | [search](https://github.com/scientistproject/Scientist.net/issues?q=is:issue+is:open+label:needs-review) | Pull requests which need code review, and approval from maintainers. | +| `under-review` | [search](https://github.com/scientistproject/Scientist.net/issues?q=is:issue+is:open+label:under-review) | Pull requests being reviewed by maintainers. | +| `requires-changes` | [search](https://github.com/scientistproject/Scientist.net/issues?q=is:issue+is:open+label:requires-changes) | Pull requests which need to be updated based on review comments and then reviewed again. | +| `needs-testing` | [search](https://github.com/scientistproject/Scientist.net/issues?q=is:issue+is:open+label:needs-testing) | Pull requests which need manual testing. | From 3ca7ffd2c77caacd60bf2642a61d39b3e631ada9 Mon Sep 17 00:00:00 2001 From: Joshua Hiles Date: Fri, 15 Dec 2023 16:42:41 +0000 Subject: [PATCH 20/26] refactor: codeql, unit test GHAs & upgrade sln to net8 --- .github/dependabot.yml | 10 +++++++ .../{codeql-analysis.yml => codeql.yml} | 19 +++++++----- .github/workflows/unit-test.yml | 29 +++++++++++++++++++ .github/workflows/ver3-unit-test.yml | 27 ----------------- Scientist.Test/Scientist.Test.csproj | 2 +- Scientist/Scientist.csproj | 2 +- 6 files changed, 52 insertions(+), 37 deletions(-) create mode 100644 .github/dependabot.yml rename .github/workflows/{codeql-analysis.yml => codeql.yml} (68%) create mode 100644 .github/workflows/unit-test.yml delete mode 100644 .github/workflows/ver3-unit-test.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..03d6816 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + - package-ecosystem: "nuget" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql.yml similarity index 68% rename from .github/workflows/codeql-analysis.yml rename to .github/workflows/codeql.yml index e604060..5fc1781 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql.yml @@ -4,7 +4,6 @@ on: push: branches: [3.0.0] pull_request: - # The branches below must be a subset of the branches above branches: [3.0.0] schedule: - cron: "0 0 * * 1" @@ -24,11 +23,10 @@ jobs: language: ["csharp"] steps: - - name: Checkout repository - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} @@ -36,12 +34,17 @@ jobs: # - name: Autobuild # uses: github/codeql-action/autobuild@v1 - - uses: actions/setup-dotnet@v1 + - uses: actions/setup-dotnet@v3 with: - dotnet-version: "6.0.x" - include-prerelease: true + dotnet-version: 8.x + cache: true + + - run: dotnet restore --locked-mode + - run: | dotnet build /p:UseSharedCompilation=false - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml new file mode 100644 index 0000000..6e7eba7 --- /dev/null +++ b/.github/workflows/unit-test.yml @@ -0,0 +1,29 @@ +name: Unit test + +on: + workflow_dispatch: + push: + branches: [3.0.0] + pull_request: + branches: [3.0.0] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-dotnet@v3 + with: + dotnet-version: 8.x + cache: true + + - name: Restore dependencies + run: dotnet restore --locked-mode + + - name: Build + run: dotnet build --no-restore + + - name: Test + run: dotnet test --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover diff --git a/.github/workflows/ver3-unit-test.yml b/.github/workflows/ver3-unit-test.yml deleted file mode 100644 index e776a0c..0000000 --- a/.github/workflows/ver3-unit-test.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: 3.0.0 Unit Test - -on: - workflow_dispatch: - push: - branches: [ 3.0.0 ] - pull_request: - branches: [ 3.0.0 ] - -jobs: - build: - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2 - - name: Setup .NET - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 6.0.x - include-prerelease: true - - name: Restore dependencies - run: dotnet restore - - name: Build - run: dotnet build --no-restore - - name: Test - run: dotnet test --no-build --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=opencover diff --git a/Scientist.Test/Scientist.Test.csproj b/Scientist.Test/Scientist.Test.csproj index ba2d143..faef22a 100644 --- a/Scientist.Test/Scientist.Test.csproj +++ b/Scientist.Test/Scientist.Test.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false diff --git a/Scientist/Scientist.csproj b/Scientist/Scientist.csproj index d15ac72..0672ddb 100644 --- a/Scientist/Scientist.csproj +++ b/Scientist/Scientist.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 enable From bfdfe1f99eaf4eda8add1a61b00bea5900a0e014 Mon Sep 17 00:00:00 2001 From: Joshua Hiles Date: Fri, 15 Dec 2023 16:45:44 +0000 Subject: [PATCH 21/26] build(packages): add packages.lock.json for nuget package caching in GHAs --- Scientist.Test/Scientist.Test.csproj | 5 +- Scientist.Test/packages.lock.json | 1188 ++++++++++++++++++++++++++ Scientist/Scientist.csproj | 5 +- Scientist/packages.lock.json | 6 + 4 files changed, 1202 insertions(+), 2 deletions(-) create mode 100644 Scientist.Test/packages.lock.json create mode 100644 Scientist/packages.lock.json diff --git a/Scientist.Test/Scientist.Test.csproj b/Scientist.Test/Scientist.Test.csproj index faef22a..ad74f98 100644 --- a/Scientist.Test/Scientist.Test.csproj +++ b/Scientist.Test/Scientist.Test.csproj @@ -30,4 +30,7 @@
-
+ + true + + \ No newline at end of file diff --git a/Scientist.Test/packages.lock.json b/Scientist.Test/packages.lock.json new file mode 100644 index 0000000..96be846 --- /dev/null +++ b/Scientist.Test/packages.lock.json @@ -0,0 +1,1188 @@ +{ + "version": 1, + "dependencies": { + "net8.0": { + "coverlet.collector": { + "type": "Direct", + "requested": "[3.1.0, )", + "resolved": "3.1.0", + "contentHash": "YzYqSRrjoP5lULBhTDcTOjuM4IDPPi6PhFsl4w8EI4WdZhE6llt7E38Tg4CHyrS+QKwyu1+9OwkdDgluOdoBTw==" + }, + "coverlet.msbuild": { + "type": "Direct", + "requested": "[3.1.0, )", + "resolved": "3.1.0", + "contentHash": "xOv5HZagq0I6uF4vt8NVVpwcA2W/uGmNcbLStao2eMk98RQH5NFPQuouh2nWWPSZrNIhGG/iYbBn2pO4s5i+ig==" + }, + "Microsoft.Extensions.Configuration.UserSecrets": { + "type": "Direct", + "requested": "[5.0.0, )", + "resolved": "5.0.0", + "contentHash": "+tK3seG68106lN277YWQvqmfyI/89w0uTu/5Gz5VYSUu5TI4mqwsaWLlSmT9Bl1yW/i1Nr06gHJxqaqB5NU9Tw==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "5.0.0", + "Microsoft.Extensions.Configuration.Json": "5.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "5.0.0", + "Microsoft.Extensions.FileProviders.Physical": "5.0.0" + } + }, + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[16.10.0, )", + "resolved": "16.10.0", + "contentHash": "/9x6TV1SUi+rtKi8UYa7ml7SEWhb0A5FuyeF0nwwUKVjdk5WaWuLPjntHVWoDuYP25KBruoxWxs7WdhDMjWxXw==", + "dependencies": { + "Microsoft.CodeCoverage": "16.10.0", + "Microsoft.TestPlatform.TestHost": "16.10.0" + } + }, + "xunit": { + "type": "Direct", + "requested": "[2.4.1, )", + "resolved": "2.4.1", + "contentHash": "XNR3Yz9QTtec16O0aKcO6+baVNpXmOnPUxDkCY97J+8krUYxPvXT1szYYEUdKk4sB8GOI2YbAjRIOm8ZnXRfzQ==", + "dependencies": { + "xunit.analyzers": "0.10.0", + "xunit.assert": "[2.4.1]", + "xunit.core": "[2.4.1]" + } + }, + "xunit.runner.visualstudio": { + "type": "Direct", + "requested": "[2.4.3, )", + "resolved": "2.4.3", + "contentHash": "kZZSmOmKA8OBlAJaquPXnJJLM9RwQ27H7BMVqfMLUcTi9xHinWGJiWksa3D4NEtz0wZ/nxd2mogObvBgJKCRhQ==" + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "16.10.0", + "contentHash": "7g0UjAwhEi2OBBv8SDV3wZ6J103cQyZbKVgDy59fnNdlbv0XpUCfdBZiSW5yVK/d2jp6faCdGh7VnI/F2JZO+Q==" + }, + "Microsoft.CSharp": { + "type": "Transitive", + "resolved": "4.0.1", + "contentHash": "17h8b5mXa87XYKrrVqdgZ38JefSUqLChUQpXgSnpzsM0nDOhE40FTeNWOJ/YmySGV6tG6T8+hjz6vxbknHJr6A==", + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Dynamic.Runtime": "4.0.11", + "System.Globalization": "4.0.11", + "System.Linq": "4.1.0", + "System.Linq.Expressions": "4.1.0", + "System.ObjectModel": "4.0.12", + "System.Reflection": "4.1.0", + "System.Reflection.Extensions": "4.0.1", + "System.Reflection.Primitives": "4.0.1", + "System.Reflection.TypeExtensions": "4.1.0", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Runtime.InteropServices": "4.1.0", + "System.Threading": "4.0.11" + } + }, + "Microsoft.Extensions.Configuration": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "LN322qEKHjuVEhhXueTUe7RNePooZmS8aGid5aK2woX3NPjSnONFyKUc6+JknOS6ce6h2tCLfKPTBXE3mN/6Ag==", + "dependencies": { + "Microsoft.Extensions.Configuration.Abstractions": "5.0.0", + "Microsoft.Extensions.Primitives": "5.0.0" + } + }, + "Microsoft.Extensions.Configuration.Abstractions": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "ETjSBHMp3OAZ4HxGQYpwyGsD8Sw5FegQXphi0rpoGMT74S4+I2mm7XJEswwn59XAaKOzC15oDSOWEE8SzDCd6Q==", + "dependencies": { + "Microsoft.Extensions.Primitives": "5.0.0" + } + }, + "Microsoft.Extensions.Configuration.FileExtensions": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "rRdspYKA18ViPOISwAihhCMbusHsARCOtDMwa23f+BGEdIjpKPlhs3LLjmKlxfhpGXBjIsS0JpXcChjRUN+PAw==", + "dependencies": { + "Microsoft.Extensions.Configuration": "5.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "5.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "5.0.0", + "Microsoft.Extensions.FileProviders.Physical": "5.0.0", + "Microsoft.Extensions.Primitives": "5.0.0" + } + }, + "Microsoft.Extensions.Configuration.Json": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "Pak8ymSUfdzPfBTLHxeOwcR32YDbuVfhnH2hkfOLnJNQd19ItlBdpMjIDY9C5O/nS2Sn9bzDMai0ZrvF7KyY/Q==", + "dependencies": { + "Microsoft.Extensions.Configuration": "5.0.0", + "Microsoft.Extensions.Configuration.Abstractions": "5.0.0", + "Microsoft.Extensions.Configuration.FileExtensions": "5.0.0", + "Microsoft.Extensions.FileProviders.Abstractions": "5.0.0" + } + }, + "Microsoft.Extensions.FileProviders.Abstractions": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "iuZIiZ3mteEb+nsUqpGXKx2cGF+cv6gWPd5jqQI4hzqdiJ6I94ddLjKhQOuRW1lueHwocIw30xbSHGhQj0zjdQ==", + "dependencies": { + "Microsoft.Extensions.Primitives": "5.0.0" + } + }, + "Microsoft.Extensions.FileProviders.Physical": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "1rkd8UO2qf21biwO7X0hL9uHP7vtfmdv/NLvKgCRHkdz1XnW8zVQJXyEYiN68WYpExgtVWn55QF0qBzgfh1mGg==", + "dependencies": { + "Microsoft.Extensions.FileProviders.Abstractions": "5.0.0", + "Microsoft.Extensions.FileSystemGlobbing": "5.0.0", + "Microsoft.Extensions.Primitives": "5.0.0" + } + }, + "Microsoft.Extensions.FileSystemGlobbing": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "ArliS8lGk8sWRtrWpqI8yUVYJpRruPjCDT+EIjrgkA/AAPRctlAkRISVZ334chAKktTLzD1+PK8F5IZpGedSqA==" + }, + "Microsoft.Extensions.Primitives": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "cI/VWn9G1fghXrNDagX9nYaaB/nokkZn0HYAawGaELQrl8InSezfe9OnfPZLcJq3esXxygh3hkq2c3qoV3SDyQ==" + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "16.10.0", + "contentHash": "DYp9eKg3zffZuePhgdUrh5tHkt1YOaSraVH87r4WXDOjag1/n08aFl1vRhWP8y2RoBLTHdcZRTDOhQyYMxAYNg==", + "dependencies": { + "NuGet.Frameworks": "5.0.0", + "System.Reflection.Metadata": "1.6.0" + } + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "16.10.0", + "contentHash": "KAlB2QQRwznIH02WNl9eAuUP6/tn4IbAw4EXrvV1POTUjxuv4Dqg0u3Nn5lC9T3WIHupCHfsTcJMgsJYdi31Ig==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "16.10.0", + "Newtonsoft.Json": "9.0.1" + } + }, + "Microsoft.Win32.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "9ZQKCWxH7Ijp9BfahvL2Zyf1cJIk8XYLF6Yjzr2yi0b2cOut/HQ31qf1ThHAgCc3WiZMdnWcfJCgN82/0UunxA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "NETStandard.Library": { + "type": "Transitive", + "resolved": "1.6.1", + "contentHash": "WcSp3+vP+yHNgS8EV5J7pZ9IRpeDuARBPN28by8zqff1wJQXm26PVU8L3/fYLBJVU7BtDyqNVWq2KlCVvSSR4A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.Win32.Primitives": "4.3.0", + "System.AppContext": "4.3.0", + "System.Collections": "4.3.0", + "System.Collections.Concurrent": "4.3.0", + "System.Console": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Diagnostics.Tools": "4.3.0", + "System.Diagnostics.Tracing": "4.3.0", + "System.Globalization": "4.3.0", + "System.Globalization.Calendars": "4.3.0", + "System.IO": "4.3.0", + "System.IO.Compression": "4.3.0", + "System.IO.Compression.ZipFile": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Linq": "4.3.0", + "System.Linq.Expressions": "4.3.0", + "System.Net.Http": "4.3.0", + "System.Net.Primitives": "4.3.0", + "System.Net.Sockets": "4.3.0", + "System.ObjectModel": "4.3.0", + "System.Reflection": "4.3.0", + "System.Reflection.Extensions": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Runtime.Numerics": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Security.Cryptography.X509Certificates": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encoding.Extensions": "4.3.0", + "System.Text.RegularExpressions": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0", + "System.Threading.Timer": "4.3.0", + "System.Xml.ReaderWriter": "4.3.0", + "System.Xml.XDocument": "4.3.0" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "9.0.1", + "contentHash": "U82mHQSKaIk+lpSVCbWYKNavmNH1i5xrExDEquU1i6I5pV6UMOqRnJRSlKO3cMPfcpp0RgDY+8jUXHdQ4IfXvw==", + "dependencies": { + "Microsoft.CSharp": "4.0.1", + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Dynamic.Runtime": "4.0.11", + "System.Globalization": "4.0.11", + "System.IO": "4.1.0", + "System.Linq": "4.1.0", + "System.Linq.Expressions": "4.1.0", + "System.ObjectModel": "4.0.12", + "System.Reflection": "4.1.0", + "System.Reflection.Extensions": "4.0.1", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Runtime.Serialization.Primitives": "4.1.1", + "System.Text.Encoding": "4.0.11", + "System.Text.Encoding.Extensions": "4.0.11", + "System.Text.RegularExpressions": "4.1.0", + "System.Threading": "4.0.11", + "System.Threading.Tasks": "4.0.11", + "System.Xml.ReaderWriter": "4.0.11", + "System.Xml.XDocument": "4.0.11" + } + }, + "NuGet.Frameworks": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "c5JVjuVAm4f7E9Vj+v09Z9s2ZsqFDjBpcsyS3M9xRo0bEdm/LVZSzLxxNvfvAwRiiE8nwe1h2G4OwiwlzFKXlA==" + }, + "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "HdSSp5MnJSsg08KMfZThpuLPJpPwE5hBXvHwoKWosyHHfe8Mh5WKT0ylEOf6yNzX6Ngjxe4Whkafh5q7Ymac4Q==" + }, + "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "+yH1a49wJMy8Zt4yx5RhJrxO/DBDByAiCzNwiETI+1S4mPdCu0OY4djdciC7Vssk0l22wQaDLrXxXkp+3+7bVA==" + }, + "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "c3YNH1GQJbfIPJeCnr4avseugSqPrxwIqzthYyZDN6EuOyNOzq+y2KSUfRcXauya1sF4foESTgwM5e1A8arAKw==" + }, + "runtime.native.System": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "c/qWt2LieNZIj1jGnVNsE2Kl23Ya2aSTBuXMD6V7k9KWr6l16Tqdwq+hJScEpWER9753NWC8h96PaVNY5Ld7Jw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, + "runtime.native.System.IO.Compression": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "INBPonS5QPEgn7naufQFXJEp3zX6L4bwHgJ/ZH78aBTpeNfQMtf7C6VrAFhlq2xxWBveIOWyFzQjJ8XzHMhdOQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, + "runtime.native.System.Net.Http": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "ZVuZJqnnegJhd2k/PtAbbIcZ3aZeITq3sj06oKfMBSfphW3HDmk/t4ObvbOk/JA/swGR0LNqMksAh/f7gpTROg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, + "runtime.native.System.Security.Cryptography.Apple": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "DloMk88juo0OuOWr56QG7MNchmafTLYWvABy36izkrLI5VledI0rq28KGs1i9wbpeT9NPQrx/wTf8U2vazqQ3Q==", + "dependencies": { + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": "4.3.0" + } + }, + "runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "NS1U+700m4KFRHR5o4vo9DSlTmlCKu/u7dtE5sUHVIPB+xpXxYQvgBgA6wEIeCz6Yfn0Z52/72WYsToCEPJnrw==", + "dependencies": { + "runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0", + "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "b3pthNgxxFcD+Pc0WSEoC0+md3MyhRS6aCEeenvNE3Fdw1HyJ18ZhRFVJJzIeR/O/jpxPboB805Ho0T3Ul7w8A==" + }, + "runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "KeLz4HClKf+nFS7p/6Fi/CqyLXh81FpiGzcmuS8DGi9lUqSnZ6Es23/gv2O+1XVGfrbNmviF7CckBpavkBoIFQ==" + }, + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "kVXCuMTrTlxq4XOOMAysuNwsXWpYeboGddNGpIgNSZmv1b6r/s/DPk0fYMB7Q5Qo4bY68o48jt4T4y5BVecbCQ==" + }, + "runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "X7IdhILzr4ROXd8mI1BUCQMSHSQwelUlBjF1JyTKCjXaOGn2fB4EKBxQbCK2VjO3WaWIdlXZL3W6TiIVnrhX4g==" + }, + "runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "nyFNiCk/r+VOiIqreLix8yN+q3Wga9+SE8BCgkf+2BwEKiNx6DyvFjCgkfV743/grxv8jHJ8gUK4XEQw7yzRYg==" + }, + "runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "ytoewC6wGorL7KoCAvRfsgoJPJbNq+64k2SqW6JcOAebWsFUvCCYgfzQMrnpvPiEl4OrblUlhF2ji+Q1+SVLrQ==" + }, + "runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "I8bKw2I8k58Wx7fMKQJn2R8lamboCAiHfHeV/pS65ScKWMMI0+wJkLYlEKvgW1D/XvSl/221clBoR2q9QNNM7A==" + }, + "runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "VB5cn/7OzUfzdnC8tqAIMQciVLiq2epm2NrAm1E9OjNRyG4lVhfR61SMcLizejzQP8R8Uf/0l5qOIbUEi+RdEg==" + }, + "System.AppContext": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "fKC+rmaLfeIzUhagxY17Q9siv/sPrjjKcfNg1Ic8IlQkZLipo8ljcaZQu4VtI4Jqbzjc2VTjzGLF6WmsRXAEgA==", + "dependencies": { + "System.Runtime": "4.3.0" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "ratu44uTIHgeBeI0dE8DWvmXVBSo4u7ozRZZHOMmK/JPpYyo0dAfgSiHlpiObMQ5lEtEyIXA40sKRYg5J6A8uQ==", + "dependencies": { + "System.Diagnostics.Debug": "4.3.0", + "System.Diagnostics.Tracing": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Collections": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3Dcj85/TBdVpL5Zr+gEEBUuFe2icOnLalmEh9hfck1PTYbbyWuZgh4fmm2ysCLTrqLQw6t3TgTyJ+VLp+Qb+Lw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Collections.Concurrent": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "ztl69Xp0Y/UXCL+3v3tEU+lIy+bvjKNUmopn1wep/a291pVPK7dxBd6T7WnlQqRog+d1a/hSsgRsmFnIBKTPLQ==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Diagnostics.Tracing": "4.3.0", + "System.Globalization": "4.3.0", + "System.Reflection": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.Console": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "DHDrIxiqk1h03m6khKWV2X8p/uvN79rgSqpilL6uzpmSfxfU5ng8VcPtW4qsDsQDHiTv6IPV9TmD5M/vElPNLg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.IO": "4.3.0", + "System.Runtime": "4.3.0", + "System.Text.Encoding": "4.3.0" + } + }, + "System.Diagnostics.Debug": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "ZUhUOdqmaG5Jk3Xdb8xi5kIyQYAA4PnTNlHx1mu9ZY3qv4ELIdKbnL/akbGaKi2RnNUWaZsAs31rvzFdewTj2g==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "tD6kosZnTAGdrEa0tZSuFyunMbt/5KYDnHdndJYGqZoNy00XVXyACd5d6KnE1YgYv3ne2CjtAfNXo/fwEhnKUA==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Tracing": "4.3.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Diagnostics.Tools": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "UUvkJfSYJMM6x527dJg2VyWPSRqIVB0Z7dbjHst1zmwTXz5CcXSYJFWRpuigfbO1Lf7yfZiIaEUesfnl/g5EyA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Diagnostics.Tracing": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "rswfv0f/Cqkh78rA5S8eN8Neocz234+emGCtTF3lxPY96F+mmmUen6tbn0glN6PMvlKQb9bPAY5e9u7fgPTkKw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Dynamic.Runtime": { + "type": "Transitive", + "resolved": "4.0.11", + "contentHash": "db34f6LHYM0U0JpE+sOmjar27BnqTVkbLJhgfwMpTdgTigG/Hna3m2MYVwnFzGGKnEJk2UXFuoVTr8WUbU91/A==", + "dependencies": { + "System.Collections": "4.0.11", + "System.Diagnostics.Debug": "4.0.11", + "System.Globalization": "4.0.11", + "System.Linq": "4.1.0", + "System.Linq.Expressions": "4.1.0", + "System.ObjectModel": "4.0.12", + "System.Reflection": "4.1.0", + "System.Reflection.Emit": "4.0.1", + "System.Reflection.Emit.ILGeneration": "4.0.1", + "System.Reflection.Primitives": "4.0.1", + "System.Reflection.TypeExtensions": "4.1.0", + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0", + "System.Runtime.Extensions": "4.1.0", + "System.Threading": "4.0.11" + } + }, + "System.Globalization": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "kYdVd2f2PAdFGblzFswE4hkNANJBKRmsfa2X5LG2AcWE1c7/4t0pYae1L8vfZ5xvE2nK/R9JprtToA61OSHWIg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Globalization.Calendars": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "GUlBtdOWT4LTV3I+9/PJW+56AnnChTaOqqTLFtdmype/L500M2LIyXgmtd9X2P2VOkmJd5c67H5SaC2QcL1bFA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Globalization": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Globalization.Extensions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "FhKmdR6MPG+pxow6wGtNAWdZh7noIOpdD5TwQ3CprzgIE1bBBoim0vbR1+AWsWjQmU7zXHgQo4TWSP6lCeiWcQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.Globalization": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.InteropServices": "4.3.0" + } + }, + "System.IO": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.IO.Compression": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "YHndyoiV90iu4iKG115ibkhrG+S3jBm8Ap9OwoUAzO5oPDAWcr0SFwQFm0HjM8WkEZWo0zvLTyLmbvTkW1bXgg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.Buffers": "4.3.0", + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0", + "runtime.native.System": "4.3.0", + "runtime.native.System.IO.Compression": "4.3.0" + } + }, + "System.IO.Compression.ZipFile": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "G4HwjEsgIwy3JFBduZ9quBkAu+eUwjIdJleuNSgmUojbH6O3mlvEIme+GHx/cLlTAPcrnnL7GqvB9pTlWRfhOg==", + "dependencies": { + "System.Buffers": "4.3.0", + "System.IO": "4.3.0", + "System.IO.Compression": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Text.Encoding": "4.3.0" + } + }, + "System.IO.FileSystem": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3wEMARTnuio+ulnvi+hkRNROYwa1kylvYahhcLk4HSoVdl+xxTFVeVlYOfLwrDPImGls0mDqbMhrza8qnWPTdA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.IO": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.IO.FileSystem.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "6QOb2XFLch7bEc4lIcJH49nJN2HV+OC3fHDgsLVsBVBk3Y4hFAnOBGzJ2lUu7CyDDFo9IBWkSsnbkT6IBwwiMw==", + "dependencies": { + "System.Runtime": "4.3.0" + } + }, + "System.Linq": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "5DbqIUpsDp0dFftytzuMmc0oeMdQwjcP/EWxsksIz/w1TcFRkZ3yKKz0PqiYFMmEwPSWw+qNVqD7PJ889JzHbw==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0" + } + }, + "System.Linq.Expressions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "PGKkrd2khG4CnlyJwxwwaWWiSiWFNBGlgXvJpeO0xCXrZ89ODrQ6tjEWS/kOqZ8GwEOUATtKtzp1eRgmYNfclg==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.Linq": "4.3.0", + "System.ObjectModel": "4.3.0", + "System.Reflection": "4.3.0", + "System.Reflection.Emit": "4.3.0", + "System.Reflection.Emit.ILGeneration": "4.3.0", + "System.Reflection.Emit.Lightweight": "4.3.0", + "System.Reflection.Extensions": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Reflection.TypeExtensions": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Net.Http": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "sYg+FtILtRQuYWSIAuNOELwVuVsxVyJGWQyOnlAzhV4xvhyFnON1bAzYYC+jjRW8JREM45R0R5Dgi8MTC5sEwA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Diagnostics.DiagnosticSource": "4.3.0", + "System.Diagnostics.Tracing": "4.3.0", + "System.Globalization": "4.3.0", + "System.Globalization.Extensions": "4.3.0", + "System.IO": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.Net.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.OpenSsl": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Security.Cryptography.X509Certificates": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0", + "runtime.native.System": "4.3.0", + "runtime.native.System.Net.Http": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Net.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "qOu+hDwFwoZPbzPvwut2qATe3ygjeQBDQj91xlsaqGFQUI5i4ZnZb8yyQuLGpDGivEPIt8EJkd1BVzVoP31FXA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0", + "System.Runtime.Handles": "4.3.0" + } + }, + "System.Net.Sockets": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "m6icV6TqQOAdgt5N/9I5KNpjom/5NFtkmGseEH+AK/hny8XrytLH3+b5M8zL/Ycg3fhIocFpUMyl/wpFnVRvdw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.IO": "4.3.0", + "System.Net.Primitives": "4.3.0", + "System.Runtime": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.ObjectModel": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "bdX+80eKv9bN6K4N+d77OankKHGn6CH711a6fcOpMQu2Fckp/Ft4L/kW9WznHpyR0NRAvJutzOMHNNlBGvxQzQ==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Reflection": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.IO": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Emit": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "228FG0jLcIwTVJyz8CLFKueVqQK36ANazUManGaJHkO0icjiIypKW7YLWLIWahyIkdh5M7mV2dJepllLyA1SKg==", + "dependencies": { + "System.IO": "4.3.0", + "System.Reflection": "4.3.0", + "System.Reflection.Emit.ILGeneration": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Emit.ILGeneration": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "59tBslAk9733NXLrUJrwNZEzbMAcu8k344OYo+wfSVygcgZ9lgBdGIzH/nrg3LYhXceynyvTc8t5/GD4Ri0/ng==", + "dependencies": { + "System.Reflection": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Emit.Lightweight": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "oadVHGSMsTmZsAF864QYN1t1QzZjIcuKU3l2S9cZOwDdDueNTrqq1yRj7koFfIGEnKpt6NjpL3rOzRhs4ryOgA==", + "dependencies": { + "System.Reflection": "4.3.0", + "System.Reflection.Emit.ILGeneration": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Extensions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "rJkrJD3kBI5B712aRu4DpSIiHRtr6QlfZSQsb0hYHrDCZORXCFjQfoipo2LaMUHoT9i1B7j7MnfaEKWDFmFQNQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Metadata": { + "type": "Transitive", + "resolved": "1.6.0", + "contentHash": "COC1aiAJjCoA5GBF+QKL2uLqEBew4JsCkQmoHKbN3TlOZKa2fKLz5CpiRQKDz0RsAOEGsVKqOD5bomsXq/4STQ==" + }, + "System.Reflection.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.TypeExtensions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "7u6ulLcZbyxB5Gq0nMkQttcdBTx57ibzw+4IOXEfR+sXYQoHvjW5LTLyNr8O22UIMrqYbchJQJnos4eooYzYJA==", + "dependencies": { + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Resources.ResourceManager": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "/zrcPkkWdZmI4F92gL/TPumP98AVDu/Wxr3CSJGQQ+XN6wbRZcyfSKVoPo17ilb3iOr0cCRqJInGwNMolqhS8A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Globalization": "4.3.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, + "System.Runtime.Extensions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "guW0uK0fn5fcJJ1tJVXYd7/1h5F+pea1r7FLSOz/f8vPEqbR2ZAknuRDvTQ8PzAilDveOxNjSfr0CHfIQfFk8g==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime.Handles": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "OKiSUN7DmTWeYb3l51A7EYaeNMnvxwE249YtZz7yooT4gOZhmTjIn48KgSsw2k2lYdLgTKNJw/ZIfSElwDRVgg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime.InteropServices": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "uv1ynXqiMK8mp1GM3jDqPCFN66eJ5w5XNomaK2XD+TuCroNTLFGeZ+WCmBMcBDyTFKou3P6cR6J/QsaqDp7fGQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Reflection": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Handles": "4.3.0" + } + }, + "System.Runtime.InteropServices.RuntimeInformation": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==", + "dependencies": { + "System.Reflection": "4.3.0", + "System.Reflection.Extensions": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Threading": "4.3.0", + "runtime.native.System": "4.3.0" + } + }, + "System.Runtime.Numerics": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "yMH+MfdzHjy17l2KESnPiF2dwq7T+xLnSJar7slyimAkUh/gTrS9/UQOtv7xarskJ2/XDSNvfLGOBQPjL7PaHQ==", + "dependencies": { + "System.Globalization": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0" + } + }, + "System.Runtime.Serialization.Primitives": { + "type": "Transitive", + "resolved": "4.1.1", + "contentHash": "HZ6Du5QrTG8MNJbf4e4qMO3JRAkIboGT5Fk804uZtg3Gq516S7hAqTm2UZKUHa7/6HUGdVy3AqMQKbns06G/cg==", + "dependencies": { + "System.Resources.ResourceManager": "4.0.1", + "System.Runtime": "4.1.0" + } + }, + "System.Security.Cryptography.Algorithms": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.Collections": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Runtime.Numerics": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "runtime.native.System.Security.Cryptography.Apple": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Security.Cryptography.Cng": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "03idZOqFlsKRL4W+LuCpJ6dBYDUWReug6lZjBa3uJWnk5sPCUXckocevTaUA8iT/MFSrY/2HXkOt753xQ/cf8g==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0" + } + }, + "System.Security.Cryptography.Csp": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "X4s/FCkEUnRGnwR3aSfVIkldBmtURMhmexALNTwpjklzxWU7yjMk7GHLKOZTNkgnWnE0q7+BCf9N2LVRWxewaA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.IO": "4.3.0", + "System.Reflection": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0" + } + }, + "System.Security.Cryptography.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.Collections": "4.3.0", + "System.Collections.Concurrent": "4.3.0", + "System.Linq": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Security.Cryptography.OpenSsl": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "h4CEgOgv5PKVF/HwaHzJRiVboL2THYCou97zpmhjghx5frc7fIvlkY1jL+lnIQyChrJDMNEXS6r7byGif8Cy4w==", + "dependencies": { + "System.Collections": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Runtime.Numerics": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Security.Cryptography.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==", + "dependencies": { + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Threading": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.Security.Cryptography.X509Certificates": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.Globalization.Calendars": "4.3.0", + "System.IO": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.Handles": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Runtime.Numerics": "4.3.0", + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Cng": "4.3.0", + "System.Security.Cryptography.Csp": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0", + "System.Security.Cryptography.OpenSsl": "4.3.0", + "System.Security.Cryptography.Primitives": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0", + "runtime.native.System": "4.3.0", + "runtime.native.System.Net.Http": "4.3.0", + "runtime.native.System.Security.Cryptography.OpenSsl": "4.3.0" + } + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Text.Encoding.Extensions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "YVMK0Bt/A43RmwizJoZ22ei2nmrhobgeiYwFzC4YAN+nue8RF6djXDMog0UCn+brerQoYVyaS+ghy9P/MUVcmw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0", + "System.Text.Encoding": "4.3.0" + } + }, + "System.Text.RegularExpressions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "RpT2DA+L660cBt1FssIE9CAGpLFdFPuheB7pLpKpn6ZXNby7jDERe8Ua/Ne2xGiwLVG2JOqziiaVCGDon5sKFA==", + "dependencies": { + "System.Runtime": "4.3.0" + } + }, + "System.Threading": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "VkUS0kOBcUf3Wwm0TSbrevDDZ6BlM+b/HRiapRFWjM5O0NS0LviG0glKmFK+hhPDd1XFeSdU1GmlLhb2CoVpIw==", + "dependencies": { + "System.Runtime": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.Threading.Tasks": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "npvJkVKl5rKXrtl1Kkm6OhOUaYGEiF9wFbppFRWSMoApKzt2PiPHT2Bb8a5sAWxprvdOAtvaARS9QYMznEUtug==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Runtime": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.Threading.Timer": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "Z6YfyYTCg7lOZjJzBjONJTFKGN9/NIYKSxhU5GRd+DTwHSZyvWp1xuI5aR+dLg+ayyC5Xv57KiY4oJ0tMO89fQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Xml.ReaderWriter": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "GrprA+Z0RUXaR4N7/eW71j1rgMnEnEVlgii49GZyAjTH7uliMnrOU3HNFBr6fEDBCJCIdlVNq9hHbaDR621XBA==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.IO.FileSystem": "4.3.0", + "System.IO.FileSystem.Primitives": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Runtime.InteropServices": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encoding.Extensions": "4.3.0", + "System.Text.RegularExpressions": "4.3.0", + "System.Threading.Tasks": "4.3.0", + "System.Threading.Tasks.Extensions": "4.3.0" + } + }, + "System.Xml.XDocument": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "5zJ0XDxAIg8iy+t4aMnQAu0MqVbqyvfoUVl1yDV61xdo3Vth45oA2FoY4pPkxYAH5f8ixpmTqXeEIya95x0aCQ==", + "dependencies": { + "System.Collections": "4.3.0", + "System.Diagnostics.Debug": "4.3.0", + "System.Diagnostics.Tools": "4.3.0", + "System.Globalization": "4.3.0", + "System.IO": "4.3.0", + "System.Reflection": "4.3.0", + "System.Resources.ResourceManager": "4.3.0", + "System.Runtime": "4.3.0", + "System.Runtime.Extensions": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading": "4.3.0", + "System.Xml.ReaderWriter": "4.3.0" + } + }, + "xunit.abstractions": { + "type": "Transitive", + "resolved": "2.0.3", + "contentHash": "pot1I4YOxlWjIb5jmwvvQNbTrZ3lJQ+jUGkGjWE3hEFM0l5gOnBWS+H3qsex68s5cO52g+44vpGzhAt+42vwKg==" + }, + "xunit.analyzers": { + "type": "Transitive", + "resolved": "0.10.0", + "contentHash": "4/IDFCJfIeg6bix9apmUtIMwvOsiwqdEexeO/R2D4GReIGPLIRODTpId/l4LRSrAJk9lEO3Zx1H0Zx6uohJDNg==" + }, + "xunit.assert": { + "type": "Transitive", + "resolved": "2.4.1", + "contentHash": "O/Oe0BS5RmSsM+LQOb041TzuPo5MdH2Rov+qXGS37X+KFG1Hxz7kopYklM5+1Y+tRGeXrOx5+Xne1RuqLFQoyQ==", + "dependencies": { + "NETStandard.Library": "1.6.1" + } + }, + "xunit.core": { + "type": "Transitive", + "resolved": "2.4.1", + "contentHash": "Zsj5OMU6JasNGERXZy8s72+pcheG6Q15atS5XpZXqAtULuyQiQ6XNnUsp1gyfC6WgqScqMvySiEHmHcOG6Eg0Q==", + "dependencies": { + "xunit.extensibility.core": "[2.4.1]", + "xunit.extensibility.execution": "[2.4.1]" + } + }, + "xunit.extensibility.core": { + "type": "Transitive", + "resolved": "2.4.1", + "contentHash": "yKZKm/8QNZnBnGZFD9SewkllHBiK0DThybQD/G4PiAmQjKtEZyHi6ET70QPU9KtSMJGRYS6Syk7EyR2EVDU4Kg==", + "dependencies": { + "NETStandard.Library": "1.6.1", + "xunit.abstractions": "2.0.3" + } + }, + "xunit.extensibility.execution": { + "type": "Transitive", + "resolved": "2.4.1", + "contentHash": "7e/1jqBpcb7frLkB6XDrHCGXAbKN4Rtdb88epYxCSRQuZDRW8UtTfdTEVpdTl8s4T56e07hOBVd4G0OdCxIY2A==", + "dependencies": { + "NETStandard.Library": "1.6.1", + "xunit.extensibility.core": "[2.4.1]" + } + }, + "scientist": { + "type": "Project" + } + } + } +} \ No newline at end of file diff --git a/Scientist/Scientist.csproj b/Scientist/Scientist.csproj index 0672ddb..f87a350 100644 --- a/Scientist/Scientist.csproj +++ b/Scientist/Scientist.csproj @@ -5,4 +5,7 @@ enable - + + true + + \ No newline at end of file diff --git a/Scientist/packages.lock.json b/Scientist/packages.lock.json new file mode 100644 index 0000000..807ab82 --- /dev/null +++ b/Scientist/packages.lock.json @@ -0,0 +1,6 @@ +{ + "version": 1, + "dependencies": { + "net8.0": {} + } +} \ No newline at end of file From cb0b705f4ebe70dcafbfc915b9cf95c5932464fd Mon Sep 17 00:00:00 2001 From: Joshua Hiles Date: Fri, 15 Dec 2023 16:56:20 +0000 Subject: [PATCH 22/26] ci: Cache dep path with wildcard --- .github/workflows/codeql.yml | 1 + .github/workflows/unit-test.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 5fc1781..f18e635 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,6 +38,7 @@ jobs: with: dotnet-version: 8.x cache: true + cache-dependency-path: "**/package-lock.json" - run: dotnet restore --locked-mode diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 6e7eba7..214c8b8 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -18,6 +18,7 @@ jobs: with: dotnet-version: 8.x cache: true + cache-dependency-path: "**/package-lock.json" - name: Restore dependencies run: dotnet restore --locked-mode From 69af920858b2fe13aedcfc50c0a7033948988e9e Mon Sep 17 00:00:00 2001 From: Joshua Hiles Date: Fri, 15 Dec 2023 16:58:18 +0000 Subject: [PATCH 23/26] ci: use packages not package --- .github/workflows/codeql.yml | 2 +- .github/workflows/unit-test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index f18e635..38e1ec6 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: with: dotnet-version: 8.x cache: true - cache-dependency-path: "**/package-lock.json" + cache-dependency-path: "**/packages-lock.json" - run: dotnet restore --locked-mode diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 214c8b8..3fceae5 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -18,7 +18,7 @@ jobs: with: dotnet-version: 8.x cache: true - cache-dependency-path: "**/package-lock.json" + cache-dependency-path: "**/packages-lock.json" - name: Restore dependencies run: dotnet restore --locked-mode From 3868f59d4c7581f09b512c07e0e09178c4265457 Mon Sep 17 00:00:00 2001 From: Joshua Hiles Date: Fri, 15 Dec 2023 16:59:28 +0000 Subject: [PATCH 24/26] ci: use packages.lock not packages-lock --- .github/workflows/codeql.yml | 2 +- .github/workflows/unit-test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 38e1ec6..fe97463 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -38,7 +38,7 @@ jobs: with: dotnet-version: 8.x cache: true - cache-dependency-path: "**/packages-lock.json" + cache-dependency-path: "**/packages.lock.json" - run: dotnet restore --locked-mode diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 3fceae5..fb27d45 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -18,7 +18,7 @@ jobs: with: dotnet-version: 8.x cache: true - cache-dependency-path: "**/packages-lock.json" + cache-dependency-path: "**/packages.lock.json" - name: Restore dependencies run: dotnet restore --locked-mode From 9ab64b00bb36e4ea547845e91f7b22df5c091bef Mon Sep 17 00:00:00 2001 From: Joshua Hiles Date: Fri, 15 Dec 2023 17:04:09 +0000 Subject: [PATCH 25/26] refactor: Remove autobuild comment --- .github/workflows/codeql.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index fe97463..e4650fd 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -30,10 +30,6 @@ jobs: with: languages: ${{ matrix.language }} - # Autobuild doesnt support .net 6 - # - name: Autobuild - # uses: github/codeql-action/autobuild@v1 - - uses: actions/setup-dotnet@v3 with: dotnet-version: 8.x From 98dd70346fc4407f9d608efc537c1f2d1b84eab4 Mon Sep 17 00:00:00 2001 From: Joshua Hiles Date: Fri, 15 Dec 2023 17:05:39 +0000 Subject: [PATCH 26/26] ci(Unit test): specify name --- .github/workflows/unit-test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index fb27d45..757c10a 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -8,7 +8,8 @@ on: branches: [3.0.0] jobs: - build: + test: + name: Test runs-on: ubuntu-latest steps: