Giter VIP home page Giter VIP logo

esy's Introduction

esy

package.json workflow for native development with Reason/OCaml

Build Status

Esy is a package manager for Reason and OCaml centered around the NPM workflow. Reason/OCaml are compiled languages and it can be daunting for developers to setup tools and develop a workflow that is intuitive and well documented. Developing apps that are natively compiled are also hard to reproduce and often require additional tooling. Esy tries address these, by offering a familiar package.json centered workflow and light-weight sandboxing.

Installation

Esy is available on NPM.

npm i -g esy

Documentation

You can find the Esy documentation on the website. You can also find them under the docs folder of the source tree.

Contributing

Please refer the documents in docs/contributing. You'll find instructions for building the source, CI setup, release process, esy internal concepts and other documentation to help you get started hacking on esy. You can also find them on the website under the contributing section

Issues

Issues are tracked at esy/esy.

History and motivation

See package.json for compilers

Maintenance and Sponsorship

This project was originally authored by Andrey Popp, and is currently maintained by ManasJayanth. The project is currently not funded and could benefit from generous sponsorships.

esy's People

Contributors

0xflotus avatar aantron avatar andreypopp avatar anmonteiro avatar bryphe avatar crossr avatar dependabot[bot] avatar eduardorfs avatar et7f3 avatar giltho avatar jaredly avatar jordwalke avatar kazcw avatar lessp avatar manasjayanth avatar matthiaskern avatar melwyn95 avatar paulshen avatar phated avatar rauanmayemir avatar rgrinberg avatar rizo avatar rohitkg98 avatar rolandpeelen avatar sahandevs avatar saitonakamura avatar tatchi avatar ulrikstrid avatar whoatedacake avatar zindel 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

esy's Issues

Jbuilder finding the wrong root out of local esy store

Repro

hub clone facebook/reason
esy i
esy b

The explanation

Reason repo has jbuild-workspace.dev file which makes jbuilder recurse up the tree to find the outermost jbuild-workspace.* file. As esy b builds within $cur__root/node_modules/.cache/_esy/store/... then jbuilder recurses up to $cur__root and starts build from there which is wrong.

Workaround

Add --root . to esy.json's jbuilder invocations.

Binary paths being overridden

With the following package.json, esy my command isn't able to see the ocaml compiler in its PATH. The act of augmenting PATH seems to remove its visibilities of dependencies' PATH components. This seems like a bug.

Thankfully, with esy, people don't usually ever have to set/export any PATHs -they just install into the right location, but we should still probably understand what's happening here.

{
  "name": "@myscope/mypackage",
  "version": "2.0.0",
  "devDependencies": {
    "ocaml": "~4.2.3000"
  },
  "peerDependencies": {
    "ocaml": "~4.2.3000"
  },
  "esy": {
    "build": [
      [ "make"]
    ],
    "install": [
      [ "cp", "-r", "-f", "$cur__target_dir", "$cur__install" ]
    ],
    "exportedEnv": {
      "PATH": {
        "scope": "global",
        "val": "FOO:$PATH"
      }
    },
    "buildsInSource": true
  }
}

Esy fails to compile a working reason

Looks like we are failing to compile a working reason, on current master branch:
reasonml/reason@2e6291c

On every version of esy since 0.28 (I tried 0.0.29-0.0.32), this series of commands fails:

$ esy install && esy build && esy make test
...
    ocamlopt src/refmt/refmt_impl.exe
