Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support validation_packages_yml (continued) #409

Merged
merged 12 commits into from
Jul 16, 2024
Merged
21 changes: 21 additions & 0 deletions ARCtrl.sln
Original file line number Diff line number Diff line change
@@ -76,6 +76,12 @@ Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ARCtrl.ValidationPackages",
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ARCtrl.Yaml", "src\Yaml\ARCtrl.Yaml.fsproj", "{4CC3AAC2-030B-4B2E-A386-9C1F68E42238}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ARCtrl.ValidationPackages.Tests", "tests\ValidationPackages\ARCtrl.ValidationPackages.Tests.fsproj", "{1CA11165-4B70-41D2-A846-50374E85385E}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ARCtrl.Yaml.Tests", "tests\Yaml\ARCtrl.Yaml.Tests.fsproj", "{5810EF87-4F85-4B4C-98E3-833AE914C628}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "ARCtrl.Contract.Tests", "tests\Contract\ARCtrl.Contract.Tests.fsproj", "{D10D12C7-B877-423B-867D-161D99E673C9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -150,6 +156,18 @@ Global
{4CC3AAC2-030B-4B2E-A386-9C1F68E42238}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4CC3AAC2-030B-4B2E-A386-9C1F68E42238}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4CC3AAC2-030B-4B2E-A386-9C1F68E42238}.Release|Any CPU.Build.0 = Release|Any CPU
{1CA11165-4B70-41D2-A846-50374E85385E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1CA11165-4B70-41D2-A846-50374E85385E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1CA11165-4B70-41D2-A846-50374E85385E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1CA11165-4B70-41D2-A846-50374E85385E}.Release|Any CPU.Build.0 = Release|Any CPU
{5810EF87-4F85-4B4C-98E3-833AE914C628}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5810EF87-4F85-4B4C-98E3-833AE914C628}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5810EF87-4F85-4B4C-98E3-833AE914C628}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5810EF87-4F85-4B4C-98E3-833AE914C628}.Release|Any CPU.Build.0 = Release|Any CPU
{D10D12C7-B877-423B-867D-161D99E673C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D10D12C7-B877-423B-867D-161D99E673C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D10D12C7-B877-423B-867D-161D99E673C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D10D12C7-B877-423B-867D-161D99E673C9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -173,6 +191,9 @@ Global
{501F6D1E-6300-4CA4-8E61-3523BCF4D533} = {64B34A6E-318D-4E6E-9262-CE52C9B85A38}
{0C35D768-BF55-4BD9-B915-35125CED65A0} = {6DA2330B-D407-4FB1-AF05-B0184034EC44}
{4CC3AAC2-030B-4B2E-A386-9C1F68E42238} = {6DA2330B-D407-4FB1-AF05-B0184034EC44}
{1CA11165-4B70-41D2-A846-50374E85385E} = {64B34A6E-318D-4E6E-9262-CE52C9B85A38}
{5810EF87-4F85-4B4C-98E3-833AE914C628} = {64B34A6E-318D-4E6E-9262-CE52C9B85A38}
{D10D12C7-B877-423B-867D-161D99E673C9} = {64B34A6E-318D-4E6E-9262-CE52C9B85A38}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {1E354DE6-99BA-421E-9EF8-E808B855A85F}
5 changes: 4 additions & 1 deletion build/ProjectInfo.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module ProjectInfo
module ProjectInfo

open Fake.Core
open Helpers
@@ -13,6 +13,9 @@ let testProjects =
"tests/Spreadsheet"
"tests/FileSystem"
"tests/ARCtrl"
"tests/Yaml"
"tests/ValidationPackages"
"tests/Contract"
]

/// Native JS test paths
44 changes: 43 additions & 1 deletion src/ARCtrl/ARC.fs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
namespace ARCtrl

open ARCtrl.ValidationPackages
open ARCtrl.FileSystem
open ARCtrl.Contract
open ARCtrl
@@ -60,7 +61,8 @@ module ARCAux =
let tree =
FileSystemTree.createRootFolder [|workflows;runs|]
|> FileSystem.create
fs.Union(tree)
fs.Union(tree)


[<AttachMembers>]
type ARC(?isa : ArcInvestigation, ?cwl : CWL.CWL, ?fs : FileSystem.FileSystem) =
@@ -570,6 +572,46 @@ type ARC(?isa : ArcInvestigation, ?cwl : CWL.CWL, ?fs : FileSystem.FileSystem) =
ARCtrl.Json.ARC.ROCrate.encoder (Option.get obj.ISA)
|> ARCtrl.Json.Encode.toJsonString (ARCtrl.Json.Encode.defaultSpaces spaces)

