Skip to content

Commit

Permalink
Merge pull request #94 from reasonml-labs/murphy/upgrade-to-rescript-11
Browse files Browse the repository at this point in the history
Upgrade to Rescript 11
  • Loading branch information
mrmurphy authored Apr 26, 2024
2 parents a207115 + 52dbfdf commit e76b729
Show file tree
Hide file tree
Showing 131 changed files with 3,982 additions and 8,310 deletions.
29 changes: 18 additions & 11 deletions .github/workflows/ppx-pr.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,21 @@ jobs:
name: PR Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Esy
run: yarn global add esy
- name: Install Dependencies
run: yarn
- name: Build PPX
run: yarn build-ppx
- name: Build Library
run: yarn build-lib
- name: Run tests
run: yarn test
- uses: actions/checkout@v2
- name: Install OPAM and OCaml
uses: avsm/setup-ocaml@v1
with:
ocaml-version: 4.12.1 # replace with your desired version
- name: Install OCaml Dependencies and build
run: |
cd ppx_src
opam install dune
eval $(opam env)
opam install -y . --deps-only
dune build
- name: Install Yarn Dependencies
run: yarn
- name: Build Library
run: yarn build-lib
- name: Run tests
run: yarn test
15 changes: 11 additions & 4 deletions .github/workflows/ppx-push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,17 @@ jobs:
- uses: actions/checkout@v2
with:
ref: ${{ github.ref }}
- name: Install esy
run: yarn global add esy
- name: Run Build
run: yarn build-ppx
- name: Install OPAM and OCaml
uses: avsm/setup-ocaml@v1
with:
ocaml-version: 4.12.1 # replace with your desired version
- name: Install OCaml Dependencies and build
run: |
cd ppx_src
opam install dune
eval $(opam env)
opam install -y . --deps-only
dune build
- name: Upload Build Mac / Linux
if: ${{ matrix.os != 'windows-latest' }}
uses: actions/upload-artifact@v2
Expand Down
4 changes: 1 addition & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ _build/
setup.data
setup.log



#Node
# Logs
logs
Expand Down Expand Up @@ -76,5 +74,5 @@ package-links.json
# dune
*.install

