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

Fable compatability #23

Merged
merged 20 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
"commands": [
"fsdocs"
]
},
"fable": {
"version": "4.19.3",
"commands": [
"fable"
]
}
}
}
70 changes: 50 additions & 20 deletions .github/workflows/build-and-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,64 @@ on:
pull_request:
branches: [ main ]


jobs:
build-and-test-linux:
test:

strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]

runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3

# SETUP .NET
- name: Setup .NET
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v3
with:
dotnet-version: 6.x.x
- name: make script executable
run: chmod u+x build.sh
- name: Build and test
working-directory: ./
run: ./build.sh runtests
- name: Restore fable
run: dotnet tool restore

build-and-test-windows:

runs-on: windows-latest
# SETUP NODE
- name: Setup Node.js environment
uses: actions/setup-node@v3
with:
node-version: 16
- name: install node modules
working-directory: ./
run: npm install --ignore-scripts

steps:
- uses: actions/checkout@v2
- name: Setup .NET
uses: actions/setup-dotnet@v1
# SETUP PYTHON
- name: Setup Python
uses: actions/setup-python@v5
with:
dotnet-version: 6.x.x
- name: Build and test
python-version: '3.12'
- name: Setup Virtual Environment
run: python -m venv .venv
- name: Setup Poetry Windows
if: matrix.os == 'windows-latest'
run: |
.\.venv\Scripts\python.exe -m pip install -U pip setuptools
.\.venv\Scripts\python.exe -m pip install poetry
.\.venv\Scripts\python.exe -m poetry install --no-root
- name: Setup Poetry Unix
if: matrix.os == 'ubuntu-latest'
run: |
./.venv/bin/python -m pip install -U pip setuptools
./.venv/bin/python -m pip install poetry
./.venv/bin/python -m poetry install --no-root

# BUILD
- name: make script executable
if: matrix.os == 'ubuntu-latest'
run: chmod u+x build.sh
- name: Test (Unix)
if: matrix.os == 'ubuntu-latest'
working-directory: ./
run: ./build.cmd runtests
run: ./build.sh runtests
- name: Test (Windows)
if: matrix.os == 'windows-latest'
run: .\build.cmd runtests
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,7 @@ docsrc/tools/FSharp.Formatting.svclog
/tests/FSharp.Stats.Tests/coverage.xml

.ionide
pkg
pkg
/tests/**/js
/tests/**/py
/.venv
33 changes: 24 additions & 9 deletions DynamicObj.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ VisualStudioVersion = 17.0.31521.260
MinimumVisualStudioVersion = 10.0.40219.1
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "DynamicObj", "src\DynamicObj\DynamicObj.fsproj", "{B8BF1554-AAC3-434E-9502-FC83B43F3704}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "UnitTests", "tests\UnitTests\UnitTests.fsproj", "{D009964D-9408-4344-B610-B73F54FE2A86}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{39AA72A1-A628-481B-A2B5-94E2BD163061}"
ProjectSection(SolutionItems) = preProject
build.cmd = build.cmd
Expand All @@ -26,17 +24,19 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".proj", ".proj", "{C3CF2F15
global.json = global.json
key.snk = key.snk
LICENSE = LICENSE
package.json = package.json
pyproject.toml = pyproject.toml
README.md = README.md
RELEASE_NOTES.md = RELEASE_NOTES.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{42AA66FC-8928-4029-BF41-52C1B49DEEDF}"
ProjectSection(SolutionItems) = preProject
docs\content\fsdocs-custom.css = docs\content\fsdocs-custom.css
docs\index.fsx = docs\index.fsx
docs\_template.fsx = docs\_template.fsx
docs\_template.html = docs\_template.html
docs\_template.ipynb = docs\_template.ipynb
docs\content\fsdocs-custom.css = docs\content\fsdocs-custom.css
docs\index.fsx = docs\index.fsx
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSharpTests", "tests\CSharpTests\CSharpTests.csproj", "{D62D0901-DB69-4C64-AC63-FBBBDCF6BC7D}"
Expand All @@ -45,6 +45,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{988D804A
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "build", "build\build.fsproj", "{C73AB951-91F2-4668-B2E0-B58298E5F664}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "DynamicObj.Immutable", "src\DynamicObj.Immutable\DynamicObj.Immutable.fsproj", "{5E7DAC28-7752-4209-B3BB-6DCE54C28AD8}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "DynamicObject.Tests", "tests\DynamicObject.Tests\DynamicObject.Tests.fsproj", "{39192F2D-164B-4905-A7D7-5C5B0FFCD2BB}"
EndProject
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "DynamicObject.Immutable.Tests", "tests\DynamicObject.Immutable.Tests\DynamicObject.Immutable.Tests.fsproj", "{0F6A539F-82D2-4BDC-8BF0-F2D261873B92}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -55,10 +61,6 @@ Global
{B8BF1554-AAC3-434E-9502-FC83B43F3704}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B8BF1554-AAC3-434E-9502-FC83B43F3704}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B8BF1554-AAC3-434E-9502-FC83B43F3704}.Release|Any CPU.Build.0 = Release|Any CPU
{D009964D-9408-4344-B610-B73F54FE2A86}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D009964D-9408-4344-B610-B73F54FE2A86}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D009964D-9408-4344-B610-B73F54FE2A86}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D009964D-9408-4344-B610-B73F54FE2A86}.Release|Any CPU.Build.0 = Release|Any CPU
{D62D0901-DB69-4C64-AC63-FBBBDCF6BC7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D62D0901-DB69-4C64-AC63-FBBBDCF6BC7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D62D0901-DB69-4C64-AC63-FBBBDCF6BC7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -67,14 +69,27 @@ Global
{C73AB951-91F2-4668-B2E0-B58298E5F664}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C73AB951-91F2-4668-B2E0-B58298E5F664}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C73AB951-91F2-4668-B2E0-B58298E5F664}.Release|Any CPU.Build.0 = Release|Any CPU
{5E7DAC28-7752-4209-B3BB-6DCE54C28AD8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E7DAC28-7752-4209-B3BB-6DCE54C28AD8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E7DAC28-7752-4209-B3BB-6DCE54C28AD8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E7DAC28-7752-4209-B3BB-6DCE54C28AD8}.Release|Any CPU.Build.0 = Release|Any CPU
{39192F2D-164B-4905-A7D7-5C5B0FFCD2BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{39192F2D-164B-4905-A7D7-5C5B0FFCD2BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39192F2D-164B-4905-A7D7-5C5B0FFCD2BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39192F2D-164B-4905-A7D7-5C5B0FFCD2BB}.Release|Any CPU.Build.0 = Release|Any CPU
{0F6A539F-82D2-4BDC-8BF0-F2D261873B92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0F6A539F-82D2-4BDC-8BF0-F2D261873B92}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0F6A539F-82D2-4BDC-8BF0-F2D261873B92}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0F6A539F-82D2-4BDC-8BF0-F2D261873B92}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{D009964D-9408-4344-B610-B73F54FE2A86} = {988D804A-3A42-4E46-B233-B64F5C22524B}
{D62D0901-DB69-4C64-AC63-FBBBDCF6BC7D} = {988D804A-3A42-4E46-B233-B64F5C22524B}
{C73AB951-91F2-4668-B2E0-B58298E5F664} = {39AA72A1-A628-481B-A2B5-94E2BD163061}
{39192F2D-164B-4905-A7D7-5C5B0FFCD2BB} = {988D804A-3A42-4E46-B233-B64F5C22524B}
{0F6A539F-82D2-4BDC-8BF0-F2D261873B92} = {988D804A-3A42-4E46-B233-B64F5C22524B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6F5C3597-4524-4A4E-94EC-44857BD0BCEC}
Expand Down
111 changes: 110 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,112 @@
# DynamicObj
F# library supporting Dynamic Objects including inheritance in functional style.
It builds on ´System.Dynamic´ but adds object inheritance.