/// <summary>
/// Returns the write contract for the input ValidationPackagesConfig object.
///
/// This will mutate the ARC file system to include the `.arc/validation_packages.yml` file if it is not already included.
Freymaurer marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
/// <param name="vpc">the config to write</param>
member this.GetValidationPackagesConfigWriteContract(vpc: ValidationPackagesConfig) =
let paths = this.FileSystem.Tree.ToFilePaths()
if not (Array.contains ValidationPackagesConfigHelper.ConfigFilePath paths) then
Array.append [|ValidationPackagesConfigHelper.ConfigFilePath|] paths
|> this.SetFilePaths
ValidationPackagesConfig.toCreateContract vpc

/// <summary>
/// Returns the delete contract for `.arc/validation_packages.yml`
///
/// If the ARC file system includes the `.arc/validation_packages.yml` file, it is removed.
/// </summary>
/// <param name="vpc"></param>
member this.GetValidationPackagesConfigDeleteContract(vpc) =
Freymaurer marked this conversation as resolved.
Show resolved Hide resolved
let paths = this.FileSystem.Tree.ToFilePaths()
if (Array.contains ValidationPackagesConfigHelper.ConfigFilePath paths) then
paths
|> Array.filter (fun p -> not (p = ValidationPackagesConfigHelper.ConfigFilePath))
|> this.SetFilePaths
ValidationPackagesConfig.toDeleteContract vpc

/// <summary>
/// Returns the read contract for `.arc/validation_packages.yml`
/// </summary>
member this.GetValidationPackagesConfigReadContract() =
ValidationPackagesConfigHelper.ReadContract

/// <summary>
/// Returns the ValidationPackagesConfig object from the given read contract if possible, otherwise returns None/null.
/// </summary>
/// <param name="contract">the input contract that contains the config in it's DTO</param>
member this.GetValidationPackagesConfigFromReadContract(contract) =
ValidationPackagesConfig.tryFromReadContract contract

//-Pseudo code-//
//// Option 1
//let fs, readcontracts = ARC.FSFromFilePaths filepaths
26 changes: 12 additions & 14 deletions src/Contract/ValidationPackagesConfig.fs
Original file line number Diff line number Diff line change
@@ -1,47 +1,45 @@
namespace ARCtrl.Contract

open ARCtrl.FileSystem
open ARCtrl.ArcPathHelper
open ARCtrl
open ARCtrl.Yaml
open ARCtrl.Helper
open ARCtrl.ValidationPackages

module ValidationPackagesConfigHelper =

let ConfigFilePath = [|ArcPathHelper.ARCConfigFolderName; ArcPathHelper.ValidationPackagesYamlFileName|] |> ArcPathHelper.combineMany

let ReadContract : Contract = {Operation = READ; DTOType = Some DTOType.YAML; Path = ConfigFilePath; DTO = None}


[<AutoOpen>]
module ValidationPackagesConfigExtensions =

let (|ValidationPackagesYamlPath|_|) (input) =
match input with
| [|ARCConfigFolderName; ValidationPackagesYamlFileName|] ->
let path = ARCtrl.ArcPathHelper.combineMany input
| [|ArcPathHelper.ARCConfigFolderName; ArcPathHelper.ValidationPackagesYamlFileName|] ->
let path = ArcPathHelper.combineMany input
Some path
| _ -> None

let internal config_file_path = [|ARCConfigFolderName; ValidationPackagesYamlFileName|] |> ARCtrl.ArcPathHelper.combineMany

type ValidationPackagesConfig with

member this.ToCreateContract () =
Contract.createCreate(config_file_path, DTOType.YAML, DTO.Text (this |> ValidationPackagesConfig.toYamlString()))

member this.ToUpdateContract () =
Contract.createUpdate(config_file_path, DTOType.YAML, DTO.Text (this |> ValidationPackagesConfig.toYamlString()))
Contract.createCreate(ValidationPackagesConfigHelper.ConfigFilePath, DTOType.YAML, DTO.Text (this |> ValidationPackagesConfig.toYamlString()))

member this.ToDeleteContract () =
Contract.createDelete(config_file_path)
Contract.createDelete(ValidationPackagesConfigHelper.ConfigFilePath)

static member toDeleteContract (config: ValidationPackagesConfig) : Contract =
config.ToDeleteContract()

static member toCreateContract (config: ValidationPackagesConfig) : Contract =
config.ToCreateContract()

static member toUpdateContract (config: ValidationPackagesConfig) : Contract =
config.ToUpdateContract()

