Replies: 3 comments 7 replies
-
The long term clean solution is rather (in my opinion) to extract things that are shared by multiple applications, and extract them into another application which the original users can then rely on to build. The cyclic dependencies across many apps tend to be a consequence of unclear ownership around definitions and business concerns. Understandably, this is really complex and hard to fix after the fact, which is why Rebar3 always required this behaviour in dependencies. Our original use cases more or less omitted huge monolithic apps, and in my opinion, the proper policy that would fit rebar3's overall design to be most consistent would be to keep these forcing functions into the compiler's DAG handling to have a uniform policy in place: deps obey the same rules as top-level apps. So the problem I see here is that allowing and absorbing workaround solutions for the sake of easing people's migrations still require adding code to support things in the same manner as if it were a fully-supported feature, which later down the road does limit the amount of things we can do in terms of migrations, optimizations and whatnot. It is code that adds complexity to the rebar3 codebase to allow external users to work-around theirs, but also code that under ideal principles is vowed to be removed as people should intend to clean up their design. I realize this is a very opinionated stance that is not helpful for your specific case, since it's essentially saying "ideally you fix this yourself and we don't have to care about it here." I think some workarounds may make sense, but I really hate adding more and more features that have to get long-term support for projects we have no visibility into. Whatever we add would need to be minimal enough to have low overheads and to be easy to take out in isolation to be acceptable, so that we can clearly wall it off as a cognitive burden for maintenance. A small one that could make sense is to look at the extension of some files when we find cross-application dependencies when we build the app sorting order, and process .erl file before .hrl files since the .erl files tend to be hard dependencies (behaviours and parse transforms) and .hrl files are not. The gotcha here is that the compiler does not currently make a distinction (or have information) about the context of what is a source or header file in the sorting function, and that the DAG structure is part of a public API so we can't just start annotating vertices for fun without breaking other compilers (we do have our own bad design and debt to carry; we could add artifact-tracking because we added new callbacks for them and can look at their presence to prevent introducing them when unsupported). What we do have however is a context mapping that each compiler can carry, which could be passed around at the call-site. This will allow to provide a small heuristic, but will still represent a major edge case for things like LFE ( |
Beta Was this translation helpful? Give feedback.
-
The one when you build the compile order
…On Fri, 29 Jan 2021, 13:37 Fred Hebert, ***@***.***> wrote:
Okay maybe there's something odd in what we're saying here. Do you mean
expanding the dependencies when building the base DAG or when defining the
compilation sorting order? Because these are two distinct steps and I'm not
100% sure what you mean there.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2465 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABJAFO6P3BJW27TAFC2EYTS4K2YZANCNFSM4V5VQOXA>
.
|
Beta Was this translation helpful? Give feedback.
-
the PR was at #2480 and has been merged. |
Beta Was this translation helpful? Give feedback.
-
Issue #2462 lead me to discover a problem which we don't really know how to tackle within the current bounds of what rebar can do, namely the fact that we have lots of "header dependency cycles", i.e. cycles where two or more applications include header files from each other. These are really harmless, but the problem is that they may cause rebar to discard the more important behavior and parse_transform dependencies. Example:
Since our use case is an old and large legacy monolith which has suffered from bad include-file discipline for years, we have lots of these cases where people include stuff all over the place, so we have quite a number of these header-file dependency cycles, and they cause Rebar to drop the more vital behavior dependencies when they are the once introducing a cycle.
My current workaround for this is to use a fork of rebar where compile-order only considers dependencies to
.erl
files, dropping once which refer to.hrl
files. This seems to work well for us, but I'm not sure how acceptable this would be to backport upstreams.Beta Was this translation helpful? Give feedback.
All reactions