PR here https://github.com/elixir-lang/elixir/pull/13647

On Thursday, June 6, 2024 at 2:48:00 PM UTC-5 Chris Miller wrote:

> Sounds great to me - and my concern that you couldn't emulate the correct 
> loading a file provided via the command line has be assuaged by realizing 
> you can find the `--dot-iex` arg in `:init.get_plain_arguments` - I'll open 
> up a pr to continue the discussion around implementation there
>
> On Thu, Jun 6, 2024 at 2:44 PM José Valim <jose....@dashbit.co> wrote:
>
>> Let's try starting with a IEx.configure(dot_iex: ...) for now. We could 
>> always support making it a list in the future for multiple paths.
>>
>> On Thu, Jun 6, 2024 at 9:42 PM Chris Miller <camil...@gmail.com> wrote:
>>
>>> > That's tricky, because nowhere in IEx ends-up loading multiple dot_iex 
>>> files, so it would be a departure.
>>> Very true - while it is technically trivial to load multiple files it is 
>>> a departure workflow wise and you _could_ end up with some conflicts 
>>> between the files - that being said, that why I had originally though a 
>>> different key name would provide a different context for the two things - 
>>> there could be the existing dot-iex concept that would work the same way as 
>>> it currently does with the addition of an IEx.Config.configuration_file(s?) 
>>> that would be an additional file(s) that are loaded either before or after 
>>> the dot-iex file
>>>
>>> > But you can always emulate multiple files with import_if_available.
>>> This is also very true! I think the only potential downside I could 
>>> think of for this is that it would be slightly more restrictive than the 
>>> multiple file approach.  If you had a `dot-iex` file configured in your 
>>> project and then ran `iex --dot-iex other_file.exs -S mix` you may be 
>>> confused by the fact that your file didn't get loaded as expected
>>>
>>> That being said - I defer to your judgement on the best approach here 
>>> and if this is valuable!
>>> As always, really appreciate your time and all of your work!
>>>
>>> On Thu, Jun 6, 2024 at 2:29 PM José Valim <jose....@dashbit.co> wrote:
>>>
>>>> That's tricky, because nowhere in IEx ends-up loading multiple dot_iex 
>>>> files, so it would be a departure. But you can always emulate multiple 
>>>> files with import_if_available.
>>>>
>>>> On Thu, Jun 6, 2024 at 9:26 PM Chris Miller <camil...@gmail.com> wrote:
>>>>
>>>>> I think that would get us pretty close to the behavior I was hoping 
>>>>> for - but I was generally hoping that instead of taking precedence over 
>>>>> an 
>>>>> existing dot-iex configured file it could be used in addition to the 
>>>>> existing dot-iex file.  This might be hyper specific to my individual 
>>>>> workflow, but I was hoping that we could add a feature to allow for 
>>>>> application level configuration while also still using the existing 
>>>>> dot-iex 
>>>>> files to provide local configuration
>>>>>
>>>>> An example would be that we would use the new application level 
>>>>> configuration to import some helper function and cat out some 
>>>>> introduction 
>>>>> / instruction to the prompt, while the local would be some functions or 
>>>>> data that I as a developer have around for development / debugging but 
>>>>> are 
>>>>> very specific to my development.
>>>>>
>>>>> What are your thoughts on this multi-file configuration?
>>>>>
>>>>> On Thu, Jun 6, 2024 at 2:19 PM José Valim <jose....@dashbit.co> wrote:
>>>>>
>>>>>> Yeah, we can add a IEx.configure(dot_iex: "..."), which takes 
>>>>>> precedence over the other ones if set. And we should read it in the same 
>>>>>> place we read everything else.
>>>>>>
>>>>>> On Thu, Jun 6, 2024 at 9:08 PM Chris Miller <camil...@gmail.com> 
>>>>>> wrote:
>>>>>>
>>>>>>> I hadn't considered the config, but thats an interesting thought - 
>>>>>>> not entirely sure if I totally get your though on the matter, but I was 
>>>>>>> able to extend the IEx.Config to track a new key (:configuration_files) 
>>>>>>> and 
>>>>>>> then extended the IEx.Evaluator to pull that value from the config and 
>>>>>>> load 
>>>>>>> the configured files plus the `.iex.exs` file.  This allows the feature 
>>>>>>> to 
>>>>>>> be used either through a call to `IEx.configure/1` before the evaluator 
>>>>>>> starts, or the config can be added into any config file, which would 
>>>>>>> allow 
>>>>>>> you to easily swap config files per env if desired 
>>>>>>>
>>>>>>> On Thursday, June 6, 2024 at 1:50:44 PM UTC-5 José Valim wrote:
>>>>>>>
>>>>>>>> I wonder if you could call something like "IEx.configure(...)" from 
>>>>>>>> the top of your mix.exs and that would be enough to configure its 
>>>>>>>> location. 
>>>>>>>> Or maybe it would only require a small tweak to make it work. 
>>>>>>>>
>>>>>>>> On Thu, Jun 6, 2024 at 8:22 PM Chris Miller <camil...@gmail.com> 
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> Actually - I am a little confused by the startup dependencies 
>>>>>>>>> between mix and iex as it seems like the Evaluator is starting after 
>>>>>>>>> mix 
>>>>>>>>> (or at least that how it appears in my tests), this patch to the 
>>>>>>>>> IEx.Evaluator seems to accomplish what I was hoping to achieve (but 
>>>>>>>>> it does 
>>>>>>>>> make IEx depend on Mix which may have been something you wanted to 
>>>>>>>>> avoid, 
>>>>>>>>> but perhaps there is some more abstract way of getting this 
>>>>>>>>> information 
>>>>>>>>> from the mix project to the evaluator) 
>>>>>>>>>
>>>>>>>>> ```elixir
>>>>>>>>>   defp load_dot_iex(state, path) do
>>>>>>>>>     candidates =
>>>>>>>>>       if path do
>>>>>>>>>         [path]
>>>>>>>>>       else
>>>>>>>>>         # Do not assume there is a $HOME
>>>>>>>>>         for dir <- [".", System.get_env("IEX_HOME") || 
>>>>>>>>> System.user_home()],
>>>>>>>>>             dir != nil,
>>>>>>>>>             do: dir |> Path.join(".iex.exs") |> Path.expand()
>>>>>>>>>       end
>>>>>>>>>
>>>>>>>>>     mix_config_file = 
>>>>>>>>> List.wrap(Mix.Project.get().cli()[:iex_configuration_file])
>>>>>>>>>
>>>>>>>>>     candidates
>>>>>>>>>     |> Enum.filter(&File.regular?/1)
>>>>>>>>>     |> Enum.take(1)
>>>>>>>>>     |> Enum.concat(mix_config_file)
>>>>>>>>>     |> Enum.reduce(state, fn path, state ->
>>>>>>>>>       eval_dot_iex(state, path)
>>>>>>>>>     end)
>>>>>>>>>   end
>>>>>>>>> ```
>>>>>>>>> Once again - sorry for the noise if this in not a feature you are 
>>>>>>>>> interested in introducing!
>>>>>>>>>
>>>>>>>>> On Thursday, June 6, 2024 at 12:43:09 PM UTC-5 Chris Miller wrote:
>>>>>>>>>
>>>>>>>>>> Thanks for the reply Jose!  The dependency order makes sense as 
>>>>>>>>>> an issue with my initial thought - one other approach is that a 
>>>>>>>>>> project 
>>>>>>>>>> could define its own method of configuring IEx if there were a hook 
>>>>>>>>>> to 
>>>>>>>>>> allow that - looking at the IEx.Evaluator I was able to make a 
>>>>>>>>>> pretty small 
>>>>>>>>>> patch to allow for this type of configuration by adding a new public 
>>>>>>>>>> function and extending the `loop` function
>>>>>>>>>>
>>>>>>>>>> ```elixir
>>>>>>>>>>   @spec load_dot_iex(pid, pid, String.t()) :: :ok | :error
>>>>>>>>>>   def load_dot_iex(evaluator, server, path) do
>>>>>>>>>>     ref = make_ref()
>>>>>>>>>>     send(evaluator, {:load_dot_iex, server, ref, self(), path})
>>>>>>>>>>
>>>>>>>>>>     receive do
>>>>>>>>>>       {^ref, result} -> result
>>>>>>>>>>     after
>>>>>>>>>>       5000 -> :error
>>>>>>>>>>     end
>>>>>>>>>>   end
>>>>>>>>>>
>>>>>>>>>>  ...
>>>>>>>>>>
>>>>>>>>>>   defp loop(%{server: server, ref: ref} = state) do
>>>>>>>>>>     receive do
>>>>>>>>>>       {:eval, ^server, code, counter, parser_state} ->
>>>>>>>>>>         {status, parser_state, state} = parse_eval_inspect(code, 
>>>>>>>>>> counter, parser_state, state)
>>>>>>>>>>         send(server, {:evaled, self(), status, parser_state})
>>>>>>>>>>         loop(state)
>>>>>>>>>>
>>>>>>>>>>       {:fields_from_env, ^server, ref, receiver, fields} ->
>>>>>>>>>>         send(receiver, {ref, Map.take(state.env, fields)})
>>>>>>>>>>         loop(state)
>>>>>>>>>>
>>>>>>>>>>       {:value_from_binding, ^server, ref, receiver, var_name, 
>>>>>>>>>> map_key_path} ->
>>>>>>>>>>         value = traverse_binding(state.binding, var_name, 
>>>>>>>>>> map_key_path)
>>>>>>>>>>         send(receiver, {ref, value})
>>>>>>>>>>         loop(state)
>>>>>>>>>>
>>>>>>>>>>       {:variables_from_binding, ^server, ref, receiver, 
>>>>>>>>>> var_prefix} ->
>>>>>>>>>>         value = find_matched_variables(state.binding, var_prefix)
>>>>>>>>>>         send(receiver, {ref, value})
>>>>>>>>>>         loop(state)
>>>>>>>>>>
>>>>>>>>>>       # NEW RECEIVE CASE TO LOAD A DOT IEX FILE PROGRAMMATICALY  
>>>>>>>>>>       {:load_dot_iex, ^server, ref, receiver, path} ->
>>>>>>>>>>         next_state = load_dot_iex(state, path)
>>>>>>>>>>         send(receiver, {ref, :ok})
>>>>>>>>>>         loop(next_state)
>>>>>>>>>>
>>>>>>>>>>       {:done, ^server, next?} ->
>>>>>>>>>>         {:ok, next?}
>>>>>>>>>>
>>>>>>>>>>       {:done, ^ref, next?} ->
>>>>>>>>>>         {:ok, next?}
>>>>>>>>>>     end
>>>>>>>>>>   end
>>>>>>>>>> ...
>>>>>>>>>>
>>>>>>>>>> I think that combining this overriding the default mix task would 
>>>>>>>>>> allow for the type of configuration that I was hoping to achieve - 
>>>>>>>>>> or if 
>>>>>>>>>> there is desire for this functionality a small change could be 
>>>>>>>>>> incorporated 
>>>>>>>>>> into mix to do this as a feature using 
>>>>>>>>>> `project.cli()[:iex_configuration_file]` or something of the sort.
>>>>>>>>>>
>>>>>>>>>> If you don't think any of this is necessary in Elixir proper I 
>>>>>>>>>> can move my work towards something at the project level, but wanted 
>>>>>>>>>> to see 
>>>>>>>>>> if there was any interest in upstreaming this concept
>>>>>>>>>> On Thursday, June 6, 2024 at 11:40:51 AM UTC-5 José Valim wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi Chris, thanks for writing.
>>>>>>>>>>>
>>>>>>>>>>> > • will be used when `iex` is run from that directory not in 
>>>>>>>>>>> the context of that mix project
>>>>>>>>>>>
>>>>>>>>>>> The reason this happens is exactly because IEx starts before 
>>>>>>>>>>> Mix, so we can't  use Mix to configure IEx. And I think that will 
>>>>>>>>>>> get in 
>>>>>>>>>>> the way of your proposal too. I hope this helps narrow down a bit 
>>>>>>>>>>> the paths 
>>>>>>>>>>> to explore.
>>>>>>>>>>>
>>>>>>>>>>> On Thu, Jun 6, 2024 at 4:23 PM Chris Miller <camil...@gmail.com> 
>>>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> Currently we use the `dot-iex` file to configure an iex shell.  
>>>>>>>>>>>> The `dot-iex` file that gets loaded is the first of these three 
>>>>>>>>>>>> things that 
>>>>>>>>>>>> is found
>>>>>>>>>>>> • --dot-iex PATH command line argument supplied to the iex 
>>>>>>>>>>>> command
>>>>>>>>>>>> • '.iex.exs' file in the directory that iex is run from
>>>>>>>>>>>> • '.iex.exs' file in directory found in the env var "IEX_HOME" 
>>>>>>>>>>>> OR the users home directory 
>>>>>>>>>>>>
>>>>>>>>>>>> The issue I am facing currently is that project level shell 
>>>>>>>>>>>> configuration is hard to manage in a way that achieves these goals
>>>>>>>>>>>> • will apply configuration when running a shell in the context 
>>>>>>>>>>>> of a particular (mix) project
>>>>>>>>>>>> • will allow for a developer to apply their own particular 
>>>>>>>>>>>> customization
>>>>>>>>>>>> • does not require any additional scripts / arguments to start 
>>>>>>>>>>>> the project
>>>>>>>>>>>>
>>>>>>>>>>>> Existing partial solutions for a project level iex configuration
>>>>>>>>>>>>
>>>>>>>>>>>> • create and commit a `.iex.exs` file for the project
>>>>>>>>>>>> -- PROS:
>>>>>>>>>>>>    • the file will be loaded when `iex -S mix` is run
>>>>>>>>>>>>    • configuration can be specific to the project as it is part 
>>>>>>>>>>>> of the source code written for the project and tracked through 
>>>>>>>>>>>> whatever svc 
>>>>>>>>>>>> is used
>>>>>>>>>>>> -- CONS:
>>>>>>>>>>>>     • does not allow for an individual developer to include 
>>>>>>>>>>>> their own configuration as expected (you could add an 
>>>>>>>>>>>> `import_if_avaiable(".dev.iex.exs")` line to the project level 
>>>>>>>>>>>> `.iex.exs` 
>>>>>>>>>>>> file to allow for this extension, but it makes the file name 
>>>>>>>>>>>> arbitrary and 
>>>>>>>>>>>> could cause some confusion)
>>>>>>>>>>>>     • will be used when `iex` is run from that directory not in 
>>>>>>>>>>>> the context of that mix project
>>>>>>>>>>>>
>>>>>>>>>>>> • create a project specific configuration file and use the 
>>>>>>>>>>>> --dot-iex command line arg
>>>>>>>>>>>> -- PROS:
>>>>>>>>>>>>     • does not interfere with running `iex` outside of the 
>>>>>>>>>>>> context of the mix project
>>>>>>>>>>>>     • can load additional configuration files by include 
>>>>>>>>>>>> `import_if_avaiable` statements
>>>>>>>>>>>> -- CONS:
>>>>>>>>>>>>     • Requires including the --dot-iex arg when running the 
>>>>>>>>>>>> `iex -S mix` command, which is prone to being forgotten, this 
>>>>>>>>>>>> could be 
>>>>>>>>>>>> wrapped in a very simple start script, but you would still need to 
>>>>>>>>>>>> remember 
>>>>>>>>>>>> to run that (I work with a largish number of elixir services and 
>>>>>>>>>>>> having 
>>>>>>>>>>>> individual start scripts or args per project can be cumbersome to 
>>>>>>>>>>>> remember)
>>>>>>>>>>>>
>>>>>>>>>>>> I think an ideal solution would be a way to configure a mix 
>>>>>>>>>>>> project to load a particular configuration file that will be 
>>>>>>>>>>>> loaded when 
>>>>>>>>>>>> the IEx.Evaluator starts IN ADDITION to the existing `dot-iex` 
>>>>>>>>>>>> file 
>>>>>>>>>>>> options.  I believe this would allow for maintainers of a project 
>>>>>>>>>>>> to 
>>>>>>>>>>>> normalize some shell configuration while still allowing developers 
>>>>>>>>>>>> the full 
>>>>>>>>>>>> ability to add their own configuration while also keeping the 
>>>>>>>>>>>> workflow of 
>>>>>>>>>>>> starting the shell more standardized across projects.
>>>>>>>>>>>>
>>>>>>>>>>>> A secondary goal might be that this could be incorporated into 
>>>>>>>>>>>> releases as well so that the `./bin/project remote` and similar 
>>>>>>>>>>>> commands 
>>>>>>>>>>>> could also load some particular configuration
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks in advance for any thoughts you had, and if I missed any 
>>>>>>>>>>>> existing options for this type of configuration, let me know! 
>>>>>>>>>>>>
>>>>>>>>>>>> -- 
>>>>>>>>>>>> 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/a956613f-7ef1-435c-8aaf-ab3af8058d5dn%40googlegroups.com
>>>>>>>>>>>>  
>>>>>>>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/a956613f-7ef1-435c-8aaf-ab3af8058d5dn%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-co...@googlegroups.com.
>>>>>>>>>
>>>>>>>> To view this discussion on the web visit 
>>>>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/085f777f-3b9c-4ef1-8787-d1396c13fc88n%40googlegroups.com
>>>>>>>>>  
>>>>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/085f777f-3b9c-4ef1-8787-d1396c13fc88n%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-co...@googlegroups.com.
>>>>>>> To view this discussion on the web visit 
>>>>>>> https://groups.google.com/d/msgid/elixir-lang-core/a01b0032-13ee-45a1-b59b-5320a70e3322n%40googlegroups.com
>>>>>>>  
>>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/a01b0032-13ee-45a1-b59b-5320a70e3322n%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>>> .
>>>>>>>
>>>>>> -- 
>>>>>> You received this message because you are subscribed to a topic in 
>>>>>> the Google Groups "elixir-lang-core" group.
>>>>>> To unsubscribe from this topic, visit 
>>>>>> https://groups.google.com/d/topic/elixir-lang-core/qphuwdQxcsc/unsubscribe
>>>>>> .
>>>>>> To unsubscribe from this group and all its topics, 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/CAGnRm4JX6KYe1En8WsCQeLhHF8SXnMB7jqps-qcwYKQwNWRimw%40mail.gmail.com
>>>>>>  
>>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4JX6KYe1En8WsCQeLhHF8SXnMB7jqps-qcwYKQwNWRimw%40mail.gmail.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-co...@googlegroups.com.
>>>>> To view this discussion on the web visit 
>>>>> https://groups.google.com/d/msgid/elixir-lang-core/CAOZBLdORTXogFXez02uX1NCU1dskL2opqFB9HQRpdGAFNEM8NA%40mail.gmail.com
>>>>>  
>>>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAOZBLdORTXogFXez02uX1NCU1dskL2opqFB9HQRpdGAFNEM8NA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>>> .
>>>>>
>>>> -- 
>>>> You received this message because you are subscribed to a topic in the 
>>>> Google Groups "elixir-lang-core" group.
>>>> To unsubscribe from this topic, visit 
>>>> https://groups.google.com/d/topic/elixir-lang-core/qphuwdQxcsc/unsubscribe
>>>> .
>>>> To unsubscribe from this group and all its topics, 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/CAGnRm4Kd6NeDoZQ%2Bx6i%3DwNj4yHK0pmoby5ay_CGkQqDcMCiCRg%40mail.gmail.com
>>>>  
>>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Kd6NeDoZQ%2Bx6i%3DwNj4yHK0pmoby5ay_CGkQqDcMCiCRg%40mail.gmail.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-co...@googlegroups.com.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/elixir-lang-core/CAOZBLdOBYmuwaURE0uXNfJa-%2B4hyjbiDjYnkMs5XowXGasNp5g%40mail.gmail.com
>>>  
>>> <https://groups.google.com/d/msgid/elixir-lang-core/CAOZBLdOBYmuwaURE0uXNfJa-%2B4hyjbiDjYnkMs5XowXGasNp5g%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> -- 
>> You received this message because you are subscribed to a topic in the 
>> Google Groups "elixir-lang-core" group.
>> To unsubscribe from this topic, visit 
>> https://groups.google.com/d/topic/elixir-lang-core/qphuwdQxcsc/unsubscribe
>> .
>> To unsubscribe from this group and all its topics, 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/CAGnRm4%2B3mtzv73tnqWo9cg%2BwEVoDgd%2ByC%3DA8RmhN%3Dj%3DVENmk4w%40mail.gmail.com
>>  
>> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4%2B3mtzv73tnqWo9cg%2BwEVoDgd%2ByC%3DA8RmhN%3Dj%3DVENmk4w%40mail.gmail.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/4a7e9633-568e-45d3-9f91-6511ae54f6f4n%40googlegroups.com.

Reply via email to