Skip to content

Commit

Permalink
Proof of concept (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
Smaug123 committed Jul 30, 2022
1 parent 6aa9309 commit e79c93f
Show file tree
Hide file tree
Showing 15 changed files with 4,214 additions and 0 deletions.
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
bin/
obj/
/packages/
riderModule.iml
/_ReSharper.Caches/
.idea/
*.user
*.DotSettings

/result
/.profile*
10 changes: 10 additions & 0 deletions MauiDotnetFlake/Async.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace MauiDotnetFlake

[<RequireQualifiedAccess>]
module Async =

let map<'a, 'b> (f : 'a -> 'b) (x : Async<'a>) : Async<'b> =
async {
let! x = x
return f x
}
159 changes: 159 additions & 0 deletions MauiDotnetFlake/Domain.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
namespace MauiDotnetFlake

open System
open System.Collections.Immutable
open System.ComponentModel
open Newtonsoft.Json

type [<JsonConverter (typeof<PackKeyJsonConverter>) ; TypeConverter (typeof<PackKeyTypeConverter>)>] PackKey =
| PackKey of string
/// Human-readable round-trip representation
override this.ToString () =
match this with
| PackKey p -> p
and PackKeyJsonConverter () =
inherit JsonConverter<PackKey> ()
override _.ReadJson (reader : JsonReader, objectType : Type, _existingValue : PackKey, _ : bool, _ : JsonSerializer) =
if objectType <> typeof<PackKey> then
failwith $"Unexpected object type for pack key: {objectType}"
let value = reader.Value |> unbox<string>
PackKey value
override _.WriteJson (writer : JsonWriter, PackKey key, _ : JsonSerializer) : unit =
writer.WriteValue key
and PackKeyTypeConverter () =
inherit TypeConverter ()
override _.CanConvertFrom (_, t : Type) : bool =
t = typeof<string>
override _.ConvertFrom (_, _, v : obj) : obj =
v |> unbox<string> |> PackKey |> box

type [<JsonConverter (typeof<WorkloadKeyJsonConverter>) ; TypeConverter (typeof<WorkloadKeyTypeConverter>)>] WorkloadKey =
| WorkloadKey of string
and WorkloadKeyJsonConverter () =
inherit JsonConverter<WorkloadKey> ()
override _.ReadJson (reader : JsonReader, objectType : Type, _existingValue : _, _ : bool, _ : JsonSerializer) : WorkloadKey =
if objectType <> typeof<WorkloadKey> then
failwith $"Unexpected object type for workload key: {objectType}"
let value = reader.Value |> unbox<string> |> WorkloadKey
value
override _.WriteJson (_ : JsonWriter, _ : WorkloadKey, _ : JsonSerializer) : unit =
failwith "do not call"
and WorkloadKeyTypeConverter () =
inherit TypeConverter ()
override _.CanConvertFrom (_, t : Type) : bool =
t = typeof<string>
override _.ConvertFrom (_, _, v : obj) : obj =
v |> unbox<string> |> WorkloadKey |> box

type WorkloadManifest =
{
/// e.g. ".NET MAUI SDK for all platforms"
Description : string
/// e.g. ["maui-blazor"]
Extends : WorkloadKey list
/// e.g. ["Microsoft.MAUI.Dependencies"]
Packs : PackKey list
}

type [<JsonConverter (typeof<PackManifestKindJsonConverter>) ; TypeConverter (typeof<PackManifestKindTypeConverter>)>] PackManifestKind =
| Library
| Framework
| Sdk
| Template
static member Parse (value : string) =
match value.ToLowerInvariant () with
| "library" -> PackManifestKind.Library
| "sdk" -> PackManifestKind.Sdk
| "framework" -> PackManifestKind.Framework
| "template" -> PackManifestKind.Template
| _ -> failwith $"Unexpected value in pack manifest kind: {value}"
member this.ToInt =
match this with
| Library -> 2
| Framework -> 1
| Sdk -> 0
| Template -> 3
override this.ToString () =
match this with
| Library -> "library"
| Framework -> "framework"
| Sdk -> "sdk"
| Template -> "template"

and PackManifestKindJsonConverter () =
inherit JsonConverter<PackManifestKind> ()
override _.ReadJson (reader : JsonReader, objectType : Type, _existingValue : PackManifestKind, _ : bool, _ : JsonSerializer) : PackManifestKind =
if objectType <> typeof<PackManifestKind> then
failwith $"Unexpected object type for pack manifest kind: {objectType}"
PackManifestKind.Parse (reader.Value |> unbox<string>)
override _.WriteJson (w : JsonWriter, v : PackManifestKind, _ : JsonSerializer) : unit =
w.WriteValue v.ToInt
and PackManifestKindTypeConverter () =
inherit TypeConverter ()
override _.CanConvertFrom (_, t : Type) : bool =
t = typeof<string>
override _.CanConvertTo (_, t : Type) : bool =
t = typeof<int>
override _.ConvertFrom (_, _, v : obj) : obj =
v |> unbox<string> |> PackManifestKind.Parse |> box
override _.ConvertTo (_, _, v : obj, _destType : Type) : obj =
(v |> unbox<PackManifestKind>).ToInt

type PackManifest =
{
Kind : PackManifestKind
Version : Version
/// Map of "win-x64": "nuget-package-name", for example
[<JsonProperty "alias-to">]
AliasTo : ImmutableDictionary<string, string>
}

type Manifest =
{
Version : Version
Workloads : Map<WorkloadKey, WorkloadManifest>
Packs : Map<PackKey, PackManifest>
}

type Registration =
{
Id : PackKey
Version : Version
Kind : PackManifestKind
ResolvedPackageId : PackKey
Path : string
IsStillPacked : bool
}

type HashString =
| HashString of string
override this.ToString () =
match this with
| HashString s -> s

/// A NuGet package such as "Microsoft.Maui.Controls.Ref.android".
type Pack =
{
Name : PackKey
Version : Version
Hash : HashString
Type : PackManifestKind
}

type WorkloadCollation =
{
/// The NuGet package that defines the manifest for this workload.
Package : string
/// The version of the NuGet package that defines the manifest for this workload.
Version : string
/// The SHA256 of the NuGet package that defines the manifest for this workload.
Hash : HashString
/// The rendered manifest of this workload.
Manifest : Manifest
}

type Platform =
| Platform of string
override this.ToString () =
match this with
| Platform p -> p
19 changes: 19 additions & 0 deletions MauiDotnetFlake/Hash.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace MauiDotnetFlake

open System
open System.IO
open System.Security.Cryptography

[<RequireQualifiedAccess>]
module Hash =
let getAsync (stream : Stream) =
async {
use c = SHA256.Create ()
let! ct = Async.CancellationToken
stream.Seek (0, SeekOrigin.Begin) |> ignore
let! hash = c.ComputeHashAsync (stream, ct) |> Async.AwaitTask
return
hash
|> Convert.ToBase64String
|> HashString
}
15 changes: 15 additions & 0 deletions MauiDotnetFlake/Map.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace MauiDotnetFlake

[<RequireQualifiedAccess>]
module Map =

let union<'k, 'v when 'k : comparison> (merge : 'v -> 'v -> 'v) (m1 : Map<'k, 'v>) (m2 : Map<'k, 'v>) =
(m1, m2)
||> Map.fold (fun acc k v ->
acc
|> Map.change k (function
| None -> Some v
| Some v2 -> Some (merge v v2)
)
)

16 changes: 16 additions & 0 deletions MauiDotnetFlake/Maui.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "maui-dotnet-flake", "maui-dotnet-flake.fsproj", "{5BE1A4A9-5DB9-4D3D-AC4D-EEBC0009257F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5BE1A4A9-5DB9-4D3D-AC4D-EEBC0009257F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5BE1A4A9-5DB9-4D3D-AC4D-EEBC0009257F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5BE1A4A9-5DB9-4D3D-AC4D-EEBC0009257F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5BE1A4A9-5DB9-4D3D-AC4D-EEBC0009257F}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

0 comments on commit e79c93f

Please sign in to comment.