rm -rf ./formatTest/**/actual_output
rm -f ./formatTest/failed_tests
rm -f ./miscTests/reactjs_jsx_ppx_tests/*.cm*
# I don't have modern enough node to test. brb.
node ./formatTest/testOprint.js
Done! 0 failures
./miscTests/rtopIntegrationTest.sh
Testing rtop...
rtop is failing! Failed to evaluate `let f = (a) => a;`
make: *** [Makefile:19: test] Error 1

On 0.0.28 it succeeds and all the tests pass.

Related: reasonml/reason#1590

I suspect this is related to the recently merged fastbuild (#23).

Strange error when building.

I've gotten this strange error when building a large project. I didn't expect the project build to succeed (I was depending on reason v 3.0.0 when the syntax was v1.0) but the error was oddly truncated and irrelevant. The package name (in package.json) is www).

  → www @ 0.0.1: build failed:

  set -e
  set -o pipefail

  	export ESY_EJECT__ROOT="/home/me/www/scripts/re/node_modules/.cache/_esy";\
  	export esy_build__sandbox_config_darwin="$ESY_EJECT__ROOT/bin/sandbox.sb";\
  	export esy_build__source_root="/home/me/www/scripts/re";\
  	export esy_build__install_root="/home/me/www/scripts/re/node_modules/.cache/_esy/store/i/www-0.0.1-7101f653";\
  	export esy_build__build_type="in-source";\
  	export esy_build__source_type="root";\
  	export esy_build__build_command=('make build' 'make install');\
  	export esy_build__install_command='';

  source "$ESY_EJECT__ROOT/bin/build-env"
  source "$ESY_EJECT__ROOT/bin/runtime.sh"

  if [ $# -eq 0 ]; then
    esyPerformBuild
  else
    esyExecCommand "$@"
  fi

Package source link mechanism

Currently we use yarn's link: dependencies which put a symlink to a local package inside node_modules/.

The problem arises during build dependency resolution. Consider the case where a linked package linked is being developed separately (being a root of its own sandbox) and as a part of some other sandbox.

Now because linked/node_modules exists (own sandbox) it leaks dependencies into other sandbox.

Instead implement link: in esy install command by placing a special file _esylink inside a package directory inside node_modules:

<root>
└─ node_modules
    └── linked
        ├── _esylink # not a symlink just has a text entry "/path/to/linked/package"
        └── node_modules

The downside is that node won't be able to resolve those linked packages.

Yarn offline cache doesn't include opam dependencies.

Since moving ocaml compiler to npm, now the offline cache is no longer corrupt, but I noticed the offline cache doesn't include @opam packages.

This might be a quick/obvious fix, or it might be more involved. If it's more involved, I think we can deprioritized it and I can just find some other workaround to getting offline checkins of dependencies. Curious to hear @andreypopp's thoughts:

Here's my project's .yarnrc:

# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

lastUpdateCheck 1508733111161
yarn-offline-mirror "./npm-packages-offline-cache"
yarn-offline-mirror-pruning true

Here's a sample section of my newly generated yarn.lock, which shows something interesting: The resolved field doesn't have a full url for @opam packages, but does for npm ones.

"@opam/utop@ >= 1.17.0":
  version "2.0.1"
  resolved "@opam/[email protected]"
  dependencies:
    "@esy-ocaml/esy-installer" "^0.0.0"
    "@esy-ocaml/substs" "^0.0.1"
    "@opam/base-threads" "*"
    "@opam/base-unix" "*"
    "@opam/cppo" "  >= 1.1.2"
    "@opam/jbuilder" "  >= 1.0.0-beta9"
    "@opam/lambda-term" " >= 1.9.0"
    "@opam/lwt" "*"
    "@opam/ocamlfind" " >= 1.7.2"
    "@opam/react" " >= 1.0.0"
  peerDependencies:
    ocaml " >= 4.2.3  < 4.6.0"

"@opam/zed@ >= 1.2.0":
  version "1.5.0"
  resolved "@opam/[email protected]"
  dependencies:
    "@esy-ocaml/esy-installer" "^0.0.0"
    "@esy-ocaml/substs" "^0.0.1"
    "@opam/base-bytes" "*"
    "@opam/camomile" " >= 0.8.0"
    "@opam/jbuilder" "  >= 1.0.0-beta7"
    "@opam/react" "*"
  peerDependencies:
    ocaml " >= 4.2.3"

ocaml@~4.2.3001:
  version "4.2.3001"
  resolved "https://registry.yarnpkg.com/ocaml/-/ocaml-4.2.3001.tgz#4bb250b8a842fb357acb2ebf1a13a0c3fa753dd6"

Here's the contents of the npm-packages-offline-cache directory:

npm-packages-offline-cache/
npm-packages-offline-cache/@esy-ocaml-esy-installer-0.0.0.tgz
npm-packages-offline-cache/ocaml-4.2.3001.tgz
npm-packages-offline-cache/@esy-ocaml-substs-0.0.1.tgz

Optimization for linked _build-projects

@jordwalke suggested:

  1. Globally lock that project during its build. Nothing else can build that project, not even if you cd into it and run a local build.
  2. When building it as a symlinked dependency, mv _build backupLocation, ln -s $cur__dest _build, and then proceed with the build.
  3. Make sure sure sure we repair the _build directory as it was before the build.

During that build, the sandbox restriction is relaxed to allow writes to _build because we know esy is hacking it to point to out of source.

This should work for jbuilder/bsb and ocamlbuild. You get full incremental builds this way even for symlinked deps.

Use different directory than `_build`.

Right now, esy creates a _build directory for top level project builds, but this is in conflict with jbuilder. I'm trying to port the ReasonNativeProject which uses jbuilder over to esy, and there's this issue.

It looks like jbuilder won't provide the ability to customize the _build directory so perhaps we can change it to something else so that we can support jbuilder projects.

Although, it will be quite weird to have two build symlinks in each project - the priority right now is to just make it so we can support jbuilder projects.

$1 unbound variable

After running esy build I get this output:

/Users/jwalke/github/esy-ocaml/esy-reason-project/node_modules/.cache/_esy/build/bin/runtime.sh: line 139: $1: unbound variable

I think it's because we use set -u.

Consider showing build output for top level app.

esy build is intentionally quiet unless there was a failure, which makes a lot of sense when building dependencies, but for building the top level app, it's pretty important to see warnings while developing, which don't block the build.
Should we relax the "quiet rule" for the top level app's esy build?

Cannot read property path of undefined.

Somewhat similar to issue #21:

screen shot 2017-11-17 at 2 16 40 pm

Here's my version:

esy-reason-project jwalke$ esy --version
0.0.35

It also happens with 0.0.37 (verified).

Here's my package.json:
I tried to install cohttp with 4.04 compiler since 4.02.3 doesn't seem to be able to have a solution for cohttp.

{
  "name": "esy-reason-project",
  "version": "0.1.0",
  "description": "Reason workflow with Esy",
  "license": "MIT",
  "esy": {
    "build":  [
      ["refmterr", "jbuilder", "build"]
    ],
    "install": [
      "esy-installer"
    ],
    "buildsInSource": "_build"
  },
  "dependencies": {
    "@opam/cohttp": "*",
    "@esy-ocaml/esy-installer": "^0.0.0",
    "@opam/jbuilder": "^1.0.0-beta14",
    "@opam/lambda-term": "^1.11.0",
    "@opam/lwt": "^3.1.0",
    "@opam/reason": "^3.0.0",
    "refmterr": "^3.0.4"
  },
  "peerDependencies": {
    "ocaml": "~4.2.3000"
  },
  "devDependencies": {
    "@opam/merlin": "^3.0.3",
    "ocaml": "esy-ocaml/ocaml#4.4.2+esy"
  }
}

Here's the yarn error log for install:

npm manifest (package.json): 
  {
    "name": "esy-reason-project",
    "version": "0.1.0",
    "description": "Reason workflow with Esy",
    "license": "MIT",
    "esy": {
      "build":  [
        ["refmterr", "jbuilder", "build"]
      ],
      "install": [
        "esy-installer"
      ],
      "buildsInSource": "_build"
    },
    "dependencies": {
      "@opam/cohttp": "*",
      "@esy-ocaml/esy-installer": "^0.0.0",
      "@opam/jbuilder": "^1.0.0-beta14",
      "@opam/lambda-term": "^1.11.0",
      "@opam/lwt": "^3.1.0",
      "@opam/reason": "^3.0.0",
      "refmterr": "^3.0.4"
    },
    "peerDependencies": {
      "ocaml": "~4.2.3000"
    },
    "devDependencies": {
      "@opam/merlin": "^3.0.3",
      "ocaml": "esy-ocaml/ocaml#4.4.2+esy"
    }
  }

yarn manifest (yarn.json): 
  No manifest

Lockfile: 
  No lockfile

Trace: 
  TypeError: Cannot read property 'path' of undefined
      at DecompressZip.module.exports.DecompressZip.extractFile (/Users/jwalke/.npm-packages/lib/node_modules/esy/bin/esy.js:200114:51)
      at /Users/jwalke/.npm-packages/lib/node_modules/esy/bin/esy.js:200098:28
      at Array.forEach (native)
      at DecompressZip.module.exports.DecompressZip.extractFiles (/Users/jwalke/.npm-packages/lib/node_modules/esy/bin/esy.js:200097:11)
      at /Users/jwalke/.npm-packages/lib/node_modules/esy/bin/esy.js:199977:21
      at _fulfilled (/Users/jwalke/.npm-packages/lib/node_modules/esy/bin/esy.js:112263:54)
      at self.promiseDispatch.done (/Users/jwalke/.npm-packages/lib/node_modules/esy/bin/esy.js:112292:30)
      at Promise.promise.promiseDispatch (/Users/jwalke/.npm-packages/lib/node_modules/esy/bin/esy.js:112225:13)
      at /Users/jwalke/.npm-packages/lib/node_modules/esy/bin/esy.js:112033:44
      at runSingle (/Users/jwalke/.npm-packages/lib/node_modules/esy/bin/esy.js:111546:13)

installing realworldocaml.org with esy

Is there a specific way to add deps to a project? Feels like you have to already have the deps installed when building realworldocaml with esy.

The point of the exercise below was to set up realworldocaml.org with esy. There docs say these are the deps
esy add @opam/core @opam/utop @opam/async @opam/yojson @opam/core_extended @opam/core_bench @opam/cohttp @opam/async_graphics @opam/cryptokit @opam/menhir

Running this command fails at @opam/async saying that dependencies it rely's one are not installed in compatible version. I then tried installing the deps individually but that didn't seem right and will take a long time even if it worked.

Project repo: esy-realworldocaml

Mostly and FYI. Thanks.

Esy import/export feature.

We already implement esy import/export in an adhoc manner. The idea behind this feature is to formatlize it into an external command and do the following:

  • Make esy release be in terms of esy export && esy import.
  • Rewrite the paths in the export to always be /________ (from root) to scrub any personal paths.
  • This allows us to remove one additional "record" in releases since it can always be assumed that client ejected paths are always /___________ (with a ton of underscores).

An exported store is just a collection of install (i) directories from a store, all zipped up into their own .tar.gz directories, which can later be placed into another store for the purposes of warming up a cache etc. .tar.gz each package install directory separately is a great balance because it keeps the total size under Github's limits, and other VCS limits.

Question: How do you determine which packages to include in the export? I propose that we just follow the exact same process as esy release just to keep it simple. You make a package.json that includes the files you want included in the export. In fact, there really wouldn't be any difference between an export and a release, correct? Perhaps you just wouldn't include any wrapped binaries. If so, that means that maybe you could run esy import on any release to relocate its artifacts into any other store.

Ability for released binaries to *not* augment findlib path.

We still want to export a wrapper script that execs the correct version of the binary, but without augmenting things like OCAMLPATH - or really any part of the environment.

Here's a couple of examples where it's important:

# The  local project's `esy` environment is overwritten by the `esyvim`
# binary wrapper's environment.
esy esyvim myFile.re

# If vim is using the globally installed `ocamlmerlin` that has a wrapper
# then the local project's `esy` environment will be overwritten by
# the global `ocamlmerlin`'s. This forces you to install merlin as a dev
# dependency which is also a good approach, but it would be nice if
# you didn't have to.  
esy vim myFile.re

This can really only be decided on a per application basis. Packages that are released must decide if it makes sense for their use case to wrap the binaries.

I'd say that esyvim would opt out of wrapping, and so would ocamlmerlin.

The other approach is to let released binaries decide if they want to wrap, but only if not already running in an environment.

esy install: Cannot read property 'length' of undefined (Ubuntu)

Steps to reproduce:

git clone https://github.com/iwankaramazow/track
cd track
docker build -t track .
docker run -it track
esy install

captura de pantalla 2017-11-02 a las 20 12 07

The dockerfile starts with the base ubuntu:17.10 image, installs node & esy.
As soon as I run esy install in the dockercontainer (e.g. on a ci), node crashes with

  TypeError: Cannot read property 'length' of undefined
      at Object.add_string (/usr/local/lib/node_modules/esy/node_modules/@esy-ocaml/esy-opam/dist/esy-opam.js:44669:15)
      at strput_acc (/usr/local/lib/node_modules/esy/node_modules/@esy-ocaml/esy-opam/dist/esy-opam.js:52981:25)
      at strput_acc (/usr/local/lib/node_modules/esy/node_modules/@esy-ocaml/esy-opam/dist/esy-opam.js:52983:11)
      at Object.strput_acc (/usr/local/lib/node_modules/esy/node_modules/@esy-ocaml/esy-opam/dist/esy-opam.js:52980:11)
      at k$prime (/usr/local/lib/node_modules/esy/node_modules/@esy-ocaml/esy-opam/dist/esy-opam.js:64574:24)
      at Object._2 (/usr/local/lib/node_modules/esy/node_modules/@esy-ocaml/esy-opam/dist/esy-opam.js:56228:12)
      at make_printf (/usr/local/lib/node_modules/esy/node_modules/@esy-ocaml/esy-opam/dist/esy-opam.js:52214:20)
      at /usr/local/lib/node_modules/esy/node_modules/@esy-ocaml/esy-opam/dist/esy-opam.js:52707:20
      at app (/usr/local/lib/node_modules/esy/node_modules/@esy-ocaml/esy-opam/dist/esy-opam.js:56125:16)
      at curry_2 (/usr/local/lib/node_modules/esy/node_modules/@esy-ocaml/esy-opam/dist/esy-opam.js:56197:18)

The stack trace & other logs can be found at
https://gist.github.com/IwanKaramazow/a00d813c9f4f9b6e7f8864aa37f1c972

The ubuntu-container probably misses some utility. What kind of tools are missing? Can we throw a warning if they aren't installed? Is that tool windows-proof?

Consider bundling `opam-installer-bin` automatically.

We discussed how to remove the dependency on opam-installer-bin, and we believed that if using jbuilder, we could just use jbuilder install. We can call jbuilder install but that too calls out to opam-installer and it's not clear how to get it to not use opam-installer. I suspect if you remove opam-installer from the PATH, it might try its own implementation, but I'm not confident it will. Since removing it from the PATH might be difficult (since some dependency might pull it in), what are your thoughts on the other extreme - having opam-installer included by default. Similar to how opam comes with opam-installer, it might make sense to just make opam-installer available in esy. You can also alias it to esy-installer if preferred.

Question: Why doesn't esy.build accept space separated string?

When my esy.build field is:

  "esy": {
    "build": [
      [
        "make build"
      ],
    ...

I get the following error:

FAILED reason-native-project, see log for details:

  ### ORIGINAL COMMAND: make build
  ### RENDERED COMMAND: "make build"
  sandbox-exec: execvp() of 'make build' failed: No such file or directory

But if I specify the build command as:

  "esy": {
    "build": [
      [
        "make",
        "build"
      ],
    ...

Then everything works fine.

I imagine new users will hit this very quickly, and the error message doesn't tell you what is wrong at all. What was the motivation behind requiring that each token be its own array string element?

yarn add @opam/whatever syntax

Im trying to test the esy-reason-project. Looks like the yarn add command is not reading the package names correctly. Tried a few different times. output below:

shingdev at cosmos in ~/code/ESY/esy-reason-project-master
$ yarn add @opam/ounit
yarn add v1.3.2
info No lockfile found.
[1/4] 🔍  Resolving packages...
error An unexpected error occurred: "https://registry.yarnpkg.com/@opam%2flambda-term: Not found".
info If you think this is a bug, please open a bug report with the information provided in "/Users/shingdev/code/ESY/esy-reason-project-master/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

shingdev at cosmos in ~/code/ESY/esy-reason-project-master
$ yarn add @opam/ounit
yarn add v1.3.2
info No lockfile found.
[1/4] 🔍  Resolving packages...
error An unexpected error occurred: "https://registry.yarnpkg.com/@opam%2flwt: Not found".
info If you think this is a bug, please open a bug report with the information provided in "/Users/shingdev/code/ESY/esy-reason-project-master/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

shingdev at cosmos in ~/code/ESY/esy-reason-project-master
$ yarn add @opam/lwt
yarn add v1.3.2
info No lockfile found.
[1/4] 🔍  Resolving packages...
error An unexpected error occurred: "https://registry.yarnpkg.com/@opam%2freason: Not found".
info If you think this is a bug, please open a bug report with the information provided in "/Users/shingdev/code/ESY/esy-reason-project-master/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

shingdev at cosmos in ~/code/ESY/esy-reason-project-master
$ yarn add @opam/reason
yarn add v1.3.2
info No lockfile found.
[1/4] 🔍  Resolving packages...
error An unexpected error occurred: "https://registry.yarnpkg.com/@opam%2flwt: Not found".
info If you think this is a bug, please open a bug report with the information provided in "/Users/shingdev/code/ESY/esy-reason-project-master/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

shingdev at cosmos in ~/code/ESY/esy-reason-project-master
$ yarn add @opam/lwt
yarn add v1.3.2
info No lockfile found.
[1/4] 🔍  Resolving packages...
error An unexpected error occurred: "https://registry.yarnpkg.com/@opam%2freason: Not found".
info If you think this is a bug, please open a bug report with the information provided in "/Users/shingdev/code/ESY/esy-reason-project-master/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.

shingdev at cosmos in ~/code/ESY/esy-reason-project-master
$ yarn add @opam/lwt
yarn add v1.3.2
info No lockfile found.
[1/4] 🔍  Resolving packages...
error An unexpected error occurred: "https://registry.yarnpkg.com/@opam%2fjbuilder: Not found".
info If you think this is a bug, please open a bug report with the information provided in "/Users/shingdev/code/ESY/esy-reason-project-master/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.
Error: https://registry.yarnpkg.com/@opam%2freason: Not found
    at Request.params.callback [as _callback] (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:62098:18)
    at Request.self.callback (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:123085:22)
    at emitTwo (events.js:125:13)
    at Request.emit (events.js:213:7)
    at Request.<anonymous> (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:124068:10)
    at emitOne (events.js:115:13)
    at Request.emit (events.js:210:7)
    at IncomingMessage.<anonymous> (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:123988:12)
    at Object.onceWrapper (events.js:314:30)
    at emitNone (events.js:110:20)
Error: https://registry.yarnpkg.com/@opam%2fre: Not found
    at Request.params.callback [as _callback] (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:62098:18)
    at Request.self.callback (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:123085:22)
    at emitTwo (events.js:125:13)
    at Request.emit (events.js:213:7)
    at Request.<anonymous> (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:124068:10)
    at emitOne (events.js:115:13)
    at Request.emit (events.js:210:7)
    at IncomingMessage.<anonymous> (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:123988:12)
    at Object.onceWrapper (events.js:314:30)
    at emitNone (events.js:110:20)

shingdev at cosmos in ~/code/ESY/esy-reason-project-master
$ yarn add @opam/jbuilder
yarn add v1.3.2
info No lockfile found.
[1/4] 🔍  Resolving packages...
error An unexpected error occurred: "https://registry.yarnpkg.com/@opam%2fjbuilder: Not found".
info If you think this is a bug, please open a bug report with the information provided in "/Users/shingdev/code/ESY/esy-reason-project-master/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.
Error: https://registry.yarnpkg.com/@opam%2freason: Not found
    at Request.params.callback [as _callback] (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:62098:18)
    at Request.self.callback (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:123085:22)
    at emitTwo (events.js:125:13)
    at Request.emit (events.js:213:7)
    at Request.<anonymous> (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:124068:10)
    at emitOne (events.js:115:13)
    at Request.emit (events.js:210:7)
    at IncomingMessage.<anonymous> (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:123988:12)
    at Object.onceWrapper (events.js:314:30)
    at emitNone (events.js:110:20)
Error: https://registry.yarnpkg.com/@opam%2fre: Not found
    at Request.params.callback [as _callback] (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:62098:18)
    at Request.self.callback (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:123085:22)
    at emitTwo (events.js:125:13)
    at Request.emit (events.js:213:7)
    at Request.<anonymous> (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:124068:10)
    at emitOne (events.js:115:13)
    at Request.emit (events.js:210:7)
    at IncomingMessage.<anonymous> (/usr/local/Cellar/yarn/1.3.2/libexec/lib/cli.js:123988:12)
    at Object.onceWrapper (events.js:314:30)
    at emitNone (events.js:110:20)

converting makebuild opam project to esy

These notes are same as on test project readme.

Notes

1. Dot notation: the project uses dot notation in its opam file to specify build

dependencies, example lwt.unix. Esy doesn't process these.

depends: [
  "ocamlbuild" {build}
  "ocamlfind" {build}
  "cohttp" {build}
  "lwt" {build}
  "lwt.unix" {build}
  "cohttp.lwt" {build}
  "Yojson" {build}
]

2. build failure error/external library "ppx_tools_versioned"

esy build v0.0.48
File "_build/.jbuilds/default/node_modules/@opam/cppo/src/jbuild", line 5, characters 0-25:
Warning: File cppo_parser.mli is both generated by a rule and present in the source tree.
As a result, the rule is currently ignored, however this will become an error in the future.
Delete file node_modules/@opam/cppo/src/cppo_parser.mli to get rid of this warning.
Error: Conflict between internal and external version of library "ocaml-migrate-parsetree":
- it is defined locally in node_modules/@opam/ocaml-migrate-parsetree/src/jbuild
- it is required by external library "ppx_tools_versioned"
- external library "ppx_tools_versioned" is required in node_modules/@opam/lwt/src/ppx/jbuild (context default)
This cannot work.
  • deleted node_modules/@opam/cppo/src/cppo_parser.mli
  • added @opam/ppx_tools_versioned
  • still got error. after following errors. cppo_parser.mli keeps rebuilding on
    esy build.

  • still requiring @opam/ppx_tools_versioned

  • error

$ esy add @opam/ppx_tools_versioned
esy add v0.0.48
[1/4] Resolving packages...
[2/4] Fetching packages...
warning Pattern ["@opam/ppx_tools_versioned@^5.0.1"] is trying to unpack in the same destination "/Users/shingdev/.esy/install-cache/v1/npm-@opam/ppx_tools_versioned-5.0.1-53c4da7071d211788ba47969a4cd3c3b" as pattern ["@opam/ppx_tools_versioned@*"]. This could result in a non deterministic behavior, skipping.
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
└─ @opam/[email protected]
Done in 4.29s.
esy build v0.0.48
File "_build/.jbuilds/default/node_modules/@opam/cppo/src/jbuild", line 5, characters 0-25:
Warning: File cppo_parser.mli is both generated by a rule and present in the source tree.
As a result, the rule is currently ignored, however this will become an error in the future.
Delete file node_modules/@opam/cppo/src/cppo_parser.mli to get rid of this warning.
Error: Conflict between internal and external version of library "ocaml-migrate-parsetree":
- it is defined locally in node_modules/@opam/ocaml-migrate-parsetree/src/jbuild
- it is required by external library "ppx_tools_versioned"
- external library "ppx_tools_versioned" is required in node_modules/@opam/lwt/src/ppx/jbuild (context default)
This cannot work.

Resolutions don't seem to make new versions available.

Reason 3.0.0 depends on OCaml 4.02.3-4.05. Master branch of facebook/reason supports OCaml 4.02.3-4.06.0. I wanted to be able to develop a project as if my pending opam-repository pull request had been accepted. My project depends on @opam/reason: ~3.0.0, but also depends on refmterr which depends on @opam/reason: ~3.0.0. I placed a resolution, saying that all Reason "@opam/reason" should resolve to the master branch of our Reason repo.

I bumped the peer dep of my project to OCaml 4.06, hoping that the resolutions would have an effect. When running esy install, it gave an error saying that no compatible version of Reason could be found - likely because no Reason hosted on opam supports OCaml 4.06. Is this merely an issue with our opam resolver? Or would this also be an issue with any other npm dependency that tries to use the resolutions field?

Possibly lower pri, but good to track this.

Consider generating `command-env` on `esy build`.

For editor integration, it's nice to be able to source the command environment as soon as the project is built. As it is, a command has to be executed in order to make that happen. That's not bad if starting esy vim, but when setting up the environment from within a GUI IDE, it's less than ideal and comes with a bunch of complications (I think that the Nuclide setup path runs with different permissions etc).

I'm curious what the downsides of generating command-env on esy build would be. It seems like some of that computational cost of computing command-env, overlaps with the env already needed to be constructed for esy build.

`esy x` doesn't return for projects with git dependencies.

esy x which blahblah

Always responds with nothing, even if blahblah is not a valid program. No command responds. I noticed that my project has a git dependency with resolutions, and another project with a git dependency + resolutions also does not respond to esy x commands. However, the Reason repo, (which has no git dependencies) correctly works with esy x commands.

Here's my package.json:

{
  "name": "esy-reason-project",
  "version": "0.1.0",
  "description": "Reason workflow with Esy",
  "license": "MIT",
  "esy": {
    "build":  [
      ["refmterr", "jbuilder", "build"]
    ],
    "install": [
      "esy-installer"
    ],
    "buildsInSource": "_build"
  },
  "dependencies": {
    "@opam/bos": "*",
    "@esy-ocaml/esy-installer": "^0.0.0",
    "@opam/jbuilder": "^1.0.0-beta14",
    "@opam/lambda-term": "^1.11.0",
    "@opam/lwt": "^3.1.0",
    "@opam/reason": "^3.0.0",
    "refmterr": "^3.0.4",
    "@opam/ounit": "*",
    "@esy-ocaml/bs-platform": "^2.0.0"
  },
  "resolutions": {
    "**/@opam/reason": "facebook/reason#master"
  },
  "peerDependencies": {
    "ocaml": "~4.2.3000"
  },
  "devDependencies": {
    "ocaml": "~4.2.3000",
    "@opam/merlin": "2.5.4"
  }
}