The library is compatible with [Fable](https://github.com/fable-compiler/Fable), allowing transpilation to `javascript` and `python`.



## Usage example

### Get started

```fsharp
#r "nuget: DynamicObj"
#r "nuget: Fable.Core" // Needed if working with Fable

open DynamicObj
open Fable.Core // Needed if working with Fable

[<AttachMembers>] // AttachMembers needed if working with Fable
type Person(id : int, name : string) =

// Include this in your class
inherit DynamicObj()

let mutable name = name

// Mutable property
member this.Name
with get() = name
and set(value) = name <- value

// Immutable property
member this.ID
with get() = id

let p = Person(1337,"John")
```

### Accessing static and dynamic properties

```fsharp

// Access Static Properties
p.GetValue("Name") // val it: obj = "John"
p.GetValue("ID") // val it: obj = 1337


// Overwrite mutable static property
p.SetValue("Name","Jane") // val it: unit = ()
// Overwrite immutable static property
p.SetValue("ID",1234) // System.Exception: Cannot set value for static, immutable property "ID"
// Set dynamic property
p.SetValue("Address","FunStreet") // val it: unit = ()


// Access Properties
p.GetValue("Name") // val it: obj = "Jane"
p.Name // val it: string = "Jane"
p.GetValue("ID") // val it: obj = 1337
p.ID // val it: int = 1337
p.GetValue("Address") // val it: obj = "FunStreet"
```

### Practical helpers

```fsharp
DynObj.format p
|> printfn "%s"
```
->
```
Name: Jane
ID: 1337
?Address: FunStreet
```

## Development

#### Requirements

- [nodejs and npm](https://nodejs.org/en/download)
- verify with `node --version` (Tested with v18.16.1)
- verify with `npm --version` (Tested with v9.2.0)
- [.NET SDK](https://dotnet.microsoft.com/en-us/download)
- verify with `dotnet --version` (Tested with 7.0.306)
- [Python](https://www.python.org/downloads/)
- verify with `py --version` (Tested with 3.12.2, known to work only for >=3.11)

#### Local Setup

On windows you can use the `setup.cmd` to run the following steps automatically!

1. Setup dotnet tools

`dotnet tool restore`


2. Install NPM dependencies

`npm install`

3. Setup python environment

`py -m venv .venv`

4. Install [Poetry](https://python-poetry.org/) and dependencies

1. `.\.venv\Scripts\python.exe -m pip install -U pip setuptools`
2. `.\.venv\Scripts\python.exe -m pip install poetry`
3. `.\.venv\Scripts\python.exe -m poetry install --no-root`

Verify correct setup with `./build.cmd runtests` ✨
Loading
Loading