Git Product home page Git Product logo

myriad's People

Contributors

7sharp9 avatar alexeyraga avatar auduchinok avatar baronfel avatar brettrowberry avatar enricosada avatar fornever avatar jaggerjo avatar krzysztof-cieslak avatar lucasteles avatar matthewcrews avatar mlaily avatar nickdarvey avatar nicoviii avatar smaug123 avatar smoothdeveloper avatar theangrybyrd avatar thecentury avatar zaymonfc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

myriad's Issues

RFC 001 - Design Proposal for plugin config

I propose that myriad adds a configuration system where the Generator attribute takes either a location of a myriad-config.toml file or in-line configuration. Either way the key/value pairs will be passed to the plugin along with the input AST.

This will mean that the current namespace parameter will move to the configuration, no changes will have to be made to the CLI tool apart from depreciating the namespace parameter. This will simply the fsproj changes needed and add flexibility to the plugins to define their own key value pairs

Question about packaging of Myriad dlls

When a user installs a Myriad plugin, my understanding is that they need to have "Myriad.Core.dll" and "Myriad.Sdk.dll" installed into their project for the plugin to work (please correct me if I am wrong).

I'm wondering if it is possible to pull down those dependencies as "dev" dependencies only so that they are not included in the release. I think this is possible with Paket, but not with regular NuGet. (Maybe this isn't so much of a Myriad question, but I thought I'd ask anyway).

Inaccuracy in README.md

Hi. Maybe is there an error in the code?

instead of
csharp create (one : Test1) (two : string) (three : float) (four : float32) : Test1
should be
csharp create (one : int) (two : string) (three : float) (four : float32) : Test1

Allow control of Lens generator style to match Aether style

Currently, myriad produces lens setter with signature 'b -> 'a -> 'b. Aether provides a bunch of utilities for working with Lenses, but does not actually create the Lenses. It assumes setters have the signature 'a -> 'b -> 'b.
I would be nice if I could use myriad to generate Lenses which can be used by Aether.
Maybe an additional attribute to indicate the lens style?

Current version not on nuget

This is not an issue with Myriad itself but with its deployment.

As far as I can see the Changelog was not updated and therefore the automatic release tried to release the 0.3.1 (tag) as 0.2.8 (changelog) which already existed and was therefore not accepted by nuget.

It would be cool if someone could fix that and release the current version also on nuget.

Update the NuGet package

Hi @7sharp9!

Could you please update the NuGet package so that it now targets the netstandard2.0?
This would allow me to use the myriad in my .net48 project.

Would it be possible to make Myriad a dotnet tool?

I recently thought about this, because with Myriad I'm adding some dependencies to my projects which I don't really need for runtime, only for buildtime. This is something a "dotnet tool" is there for in my mind. E.g. in most of my projects I have "paket" as a development dependency but not runtime dependency and it is a dotnet tool too.

Do you think it would be possible to make myriad a dotnet tool too? Are there reasons to avoid doing that? What do you think?

Plugin naming convention

I'm assuming you don't want to have every plugin written for Myriad under this repository. What naming convention do you think Myriad should recommend to naming of packages? Something like {{OwnerNamespace}}.Myriad.Plugin.{{PluginName}}? This would give people the ability to search for these relatively quickly on nuget but it would be (somewhat) clear it's not coming from Myriad directly.

Namespace repeating in Generated.fs

The Generated.fs file seems to create a namespace for each plugin, even if the plugin has not run.

//------------------------------------------------------------------------------
//        This code was generated by myriad.
//        Changes to this file will be lost when the code is regenerated.
//------------------------------------------------------------------------------
namespace rec DataSchema


namespace rec DataSchema


namespace rec DataSchema

{{ My generated code }}

Is this intentional?

Support for generic types

Using Myriad I noticed that when the records have a generic type parameter the generated code does not include the type parameter, so it fails to compile.

Input code:

[<Generator.Fields "fields">]
[<Generator.Lenses("lenses")>]
type InputType<'T> = {
    Field1: int
    Field2: 'T
}