Allow projects to remove dependency on `opam-installer`

It's possible to remove the dependency on opam-installer for projects that use build systems, that have a deep understanding of ocamlfind. jbuilder is one of these build systems. If it cannot find opam, it will use the $OCAMLFIND_DESTDIR variable. I found one issue, and I suspect another one will emerge:

  1. Even if my project does not depend on opam-installer-bin, even if some other project depends on it, it will be added to my PATH while running build commands, and jbuilder will think that opam is installed, and will try to use opam-installer to install my library. A longer term (harder) fix is to distinguish those "build-time-only" dependencies which won't augment PATH transitively. I'm hoping there's a shorter term fix.
  2. I'm not able to test if this is a problem due to number 1, but I think $OCAMLFIND_DESTDIR variable is configured slightly differently than it should be. Here's what it is for my ReasonNativeProject:
  • Inside of esy build-shell: the variable is set to /Users/jwalke/.esy/3.x.x________________________________________________________________/s/reason_native_project-0.0.1-a00bddbe/lib
  • With esy sh -c 'echo $OCAMLFIND_DESTDIR' it points to the cache: /Users/jwalke/github/ReasonNativeProject/node_modules/.cache/_esy/store/s/reason_native_project-0.0.1-a00bddbe/lib

I'm not sure if build-shell should also be pointing to the local project build cache.
But also notice that they have the trailing /lib. Is this expected? esy sh -c echo $cur__install prints the location of the local build cache but without the lib: /Users/jwalke/github/ReasonNativeProject/node_modules/.cache/_esy/store/s/reason_native_project-0.0.1-a00bddbe. I suspect if I had a workaround for number 1, this trailing /lib would cause a problem.

More constrained, compatible variable substitution.

Proposal: #{this} may represent a special esy variable for which portions are expanded ahead of time. This is analogous to opam variables.

It is intentionally invalid bash, so that there's no conflict.

It is more constrained than general string concat. Within #{ }, you can
refer to esy substitution variables like:

  • #{@opam/ocamlfind.install}
  • #{cur.bin}

It's more x-platform:

  • Within #{ }, any / (apart from package @scoping/likethis) is automatically
    converted to platform appropriate directory join.
  • Within #{ }, colon : represents platform compatible path join
    (automatically could be converted to ; on windows).
  • Users would understand that #{ } is substituted at the time packages are
    being built. They are completely replaced by the time anything runs.
  • Within #{ }, $VAR_NAME is converted to the platform appropriate env var.
  • You may still use platform specific variables like $THIS outside of #{ },
    but you'll get no help in automatically converting them to platform agnostic
    path manipulations.

Example:

ocamlFind:

// Before:
"exportedEnv": {
  "OCAMLLIB": {
    "val": "$opam__slash__ocamlfind__install/lib/ocaml",
    "scope": "global"
  }
}
// After:
"exportedEnv": {
  "OCAMLLIB": {
    "val": "#{@opam/ocamlfind.install/lib/ocaml}",
    "scope": "global"
  }
}

