chlorinejs / lein-bower

Leiningen plugin for managing Bower dependencies in Clojure projects
66 stars 13 forks source link

Support for saving dependencies #14

Closed jdreux closed 7 years ago

jdreux commented 10 years ago

Would love to be able to save dependencies from the command line - it's one of best features of bower IMO!

Example: lein bower install bootstrap --save would fetch the dependency but also add it to the project.clj. Is this possible in the current state of affairs? If not I would love to submit a pull request, provided I get some direction.

radhikalism commented 10 years ago

I don't think it's possible currently, but it is an interesting proposal.

This sounds like a use case for an eventual lein 'change' task, which would handle general rewriting of project.clj contents, as Phil H described here: http://librelist.com/browser//leiningen/2014/5/1/release-task/

The difficulty is that project.clj files are not trivial to rewrite, without risking loss of information, even for a special case like a vector of bower deps. Without a generalized leiningen API for carrying it out, any specific rewriting solution per plugin is likely to be brittle.

Another approach might be to write a sidecar file for lein-bower specifically, which holds persistent rewritable state that the plugin manages and injects into the bower file as needed. Feels messy, though. I'd prefer to reuse project.clj, but until that's feasible, maybe this will help?

jdreux commented 10 years ago

Hey yes that would help but then one might as well fallback on the bower.json file. Lein-bower the becomes a way of invoking the bower task during builds and such which has it's uses but it's a different animal. 

May I ask what is the risk of rewriting the project.clj file? From here it would seem like a fairly simple task to append/remove deps from that vector.

On Sun, Sep 14, 2014 at 7:28 AM, Abhishek Reddy notifications@github.com wrote:

I don't think it's possible currently, but it is an interesting proposal. This sounds like a use case for an eventual lein 'change' task, which would handle general rewriting of project.clj contents, as Phil H described here: http://librelist.com/browser//leiningen/2014/5/1/release-task/ The difficulty is that project.clj files are not trivial to rewrite, without risking loss of information, even for a special case like a vector of bower deps. Without a generalized leiningen API for carrying it out, any specific rewriting solution per plugin is likely to be brittle.

Another approach might be to write a sidecar file for lein-bower specifically, which holds persistent rewritable state that the plugin manages and injects into the bower file as needed. Feels messy, though. I'd prefer to reuse project.clj, but until that's feasible, maybe this will help?

Reply to this email directly or view it on GitHub: https://github.com/chlorinejs/lein-bower/issues/14#issuecomment-55522768

radhikalism commented 10 years ago

The main difficulty rewriting the project.clj file is that it contains code and needs to be evaluated. Evaluation is inherently lossy, as you'll lose whitespace, comments, order, and unquoted forms (e.g. the outer form in (let [...] (defproject ...))), so you can't easily reconstruct the bulk of the original code after altering the project map. There are ways to preserve that original information, but you'd need a transformer that's effectively a structural source code editor to reflect alterations to the project map. I don't think that's infeasible, but it is a very general solution that probably should be provided by leiningen itself. The good news is that Phil H seems to think it's useful, so it might be on the roadmap.

Otherwise, you can make assumptions that most project.clj files in the wild don't have unusual characteristics, so a regex replace might be enough. But I imagine that will keep breaking for plenty of edge cases.

Finally, keeping a sidecar file isn't as bad as falling back to bower.json, I think, because it doesn't give you that full second steering wheel or leaky abstraction. The bower file will remain abstracted by the lein-bower plugin. The additional file would be managed by the plugin, but otherwise need not give the user more options than the plugin needs, and no guarantee of format or reusability, so they're not encouraged to directly touch it. The benefit of lein-bower and its friends is that, as a human user or another build tool, you only need to play with project.clj (one steering wheel or integration point), and the plugins smooth out the heterogeneous set of other build/package tools. I expect that will still be the case if lein-bower had its own state file.

hackeryarn commented 7 years ago

I don't think this goes well with how Clojure/ClojureScript projects dependencies are managed in general, and I would like to stick to a consistent paradigm.

I am closing as this is something we most likely will not implement.