static member tryFromReadContract (c:Contract) =
match c with
| {Operation = READ; DTOType = Some DTOType.YAML; DTO = Some (DTO.Text yaml)} ->
| {Operation = READ; DTOType = Some DTOType.YAML; Path = p; DTO = Some (DTO.Text yaml)} when p = ValidationPackagesConfigHelper.ConfigFilePath ->
yaml
|> ValidationPackagesConfig.fromYamlString
|> Some
12 changes: 11 additions & 1 deletion src/ValidationPackages/ValidationPackage.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace ARCtrl.ValidationPackages
namespace ARCtrl.ValidationPackages

open ARCtrl.Helper
open Fable.Core
@@ -22,6 +22,16 @@ type ValidationPackage(name, ?version) =
member this.Copy() =
ValidationPackage.make this.Name this.Version

/// Pretty printer
override this.ToString() =
[
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe do not use yaml style for pretty printing, or use YAMLicious to generate this. But i would prefer typical f# printing syntax

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is just taste, i would prefer keeping it as many tests would need to be adapted

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, i think the to string is valuable here because it represents something that only ever exists as a yaml file in the arc.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is just that the ToString function should not be responsible for YAML formatting, this should be a different function.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is not. it is just for printing. formatting for actual yaml export is done with yamlicious.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then why do we have tests for this? 😮

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i just tested everything that i added

"{"
$" Name = {this.Name}"
if version.IsSome then $" Version = {this.Version.Value}"
"}"
]
|> String.concat System.Environment.NewLine

override this.Equals(obj) =
match obj with
| :? ValidationPackage as other_vp -> other_vp.Name = this.Name && other_vp.Version = this.Version
36 changes: 30 additions & 6 deletions src/ValidationPackages/ValidationPackagesConfig.fs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
namespace ARCtrl.ValidationPackages
namespace ARCtrl.ValidationPackages

open ARCtrl.Helper
open Fable.Core

[<AttachMembers>]
type ValidationPackagesConfig(validation_packages, ?arc_specification) =

let mutable _validation_packages : ResizeArray<ValidationPackage> = validation_packages
let mutable _arc_specification : string option = arc_specification
let mutable _validation_packages : ResizeArray<ValidationPackage> = validation_packages

member this.ValidationPackages
with get() = _validation_packages
@@ -22,15 +22,39 @@ type ValidationPackagesConfig(validation_packages, ?arc_specification) =
member this.Copy() =
ValidationPackagesConfig.make this.ValidationPackages this.ARCSpecification

override this.Equals(obj) =
match obj with
| :? ValidationPackagesConfig as other_vpc -> other_vpc.ValidationPackages = this.ValidationPackages && other_vpc.ARCSpecification = this.ARCSpecification

/// Pretty printer
override this.ToString() =
[
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as ValidationPackage.ToString()

"{"
if this.ARCSpecification.IsSome then $" ARCSpecification = {this.ARCSpecification.Value}"
" ValidationPackages = ["
this.ValidationPackages
|> Seq.map (fun vp -> vp.ToString())
|> String.concat $";{System.Environment.NewLine}"
"]"
"}"
]
|> String.concat System.Environment.NewLine

member this.StructurallyEquals (other: ValidationPackagesConfig) =
let sort = Array.ofSeq >> Array.sortBy (fun (vp: ValidationPackage) -> vp.Name, vp.Version)
let specs = this.ARCSpecification = other.ARCSpecification
Freymaurer marked this conversation as resolved.
Show resolved Hide resolved
let packages = Seq.compare (sort this.ValidationPackages) (sort other.ValidationPackages)
specs && packages

member this.ReferenceEquals (other: ValidationPackagesConfig) = System.Object.ReferenceEquals(this,other)

override this.Equals other =
match other with
| :? ValidationPackagesConfig as other_vp ->
this.StructurallyEquals(other_vp)
| _ -> false

override this.GetHashCode() =
[|
this.ValidationPackages.GetHashCode() |> box
HashCodes.boxHashOption this.ARCSpecification
this.ValidationPackages |> HashCodes.boxHashSeq
|]
|> HashCodes.boxHashArray
|> fun x -> x :?> int
28 changes: 1 addition & 27 deletions src/Yaml/Decode.fs
Original file line number Diff line number Diff line change
@@ -1,33 +1,7 @@
namespace Arctrl.Yaml
namespace ARCtrl.Yaml

module Decode =

// yamlicious equivalents for this?