ctypes:

// Before:
"exportedEnv": {
  "CAML_LD_LIBRARY_PATH": {
    "val": "$opam__slash__ctypes__lib/ctypes:$CAML_LD_LIBRARY_PATH",
    "scope": "global"
  }
}
// After:
"exportedEnv": {
  "CAML_LD_LIBRARY_PATH": {
    "val": "#{@opam/ctypes.lib/ctypes:$CAML_LD_LIBRARY_PATH}",
    "scope": "global"
  }
}

If this is a good long term approach, then we could start small, by simply migrating to the new form, even if we don't do any special casing of / and : - just so that it's future proof when we do special case them.

`file:` dependencies appear to be built twice: (Now with 200% more Repro)

Repro:

  1. Clone esy-reason-project, and copy the package.json from the example below into the project.
  2. Clone BetterErrors in the directory right next to it. cd esy-reason-project && rm esy.lock && rm -r node_modules && esy install.

The package.json from step one should look like this:

{
  "name": "esy-reason-project",
  "version": "0.1.0",
  "description": "Reason workflow with Esy",
  "license": "MIT",
  "esy": {
    "build": [
      "jbuilder build 2>&1 | esy berror.exe --path-to-refmttype refmttype"
    ],
    "install": [
      "esy-installer"
    ],
    "buildsInSource": "_build"
  },
  "dependencies": {
    "@esy-ocaml/esy-installer": "^0.0.0",
    "@opam/jbuilder": "^1.0.0-beta14",
    "@opam/lambda-term": "^1.11.0",
    "@opam/lwt": "^3.1.0",
    "@opam/reason": "^3.0.0",
    "ocamlBetterErrors": "file:../BetterErrors"
  },
  "peerDependencies": {
    "ocaml": "~4.2.3000"
  },
  "devDependencies": {
    "@opam/merlin": "^3.0.3",
    "ocaml": "~4.2.3000"
  }
}