Generated:

module InputTypeLenses =
    open Myr
    let Field1 =
        (fun (x: InputType) -> x.Field1), (fun (x: InputType) (value: int) -> { x with Field1 = value })

    let Field2 =
        (fun (x: InputType) -> x.Field2), (fun (x: InputType) (value: 'T) -> { x with Field2 = value })

module InputType =
    open Myr
    let Field1 (x: InputType) = x.Field1
    let Field2 (x: InputType) = x.Field2
    let create (field1: int) (field2: 'T): InputType = { Field1 = field1; Field2 = field2 }
    let map (mapField1: int -> int) (mapField2: 'T -> 'T) (record': InputType) =
        { record' with
              Field1 = mapField1 record'.Field1
              Field2 = mapField2 record'.Field2 }

Am I missing something or is this feature missing?

Myriad.Plugin.Template

Discussed in https://github.com/MoiraeSoftware/myriad/discussions/117

Originally posted by JordanMarr August 27, 2021
I think that one of the biggest hurdles to Myriad development is just getting started.

A dotnet template could go a long way in making it super easy for interested developers to start tinkering immediately without having to get their projects wired up properly. Ideally, it would provide a project for their plugin with a really basic plugin implementation that they can modify, and a test project that allows them to tinker with it out of the box without having to wire anything up.

Something like this:

dotnet new -i Myriad.Plugin.Template
dotnet new Myriad -o Templatron.Plugin

Creates:

  • Templatron.sln
  • Templatron.Plugin.fsproj
  • Templatron.Plugin.Tests.fsproj

Even better if the plugin project is already NuGet ready.

Plugin loading third party dependencies

When trying to load information from a third party dependency in a plugin, I'm getting the error:

EXEC : error : inputfile Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed doesn not exist

How do you think we should go about finding the place to load these 3rd party dependencies?

Plugin activation

I think that the way I am activating my "ssdt" Myriad plugin for SqlHydra is a little different from your examples.
For example, you usually activate your plugin by marking an F# object with an attribute (i.e. [<Generator.DuCases>]).

But in the case of SqlHydra "ssdt" plugin, my source <MyriadFile> is a .dacpac file.
So far this has worked fine because I only have one plugin in SqlHydra.dll.
The issue is that, currently, my plugin will only work if it is the only plugin.

Last night I had some problems when I started creating a second plugin.
For starters, the new plugin doesn't even require an input file at all. Really just needs to get some stuff out of the .toml config and then run on build. But there is no workflow currently to handle this kind of plugin since the <MyriadFile> usually points an fs file containing an attribute that will activate a named plugin. In my scenario, I had two plugins, one that points to a .dacpac file, and another that doesn't need an input file at all, and Myriad seemed to be just using the first plugin it could find.
(I was able to comment one out which would then allow me to use the other).

So I'm thinking that perhaps both my plugin workflows could be accommodated with an additions to the MSBuild configuration.

Plugin Activation: non-fsharp MyriadFile

This style of plugin relies on a non-fsharp file (i.e. dacpac), and so it needs a way to specify the name of the plugin to run from the MSBuild config. Maybe something like this:

    <ItemGroup>
         <!-- Specify the .fs output file (to be generated by Myriad) -->
        <Compile Include="AdventureWorks.fs">
            <!-- Specify the .dacpac input  file -->
            <MyriadFile>../AdventureWorks/bin/Debug/AdventureWorks.dacpac</MyriadFile>
            <MyriadPlugin>ssdt<MyriadPlugin>
        </Compile>
    </ItemGroup>

Plugin Activation: no MyriadFile

This style of plugin can get all the input information it needs via a toml config section; it does not need an input MyriadFile at all.
Maybe this case would just need:

    <ItemGroup>
         <!-- Specify the .fs output file (to be generated by Myriad) -->
        <Compile Include="Generated.fs">
            <!-- No input file needed - just specify the plugin only -->
            <MyriadPlugin>newplugin<MyriadPlugin>
        </Compile>
    </ItemGroup>

Lens generator: implement prisms for multi case discriminated unions

The way Aether deals with this is to assume the following optics are defined

type MyUnion =
    | First of int
    | Second of string

    (* Prism<MyUnion,int> *)
    static member First_ =
        (fun m ->
            match m with 
            | First i -> Some i
            | _ -> None),
        (fun i m ->
            match m with
            | First _ -> First i
            | m -> m)

If Myriad could generate these automatically for me, along with #103, then I think it completes support for Aether.

Removing redundant parens Lenses attribute generates incorrect code

When removing the extra parens in the attribute:

[<Generator.Lenses ("lens")>]
type RecordWithEmptyWrapperName =
{ one_empty_wrapper_name: int }

The following code is produced:

namespace rec globalmodule LensesGeneratorFailure =
    let (!CompilationError) =
        "Unsupported syntax of specifying the wrapper name for type [RecordWithEmptyWrapperName].
Expr: Const
  (String
     (\"lens\",
      C:\Developer\solutions\myriad\test\Myriad.IntegrationPluginTests\Input.fs (14,19--14,25) IsSynthetic=false),
   C:\Developer\solutions\myriad\test\Myriad.IntegrationPluginTests\Input.fs (14,19--14,25) IsSynthetic=false)"

Have a way to exclude certain plugins from running on certain files (in proj files)

e.g.

    <Compile Include="Generated.fs">
      <MyriadFile>Input.fs</MyriadFile> 
      <MyriadNameSpace>Test</MyriadNameSpace>
      <MyriadExcludePlugins>lenses</MyriadExcludePlugins >
    </Compile>

or maybe:

    <Compile Include="Generated.fs">
      <MyriadFile>myRecords.toml</MyriadFile> 
      <MyriadNameSpace>Test</MyriadNameSpace>
      <MyriadOnlyIncludePlugins>toml</MyriadOnlyIncludePlugins >
    </Compile>
Thoughts?

@baronfel , @Krzysztof-Cieslak , @TheAngryByrd 

The namespace 'Plugins' is not defined (building sample project in repo)

Hi! I'm looking to try out Myriad in a project, and currently the sample project in the repo + instructions on how to use it both produce build errors due to the missing namespace Plugins.

Steps to reproduce

cd myriad
dotnet tool restore
dotnet fake build
cd samples/Example
dotnet build

Expected Behavior

Project builds successfully

Resulting Behavior

C:\Users\dthorpe\code\myriad\samples\Example\Library.fs(4,3): error FS0039: The namespace or module 'Generator' is not defined. [C:\Users\dthorpe\code\myriad\samples\Example\Example.fsproj]

Build FAILED.

C:\Users\dthorpe\code\myriad\samples\Example\Library.fs(2,13): error FS0039: The namespace 'Plugins' is not defined. [C:\Users\dthorpe\code\myriad\samples\Example\Example.fsproj]
C:\Users\dthorpe\code\myriad\samples\Example\Library.fs(4,3): error FS0039: The namespace or module 'Generator' is not defined. [C:\Users\dthorpe\code\myriad\samples\Example\Example.fsproj]
    0 Warning(s)
    2 Error(s)

Latest version does not show call stack for exceptions

I have recently upgraded from 0.2.8 to 0.4.0.

I used to get the full stack trace in the logs on exceptions, now, even with --verbose, I only get the error message.

I also tried to attach the debugger and didn't hit the exception (but that may be an issue with JetBrains Rider, I need to investigate)

Thank you for this library.

How to use this goodness from my project?

I am looking around the repo and I not entirely sure how to use this in my project.

I see that Myriad.Sdk is available as a nuget package which I I can install and add to my project's (.fsproj) file, along with that I give it the input file that contains the type definitions and the path of the output file where the generated code will be located.

However, what confuses me is where do I write the code that converts the input file and generates the output file?

DU with RequireQualifiedAccess attribute not being qualified

When using the DU Generation plugin, the [<RequireQualifiedAccess>] attribute on DUs is not being honored in the outputted code.

Example DU

[<RequireQualifiedAccess; Generator.DuCases "ducases">]
type MyNewDU =
    | A
    | B

Generates the following

module MyNewDU =
    open Test.Domain
    let toString (x: MyNewDU) =
        match x with
        | A -> "A"
        | B -> "B"

    let fromString (x: string) =
        match x with
        | "A" -> Some A
        | "B" -> Some B
        | _ -> None

    let toTag (x: MyNewDU) =
        match x with
        | A -> 0
        | B -> 1

    let isA (x: MyNewDU) =
        match x with
        | A -> true
        | _ -> false

    let isB (x: MyNewDU) =
        match x with
        | B -> true
        | _ -> false

But I believe should generate

module MyNewDU =
    open Test.Domain
    let toString (x: MyNewDU) =
        match x with
        | MyNewDU.A -> "A"
        | MyNewDU.B -> "B"

    let fromString (x: string) =
        match x with
        | "A" -> Some MyNewDU.A
        | "B" -> Some MyNewDU.B
        | _ -> None

    let toTag (x: MyNewDU) =
        match x with
        | MyNewDU.A -> 0
        | MyNewDU.B -> 1

    let isA (x: MyNewDU) =
        match x with
        | MyNewDU.A -> true
        | _ -> false

    let isB (x: MyNewDU) =
        match x with
        | MyNewDU.B -> true
        | _ -> false

Feature: propagate options to the plugin context?

It would awesome to have the ability to get configure options / parameters for the generation, i.e.

<Compile Include="Generated.fs">
     <MyriadOptions>
        <LowerCaseFunctions>true</LowerCaseFunctions>
        <ServerEndpoint>http://localhost:5000</ServerEndpoint>
     </MyriadOptions>
     <MyriadFile>Library.fs</MyriadFile>
     <MyriadNameSpace>Test</MyriadNameSpace>
 </Compile>

There parameters would then be available from the plugin context during code generation, even starting with Map<string, string> would be tremendously helpful.

Workaround

I guess you could specify the options from the MyriadFile and read them from the plugin

Using reflection in plugin causes error

Thank you for this library.

I am successfully generating code using a plugin. As soon as I add

            let t =
                Assembly.GetAssembly(typeof<Pulumi.Azure.Config>)

or a typeof<T> in a plugin file, I get the following error:

ERROR: inputfile Pulumi.Azure, Version=3.11.0.0, Culture=neutral, PublicKeyToken=null doesn not exist

Is there anything I am missing or is it not supported?

EDIT: Same happens using a type provider (E.G. FSharp.Data.JsonProvider)

Thank you

Getting value from Literal/Const

Let's say I have the following code in my Types.fs file.

module A = 
    let [<Literal>] MyConst = "Hello"
    type MyAttribute(thing : string) =
        inherit System.Attribute()
        let _thing = thing
    type Thing = {
        [<MyAttribute(MyConst)>]
        Foo : string
    }

When looking at the AST of this code, the attributes for the field Foo:

{ Attributes =
   [{ TypeName =
                LongIdentWithDots
                  ([MyAttribute],
                   [])
      ArgExpr =
               Paren
                 (Ident MyConst,
                  tmp.fsx (8,25--8,26) IsSynthetic=false,
                  Some
                    tmp.fsx (8,33--8,34) IsSynthetic=false,
                  tmp.fsx (8,25--8,34) IsSynthetic=false)
      Target = None
      AppliesToGetterAndSetter =
                                false
      Range =
             tmp.fsx (8,14--8,25) IsSynthetic=false }]
   Range =
          tmp.fsx (8,12--8,36) IsSynthetic=false }

I get told that the data in the Attribute is MyConst. Do you know if there is a way I'd be able to get the value from that?

Generate multiple files

Is there a way to generate multiple files? If not, can you please consider adding this feature?

In my project I'm using Myriad to generate a bunch of computational expression builders from a JSON containing cloud resources (using Pulumi).

This ends up generating a 120000 lines file. It gets quite ugly for the IDE to process that single file.

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.