diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 31607fa..8ce4624 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -6,20 +6,89 @@ on: pull_request: branches: [ main ] +env: + DOTNET_NOLOGO: true + DOTNET_CLI_TELEMETRY_OPTOUT: true + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + jobs: build: + strategy: + matrix: + config: + - Release + - Debug runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Setup .NET - uses: actions/setup-dotnet@v1 + uses: actions/setup-dotnet@v3 with: - dotnet-version: 6.0.x + dotnet-version: 7.0.x - name: Restore dependencies run: dotnet restore - name: Build - run: dotnet build --no-restore + run: dotnet build --no-restore --configuration ${{matrix.config}} - name: Test - run: dotnet test --no-build --verbosity normal + run: dotnet test --no-build --verbosity normal --configuration ${{matrix.config}} + + check-dotnet-format: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Install Nix + uses: cachix/install-nix-action@v17 + with: + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - name: Run Fantomas + run: nix run .#fantomas -- -r --check . + + check-nix-format: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Install Nix + uses: cachix/install-nix-action@v17 + with: + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - name: Run Alejandra + run: nix develop --command alejandra --check . + + shellcheck: + name: Shellcheck + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + name: Checkout + - name: Install Nix + uses: cachix/install-nix-action@v17 + with: + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - name: Run ShellCheck + run: nix develop --command bash -c "find . -type f -name '*.sh' | xargs shellcheck" + + linkcheck: + name: Check links + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Install Nix + uses: cachix/install-nix-action@v17 + with: + extra_nix_config: | + access-tokens = github.com=${{ secrets.GITHUB_TOKEN }} + - name: Run link checker + run: nix develop --command markdown-link-check README.md + + all-required-checks-complete: + needs: [check-dotnet-format, check-nix-format, build, shellcheck, linkcheck] + runs-on: ubuntu-latest + steps: + - run: echo "All required checks complete." diff --git a/.gitignore b/.gitignore index 3b87120..7351cd5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,21 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + # User-specific files +*.rsuser *.suo *.user *.userosscache *.sln.docstates +# User-specific files (MonoDevelop/Xamarin Studio) *.userprefs +# Mono auto generated files +mono_crash.* + # Build results [Dd]ebug/ [Dd]ebugPublic/ @@ -13,27 +23,89 @@ [Rr]eleases/ x64/ x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ +[Ll]ogs/ -# Visual Studio 2015 cache/options directory +# Visual Studio 2015/2017 cache/options directory .vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ -# MSTest test results +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* # NUnit *.VisualState.xml TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ # .NET Core project.lock.json project.fragment.lock.json artifacts/ -**/Properties/launchSettings.json + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb # Visual Studio profiler *.psess @@ -41,30 +113,249 @@ artifacts/ *.vspx *.sap -# ReSharper +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user -# Visual Studio coverage +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results *.coverage *.coveragexml -# NuGet +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages *.nupkg -**/packages/* -!**/packages/build/ +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files *.nuget.props *.nuget.targets -# Paket +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager .paket/paket.exe paket-files/ -# FAKE +# FAKE - F# Make .fake/ -# Rider +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + .idea/ -*.sln.iml -*.DotSettings + +/result +.DS_Store + +/.profile +/.profile-*-link diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e1d31cd --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Patrick Stevens + +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/README.md b/README.md new file mode 100644 index 0000000..7bc6640 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Ray Tracing in One Weekend + +This is [Ray Tracing in One Weekend](https://raytracing.github.io/books/RayTracingInOneWeekend.html), in F#. diff --git a/RayTracing.App/LoadImage.fs b/RayTracing.App/LoadImage.fs index 3365dce..ba76c4c 100644 --- a/RayTracing.App/LoadImage.fs +++ b/RayTracing.App/LoadImage.fs @@ -1,12 +1,12 @@ namespace RayTracing.App -open System.Drawing open System.Reflection +open SkiaSharp [] module LoadImage = - let fromResource (name : string) : Bitmap = + let fromResource (name : string) : SKBitmap = let assy = Assembly.GetExecutingAssembly () use resource = @@ -15,5 +15,4 @@ module LoadImage = |> Seq.head |> assy.GetManifestResourceStream - let b = new Bitmap (resource) - b + SKBitmap.Decode resource diff --git a/RayTracing.App/RayTracing.App.fsproj b/RayTracing.App/RayTracing.App.fsproj index 71cdcbc..8c244c1 100644 --- a/RayTracing.App/RayTracing.App.fsproj +++ b/RayTracing.App/RayTracing.App.fsproj @@ -1,23 +1,23 @@ - - - - net6.0 - Exe - - - - - - - - - - - - - - - - - - + + + + net7.0 + Exe + + + + + + + + + + + + + + + + + + diff --git a/RayTracing.Test/RayTracing.Test.fsproj b/RayTracing.Test/RayTracing.Test.fsproj index b5e08ec..4cc213e 100644 --- a/RayTracing.Test/RayTracing.Test.fsproj +++ b/RayTracing.Test/RayTracing.Test.fsproj @@ -1,33 +1,33 @@ - - - - net6.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + net7.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RayTracing/ImageOutput.fs b/RayTracing/ImageOutput.fs index 1666ee1..7d6d351 100644 --- a/RayTracing/ImageOutput.fs +++ b/RayTracing/ImageOutput.fs @@ -3,10 +3,10 @@ open System open System.Collections.Generic open System.Collections.Immutable -open System.Drawing.Imaging open System.IO open System.IO.Abstractions open System.Text +open SkiaSharp [] module PixelOutput = @@ -31,17 +31,14 @@ module PixelOutput = let blue = pixel.Blue sprintf "%i %i %i" red green blue - let toSystem (gammaCorrect : bool) (pixel : Pixel) : System.Drawing.Color = + let toSkia (gammaCorrect : bool) (pixel : Pixel) : SKColor = if gammaCorrect then let red = correct pixel.Red let green = correct pixel.Green let blue = correct pixel.Blue - Drawing.Color.FromArgb (255, int red, int green, int blue) + SKColor (red, green, blue, 255uy) else - let red = pixel.Red - let green = pixel.Green - let blue = pixel.Blue - Drawing.Color.FromArgb (255, int red, int green, int blue) + SKColor (pixel.Red, pixel.Green, pixel.Blue, 255uy) [] module ImageOutput = @@ -248,26 +245,28 @@ module Png = let maxCol = pixels.[0].Length async { - use img = new System.Drawing.Bitmap (maxCol, maxRow) + use img = new SKBitmap (maxCol, maxRow) let writeRow (row : int) = for col in 0 .. pixels.[row].Length - 2 do - let colour = PixelOutput.toSystem gammaCorrect pixels.[row].[col] + let colour = PixelOutput.toSkia gammaCorrect pixels.[row].[col] img.SetPixel (col, row, colour) incrementProgress 1.0 - let colour = - PixelOutput.toSystem gammaCorrect pixels.[row].[pixels.[row].Length - 1] + let colour = PixelOutput.toSkia gammaCorrect pixels.[row].[pixels.[row].Length - 1] img.SetPixel (pixels.[row].Length - 1, row, colour) incrementProgress 1.0 - for row in 0 .. pixels.Length - 2 do + for row = 0 to pixels.Length - 2 do writeRow row writeRow (pixels.Length - 1) use fileStream = output.OpenWrite () - img.Save (fileStream, ImageFormat.Png) + + if not (img.Encode (fileStream, SKEncodedImageFormat.Png, 100)) then + return failwith "unable to encode image as PNG" + return () } diff --git a/RayTracing/RayTracing.fsproj b/RayTracing/RayTracing.fsproj index 9648b0d..6ee5c6d 100644 --- a/RayTracing/RayTracing.fsproj +++ b/RayTracing/RayTracing.fsproj @@ -1,32 +1,32 @@ - - - - net6.0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + net7.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/RayTracing/Texture.fs b/RayTracing/Texture.fs index d653575..3383c48 100644 --- a/RayTracing/Texture.fs +++ b/RayTracing/Texture.fs @@ -1,5 +1,7 @@ namespace RayTracing +open SkiaSharp + [] type Texture = | Colour of Pixel @@ -25,7 +27,7 @@ type ParameterisedTexture = [] module ParameterisedTexture = - let ofImage (img : System.Drawing.Bitmap) : ParameterisedTexture = + let ofImage (img : SKBitmap) : ParameterisedTexture = Array.init img.Height (fun y -> @@ -37,9 +39,9 @@ module ParameterisedTexture = let p = img.GetPixel (x, y) { - Red = p.R - Green = p.G - Blue = p.B + Red = p.Red + Green = p.Green + Blue = p.Blue } ) ) diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..c123c17 --- /dev/null +++ b/flake.lock @@ -0,0 +1,42 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1667395993, + "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1672350804, + "narHash": "sha256-jo6zkiCabUBn3ObuKXHGqqORUMH27gYDIFFfLq5P4wg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "677ed08a50931e38382dbef01cba08a8f7eac8f6", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-unstable", + "type": "indirect" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..e8dfcc3 --- /dev/null +++ b/flake.nix @@ -0,0 +1,81 @@ +{ + description = "Ray Tracing in One Weekend"; + inputs = { + nixpkgs.url = "nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + outputs = { + self, + nixpkgs, + flake-utils, + ... + }: + flake-utils.lib.eachDefaultSystem ( + system: let + pkgs = import nixpkgs {inherit system;}; + projectFile = "./RayTracing.App/RayTracing.App.fsproj"; + testProjectFile = "./RayTracing.Test/RayTracing.Test.fsproj"; + pname = "RayTracing"; + dotnet-sdk = pkgs.dotnet-sdk_7; + dotnet-runtime = pkgs.dotnetCorePackages.runtime_7_0; + version = "0.0.1"; + dotnetTool = toolName: toolVersion: sha256: + pkgs.stdenvNoCC.mkDerivation rec { + name = toolName; + version = toolVersion; + nativeBuildInputs = [pkgs.makeWrapper]; + src = pkgs.fetchNuGet { + pname = name; + version = version; + sha256 = sha256; + installPhase = ''mkdir -p $out/bin && cp -r tools/net6.0/any/* $out/bin''; + }; + installPhase = '' + runHook preInstall + mkdir -p "$out/lib" + cp -r ./bin/* "$out/lib" + makeWrapper "${dotnet-runtime}/bin/dotnet" "$out/bin/${name}" --add-flags "$out/lib/${name}.dll" + runHook postInstall + ''; + }; + in { + packages = { + fantomas = dotnetTool "fantomas" "5.2.0-alpha-010" "sha256-CuoROZBBhaK0IFjbKNLvzgX4GXwuIybqIvCtuqROBMk="; + fetchDeps = let + flags = []; + runtimeIds = map (system: pkgs.dotnetCorePackages.systemToDotnetRid system) dotnet-sdk.meta.platforms; + in + pkgs.writeShellScript "fetch-${pname}-deps" (builtins.readFile (pkgs.substituteAll { + src = ./nix/fetchDeps.sh; + pname = pname; + binPath = pkgs.lib.makeBinPath [pkgs.coreutils dotnet-sdk (pkgs.nuget-to-nix.override {inherit dotnet-sdk;})]; + projectFiles = toString (pkgs.lib.toList projectFile); + testProjectFiles = toString (pkgs.lib.toList testProjectFile); + rids = pkgs.lib.concatStringsSep "\" \"" runtimeIds; + packages = dotnet-sdk.packages; + storeSrc = pkgs.srcOnly { + src = ./.; + pname = pname; + version = version; + }; + })); + default = pkgs.buildDotnetModule { + pname = pname; + version = version; + src = ./.; + projectFile = projectFile; + nugetDeps = ./nix/deps.nix; + doCheck = true; + dotnet-sdk = dotnet-sdk; + dotnet-runtime = dotnet-runtime; + }; + }; + devShells = let + in { + default = pkgs.mkShell { + buildInputs = [pkgs.dotnet-sdk_7 pkgs.git pkgs.alejandra pkgs.nodePackages.markdown-link-check]; + }; + }; + } + ); +} diff --git a/nix/deps.nix b/nix/deps.nix new file mode 100644 index 0000000..af5f216 --- /dev/null +++ b/nix/deps.nix @@ -0,0 +1,409 @@ +# This file was automatically generated by passthru.fetch-deps. +# Please don't edit it manually, your changes might get overwritten! +{fetchNuGet}: [ + (fetchNuGet { + pname = "FsCheck"; + version = "3.0.0-alpha5"; + sha256 = "0qzj81iki8n0k7c63g36cagcfrriaw5g0bpgnn66whp925i392x7"; + }) + (fetchNuGet { + pname = "FSharp.Core"; + version = "7.0.0"; + sha256 = "1pgk3qk9p1s53wvja17744x4bf7zs3a3wf0dmxi66w1w06z7i85x"; + }) + (fetchNuGet { + pname = "FsUnit"; + version = "4.0.4"; + sha256 = "19fpbl874klvq3bd5vnryj2zn3c7ivwfyk16hakbrxw6qwb64gpn"; + }) + (fetchNuGet { + pname = "Microsoft.CodeCoverage"; + version = "16.8.0"; + sha256 = "1y05sjk7wgd29a47v1yhn2s1lrd8wgazkilvmjbvivmrrm3fqjs8"; + }) + (fetchNuGet { + pname = "Microsoft.CSharp"; + version = "4.0.1"; + sha256 = "0zxc0apx1gcx361jlq8smc9pfdgmyjh6hpka8dypc9w23nlsh6yj"; + }) + (fetchNuGet { + pname = "Microsoft.NET.Test.Sdk"; + version = "16.8.0"; + sha256 = "1ln2mva7j2mpsj9rdhpk8vhm3pgd8wn563xqdcwd38avnhp74rm9"; + }) + (fetchNuGet { + pname = "Microsoft.NETCore.Platforms"; + version = "1.0.1"; + sha256 = "01al6cfxp68dscl15z7rxfw9zvhm64dncsw09a1vmdkacsa2v6lr"; + }) + (fetchNuGet { + pname = "Microsoft.NETCore.Platforms"; + version = "1.1.0"; + sha256 = "08vh1r12g6ykjygq5d3vq09zylgb84l63k49jc4v8faw9g93iqqm"; + }) + (fetchNuGet { + pname = "Microsoft.NETCore.Platforms"; + version = "5.0.0"; + sha256 = "0mwpwdflidzgzfx2dlpkvvnkgkr2ayaf0s80737h4wa35gaj11rc"; + }) + (fetchNuGet { + pname = "Microsoft.NETCore.Platforms"; + version = "6.0.0-preview.3.21201.4"; + sha256 = "09qznsrkx60j17adp6rzgxcb9k2a04bl06lni4xz7rlpg2k1qry7"; + }) + (fetchNuGet { + pname = "Microsoft.NETCore.Targets"; + version = "1.0.1"; + sha256 = "0ppdkwy6s9p7x9jix3v4402wb171cdiibq7js7i13nxpdky7074p"; + }) + (fetchNuGet { + pname = "Microsoft.TestPlatform.ObjectModel"; + version = "16.8.0"; + sha256 = "0ii9d88py6mjsxzj9v3zx4izh6rb9ma6s9kj85xmc0xrw7jc2g3m"; + }) + (fetchNuGet { + pname = "Microsoft.TestPlatform.TestHost"; + version = "16.8.0"; + sha256 = "1rh8cga1km3jfafkwfjr0dwqrxb4306hf7fipwba9h02w7vlhb9a"; + }) + (fetchNuGet { + pname = "Microsoft.Win32.SystemEvents"; + version = "6.0.0-preview.3.21201.4"; + sha256 = "1mqhif4b7524c1gjk0md10gyg2mn30fjzcd0v33crin4xfl6ppcz"; + }) + (fetchNuGet { + pname = "NETStandard.Library"; + version = "2.0.0"; + sha256 = "1bc4ba8ahgk15m8k4nd7x406nhi0kwqzbgjk2dmw52ss553xz7iy"; + }) + (fetchNuGet { + pname = "NETStandard.Library"; + version = "2.0.3"; + sha256 = "1fn9fxppfcg4jgypp2pmrpr6awl3qz1xmnri0cygpkwvyx27df1y"; + }) + (fetchNuGet { + pname = "Newtonsoft.Json"; + version = "9.0.1"; + sha256 = "0mcy0i7pnfpqm4pcaiyzzji4g0c8i3a5gjz28rrr28110np8304r"; + }) + (fetchNuGet { + pname = "NuGet.Frameworks"; + version = "5.0.0"; + sha256 = "18ijvmj13cwjdrrm52c8fpq021531zaz4mj4b4zapxaqzzxf2qjr"; + }) + (fetchNuGet { + pname = "NUnit"; + version = "3.13.1"; + sha256 = "07156gr0yl9rqhyj44cp1xz9jpngbl5kb7ci3qfy9fcp01dczmm9"; + }) + (fetchNuGet { + pname = "NUnit3TestAdapter"; + version = "4.0.0-beta.1"; + sha256 = "1dia3bpbsjwq5z18v4jvx7hcz8yldym84nssgigw6m2r76iwx94j"; + }) + (fetchNuGet { + pname = "runtime.any.System.Collections"; + version = "4.0.11"; + sha256 = "1x44bm1cgv28zmrp095wf9mn8a6a0ivnzp9v14dcbhx06igxzgg0"; + }) + (fetchNuGet { + pname = "runtime.any.System.Diagnostics.Tools"; + version = "4.0.1"; + sha256 = "0qcpm90hrm9gx9pmxlvfml65jm0bwpr5dg3r7l7xm9nvmibvc7n7"; + }) + (fetchNuGet { + pname = "runtime.any.System.Globalization"; + version = "4.0.11"; + sha256 = "0240rp66pi5bw1xklmh421hj7arwcdmjmgfkiq1cbc6nrm8ah286"; + }) + (fetchNuGet { + pname = "runtime.any.System.IO"; + version = "4.1.0"; + sha256 = "0kasfkjiml2kk8prnyn1990nhsahnjggvqwszqjdsfwfl43vpcb5"; + }) + (fetchNuGet { + pname = "runtime.any.System.Reflection"; + version = "4.1.0"; + sha256 = "06kcs059d5czyakx75rvlwa2mr86156w18fs7chd03f7084l7mq6"; + }) + (fetchNuGet { + pname = "runtime.any.System.Reflection.Extensions"; + version = "4.0.1"; + sha256 = "05k34ijz9g9csh0vbbv3g3lrxl163izwcfncmbcl7k073h32rzkr"; + }) + (fetchNuGet { + pname = "runtime.any.System.Reflection.Primitives"; + version = "4.0.1"; + sha256 = "1zxrpvixr5fqzkxpnin6g6gjq6xajy1snghz99ds2dwbhm276rhz"; + }) + (fetchNuGet { + pname = "runtime.any.System.Resources.ResourceManager"; + version = "4.0.1"; + sha256 = "1jmgs7hynb2rff48623wnyb37558bbh1q28k9c249j5r5sgsr5kr"; + }) + (fetchNuGet { + pname = "runtime.any.System.Runtime"; + version = "4.1.0"; + sha256 = "0mjr2bi7wvnkphfjqgkyf8vfyvy15a829jz6mivl6jmksh2bx40m"; + }) + (fetchNuGet { + pname = "runtime.any.System.Runtime.Handles"; + version = "4.0.1"; + sha256 = "1kswgqhy34qvc49i981fk711s7knd6z13bp0rin8ms6axkh98nas"; + }) + (fetchNuGet { + pname = "runtime.any.System.Runtime.InteropServices"; + version = "4.1.0"; + sha256 = "0gm8if0hcmp1qys1wmx4970k2x62pqvldgljsyzbjhiy5644vl8z"; + }) + (fetchNuGet { + pname = "runtime.any.System.Text.Encoding"; + version = "4.0.11"; + sha256 = "0m4vgmzi1ky8xlj0r7xcyazxln3j9dlialnk6d2gmgrfnzf8f9m7"; + }) + (fetchNuGet { + pname = "runtime.any.System.Text.Encoding.Extensions"; + version = "4.0.11"; + sha256 = "0d1rxxpvg9v7wlibsfgz0r4hwigpadas822qf8m8fs1gma9gs877"; + }) + (fetchNuGet { + pname = "runtime.any.System.Threading.Tasks"; + version = "4.0.11"; + sha256 = "1qzdp09qs8br5qxzlm1lgbjn4n57fk8vr1lzrmli2ysdg6x1xzvk"; + }) + (fetchNuGet { + pname = "runtime.native.System"; + version = "4.0.0"; + sha256 = "1ppk69xk59ggacj9n7g6fyxvzmk1g5p4fkijm0d7xqfkig98qrkf"; + }) + (fetchNuGet { + pname = "runtime.native.System.Security.Cryptography"; + version = "4.0.0"; + sha256 = "0k57aa2c3b10wl3hfqbgrl7xq7g8hh3a3ir44b31dn5p61iiw3z9"; + }) + (fetchNuGet { + pname = "runtime.unix.System.Diagnostics.Debug"; + version = "4.0.11"; + sha256 = "05ndbai4vpqrry0ghbfgqc8xblmplwjgndxmdn1zklqimczwjg2d"; + }) + (fetchNuGet { + pname = "runtime.unix.System.IO.FileSystem"; + version = "4.0.1"; + sha256 = "02wnlydnbhai0zy7c3kihg0cis0l1b2z78kyi1ci47c5v0jklwha"; + }) + (fetchNuGet { + pname = "runtime.unix.System.Private.Uri"; + version = "4.0.1"; + sha256 = "0ic5dgc45jkhcr1g9xmmzjm7ffiw4cymm0fprczlx4fnww4783nm"; + }) + (fetchNuGet { + pname = "runtime.unix.System.Runtime.Extensions"; + version = "4.1.0"; + sha256 = "0x1cwd7cvifzmn5x1wafvj75zdxlk3mxy860igh3x1wx0s8167y4"; + }) + (fetchNuGet { + pname = "Spectre.Console"; + version = "0.38.1-preview.0.17"; + sha256 = "0jfr0dp3ry7s1hdd9qnk1yagb0ydv85kl9vnw99s1apwmcxaw1xw"; + }) + (fetchNuGet { + pname = "System.Collections"; + version = "4.0.11"; + sha256 = "1ga40f5lrwldiyw6vy67d0sg7jd7ww6kgwbksm19wrvq9hr0bsm6"; + }) + (fetchNuGet { + pname = "System.Diagnostics.Debug"; + version = "4.0.11"; + sha256 = "0gmjghrqmlgzxivd2xl50ncbglb7ljzb66rlx8ws6dv8jm0d5siz"; + }) + (fetchNuGet { + pname = "System.Diagnostics.Tools"; + version = "4.0.1"; + sha256 = "19cknvg07yhakcvpxg3cxa0bwadplin6kyxd8mpjjpwnp56nl85x"; + }) + (fetchNuGet { + pname = "System.Drawing.Common"; + version = "6.0.0-preview.3.21201.4"; + sha256 = "1dx6s1s4xwaya6da49xa30n1sbzgs73fwiwh70jdr67q3iy4zcr5"; + }) + (fetchNuGet { + pname = "System.Dynamic.Runtime"; + version = "4.0.11"; + sha256 = "1pla2dx8gkidf7xkciig6nifdsb494axjvzvann8g2lp3dbqasm9"; + }) + (fetchNuGet { + pname = "System.Globalization"; + version = "4.0.11"; + sha256 = "070c5jbas2v7smm660zaf1gh0489xanjqymkvafcs4f8cdrs1d5d"; + }) + (fetchNuGet { + pname = "System.IO"; + version = "4.1.0"; + sha256 = "1g0yb8p11vfd0kbkyzlfsbsp5z44lwsvyc0h3dpw6vqnbi035ajp"; + }) + (fetchNuGet { + pname = "System.IO.Abstractions"; + version = "13.2.28"; + sha256 = "1jcjvpyw88xkiii9qh5f7mlvp5f6v3dsj7rhw7msjwv2bp001d24"; + }) + (fetchNuGet { + pname = "System.IO.Abstractions.TestingHelpers"; + version = "13.2.28"; + sha256 = "055pa7xv2nr7nrm9hsxfgakcc62hi6iivg30xqkkkmsldjqr29ip"; + }) + (fetchNuGet { + pname = "System.IO.FileSystem"; + version = "4.0.1"; + sha256 = "0kgfpw6w4djqra3w5crrg8xivbanh1w9dh3qapb28q060wb9flp1"; + }) + (fetchNuGet { + pname = "System.IO.FileSystem.AccessControl"; + version = "5.0.0"; + sha256 = "0ixl68plva0fsj3byv76bai7vkin86s6wyzr8vcav3szl862blvk"; + }) + (fetchNuGet { + pname = "System.IO.FileSystem.Primitives"; + version = "4.0.1"; + sha256 = "1s0mniajj3lvbyf7vfb5shp4ink5yibsx945k6lvxa96r8la1612"; + }) + (fetchNuGet { + pname = "System.Linq"; + version = "4.1.0"; + sha256 = "1ppg83svb39hj4hpp5k7kcryzrf3sfnm08vxd5sm2drrijsla2k5"; + }) + (fetchNuGet { + pname = "System.Linq.Expressions"; + version = "4.1.0"; + sha256 = "1gpdxl6ip06cnab7n3zlcg6mqp7kknf73s8wjinzi4p0apw82fpg"; + }) + (fetchNuGet { + pname = "System.ObjectModel"; + version = "4.0.12"; + sha256 = "1sybkfi60a4588xn34nd9a58png36i0xr4y4v4kqpg8wlvy5krrj"; + }) + (fetchNuGet { + pname = "System.Private.Uri"; + version = "4.0.1"; + sha256 = "0k57qhawjysm4cpbfpc49kl4av7lji310kjcamkl23bwgij5ld9j"; + }) + (fetchNuGet { + pname = "System.Reflection"; + version = "4.1.0"; + sha256 = "1js89429pfw79mxvbzp8p3q93il6rdff332hddhzi5wqglc4gml9"; + }) + (fetchNuGet { + pname = "System.Reflection.Emit"; + version = "4.0.1"; + sha256 = "0ydqcsvh6smi41gyaakglnv252625hf29f7kywy2c70nhii2ylqp"; + }) + (fetchNuGet { + pname = "System.Reflection.Emit.ILGeneration"; + version = "4.0.1"; + sha256 = "1pcd2ig6bg144y10w7yxgc9d22r7c7ww7qn1frdfwgxr24j9wvv0"; + }) + (fetchNuGet { + pname = "System.Reflection.Emit.Lightweight"; + version = "4.0.1"; + sha256 = "1s4b043zdbx9k39lfhvsk68msv1nxbidhkq6nbm27q7sf8xcsnxr"; + }) + (fetchNuGet { + pname = "System.Reflection.Extensions"; + version = "4.0.1"; + sha256 = "0m7wqwq0zqq9gbpiqvgk3sr92cbrw7cp3xn53xvw7zj6rz6fdirn"; + }) + (fetchNuGet { + pname = "System.Reflection.Primitives"; + version = "4.0.1"; + sha256 = "1bangaabhsl4k9fg8khn83wm6yial8ik1sza7401621jc6jrym28"; + }) + (fetchNuGet { + pname = "System.Reflection.TypeExtensions"; + version = "4.1.0"; + sha256 = "1bjli8a7sc7jlxqgcagl9nh8axzfl11f4ld3rjqsyxc516iijij7"; + }) + (fetchNuGet { + pname = "System.Resources.ResourceManager"; + version = "4.0.1"; + sha256 = "0b4i7mncaf8cnai85jv3wnw6hps140cxz8vylv2bik6wyzgvz7bi"; + }) + (fetchNuGet { + pname = "System.Runtime"; + version = "4.1.0"; + sha256 = "02hdkgk13rvsd6r9yafbwzss8kr55wnj8d5c7xjnp8gqrwc8sn0m"; + }) + (fetchNuGet { + pname = "System.Runtime.Extensions"; + version = "4.1.0"; + sha256 = "0rw4rm4vsm3h3szxp9iijc3ksyviwsv6f63dng3vhqyg4vjdkc2z"; + }) + (fetchNuGet { + pname = "System.Runtime.Handles"; + version = "4.0.1"; + sha256 = "1g0zrdi5508v49pfm3iii2hn6nm00bgvfpjq1zxknfjrxxa20r4g"; + }) + (fetchNuGet { + pname = "System.Runtime.InteropServices"; + version = "4.1.0"; + sha256 = "01kxqppx3dr3b6b286xafqilv4s2n0gqvfgzfd4z943ga9i81is1"; + }) + (fetchNuGet { + pname = "System.Runtime.Serialization.Primitives"; + version = "4.1.1"; + sha256 = "042rfjixknlr6r10vx2pgf56yming8lkjikamg3g4v29ikk78h7k"; + }) + (fetchNuGet { + pname = "System.Security.AccessControl"; + version = "5.0.0"; + sha256 = "17n3lrrl6vahkqmhlpn3w20afgz09n7i6rv0r3qypngwi7wqdr5r"; + }) + (fetchNuGet { + pname = "System.Security.Principal.Windows"; + version = "5.0.0"; + sha256 = "1mpk7xj76lxgz97a5yg93wi8lj0l8p157a5d50mmjy3gbz1904q8"; + }) + (fetchNuGet { + pname = "System.Text.Encoding"; + version = "4.0.11"; + sha256 = "1dyqv0hijg265dwxg6l7aiv74102d6xjiwplh2ar1ly6xfaa4iiw"; + }) + (fetchNuGet { + pname = "System.Text.Encoding.Extensions"; + version = "4.0.11"; + sha256 = "08nsfrpiwsg9x5ml4xyl3zyvjfdi4mvbqf93kjdh11j4fwkznizs"; + }) + (fetchNuGet { + pname = "System.Text.RegularExpressions"; + version = "4.1.0"; + sha256 = "1mw7vfkkyd04yn2fbhm38msk7dz2xwvib14ygjsb8dq2lcvr18y7"; + }) + (fetchNuGet { + pname = "System.Threading"; + version = "4.0.11"; + sha256 = "19x946h926bzvbsgj28csn46gak2crv2skpwsx80hbgazmkgb1ls"; + }) + (fetchNuGet { + pname = "System.Threading.Tasks"; + version = "4.0.11"; + sha256 = "0nr1r41rak82qfa5m0lhk9mp0k93bvfd7bbd9sdzwx9mb36g28p5"; + }) + (fetchNuGet { + pname = "System.Threading.Tasks.Extensions"; + version = "4.0.0"; + sha256 = "1cb51z062mvc2i8blpzmpn9d9mm4y307xrwi65di8ri18cz5r1zr"; + }) + (fetchNuGet { + pname = "System.Xml.ReaderWriter"; + version = "4.0.11"; + sha256 = "0c6ky1jk5ada9m94wcadih98l6k1fvf6vi7vhn1msjixaha419l5"; + }) + (fetchNuGet { + pname = "System.Xml.XDocument"; + version = "4.0.11"; + sha256 = "0n4lvpqzy9kc7qy1a4acwwd7b7pnvygv895az5640idl2y9zbz18"; + }) + (fetchNuGet { + pname = "Wcwidth"; + version = "0.2.0"; + sha256 = "0p7zaisix9ql4v5nyl9gfc93xcyj74j01rwvgm7jw29js3wlj10s"; + }) +] diff --git a/nix/fetchDeps.sh b/nix/fetchDeps.sh new file mode 100644 index 0000000..e15b822 --- /dev/null +++ b/nix/fetchDeps.sh @@ -0,0 +1,73 @@ +#!/bin/bash + +# This file was adapted from +# https://github.com/NixOS/nixpkgs/blob/b981d811453ab84fb3ea593a9b33b960f1ab9147/pkgs/build-support/dotnet/build-dotnet-module/default.nix#L173 +set -euo pipefail +export PATH="@binPath@" +for arg in "$@"; do + case "$arg" in + --keep-sources|-k) + keepSources=1 + shift + ;; + --help|-h) + echo "usage: $0 [--keep-sources] [--help] " + echo " The path to write the lockfile to. A temporary file is used if this is not set" + echo " --keep-sources Don't remove temporary directories upon exit, useful for debugging" + echo " --help Show this help message" + exit + ;; + esac +done +tmp=$(mktemp -td "@pname@-tmp-XXXXXX") +export tmp +HOME=$tmp/home +exitTrap() { + test -n "${ranTrap-}" && return + ranTrap=1 + if test -n "${keepSources-}"; then + echo -e "Path to the source: $tmp/src\nPath to the fake home: $tmp/home" + else + rm -rf "$tmp" + fi + # Since mktemp is used this will be empty if the script didnt succesfully complete + if ! test -s "$depsFile"; then + rm -rf "$depsFile" + fi +} +trap exitTrap EXIT INT TERM +dotnetRestore() { + local -r project="${1-}" + local -r rid="$2" + dotnet restore "${project-}" \ + -p:ContinuousIntegrationBuild=true \ + -p:Deterministic=true \ + --packages "$tmp/nuget_pkgs" \ + --runtime "$rid" \ + --no-cache \ + --force +} +declare -a projectFiles=( @projectFiles@ ) +declare -a testProjectFiles=( @testProjectFiles@ ) +export DOTNET_NOLOGO=1 +export DOTNET_CLI_TELEMETRY_OPTOUT=1 +depsFile=$(realpath "${1:-$(mktemp -t "@pname@-deps-XXXXXX.nix")}") +mkdir -p "$tmp/nuget_pkgs" +storeSrc="@storeSrc@" +src="$tmp/src" +cp -rT "$storeSrc" "$src" +chmod -R +w "$src" +cd "$src" +echo "Restoring project..." +rids=("@rids@") +for rid in "${rids[@]}"; do + (( ${#projectFiles[@]} == 0 )) && dotnetRestore "" "$rid" + for project in "${projectFiles[@]-}" "${testProjectFiles[@]-}"; do + dotnetRestore "$project" "$rid" + done +done +echo "Successfully restored project" +echo "Writing lockfile..." +echo -e "# This file was automatically generated by passthru.fetch-deps.\n# Please don't edit it manually, your changes might get overwritten!\n" > "$depsFile" +nuget-to-nix "$tmp/nuget_pkgs" "@packages@" >> "$depsFile" +echo "Successfully wrote lockfile to $depsFile"