Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Profile merge concatenates things that don't make sense #878

Closed
trptcolin opened this issue Dec 6, 2012 · 16 comments
Closed

Profile merge concatenates things that don't make sense #878

trptcolin opened this issue Dec 6, 2012 · 16 comments
Assignees
Labels
Milestone

Comments

@trptcolin
Copy link
Collaborator

If I have this in ~/.lein/profiles.clj

{:user {:repl-options {:init (set! *print-length* 20)}}}

and this in my project.clj:

{:user {:repl-options {:init (println "HI!")}}}

then the merged :repl-options end up being:

{:init (println "hi!" set! *print-length* 20)

because of meta-merge.

Ideally there would be something like a list of all the forms - is the full list of profile settings exposed anywhere that would allow the repl task to do something custom? I'm not sure what the right thing to do here would be. :(

@technomancy
Copy link
Owner

I think the right thing to do here is to make the :init value a vector containing a number of forms. But I understand the problems you get from putting the wrong thing in are going to be difficult to debug.

@hypirion
Copy link
Collaborator

This is an issue more general than just for :repl-options :init. Merging will also mix up other things such as pom-additions and aliases (and possibly future values). If you for instance have this within ~/.lein/profiles.clj

{:aliases {"test" ["do" "test," "midje"]}}

then having

{:aliases {"test" "midje"}}

will give you a type mismatch, and having

{:aliases {"test" ["do" "test," "midje"]}}

Will attempt to do lein do test, midje do test, midje.

Instead of solving this specific case, I think it would be nice with a solution that can handle multiple cases and minimizes work if/when another case pops up.

@technomancy
Copy link
Owner

Oy; quite right. This is tricky; it seems that ^:replace/^:displace metadata may need to be associated with keys rather than values.

We could enumerate all the non-merge keys in Leiningen itself, but plugins could introduce their own keys that need special handling too. I can't think of a simple way to do this; it may get messy.

@technomancy
Copy link
Owner

In the mean time I think :init for the repl can be addressed. However, rather than switching it for a vector I think it could probably be replaced by :injections in the :repl profile maybe.

@technomancy
Copy link
Owner

Oh... the problem with doing this in the :repl profile is that putting that profile in project.clj will shadow Leiningen's built-in :repl profile that brings in the nREPL dependency. Do we need two separate profiles for this? Perhaps a :leiningen/repl that brings in the needed deps and a :repl for user use?

@hugoduncan
Copy link
Contributor

:test-selectors seems to suffer from this too.

@hugoduncan
Copy link
Contributor

FWIW, in pallet we use https://github.com/pallet/pallet-map-merge to do key specific merging.

technomancy added a commit that referenced this issue Feb 26, 2013
Gotta love how quote silently discards metadata wooooo.
@ghost ghost assigned hypirion Mar 15, 2013
@technomancy
Copy link
Owner

I'm starting to think the best thing to do here is to default to ^:replace behaviour and only merge when explicitly asked for.

@akatov
Copy link

akatov commented Oct 31, 2013

what is the status of this? any updates?

@hypirion
Copy link
Collaborator

I have some notes on this, but this won't be done before 3.0.0 to keep backwards compatibility.

@devth
Copy link
Contributor

devth commented Apr 7, 2017

Is this a benign / ignorable error or does it actually cause problems?
Regardless of whether the types match, I'd expect the last value to win / override.

@technomancy
Copy link
Owner

technomancy commented Apr 7, 2017 via email

@devth
Copy link
Contributor

devth commented Apr 7, 2017

To clarify: I only meant when there's a type conflict. Always merge when possible. Fallback to replace when not.

@technomancy
Copy link
Owner

technomancy commented Apr 7, 2017 via email

@delitescere
Copy link

delitescere commented Jun 20, 2018

Indeed, still a problem. I found it when using a combination of reloaded.repl, where I have my own :repl-options {:init (go)}, and the mvxcvi/whidbey plugin which injects another :init key.

See the specific whidbey source and leiningen issue #1997

$ lein repl
Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: do in this context, compiling:(/private/var/folders/ss/g9z18f215rv1761klgh17nlc0000gn/T/form-init2887089488392703524.clj:1:7961)
	at clojure.lang.Compiler.analyze(Compiler.java:6688)
	at clojure.lang.Compiler.analyze(Compiler.java:6625)
...
	at clojure.main.main(main.java:37)
Caused by: java.lang.RuntimeException: Unable to resolve symbol: do in this context
...
	at clojure.lang.Compiler.analyzeSymbol(Compiler.java:7069)
	at clojure.lang.Compiler.analyze(Compiler.java:6648)
	... 28 more
$ lein with-profile +whidbey/repl,+repl cprint :repl-options
{:init (do
        (clojure.core/require (quote whidbey.repl))
        (whidbey.repl/init! nil)
        go),
 :nrepl-context {:interactive-eval {:renderer whidbey.repl/render-str}},
 :nrepl-middleware [clojure.tools.nrepl.middleware.render-values/render-values],

$ lein with-profile +repl cprint :repl-options
{:init (go), :timeout 600000}

$ lein with-profile +whidbey/repl cprint :repl-options
{:init (do (clojure.core/require (quote whidbey.repl)) (whidbey.repl/init! nil)),
 :nrepl-context {:interactive-eval {:renderer whidbey.repl/render-str}},
 :nrepl-middleware [clojure.tools.nrepl.middleware.render-values/render-values]}

Notice, though that the expanded form is not the same as the source. require has become fully-qualified, but do has not.

Also, the parens around go have been removed in the combined form, but even double-parens in project.clj does nothing useful (the problem is still the do symbol is not found):

$ lein with-profile +whidbey/repl,+repl cprint :repl-options
{:init (do
        (clojure.core/require (quote whidbey.repl))
        (whidbey.repl/init! nil)
        (go)),
 :nrepl-context {:interactive-eval {:renderer whidbey.repl/render-str}},
 :nrepl-middleware [clojure.tools.nrepl.middleware.render-values/render-values],
 :timeout 600000}

The only "workaround" is to remove my :init (go) from the :repl-options in my project.clj. Then the whidbey init takes hold properly, and I get to type (go) manually.

cichli added a commit to cichli/whidbey that referenced this issue Feb 16, 2019
Leiningen doesn't know how to merge this option - see technomancy/leiningen#878.
Instead, use ^:replace metadata to overwrite it completely with a form that
evaluates any existing value before evaluating our init code.
cichli added a commit to cichli/whidbey that referenced this issue Feb 16, 2019
Leiningen doesn't know how to merge this option - see technomancy/leiningen#878.
Instead, use ^:replace metadata to overwrite it completely with a form that
evaluates any existing value before evaluating our init code.
cichli added a commit to cichli/whidbey that referenced this issue Feb 27, 2019
Leiningen doesn't know how to merge these - see technomancy/leiningen#878.
Instead, use ^:replace metadata to overwrite it completely with a form that
evaluates any existing value before evaluating our init code.
cichli added a commit to cichli/whidbey that referenced this issue Feb 27, 2019
Leiningen doesn't know how to merge these - see technomancy/leiningen#878.
Instead, use ^:replace metadata to overwrite it completely with a form that
evaluates any existing value before evaluating our init code.
@technomancy
Copy link
Owner

At this point any changes to this behavior are likely to be more disruptive than the problematic behavior itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants