roomkey / lein-v

Drive leiningen project version from git instead of the other way around
48 stars 11 forks source link

ns declaration in version.clj should be customizable #21

Open timgilbert opened 6 years ago

timgilbert commented 6 years ago

This plugin looks great, but I've got a feature request. I have a few different internal libraries that I'd like to use the version.clj functionality for, let's say alpha and beta, which are packaged up as jars and then used by my main application, app. If all of them declare a top-level version namespace, I won't have any way to specifically get alpha.version or app.version.

With the EDN files I can work around this since from beta I can generate the file in resources/beta/version.edn, and then from app I can slurp in beta/version.edn to get that specific version.

Anyways, what I'd like to be able to do is something like lein v cache src/beta clj beta.version and then wind up with a file src/beta/version.clj which starts with (ns beta.version).

I can probably cook up a pull request for this if it seems like a good idea, but I thought I'd raise the issue first.

simongray commented 6 years ago

I'll have to second this. The plugin solves a problem I had, but every compile shoots out a warning message because of the single namespace.

brunchboy commented 5 years ago

I have the same problem as well, I need to be able to have different libraries working with their own versions, all in the same JVM (and eventually überjar). I am super excited to have discovered lein-v, and would be able to use it everywhere if I could have the version namespace be configurable and nested within a project-specific prefix.

brunchboy commented 5 years ago

If I can find a little extra time in my spare time for projects, I might try my hand at a pull request for this as well (unless someone else pounces on it first, of course!)

I can see a few ways to go, to maintain backwards compatibility. One would be to add a :lein-v key to the overall project map which could contain the configuration information, along the lines of:

  :lein-v {:version-namespace 'my.project.version}

which, if your cache directory was src, would create the file src/my/project/version.clj (along with any other formats you requested). The default value would be 'version, which would be backwards-compatible with previous releases.

A variation could be:

  :lein-v {:version-namespace-prefix 'my.project}

which would yield the same result. In both cases, the file would begin (ns my.project.version). In this case, the default, backward-compatible, value would simply be nil, and you would have no way of changing the name of the version file(s) themselves.

If neither of these appeals, and you want to avoid adding any in-project configuration settings, the meaning of the cache directory could be complected, supporting some sort of compound value like src:my.project which, when a colon was present, would mean the value before the colon was the source directory root, and the value after the colon was the version namespace prefix (or the entire namespace, if we want to support renaming the version files).

What do people think?

simongray commented 5 years ago

@brunchboy Sounds good.

In the meantime I moved to lein-git-version which serves my needs.

brunchboy commented 5 years ago

Ah, thanks for calling that to my attention, @simongray, I almost switched to lein-git-version myself, but I don’t like how hard it is to obtain the synthetic version number from within the edn file: you basically need to replicate the code of the :status-to-version function from your project.clj inside your own code when you want to display the effective version number of a snapshot build.

Speaking of that, how are you able to build snapshot JARs at all, without having put a :status-to-version function in your own project.clj? In my case, without that, as soon as I tried lein jar in my current state, in which my project is depending on a snapshot release of one of my libraries, Leiningen refused to build it, because the project was not configured to include -SNAPSHOT in the version string.

But after adding :status-to-version, I was able to do builds, and get a version.edn file inside a suitably project-specific resource subdirectory. But as I was about to change my code to read in and parse version.edn, I realized I could get the same results with lein-v, by simply changing that to generate in edn rather than clj format, in a suitable resource subdirectory. In other words, by adding this to my :prep-tasks entry:

["v" "cache" "resources/my/project" "edn"]

And since I prefer the flexibility lein-v gives me in choosing what specific snapshot version I am currently working on (by setting up a git tag with the snapshot version in it), and the way it includes hash, distance, and dirty qualifiers in the version string itself), I am sticking with lein-v. And since I can work with edn, I don’t even really need this issue resolved any more, I just need to do my own lazy loading and caching if I don’t want to repeatedly parse the file, which was a nice thing the namespace approach gave me for free.

brunchboy commented 5 years ago

It wasn’t even that hard to add lazy loading and caching (of course not, this is Clojure 😉) so maybe the only thing that is needed is to update the README showing an example like this as the way to make your version file not clash with other projects using the same technique to version themselves within a single jar.

simongray commented 5 years ago

@brunchboy I guess the reason why it works in my case is that I don't include the version number in my jars.

brunchboy commented 5 years ago

Have you tried building a jar when you have a dependency on a snapshot library? I don’t think it will work no matter what you call the jar.