Skip to content

Commit 3087b7c

Browse files
committed
Completely reorganize docs
1 parent f43eb43 commit 3087b7c

2 files changed

Lines changed: 139 additions & 111 deletions

File tree

README.md

Lines changed: 138 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
# ReasonProject
22

3-
Reason project environment via `npm`.
3+
Installation of [`Reason`](http://facebook.github.io/reason/) project and
4+
development environments via `npm`.
45

5-
- Local sandboxed `Reason` projects.
6-
- Installation of `Reason` tools globally.
6+
> Requirements: `npm` (currently tested on Mac, Linux, and Windows Linux subsystem).
77
8-
Those two features may sound completely different, but the truth is that they
9-
are very similar, and therefore it makes sense to have `ReasonProject` handle
10-
both.
8+
`ReasonProject` installs the `Reason` toolchain into a local directory using
9+
`npm`. `ReasonProject` can therefore be used as a template for new projects,
10+
but can also be used to install the toolchain [into the global
11+
environment](#reasonproject-editor-support). `ReasonProject` includes: the
12+
compiler toolchain, the source formatter, REPL, and IDE support for popular
13+
editors.
1114

1215
> A sandboxed environment models dependencies and builds them into a local
1316
> directory so that it works reliably for anyone. Installing tools into your
@@ -19,7 +22,7 @@ both.
1922

2023
[![Build Status](https://travis-ci.org/reasonml/ReasonProject.svg?branch=master)](https://travis-ci.org/reasonml/ReasonProject)
2124

22-
## Get Started:
25+
## Install
2326

2427
Install by cloning the repo and running `npm install`. This installs all
2528
dependencies locally into the `ReasonProject` directory.
@@ -30,53 +33,70 @@ cd ReasonProject
3033
npm install
3134
```
3235

36+
## Project Commands
37+
38+
Once built, `ReasonProject` generates an *environment* that you can temporarily
39+
load when executing commands. The environment contains an enhanced `PATH`
40+
containing binaries built by your dependencies, but this environment isn't
41+
loaded into your global path. Some `npm run` commands have been setup to allow
42+
you to run some basic tasks, as well as any custom command, all within the
43+
project environment.
44+
45+
46+
3347
### Run, Change, Rebuild
3448

3549
There are a couple of built in commands declared in `package.json` that you can
3650
execute via `npm run`. For example: `"npm run start"`, `"npm run reasonBuild"`
3751
and `"npm run clean"`. You can also [add your
38-
own](#reasonproject-get-started-add-your-own-scripts) commands.
52+
own](#reasonproject-developing-your-project-add-your-own-scripts) named scripts
53+
which give you a nicer alias like `npm run myScriptName`.
3954

4055

4156
```sh
42-
npm run start # Runs the compiled app
4357
npm run reasonBuild # Rebuilds after changing
58+
npm run start # Runs the compiled app
4459
npm run clean # Clean if you need to!
4560
```
4661

62+
A single test file `./src/Test.re` is included. Make a simple change to it and
63+
then run the commands above to see it effect the output.
64+
4765

4866
### REPL
4967

50-
The `rtop` REPL is built into the sandbox, and the command `npm run top` which
51-
starts the REPL is predefined in `package.json`.
68+
The `rtop` REPL is built into the sandbox. The command `npm run top` starts the
69+
REPL.
5270

5371
```sh
5472
# Opens `rtop` from the sandbox.
5573
npm run top
5674
```
5775

58-
### Environment Commands
5976

60-
Once built, `ReasonProject` generates an environment that you can temporarily
61-
load to execute commands within. The environment contains an enhanced `PATH`
62-
that contains binaries built by your dependencies, but this environment isn't
63-
loaded automatically. To temporarily load this environment, execute the
64-
predefined `npm run env --` command. You should pass the *actual* command you
65-
want to run after `--`.
77+
### Custom Commands
78+
79+
To do anything beyond those basic, preconfigured commands, you just prefix your
80+
command with `npm run env --`. You should pass the *actual* command you want to
81+
run after `--`.
6682

6783
```sh
84+
# By default nothing is found!
85+
which refmt
6886

69-
npm run env -- which refmt
87+
> Not Found!
7088

71-
> ReasonProject/node_modules/reason/_build/ocamlfind/bin/refmt
89+
# Prefix with "npm run env --" and it finds it!
90+
npm run env -- which refmt
7291

92+
> ~/ReasonProject/node_modules/reason/_build/ocamlfind/bin/refmt
7393
```
7494

75-
The previous command would likely fail if not prefixed with `npm run env --`
76-
because the dependencies are the ones that built `refmt` in this case. `npm
77-
run env` makes all the things from our dependencies available.
95+
If this becomes tedious, you can [add your
96+
own](#reasonproject-developing-your-project-add-your-own-scripts) named scripts
97+
so that you can do `npm run yourScriptName` instead.
7898

79-
### Editor Support
99+
## Editor Support
80100

81101
#### Prepare Your Editor
82102

@@ -115,16 +135,16 @@ ensures that your editor will find the editor support in your environment
115135
variables.
116136

117137
> Note: If you use `atom`, and already have `opam` installed, then there's a
118-
known issue where `atom` has problems loading, but you can fix it easily
119-
by commenting out any part in your `bashrc` that sources opam environments.
120-
We will come up with a long term solution at some point.
138+
> known issue where `atom` has problems loading, but you can fix it easily by
139+
> commenting out any part in your `bashrc` that sources opam environments. We
140+
> will come up with a long term solution at some point.
121141
122-
##### Just Using Global Paths
142+
##### Using Global Paths
123143

124144
Pure sandboxed based development doesn't always work for certain workflows.
125-
Prefixing *all* commands with `npm run env` may not work well. In that case,
126-
you can easily inject your successfully built project's environment into the
127-
global `PATH`, by putting the following in your `.bashrc`:
145+
(prefixing *all* commands with `npm run` may not work well). In that case, you
146+
can easily inject your successfully built project's environment into the global
147+
`PATH`, by putting the following in your `.bashrc`:
128148

129149
```sh
130150
# In your .bashrc
@@ -134,15 +154,9 @@ pushd ~/pathTo/ReasonProject/ && \
134154
```
135155

136156

137-
### Multiple Projects
138-
139-
You can have multiple clones/forks/builds of `ReasonProject` for each of your
140-
projects. When you make changes, you can share the project easily with anyone
141-
else. It's common to have multiple `ReasonProject`s simultaneously. If also
142-
using global environment variables, it's wise to also have one special
143-
`ReasonProject`, that is only used for augmenting the global path.
157+
## Developing Your Project
144158

145-
### Making It Your Project
159+
### Making It Yours
146160
`ReasonProject` is meant to be the starting point of your own project. You'll want
147161
to make use of existing libraries in your app, so
148162
browse the growing set of `opam` packages ported to `npm` under
@@ -162,62 +176,94 @@ npm install --save @opam-alpha/cstruct
162176

163177
**Option `2`:** Edit the `package.json` manually to include your new dependency and run `npm install`.
164178

165-
> Note: Sometimes options `1` and `2` above fail because some *other* dependency that is
166-
rebuilt as a result of the `install` was not designed to build in an idempotent manner.
167-
In that case, just add the new dependency to your `package.json` `"dependencies"`,
168-
`rm -r node_modules`, and then run `npm install`. This installs from a clean slate.
179+
> Note: Sometimes options `1` and `2` above fail because some *other*
180+
> dependency that is rebuilt as a result of the `install` was not designed to
181+
> build in an idempotent manner. In that case, just add the new dependency to
182+
> your `package.json` `"dependencies"`, `rm -r node_modules`, and then run `npm
183+
> install`. This installs from a clean slate.
169184
170185

171186
> Note: `opam-alpha` is "alpha" - we may move to a new namespace `opam-beta`
172-
once we apply the lessons we've learned from `opam-alpha`. All the should exist
173-
as they are, but a next generation `opam-beta` universe on `npm` would have
174-
everything `opam-alpha` has (and then some). The work to upgrade your projects
175-
will likely be minimal.
187+
> once we apply the lessons we've learned from `opam-alpha`. All the should
188+
> exist as they are, but a next generation `opam-beta` universe on `npm` would
189+
> have everything `opam-alpha` has (and then some). The work to upgrade your
190+
> projects will likely be minimal.
176191
177192

193+
This merely adds and builds the dependency. It doesn't mean your build system
194+
will know to link to it. Accomplishing that is build system dependent, but if
195+
using the example build system (`rebuild`, which is based on `ocamlbuild`), you
196+
can get an idea for the options by doing `npm run buildHelp`. Typically you
197+
need to configure the `reasonBuild` entry in `package.json` to add the `-pkg
198+
dependencyPackage`. Consult your dependency's docs.
199+
178200
### Add Your Own Scripts
179-
- `npm` allows `scripts` to be specified in your project's `package.json`.
180-
These `scripts` are a named set of commands.
181-
- A few scripts have special meaning, such as the `postinstall` script. The
182-
`postinstall` script is how your project compiles itself. It is guaranteed
183-
that the `postinstall` script executes any time you run `npm install` in this
184-
package, or any time another package installs you as a dependency. You're
185-
also guaranteed that your `postinstall` script is executed *after* all of
186-
your dependencies' `postinstall` scripts.
187-
- You can add new named scripts in the `package.json` `scripts` field. Once
188-
added, you can then run them via `npm run scriptName` from within the project
189-
root.
190-
- `eval $(dependencyEnv)` is commonly used in these `scripts`. The `eval`
191-
manages the environment, and ensures that important
192-
binaries (such as `refmt`) are in the `PATH`. `dependencyEnv` ensures that
193-
the environment is augmented only for the duration of that `script` running,
194-
and only in ways that you or your immediate dependencies decide. When
195-
the entire purpose of developer tools is to generate a binary (such as a
196-
compiler) to be included in your `PATH`, or produce a library whose path
197-
should be specified in an special environment variable, it's almost like the
198-
environment variable is the public API of that package. `dependencyEnv`
199-
allows your script to see the environment variables that your immediate
200-
dependencies wanted to publish as their public API. You can learn how
201-
packages can publish environment variables in the [dependency-env
202-
repo](https://github.com/npm-ml/dependency-env).
203-
204-
205-
### Creating Reusable Libraries
206-
207-
- To turn this example project into a library that other people can depend on
208-
via `npm`... (coming soon).
209-
210-
211-
### Debugging Failed Dependencies
212-
213-
When `npm install` fails to install one of your dependencies successfully, it's
214-
typically because a `postinstall` step of a package has failed. Read
215-
the logs to determine which one is failing. `npm` will delete the directory
216-
of the failed package so it won't be in `node_modules`, but it's in the cache, so you
217-
can usually install it explicitly, and debug the installation. Suppose the
201+
202+
`npm` allows `scripts` to be specified in your project's `package.json`. These
203+
`scripts` are a named set of commands. A few scripts have special meaning, such
204+
as the `postinstall` script.
205+
206+
> The `postinstall` script is how your project compiles itself. It is
207+
> guaranteed that the `postinstall` script executes any time you run `npm
208+
> install` in this package, or any time another package installs you as a
209+
> dependency. You're also guaranteed that your `postinstall` script is executed
210+
> *after* all of your dependencies' `postinstall` scripts.
211+
212+
You can add new named scripts in the `package.json` `scripts` field. Once
213+
added, you can then run them via `npm run scriptName` from within the project
214+
root.
215+
216+
###### Making Sure Your Scripts See The Environment
217+
218+
`eval $(dependencyEnv)` is commonly used in these `scripts`. This `eval`
219+
statement augments the environment for the duration of the named script, which
220+
ensures that important binaries (such as `refmt`) are in the `PATH`.
221+
222+
> When the entire purpose of developer tools is to generate a binary (such as a
223+
> compiler) to be included in your `PATH`, or produce a library whose path
224+
> should be specified in an special environment variable, it's almost like the
225+
> environment variable is the public API of that package. `dependencyEnv`
226+
> allows your script to see the environment variables that your immediate
227+
> dependencies wanted to publish as their public API. You can learn how
228+
> packages can publish environment variables in the [dependency-env
229+
> repo](https://github.com/npm-ml/dependency-env).
230+
231+
### Multiple Projects
232+
233+
You can have multiple clones/forks/builds of `ReasonProject` - one for each of
234+
your projects. When you make changes, you can share the project easily with
235+
anyone else because you are modelling all dependencies via `package.json`. If
236+
also [using the global
237+
environment](#reasonproject-editor-support), you may want to
238+
designate one special `ReasonProject`, that is only used for augmenting the
239+
global path.
240+
241+
242+
### Creating Libraries
243+
244+
`ReasonProject` sets up your environment for building an application. We
245+
haven't yet mentioned how to then share your work with other people *as* an
246+
`npm` dependency itself. More coming soon.
247+
248+
249+
## Troubleshooting
250+
251+
In general, if something goes wrong, try deleting the local `node_modules`
252+
directory that was installed, and then try reinstalling using `npm install -f`
253+
(to avoid using a stale cache). Then if that doesn't work, follow the following
254+
steps to debug your specific failed dependency.
255+
256+
#### Debugging Failed Dependencies
257+
258+
When `npm install` fails to install one of your dependencies, it's typically
259+
because a `postinstall` step of a package has failed. Read the logs to
260+
determine which one is failing. `npm` will delete the directory of the failed
261+
package so the failed install won't be in `node_modules`, but you can
262+
usually try to reinstall it explicitly, and debug the installation. Suppose the
218263
`@opam-alpha/qcheck` package failed to install. Let's recreate the failure so
219264
we can debug it.
220265

266+
#####Do a dry run:
221267
Let's see what an `npm install` for this package *would* install. The `--dry-run`
222268
flag avoids actually installing anything.
223269

@@ -229,15 +275,16 @@ In my project, it says it would only need to install the following packages.
229275
That's because all of the other ones must have already been installed in
230276
`node_modules`.
231277

232-
Output:
233278
```sh
279+
# Output
234280
test@1.0.0 /Users/jwalke/Desktop/tmp
235281
└─┬ @opam-alpha/qcheck@0.4.0
236-
└── qcheck-actual@0.4.0 (git://github.com/npm-opam/qcheck.git
282+
└── qcheck-actual@0.4.0 (git://github.com/npm-opam/qcheck.git)
237283
```
238-
(Note: Sometimes it won't traverse `git` dependencies to find all the potentially installed
239-
package. That's okay).
284+
> Note: Sometimes it won't traverse `git` dependencies to find all the potentially installed
285+
package. That's okay.
240286

287+
###### Install Source Without Building
241288
So we want to install that now, but *without* executing the install scripts so we
242289
pass the `--ignore-scripts` flag. Without that flag, it would fail when running
243290
the scripts again, and then remove the package again!
@@ -248,13 +295,7 @@ npm install --ignore-scripts @opam-alpha/qcheck@0.4.0
248295

249296
This will just install the source code, and let us know what it actually installed.
250297

251-
Ouput:
252-
```
253-
test@1.0.0 /Users/jwalke/Desktop/tmp
254-
└─┬ @opam-alpha/qcheck@0.4.0
255-
└── qcheck-actual@0.4.0 (git://github.com/npm-opam/qcheck.git
256-
```
257-
298+
###### Try The Build Manually, In Place
258299
Now, make sure `npm` didn't do something weird with installing new versions of package
259300
that didn't show up in the dry run, and make sure it installed things
260301
as flat as possible in `node_modules`, as opposed to nesting `node_modules`
@@ -280,20 +321,6 @@ from the top again. This just makes sure you've got everything
280321
nice and clean as if you installed it for the first time.
281322

282323

283-
## Troubleshooting:
284-
- Check to make sure everything is installed correctly. There's a `script`
285-
already setup that will help you test the location of where `Reason` has been
286-
compiled into.
287-
288-
- If something goes wrong, try deleting the local `node_modules` directory that
289-
was installed, and then try reinstalling using `npm install -f`.
290-
291324
```
292325
npm run whereisocamlmerlin
293326
```
294-
295-
## TODO:
296-
297-
- This also installs sandboxed IDE support for Vim/Atom/Emacs. We need to
298-
upgrade all of the plugins to automatically search for IDE plugins inside of
299-
the `./node_modules` directory.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"scripts": {
2828

2929
"postinstall": "npm run reasonBuild",
30+
"buildHelp": "eval $(dependencyEnv) && nopam && rebuild --help",
3031
"reasonBuild": "eval $(dependencyEnv) && nopam && rebuild -I src ./src/Test.native 2>&1 | refmterr",
3132
"reasonbuild": "npm run reasonBuild",
3233

0 commit comments

Comments
 (0)