I was about to create another thread kind of related to this, please my 
apologies if I misunderstood.

Recently I started working on a package, and I wanted to share as part of 
the package a lot of TestSupport codes that people would take advantage of 
in testing. So the dilemma I am having is where to put that TestSupport 
files:

A. Create a new package called `myname_test_support` just so people could 
add the package as `only: [:test]` dependency? This is ideally the cleanest 
way but at a high cost of maintains.
B. Add the test support files as part of `myname` and document that people 
shouldn't use the modules in production? This is the easiest way but we 
bundle things in to production code that we don't want, or in the worst 
case, some programmers don't read the manual and use it as normal 
production code.
C. Trying to do some sort of dead-code elimination doing like `if 
Mix.group_choice(:mode, "test") == :test do  .... end` wrapping the entire 
code in that module? Maybe this is what may be related to this topic, I 
can't tell. Also, I wouldn't like to bundle those stuff into prod btw, not 
sure if things like that in your proposal would still do it.
On Friday, August 13, 2021 at 3:08:07 PM UTC-4 José Valim wrote:

> From an initial glance, I don't think this needs to be pushed to the 
> tooling.
>
> I would create an application that sits in the middle and works as an 
> adapter that knows how to interface with both libraries, and the user can 
> configure which one they choose. Both libraries are optional dependencies 
> but the adapter can ensure at least one is available. Not much different 
> than how Ecto SQL can work with multiple or zero libraries.
>
> On Fri, Aug 13, 2021 at 8:39 PM Zach Daniel <zachary....@gmail.com> wrote:
>
>> I originally opened a github issue on hex, but it was pointed out 
>> (correctly) that this is actually a `mix` proposal not a `hex` proposal.  
>> https://github.com/hexpm/hex/issues/899
>>
>> Original Proposal Text:
>>
>> # The problem
>>
>> Ash Framework comes with a dependency called [picosat_elixir](
>> https://github.com/bitwalker/picosat_elixir), which uses a NIF. This 
>> causes problems for some users, so I've implemented a (slower) alternative 
>> natively in Elixir using [csp](https://github.com/Lakret/csp). However, 
>> I don't really want most people using the `csp` dependency unless they 
>> encounter problems with the `picosat_elixir` dependency. So I'm looking for 
>> behavior that is essentially "one of these dependencies needs to be 
>> specified, but if none of them are, use `picosat_elixir` as the default". 
>> This seems like it could be useful for other use cases, like 
>> `json_formatter` or `http_library`, allowing for a more seamless initial 
>> installation process, and automatically choosing the recommended library.
>>
>>
>> # The temporary hacky workaround
>> I haven't actually released this yet, but in Ash we'd have:
>>
>> ```elixir
>> {:picosat_elixir, "~> 0.1.5"},
>> {:csp, "~> 0.1.0", optional: true},
>> ```
>>
>> And then there is a troubleshooting guide that instructs people who 
>> really can't get picosat_elixir set up to add the following to their 
>> dependencies:
>>
>> ```elixir
>> {:picosat_elixir, override: true, only: []},
>> {:csp, "~> 0.1.0"},
>> ```
>>
>> Less than ideal :D
>>
>> # The proposal: Optional Dependency Groups
>>
>> This is just one potential way it could be implemented:
>>
>> ```elixir
>> defp deps do
>>   {:picosat_elixir, "~> 0.1.5", group_default: true, group: "Sat Solver"},
>>   {:csp, "~> 0.1.0", group: "Sat Solver"}
>> end
>> ```
>>
>> We could also use `priority`, e.g `group_priority: 1`, `group_priority: 
>> 2`, and then choose the highest priority dependency that has no conflicts.
>>
>> And then of course if one of the dependencies is explicitly configured in 
>> the user's `deps` then we just use that one no matter what.
>>
>> The benefits of a strategy like this:
>>
>> Right now, the typical way of switching on dependencies is something like:
>>
>> ```elixir
>> if Code.ensure_loaded?(ModuleInDependency) do
>>   ...
>> end
>> ```
>>
>> That is theoretically brittle depending on what module you choose. Some 
>> other dependency they use could also (very unlikely, but possible) define a 
>> module of the same name. But since mix has the group names, we could do 
>> something like this:
>>
>> ```elixir
>> if Mix.group_choice(:ash, "Sat Solver") == :picosat_elixir do
>>   ....
>> end
>> ```
>>
>> I'm sure there are probably a few aspects of this I haven't considered, 
>> but it seems like it could be useful for others as well.
>>
>> We could also display the group something was installed for/the reason of 
>> it when installing, e.g
>>
>> ```elixir
>> csp 0.1.0 (Group: "Sat Solver")
>> ```
>> Images of the comments attached:
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "elixir-lang-core" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to elixir-lang-co...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/elixir-lang-core/2595654f-86ce-4524-9233-f0bf4614561en%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/elixir-lang-core/2595654f-86ce-4524-9233-f0bf4614561en%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/e70ee1a0-3534-407a-927e-270e5f3ddbffn%40googlegroups.com.

Reply via email to