The install and build should go as expected.

However, now you can repro the bug once it's built successfully:

  1. Edit the package.json "description" field in any way.
  2. Then run esy build.

You will see the following output - the file: dependency being built twice every time.

esy build
esy build v0.0.34
  → ocamlBetterErrors @ 3.0.0                        BUILT unchanged
esy build v0.0.34
  → ocamlBetterErrors @ 3.0.0                        BUILT in 1.009s
  → esy-reason-project @ 0.1.0

rm node_modules/.cache and the problem will go away!

`file:` dependencies that fail to build point to wrong log file

package.json

{
  "name": "wall-example",
  "version": "0.0.1",
  "dependencies": {
    "@opam/wall": "file:/Users/me/github/wall"
  },
  "esy": {
    "build": [
      "make example"
    ]
  },
  "peerDependencies": {
    "ocaml": "esy-ocaml/ocaml#4.4.2+esy"
  },
  "devDependencies": {
    "ocaml": "esy-ocaml/ocaml#4.4.2+esy"
  },
  "resolutions": {
    "**/@opam/ocamlbuild": "esy-ocaml/ocamlbuild#0.11.0-esy"
  }
}

esy install && esy build gives an error on the file: dependency of wall -
for an unrelated build reason.

However, it tries to tell me about the error log in the global cache, when it's
actually located in the local node_modules store so it can't find it.

esy build v0.0.34
  → @opam/stb_truetype @ 0.3.0                       BUILT unchanged
  → @opam/wall @ 0.0.1                              FAILED

ENOENT: no such file or directory, open '/Users/me/.esy/3/.0.1-618fe6e8/_esy/log'
Error: ENOENT: no such file or directory, open '/Users/me/.esy/3/.0.1-618fe6e8/_esy/log'
    at Error (native)
    at Object.fs.openSync (fs.js:641:18)
    at Object.fs.readFileSync (fs.js:509:33)
    at Object.readFileSync (/Users/me/.npm-packages/lib/node_modules/esy/bin/esy.js:27339:13)
    at reportBuildError (/Users/me/.npm-packages/lib/node_modules/esy/bin/esy.js:58486:45)
    at _callee2$ (/Users/me/.npm-packages/lib/node_modules/esy/bin/esy.js:58325:15)
    at tryCatch (/Users/me/.npm-packages/lib/node_modules/esy/bin/esy.js:120099:40)
    at GeneratorFunctionPrototype.invoke [as _invoke] (/Users/me/.npm-packages/lib/node_modules/esy/bin/esy.js:120333:22)
    at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (/Users/me/.npm-packages/lib/node_modules/esy/bin/esy.js:120151:21)
    at step (/Users/me/.npm-packages/lib/node_modules/esy/bin/esy.js:102:30)

Actual File Is AT:

node_modules/.cache/_esy/store/b/opam__slash__wall-0.0.1-618fe6e8/_esy/log

Corrupt `build-dependencies` invalid syntax.

The generated build-dependencies file is corrupt. See the fiif:

prevMtime=$(cat "/Users/jwalke/github/wall-example/node_modules/.cache/_esy/store/b/opam__slash__wall-0.0.1-7c1bef1c/_esy/mtime")
curMtime=$(findMaxMtime "/Users/jwalke/github/wall-example/node_modules/@opam/wall")
if [ "$curMtime" -gt "$prevMtime" ]; then
  buildDependencies
  return
fiif [ ! -d "/Users/jwalke/github/wall-example/node_modules/.cache/_esy/store/i/opam__slash__stb___truetype-0.3.0-321cb8bf" ]; then
  buildDependencies
  return
fi

The top level project is wall-example, which has wall as a file:/ dependendency which itself has stb_truetype as another file dependency of wall.

Installing a bs dependency and workflow

so let say I want to run the following module, LogIt.re, with esy.

  • Logit.re
type company = {
  name: string,
  url: string
};

module Decode = {
  let company = (json) =>
    Json.Decode.{name: json |> field("name", string), url: json |> field("url", string)};
};

let co = {|

     {"name": "Agriconomie", "url": "http://www.agriconomie.com/"}

|};

co |> Js.Json.parseExn |> Decode.company |> Js.log;
  1. I started by cloning, installing, building and testing the easy-reason starter.
  2. What directory would i put this module in?
  3. It requires bs-json for Json.Decode. Do I run esy add bs-json? running esy build after installing get the following error