_esy/
_opam
*.exe
6 changes: 3 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"ocaml.sandbox": {
"kind": "esy",
"root": "${workspaceFolder:decco}"
"kind": "opam",
"switch": "${workspaceFolder:decco}"
}
}
}
33 changes: 22 additions & 11 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ When contributing to this repository, please first discuss the change you wish t
- git clone https://github.com/reasonml-labs/decco
- cd decco
- yarn install
- See the steps below to get ocaml set up
- yarn build-ppx
- # Make your changes, commits, etc
- Open the PR
Expand All @@ -30,23 +31,33 @@ In order to see what are the scripts available on the repository, run `yarn run`
You would need to have [opam](https://opam.ocaml.org) installed.

- cd ppx_src;
- opam switch create . 4.06.0 --deps-only # If it's the first time you create a switch from 4.06, it can take a while.
- opam switch create . 4.12.1 --deps-only # If it's the first time you create a switch it can take a while.
- eval $(opam env)
- opam install -y ocaml-lsp-server dune ocaml ppx_tools_versioned reason # Install ppx's dependencies inside the switch
- opam install -y . --deps-only
- Profit, this should make your editor a little more smart

### Testing

Unit testing is done in BuckleScript and bs-jest, lives under `test/__tests__`.
Unit testing is done in ReScript and rescript-jest, lives under `test/__tests__`.

A trick to see the output of the ppx is running bsc directly on the terminal:
## Iterating

```
npx bsc -bs-package-name decco -bs-package-output commonjs:lib/js/test/__tests__ -I test/__tests__ -I test -I src -I ./node_modules/@glennsl/bs-jest/lib/ocaml -ppx ./ppx -w +A-9-40-42 -dsource -bs-super-errors FILE_I_WANT_TO_COMPILE
```
Working on PPXs can be a real pain because you don't get to easily see the product of your work. There are some tools to help though.

For example:
### Preview PPX

```
npx bsc -bs-package-name decco -bs-package-output commonjs:lib/js/test/__tests__ -I test/__tests__ -I test -I src -I ./node_modules/@glennsl/bs-jest/lib/ocaml -ppx ./ppx -w +A-9-40-42 -dsource -bs-super-errors test/__tests__/test.re
```
See the output of your PPX as ReScript code by running `yarn run preview-ppx <file name>`

**Gotcha**: This PPX'd output isn't ReScript syntax generated by the PPX. The PPX runs on the AST, which is OCaml. What you see here is the result of the transformed AST rendered back into ReScript by the compiler's formatting tool

If you want to see what's really going on under the hood, read more:

### Inspect the Parsetree (AST)

See a text representation of the tree you're really operating on, and the real results of your PPX by running `yarn run print-parse-tree-with-ppx`

You'll probably get compiler errors, because that's calling a private API of bsc that isn't including dependencies. But your goal here is really just to inspect the tree.

## Figure out what to write

I suggest that when you're trying to get something written, you write the ReScript syntax for what you're trying to achieve, inspect its AST using the command above, and then use the same command on your PPX to see what you're actually getting.
90 changes: 50 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,39 @@

## Project Status

Decco is not being actively maintained, but PRs will be accepted and appreciated.
Decco is lazily maintained by it users, but it's not being actively developed, since its feature set is complete enough for general production use. If you find a major bug that you need fixed, it'll probably be your job to fix it. 💪

## What is it?

A Bucklescript PPX which generates JSON serializers and deserializers for user-defined types.
A Rescript PPX which generates JSON serializers and deserializers for user-defined types.

Example:

```reason
```rescript
/* Define types */
[@decco] type variant('a) = A | B(int) | C(int, 'a);
@decco type variant<'a> = A | B(int) | C(int, 'a);
/*
* Rescript@9+ users do not use [brackets] for the ppx:
* @decco type variant('a) = A | B(int) | C(int, 'a)
*/
type dict = Js.Dict.t(string);
[@decco] type mytype = {
type dict = Js.Dict.t<string>;
@decco
type mytype = {
s: string,
i: int,
o: option(int),
complex: array(option(list(variant(string)))),
[@decco.default 1.0] f: float,
[@decco.key "other_key"] otherKey: string,
magic: [@decco.codec Decco.Codecs.magic] dict,
o: option<int>,
complex: array<option<list<variant<string>>>>,
@decco.default(1.0) f: float,
@decco.key("other_key") otherKey: string,
magic: @decco.codec(Decco.Codecs.magic) dict,
};
/* Use <typename>_encode to encode */
let encoded = mytype_encode({
s: "hello",
i: 12,
o: None,
complex: [| Some([ C(25, "bullseye") ]) |],
complex: [Some(list{ C(25, "bullseye") })],
f: 13.,
otherKey: "other",
magic: Js.Dict.fromArray([|("key","value")|]),
magic: Js.Dict.fromArray([("key","value")]),
});
Js.log(Js.Json.stringifyWithSpace(encoded, 2));
Expand All @@ -54,17 +50,19 @@ Js.log(Js.Json.stringifyWithSpace(encoded, 2));
/* Use <typename>_decode to decode */
let { s, i, o, complex, f, otherKey, magic } =
mytype_decode(encoded)
|> Belt.Result.getExn;
mytype_decode(encoded)->Belt.Result.getExn;
```

## How do I install it?

1. Install package

```
npm i decco
```

2. Update your `bsconfig.json`
2. Update your `rescript.json` (or bsconfig.json if you haven't changed its name)

```json
{
...,
Expand All @@ -76,62 +74,74 @@ npm i decco

Adding `decco/ppx` to `ppx-flags` will enable the PPX. Adding decco to `bs-dependencies` is required because the code generated by the PPX references the `Decco` module.

**Note:** If you need to use decco with BuckleScript 5, install `@ryb73/decco` version ^0.1.0 by [following the old ReadMe here](https://github.com/reasonml-labs/decco/blob/0452fc42fa4cd4230d394c718e7f62a0384ce045/README.md).
## Compatibility

Decco 2.0.0 and above work with ReScript 11 in uncurried mode. If you need to use Decco with an older version of ReScript, install decco version `1.6.0`

If you need to use decco with BuckleScript 5, install `@ryb73/decco` version ^0.1.0 by [following the old ReadMe here](https://github.com/reasonml-labs/decco/blob/0452fc42fa4cd4230d394c718e7f62a0384ce045/README.md).

## How do I use it?

See [`test.re`](test/__tests__/test.re) for some examples.
See the test folder in this repo for some examples.

## Reference

### Attributes
#### [@decco]

#### @decco

Applies to: type declarations, type signatures

Indicates that an encoder and decoder should be generated for the given type.

#### [@decco.encode]
#### @decco.encode

Applies to: type declarations, type signatures

Indicates than an encoder (but no decoder) should be generated for the given type.

#### [@decco.decode]
#### @decco.decode

Applies to: type declarations, type signatures

Indicates than an decoder (but no encoder) should be generated for the given type.

#### [@decco.codec]
#### @decco.codec

Applies to: type expressions

Specifies custom encoders and decoders for the type. Note that both an encoder and decoder must be specified, even if the type expression is within a type for which [@decco.encode] or [@decco.decode] was specified.
Specifies custom encoders and decoders for the type. Note that both an encoder and decoder must be specified, even if the type expression is within a type for which @decco.encode or @decco.decode was specified.

```reason
[@decco] type t = [@decco.codec (fancyEncoder, fancyDecoder)] fancyType;
```rescript
@decco type t = @decco.codec((fancyEncoder, fancyDecoder)) fancyType;
```

#### [@decco.key]
#### @decco.key

Applies to: record fields

By default, Reason record fields map to JS object fields of the same name. Use [@decco.key] to specify a custom JS field name. Useful if the JS field name is invalid as a Reason record field name.
By default, ReScript record fields map to JS object fields of the same name. Use @decco.key to specify a custom JS field name. Useful if the JS field name is invalid as a ReScript record field name.

```reason
[@decco]
```rescript
@decco
type record = {
[@decco.key "other_key"] otherKey: string,
@decco.key("other_key") otherKey: string,
};
```

#### [@decco.default]
#### @decco.default

Applies to: record fields
Default: `Js.Json.null`

When decoding a record, the default value will be used for keys that are missing from the JSON object being decoded.

```reason
[@decco] type record = {
[@decco.default "def"] s: string,
```rescript
@decco type record = {
@decco.default("def") s: string,
};
let {s} = Js.Json.parseExn("{}") |> record_decode |> Belt.Result.getExn;
let {s} = Js.Json.parseExn("{}")->record_decode->Belt.Result.getExn;
Js.log(s); /* def */
```

Expand Down
16 changes: 16 additions & 0 deletions bin/preview-ppx-watch.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

file_path=$1

if [ -z "$file_path" ]; then
echo "Please provide a file path as an argument to see what the PPX will do to it."
exit 1
fi

if ! command -v watch &>/dev/null; then
echo "watch command not found. Please install it using Homebrew:"
echo "brew install watch"
exit 1
fi

/opt/homebrew/bin/watch -n 1 -c -d "./node_modules/rescript/bsc -ppx ./ppx -bs-no-builtin-ppx -reprint-source $file_path"
10 changes: 10 additions & 0 deletions bin/preview-ppx.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

file_path=$1

if [ -z "$file_path" ]; then
echo "Please provide a file path as an argument to see what the PPX will do to it."
exit 1
fi

./node_modules/rescript/bsc -ppx ./ppx -bs-no-builtin-ppx -reprint-source $file_path
23 changes: 0 additions & 23 deletions bsconfig.json

This file was deleted.

Loading

0 comments on commit e76b729

Please sign in to comment.