Here are some miscellaneous contribution guides.

## Using Esy in Development (Experimental)

You can use [esy](https://esy.sh) to develop bucklescript. By default esy will do "out of source builds" which means that all the changes will happen outside the current directory. To be able to bspack the needed files and get sources that you can commit you will have to change the following in the `esy.json`.

```diff
-"buildsInSource": true,
+"buildsInSource": "unsafe",
```

When that is changed you just run the following command it will build everything you need.

    esy

By default we depend on the 4.02.3+BS OCaml compiler. To be able to build with the 4.06.1+BS compiler we have a `4061.json` file that just extends the `esy.json` and overrides the OCaml dependency. To use this file instead you simply run this command instead.

    esy @4061

If there are problems building try to run one of the following depending on what you're building

```
esy clean
esy @4061 clean
```

## Upgrading the Reason version within BuckleScript

Each BuckleScript release is coupled to a specific Reason syntax version, which currently needs to be updated manually once in a while.

It's important that we need to update two specific files:

- `jscomp/main/refmt_api.ml`: Contains the programmatic interface for the refmt syntax converter (responsible for transforming Reason string code to an OCaml AST) -> Only used in the BuckleScript JS Playground
- `lib/4.06.1/refmt_main3.ml`: The refmt binary used within BuckleScript itself. The `3` corresponds to the corresponding major version of refmt -> Used to build the vendored `refmt`, aka. `bsrefmt`

Both files are generated by using the `jscomp/bin/bspack.exe` binary (which is also built automatically when you build the compiler inside this repository) on the refmt parser. In more detail, `bspack.exe` resolves all dependencies of one specific `.ml` input file, puts them in the right order and copies all the source code with the target input file in one huge `.ml` bundle.

So the two files mentioned above, `refmt_api.ml` and `refmt_main3.ml`, are bspacked within the Reason repository and then checked into the BuckleScript repository (we call this `vendoring` or `snapshotting`).
Here are the instructions on building your own Reason snapshots (make sure you to have everything set up for building the playground bundle first, as mentioned above):

```
# Let's go up one level and clone Reason in a sibling directory next to your `bucklescript` repo
cd ..
git clone https://github.com/facebook/reason

cd reason

# You should already have created this switch by now, see playground build setup instructions in "Contributing to the BS Playground Bundle"
opam switch 4.06.1
opam pin add -y reason .
opam pin add -y rtop .

# Let's do the bspacking process for refmt_api.ml and refmt_binary.ml
cd bspacks

# Initial setup of certain dependencies before we can bspack everthing in one file
./downloadSomeDependencies.sh

# bspack and compile the files
BSPACK_EXE=/path/to/bucklescript/jscomp/bin/bspack.exe ./reason_bspack406.sh
```

Now copy the files to bucklescript and do a rebuild to verify the changes:

```
# still in reason/bspacks directory
cp build/refmt_api.ml ../../bucklescript/jscomp/main/refmt_api.ml
cp build/refmt_binary.ml ../../bucklescript/lib/4.06.1/refmt_main3.ml

# Build the whole compiler
node scripts/ninja.js config && node scripts/ninja.js build

# Build the playground
BS_PLAYGROUND=../playground node scripts/repl.js
```

You should now have the newest `refmt` binary for the actual compiler, and for the playground, a new `playground/exports.js` file with the new Reason version included.

**Important:** Always verify that the updated Reason version is in sync in the
`refmt.exe` and the playground bundle. Use `lib/bsrefmt --version` and for the
playground API `window.reason.version` (not final) to get the bundled
version.