$ esy build
  → bs-json @ 0.2.4                                  BUILT in 0.023s
  → esy-reason-project @ 0.1.0
  → esy-reason-project @ 0.1.0: build failed:

  # COMMAND: refmterr jbuilder build
        ocamlc lib/lib.{cmi,cmo,cmt}
  refmt lib/Logit.re.ml
  ocamldep lib/lib.depends.ocamldep-output
  ocamlc lib/lib__Logit.{cmi,cmo,cmt} (exit 2)
  (cd _build/default && /Users/shingdev/.esy/3/i/ocaml-4.2.3001-82b3b0b7/bin/ocamlc.opt -w -40 -w +26 -g -bin-annot -I /Users/shingdev/.esy/3/i/opam__slash__camomile-0.8.7-8778e185/lib/camomile -I /Users/shingdev/.esy/3/i/opam__slash__lambda_term-1.12.0-8b2df3e3/lib/lambda-term -I /Users/shingdev/.esy/3/i/opam__slash__lwt-3.1.0-52b34212/lib/lwt -I /Users/shingdev/.esy/3/i/opam__slash__lwt___react-1.1.0-b2383eb4/lib/lwt_react -I /Users/shingdev/.esy/3/i/opam__slash__ocamlfind-1.7.3-1bbb67dd/lib/bytes -I /Users/shingdev/.esy/3/i/opam__slash__ocamlfind-1.7.3-1bbb67dd/lib/ocaml -I /Users/shingdev/.esy/3/i/opam__slash__react-1.2.1-b5c79337/lib/react -I /Users/shingdev/.esy/3/i/opam__slash__result-1.2.0-b8d0c7ef/lib/result -I /Users/shingdev/.esy/3/i/opam__slash__zed-1.6.0-e838b04b/lib/zed -no-alias-deps -I lib -open Lib -o lib/lib__Logit.cmo -c -impl lib/Logit.re.ml)
  lib/Logit.re:8 4-15
   5 │
   6 │ module Decode = {
   7 │   let company = (json) =>
   8 │     Json.Decode.{name: json |> field("name", string), url: json |> field("url", string)};
   9 │ };
  10 │
  11 │ let co = {|

  Error: Module `Json;` not found in included libraries.
  Hint: your build rules might be missing a link. If you're using:
   - Oasis: make sure you have `json;` under `BuildDepends` in your _oasis file.
   - ocamlbuild: make sure you have `-pkgs json;` in your build command.
   - ocamlc | ocamlopt: make sure you have `-I +json;` in your build command before the source files.
   - ocamlfind: make sure you have `-package json; -linkpkg` in your build command.
  • package.json after install
{
  "name": "esy-reason-project",
  "version": "0.1.0",
  "description": "Reason workflow with Esy",
  "license": "MIT",
  "esy": {
    "build": [
      [
        "refmterr",
        "jbuilder",
        "build"
      ]
    ],
    "install": [
      "esy-installer"
    ],
    "buildsinsource": "_build"    
  },
  "dependencies": {
    "@esy-ocaml/esy-installer": "^0.0.0",
    "@opam/jbuilder": "^1.0.0-beta14",
    "@opam/lambda-term": "^1.11.0",
    "@opam/lwt": "^3.1.0",
    "@opam/reason": "^3.0.0",
    "bs-json": "^0.2.4",
    "refmterr": "^3.0.4"
  },
  "peerDependencies": {
    "ocaml": "~4.2.3000"
  },
  "devDependencies": {
    "@opam/merlin": "^3.0.3",
    "ocaml": "~4.2.3000"
  }
}

Thank you.

Completely ignore any dependencies that don't have an "esy" field in package.json.

This is a Good First Task for anyone looking to help out.

We should ignore any dependencies (even dev dependencies) that don't have an esy field in their package.json. If we encourage people to use esy to not only manage their opam projects, but also their JavaScript projects, then we'll get into situations where npm pacakges have a lot of devDependencies that are totally irrelevant. Currently, they are added to various PATHs, completely pointlessly. It only serves to hurt performance, so let's skip over them.

Difference in `esy build-shell` and `esy build`

In an unrelated issue I noticed a difference in the environment between esy build-shell and esy build:

I think $OCAMLFIND_DESTDIR variable is configured slightly differently than it should be. Here's what it is for my ReasonNativeProject:
Inside of esy build-shell: the variable is set to /Users/jwalke/.esy/3.x.x________________________________________________________________/s/reason_native_project-0.0.1-a00bddbe/lib
With esy sh -c 'echo $OCAMLFIND_DESTDIR' it points to the local project cache: /Users/jwalke/github/ReasonNativeProject/node_modules/.cache/_esy/store/s/reason_native_project-0.0.1-a00bddbe/lib

I don't think OCAMLFIND_DESTDIR is used for anything right now, but this made me wonder if other variables differ as well - and should they?

I don't think we want to be polluting the global .esy cache with local project builds, and I could see that happening if the build-shell env vars didn't take into account the local sandbox.

Brainstorm/questions for "esy fast build"

  1. I wonder how the esy my command environment will play with this "fast build command" feature we've been discussing. esy build creates a full build of all dependencies, and totally clean build of the current project into a local ./node_modules/.cache directory. esy my command then augments the current environment with all the dependencies as well as the current project's full clean build in the ./node_modules/.cache directory. If we have a "fast build command", that wouldn't create a full clean build, but rather do one in the current source tree. You could imagine doing both esy build and then also the "fast build". What would esy my command augment the environment with? The full clean build in node_modules/.cache? The locally build project? Or perhaps whichever one was last executed?
  2. Since esy my command augments the environment with a few more env variables (so it works with editors etc), I think you were correct that for "fast rebuilds", we will need something other than esy make build. We want the "fast build" feature to have the exact same environment as esy build but without all the file copying.

`esy my command` doesn't augment `OCAMLPATH` with local build.

I noticed that esy sh -c 'echo $PATH' intuitively includes the bin directory for the currently built project. However, esy sh -c 'echo $OCAMLPATH' doesn't include the current project's library directory. Is this intended? If so feel free to close, otherwise I'm curious about the reasoning.

I was creating a tutorial/example and I wanted to demonstrate how after building your local project, it's libraries were installed and visible by way of esy ocaml list. But I noticed my library wasn't showing up because the esy command doesn't augment OCAMLPATH the way it does PATH.

Improve error reporting for "esy install" command

At least we have two issues:

  • When deps are masked by the OCaml version constraint we need to report that
  • When dep specified by resolutions doesn't satisfy constraints we need to report the package the constraint originated from (this might be the case we need to add another resolution for that package)

`esy clean` fails to remove _build directory

On esy 0.0.35, on the reason project:

~/src/reason$ esy clean
rm: cannot remove '/home/zach/src/reason/_build': Is a directory

Best guess is we just need to make it a rm -rf command.

I think this only happens after having executed esy make, as that's what creates the _build directory in the project folder. Using esy make clean works.

new esy x command runs slow

Version:0.0.37
On the Reason repo, I ran esy install && esy build. Then running esy x which refmt is really slow for some reason. Fifteen seconds each time. Is it rebuilding the repo each time?

Make esy invocation faster

Currently esy invocation does:

  • esy install
  • esy build

esy install part is slow as it spawns Node process which checks esy.lock and node_modules for staleness. Consider ejecting that into a bash script.

Converting OPAM packages manually

From readme: Converting OPAM packages manually

If im understanding this correctly the script is uses import-opam to import lwt 3.1.0 and ./opam to a generated package.json file.

We would then import the lwt with package.json into our esy project via something like esy add path/to/lwt. Didnt get this far because the import-opam command fail as seen below.

shingdev at cosmos in ~/code/ESY
$ git clone https://github.com/ocsigen/lwt
Cloning into 'lwt'...
remote: Counting objects: 10558, done.
remote: Compressing objects: 100% (97/97), done.
remote: Total 10558 (delta 139), reused 148 (delta 113), pack-reused 10347
Receiving objects: 100% (10558/10558), 7.48 MiB | 7.31 MiB/s, done.
Resolving deltas: 100% (6923/6923), done.

shingdev at cosmos in ~/code/ESY
$ cd lwt/

shingdev at cosmos in ~/code/ESY/lwt on master
$ esy import-opam lwt 3.1.0 ./opam > package.json

shingdev at cosmos in ~/code/ESY/lwt on master [?]
$ cat package.json
error: ENOENT: no such file or directory, open './opam'
Error: ENOENT: no such file or directory, open './opam'

Have Merlin (or editors) source the correct `OCAMLPATH` automatically.

Merlin works by examining the OCAMLPATH. It does this correctly (I previously thought there was an issue in merlin). This works with opam because opam has you install all dependencies globally.

Right now, if you open a project in your editor with vim etc, merlin sees the OCAMLPATH that your version of ocamlmerlin was built with. If using reason-cli, that will be the OCAMLPATH of reason-cli's dependencies etc. If using opam, that will be the global opam switch's `OCAMLPATH and so on.

Since we'd like to discourage global switches and discourage people from having to configure environment variables, we would like a better solution.

Option 1: Make all editor plugins read from a generated .ocamlpath file (really, more generally, we'd want a more general .env file (there's precedence for this)).

Downsides:

  • We'd have to write the editor plugins and they are a little tricky.
    • The trick is creating the illusion that environment configuration shadows an underlying "base" env (which is the environment without your build's influence). So the algorithm for sourcing should maintain a base environment and a current "overlay" and always update correctly when things are added/removed to the overlay.
    • We have to determine the right file to source - what if you have multiple files open from multiple projects? Which environment computation do you use to get the .env file? Perhaps we could reuse some of merlin's own logic for resolving .merlin files?
  • Our editor plugins need to know when to re-source that environment(s?) anytime the env script changes.

Upsides:

  • This appears to be a pretty well established pattern for other languages like ruby (ruby envs) so maybe we can just copy their editor plugins (saves work).

Option 2: Have the package manager generate a .merlin file consisting of of "FINDLIB_PATH " + OCAMLPATH.split(':'). The FINDLIB_PATH entry in .merlin totally works in merlin even today.
Upsides:

  • It would work with all merlin versions and doesn't require a change to merlin and doesn't require writing many editor plugins.

Downsides:

  • We still would want to build that env sourcing addition to our editor plugins anyways for other good reasons.
  • It wouldn't work when there's already a .merlin file. Fortunately for your typical jbuilder project, we could get away with this because the top level directory of a project does not have a .merlin computed. For other projects we wouldn't be so lucky and we'd have to mutate the project's .merlin file. Otherwise we'd need to make merlin support multiple .merlin files (also a cool feature though).
  • esy should generate this on esy build, and right now the file system sandbox errors (correctly so). We'd have to whitelist this.

Perhaps we should actually implement both of these in the long term. But what's the best/fastest way to get the feature into people's hands?

cc @let-def
cc @IwanKaramazow

@opam/num build fails

Relevant log:

### ORIGINAL COMMAND: make
### RENDERED COMMAND: make
### CWD: /Users/andreypopp/.esy/3______________________________________________________________/b/opam__slash__num-1.1.0-ffa36e64
...
### ORIGINAL COMMAND: make install
### RENDERED COMMAND: make install
### CWD: /Users/andreypopp/.esy/3______________________________________________________________/b/opam__slash__num-1.1.0-ffa36e64
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C src install
ocamlfind install num META
Installed /Users/andreypopp/.esy/3______________________________________________________________/s/opam__slash__num-1.1.0-ffa36e64/lib/num/META
install -m 644 nums.cma libnums.a big_int.cmi nat.cmi num.cmi ratio.cmi arith_status.cmi big_int.mli nat.mli num.mli ratio.mli arith_status.mli big_int.cmti nat.cmti num.cmti ratio.cmti arith_status.cmti nums.cmxa nums.a big_int.cmx nat.cmx num.cmx ratio.cmx arith_status.cmx nums.cmxs /Users/andreypopp/.esy/3______________________________________________________________/i/opam__slash__ocamlfind-1.7.3-b7348a7e/lib/ocaml
install: /Users/andreypopp/.esy/3______________________________________________________________/i/opam__slash__ocamlfind-1.7.3-b7348a7e/lib/ocaml/nums.cma: Operation not permitted
make[1]: *** [install] Error 71
make: *** [install] Error 2

Make sure projects can be moved on disk.

Perhaps lower priority, but we should make it so that projects can be moved on disk.

I had a project esy-reason-project, which I moved to another-reason-project, and it failed with this line when trying to run esy build:

/Users/jwalke/Desktop/another-reason-project/node_modules/.cache/_esy/build/bin/build: line 9: /Users/jwalke/Desktop/esy-reason-project/node_modules/.cache/_esy/build/bin/build-dependencies: No such file or directory

Make `esy eject` resilient to multiple calls to postinstall

End goal: Make it so people can do yarn install -g http://url-for/reason-cli.tar.gz.
Right now people can install reason-cli with yarn but yarn has this problem that when you later install any other package globally, it will recall your reason-cli postinstall. I believe the solution could be pretty simple - we could just check to see if we've already invoked postinstall in the past (by looking at the directory layout or something) and then bail out. This is also a blocker to using esy/reason-cli internally, since we have to use yarn to install reason-cli (for not-important/interesting reasons).

esy link workflow errror:

Here's my main esy.json:

{
  "name": "@opam/wall",
  "version": "0.0.1",
  "dependencies": {
    "@esy-ocaml/substs": "^0.0.1",
    "@esy-ocaml/esy-installer": "^0.0.0",
    "@opam/ocamlfind": "",
    "@opam/gg": "*",
    "@opam/tgls": "*",
    "@opam/tsdl": "*",
    "@opam/result": "*",
    "@opam/stb_image": "*",
    "@opam/stb_truetype": "*",
    "@opam/grenier": "*",
    "@esy-ocaml/sdl2": "file:../esy-ocaml/SDL-mirror"
  },
  "peerDependencies": {
    "ocaml": "*"
  },
  "esy": {
    "build": [
      [ "make" ],
      [ "make", "install" ],
      [ "esy-installer" ]
    ],
    "buildsInSource": true
  },
  "devDependencies": {
    "ocaml": "~4.2.3000"
  }
}

Notice that I haven't published @esy-opam/sdl2 yet, but I have a clone locally.
I run esy install and it correctly installs everything.
Then I run esy add link:../esy-ocaml/SDL-mirror.
It creates a package.json with the following contents:

{
  "name": "@opam/wall",
  "version": "0.0.1",
  "dependencies": {
    "@esy-ocaml/esy-installer": "^0.0.0",
    "@esy-ocaml/sdl2": "link:../esy-ocaml/SDL-mirror",
    "@esy-ocaml/substs": "^0.0.1",
    "@opam/gg": "*",
    "@opam/grenier": "*",
    "@opam/ocamlfind": "",
    "@opam/result": "*",
    "@opam/stb_image": "*",
    "@opam/stb_truetype": "*",
    "@opam/tgls": "*",
    "@opam/tsdl": "*"
  },
  "peerDependencies": {
    "ocaml": "*"
  },
  "esy": {
    "build": [
      [
        "make"
      ],
      [
        "make",
        "install"
      ],
      [
        "esy-installer"
      ]
    ],
    "buildsInSource": true
  },
  "devDependencies": {
    "ocaml": "~4.2.3000"
  }
}

And then begins building after the add command with the following error:


FAILED @esy-ocaml/sdl2 (node_modules/@esy-ocaml/sdl2)
  The error below is likely a bug in Esy itself, please report it.

  Error: EINVAL: invalid argument, readlink '/Users/jwalke/github/wall/node_modules/.cache/_esy/store/b/esy_ocaml__slash__sdl2-2.0.5-cea959ab'
    at Error (native)

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.