//let helpers =
// #if FABLE_COMPILER_PYTHON
// Thoth.Json.Python.Decode.helpers
// #endif
// #if FABLE_COMPILER_JAVASCRIPT
// Thoth.Json.JavaScript.Decode.helpers
// #endif
// #if !FABLE_COMPILER
// Thoth.Json.Newtonsoft.Decode.helpers
// #endif

//let inline fromJsonString (decoder : Decoder<'a>) (s : string) : 'a =
// #if FABLE_COMPILER_PYTHON
// match Thoth.Json.Python.Decode.fromString decoder s with
// #endif
// #if FABLE_COMPILER_JAVASCRIPT
// match Thoth.Json.JavaScript.Decode.fromString decoder s with
// #endif
// #if !FABLE_COMPILER
// match Thoth.Json.Newtonsoft.Decode.fromString decoder s with
// #endif
// | Ok a -> a
// | Error e -> failwith (sprintf "Error decoding string: %O" e)

open YAMLicious
open YAMLicious.YAMLiciousTypes
open YAMLicious.Reader
2 changes: 1 addition & 1 deletion src/Yaml/Encode.fs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace Arctrl.Yaml
namespace ARCtrl.Yaml

module Encode =

15 changes: 9 additions & 6 deletions src/Yaml/ValidationPackage.fs
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
namespace ARCtrl.Yaml
namespace ARCtrl.Yaml

open ARCtrl.ValidationPackages
open YAMLicious
open YAMLicious.YAMLiciousTypes

module ValidationPackage =

let [<Literal>] NAME_KEY = "name"
let [<Literal>] VERSION_KEY = "version"

let encoder (validationpackage : ValidationPackage) =
[
"name", Encode.string validationpackage.Name
Encode.tryInclude "version" Encode.string (validationpackage.Version)
NAME_KEY, Encode.string validationpackage.Name
Encode.tryInclude VERSION_KEY Encode.string (validationpackage.Version)
]
|> Encode.choose
|> Encode.object

let decoder : (YAMLElement -> ValidationPackage) =
Decode.object (fun get ->
ValidationPackage(
name = get.Required.Field "name" Decode.string,
?version = get.Optional.Field "version" Decode.string
name = get.Required.Field NAME_KEY Decode.string,
?version = get.Optional.Field VERSION_KEY Decode.string
)
)

[<AutoOpen>]
module ValidationPackageExtensions =

open Arctrl.Yaml
open ARCtrl.Yaml
type ValidationPackage with

static member fromYamlString (s:string) =
15 changes: 9 additions & 6 deletions src/Yaml/ValidationPackagesConfig.fs
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
namespace ARCtrl.Yaml
namespace ARCtrl.Yaml

open ARCtrl.ValidationPackages
open YAMLicious
open YAMLicious.YAMLiciousTypes

module ValidationPackagesConfig =

let [<Literal>] ARC_SPECIFICATION_KEY = "arc_specification"
let [<Literal>] VALIDATION_PACKAGES_KEY = "validation_packages"

let encoder (validationpackage : ValidationPackagesConfig) =
[
"validation_packages", Encode.resizearray ValidationPackage.encoder validationpackage.ValidationPackages
Encode.tryInclude "arc_specification" Encode.string (validationpackage.ARCSpecification)
Encode.tryInclude ARC_SPECIFICATION_KEY Encode.string (validationpackage.ARCSpecification)
VALIDATION_PACKAGES_KEY, Encode.resizearray ValidationPackage.encoder validationpackage.ValidationPackages
]
|> Encode.choose
|> Encode.object

let decoder : (YAMLElement -> ValidationPackagesConfig) =
Decode.object (fun get ->
ValidationPackagesConfig(
validation_packages = get.Required.Field "validation_packages" (Decode.resizearray ValidationPackage.decoder),
?arc_specification = get.Optional.Field "arc_specification" Decode.string
validation_packages = get.Required.Field VALIDATION_PACKAGES_KEY (Decode.resizearray ValidationPackage.decoder),
?arc_specification = get.Optional.Field ARC_SPECIFICATION_KEY Decode.string
)
)

[<AutoOpen>]
module ValidationPackageConfigExtensions =

open Arctrl.Yaml
open ARCtrl.Yaml
type ValidationPackagesConfig with

static member fromYamlString (s:string) =
1 change: 1 addition & 0 deletions tests/ARCtrl/ARCtrl.Tests.fsproj
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
<Compile Include="WebRequest.Tests.fs" />
<Compile Include="ARCtrl.Contracts.Tests.fs" />
<Compile Include="ARCtrl.Tests.fs" />
<Compile Include="ValidationPackagesConfig.Tests.fs" />
<Compile Include="Main.fs" />
</ItemGroup>
<ItemGroup>
Loading
Loading