On 2019/08/15 18:51:29, Joan Touzet <woh...@apache.org> wrote:
> Hi Ilya,
>
>
> On 2019-08-15 10:09, Ilya Khlopotov wrote:
> > Hello,
> >
> > There is an https://github.com/apache/couchdb/issues/1428 issue about
> > migrating to rebar3 or mix. I did an experiment to switch from rebar into
> > mix and wanted to share the results. The code for experiment is here
> > https://github.com/apache/couchdb/compare/master...cloudant:switch-to-mix.
> > Overall I am happy with the experiment.
> >
> > # Requirements
> >
> > 1. Should be able to compile dependencies which use either rebar or rebar3
> > 2. Should be able to lock dependencies to specific versions using
> > references to commits
> > 3. Should be able to call eunit test suite
> > 4. Should be able to compile NIFs
> > 5. Should be easy to install plugins
> > 6. Should support dialyzer
> > 7. Should support release managers
> > 8. Support for raw dependencies
> > 9. Produce source tarball suitable for offline compilation (ASF requirement)
> >
> > # How mix supports the requirements
> >
> > 1. Mix is able to figure out which build tool to use. There is also a
> > possibility to specify build tool individually for a given dependency.
> > `manager: mix | rebar | rebar3 | make`. There is also support for calling
> > arbitrary shell command configured via `compile: <command>`. The manual
> > step is required to install the needed tools `mix local.rebar --force`.
> > However there are means to automate that step (we can use Makefile or
> > define a `bootstrap` mix alias )
> > 2. Dependencies are locked via `mix.lock` file.
>
> I don't have any strong opinions one way or the other, but I did see
> Garren asking about 'hex' instead of / in conjunction with 'mix' for
> dependency management. Is this effort combined with his or independent?
> I don't know the tools well enough.
mix works very well with hex
>
> > 3. Eunit is supported via one of the mix plugins. Both plugins are very old
> > but it should be easy to write our own (32 lines of code).
> > - https://github.com/dantswain/mix_eunit
> > - https://github.com/talentdeficit/mixunit
> > 4. NIFs can be compiled using one of the following approaches:
> > - specify `rebar` as build manager for a dependency (easiest)
>
> Are you considering staying with rebar2 here, or moving to rebar(3)? It
> would be nice not to have to keep supporting (and shipping!) our fork of
> rebar2.
I considered to stay with rebar2 for first iteration. Could you remind me why
we are forking rebar?
I did check that our version has no differences from upstream.
git remote -v
origin https://github.com/apache/couchdb-rebar (fetch)
origin https://github.com/apache/couchdb-rebar (push)
upstream https://github.com/rebar/rebar (fetch)
upstream https://github.com/rebar/rebar (push)
git log --oneline origin/master | head
0c435f3 Update master with mainline rebar (v2)
b6d3094 Merge pull request #620 from tuncer/travis-dialyze
8a2aca0 travis-ci: allow Dialyzer job to fail
16d5dfe travis-ci: update otp versions
4e372a3 travis-ci: enable 20.1
73feb5f rebar_xref: ignore opaque type match Dialyzer warning
b05882a rebar_cover: ignore opaque type match Dialyzer warning
903c89d rebar_utils: fix Dialyzer warning
b36e72b Run Dialyzer on Travis-CI
4bd43fe Merge pull request #645 from Juliusan/log_fix
git log --oneline upstream/master | head
b6d3094 Merge pull request #620 from tuncer/travis-dialyze
8a2aca0 travis-ci: allow Dialyzer job to fail
16d5dfe travis-ci: update otp versions
4e372a3 travis-ci: enable 20.1
73feb5f rebar_xref: ignore opaque type match Dialyzer warning
b05882a rebar_cover: ignore opaque type match Dialyzer warning
903c89d rebar_utils: fix Dialyzer warning
b36e72b Run Dialyzer on Travis-CI
4bd43fe Merge pull request #645 from Juliusan/log_fix
2276f85 Log out success message with newlines
git diff origin/master upstream/master
>
> > - call a Makefile from mix.exs. See examples:
> > - https://github.com/SweetIQ/expostal/blob/master/mix.exs#L9
> > - https://github.com/asaaki/discount.ex/blob/master/mix.exs#L6
> > - use https://github.com/davisp/erlang-native-compiler
> > - use https://github.com/blt/port_compiler
>
> Paul left a comment about this on the roadmap issue just today. Can you
> respond to his comment (it was related tot dependencies-of-dependencies,
> i.e. jiffy)
>
> He also raised the concern that it may force us to use only the very
> latest Erlang versions - can you comment on this? Does the current
> hex/mix situation require a minimum version? What version is that?
I did use erlang 20.3.8.14 and elixir 1.6.6. However 1.6.6. is supported on
erlang 19 which is AFAIK a minimal erlang version CouchDB supports.
> > 5. Installing plugins for mix is similar to rebar3. It is sufficient to
> > just specify list of plugins in the deps in mix.exs
> > 6. There are multiple dyalizer plugins to choose from
> > - https://github.com/jeremyjh/dialyxir
> > - https://github.com/gabrielgatu/mix-dialyzer
>
> I know this is a requirement for Cloudant, but today isn't for base
> CouchDB. I would prefer not to introduce this requirement at the same
> time as migrating build tool.
The reason I mentioned it here is because we have 'make dialyze' command.
> > 7. Multiple release managers are supported via mix plugins
> > - distillery is supported via
> > https://hexdocs.pm/distillery/Mix.Releases.Plugin.html
> > - relx and reltools can be used via https://github.com/bitwalker/exrm
> > (deprecated in favor of distillery)
> > - we can also roll our own mix alias using
> > https://github.com/okeuday/reltool_util
> > - latest elixir versions have `release` command out of the box
> > 8. Raw dependencies are supported via `compile: false` option
> > 9. I think it is doable. In the worst case scenario we could just tar the
> > content of `src` directory after calling `mix deps.get`
> >
> > # Warts of mix in the context of CouchDB project
> >
> > - CouchDB doesn't use standard elixir directories layout which caused
> > include_lib directives to not work. To solve this issue absolute path to
> > `<root>/src` need to be added into include path
> > - for dependencies managed by mix it is done via `erlc_options` parameter
> > - Unfortunately when we call out to rebar there is no way to modify
> > arguments. The problem was solved via setting `ERL_COMPILER_OPTIONS`
> > environment variable. Which is not very elegant solution.
>
> This may also cause problems on Windows, where we have very specific
> requirements for compiler options so as to ensure the correct libraries
> are linked for couchjs and so on.
>
> Have you tried compiling on that platform? ;) (Please don't make me do
> all the work here, again...)
>
> > - We need to create empty `rebar.config` file for erlang applications which
> > do not have `rebar.config` (all applications in couchdb repo). This problem
> > can be fixed by adding mix.exs to dependencies we have control over.
> > - The mix is slow when we have to call out to rebar. This problem can be
> > fixed by adding mix.exs to dependencies we have control over.
>
> How much slower? Can you post a comparison of `time make couch` between
> master and your branch?
master:
> time bin/rebar get-deps update-deps
real 0m37.514s
user 0m1.960s
sys 0m3.300s
> time make couch
real 0m49.677s
user 0m46.910s
sys 0m22.210s
mix:
> time mix do deps.get
real 0m24.405s
user 0m1.590s
sys 0m1.270s
> time mix deps.compile
real 3m47.968s
user 0m0.860s
sys 0m0.640s
> > # Roadmap
> >
> > The full conversion would take some time and if we decide to go with mix it
> > makes sense to do it incrementally. Possible roadmap could be:
> > - initial PR
> > - offload dependency fetching to mix.exs and generate rebar.config so
> > release machinery still works
> > - Update Makefile targets to call mix
> > - Choose or implement eunit plugin for mix
> > - Support running tests individually (replacement for `make eunit apps=
> > tests= suites=`)
> > - Replace rebar plugins we use with alternative solutions
> > - Figure out how to use dialyzer
> > - Figure out how to use mix for preparing release
>
> Anything that lands on master must support release preparation. If your
> incremental approach breaks `make dist`, you'll need to stage all of
> your incremental changes on a feature branch and fix `make dist` before
> merging to master. master needs to be releasable at all times.
+1000
> > Best regards,
> > ILYA (aka iilyak)
>
> -Joan "release engineer hat is now off" Touzet
>
>