in reply to Re: Using a Single Point of Truth for $VERSION in a distribution?
in thread Using a Single Point of Truth for $VERSION in a distribution?

I will have to look into Dist::Zilla, with thanks for the hint to hippo and 1nickt, but from this description, it does not seem to do what I want — if the other modules are to carry the same version as the "lead" module (which in WARC exists in part for that purpose) then I firmly believe that they should actually alias that value to make it obvious that they do not have independent versions. Perl understands this, but the CPAN indexer does not.

If I put separate $VERSION literals in each module, I want them updated if and only if that module has been changed since its version was last updated. Does Dist::Zilla support this or am I back to needing to write something that does what I want?

Is there a convention that module versions should be "dense" or is skipping versions acceptable?

Is there a convention for bundling distribution-specific maintenance tools into a distribution? A way to distribute a specialized support tool on a "this works for me and this distribution; feel free to use or adapt it for your work" basis?

If I was afraid of learning curves, I would not be contributing to CPAN...

Replies are listed 'Best First'.
Re^3: Using a Single Point of Truth for $VERSION in a distribution?
by dsheroh (Monsignor) on Apr 18, 2020 at 11:17 UTC
    If I put separate $VERSION literals in each module, I want them updated if and only if that module has been changed since its version was last updated.
    From a module user's viewpoint, that is an astoundingly bad idea, assuming that all the modules are packaged in a single distribution. This has nothing to do with a fetish for "density", but think about the confusion it's likely to cause users if they install MyModule 1.23 and it comes bundled with MyModule::Foo 1.21 and MyModule::Bar 1.00. "Ah, crap! I've got an old version of MyModule::Bar - I should update that and get the current version, but when I go to install 1.23, nothing happens! WTF?!? Is this thing broken? Has Bar been deprecated or discontinued? Where are they hiding the current version, if it even exists?"

    I get the impression that your real goal here is that you're trying to minimize the number of "meaningless" changes committed to your git repository. Dist::Zilla can provide this for you, while also having the same version number in each file. Not because it aliases the main module's version number into all the other files, but because it allows you to put "tags" into the file representing metadata (such as a version number) and then replaces the tags with the actual metadata values when it builds the release package. The "real" version of the file, the one in git, contains the tags, so it never needs to change for metadata updates, while the distributed versions contain the literal metadata values in each file.

    And, yeah, I realize that you may be a bit iffy about the distributed files not being identical to the files in git (I know I was, when I first heard about Dist::Zilla), but it's not really any different than a C program where you keep the source files in git, but distribute compiled binaries. The "compiling" that dzil does when building the release is much simpler and less extensive than what a C compiler does, but it still fits the same general pattern of "keep your manually-created source files in git, but not the files generated automatically from them".

      Now that you mention it, I have encountered that problem when trying to trace Changes across modules that have been split from or combined into parent distributions.

      You are close: I am trying to preserve the invariant that each file is only changed in the repository when it is meaningfully changed. A file that has not been meaningfully changed since release 0.0.1, should indicate as such in Git, at least on the master branch... and that gives me an idea that preserves the ability to run prove on the working tree even though the tests verify that $VERSION is checked... I could have the release scripts replace the typeglob aliases with $VERSION literals, build and test the new release, store the release tarball, then use git reset to revert back to the development line in the post-release script.

Re^3: Using a Single Point of Truth for $VERSION in a distribution?
by 1nickt (Canon) on Apr 18, 2020 at 01:02 UTC

    Hi again jcb.

    The remark about people fearful of learning curves had to do with the large number of negative opinions about dzil you'll hear (from people who don't use it) ... not directed at you.

    "then I firmly believe that they should actually alias that value to make it obvious that they do not have independent versions. Perl understands this, but the CPAN indexer does not."

    "If I put separate $VERSION literals in each module, I want them updated if and only if that module has been changed since its version was last updated."

    I'm afraid I'm less clear now about what you want. The second statement seems to contradict the goal implied by the first, namely that the non-primary modules should always carry the same version as the primary one. The second statement seems to imply that the different modules would/could have differing versions. It's up to you how to do it, but from what I've observed there's a lot less maintenance for the distro author if all the modules get their version number bumped together than trying to ensure that the right dependency versions are required in the build specs.

    Here's the dzil tutorial on version numbering. It addresses just the case where all modules in your distro have the same version number, showing a few plugins to do that in different ways.

    There are two-and-a-half pages of results for a metaCPAN search for 'Dist::Zilla::Plugin::Version' so I'll let you browse through them. Do your due diligence -- lots of people of varying abilities write dzil plugins. A useful technique is to look at the dist.ini of distros you admire.

    I have done no such due diligence on Dist::Zilla::Plugin::SurgicalPkgVersion but it seems to do what I think you meant by your second comment cited above ;-)

    Hope this helps!


    The way forward always starts with a minimal test.

      I have now had time to read the Dist::Zilla tutorial and after checking its dependencies, I believe that I will have to pass on dzil for now.

      To use a term I have seen elsewhere in the Monastery, my conclusion was ETOOMUCHMAGIC. Dist::Zilla seems to be the type of tool that I have had problems with in the past, being elegant, complex, powerful, — and fragile. It will work and it will work very well and the details of making it work will be forgotten. Then a future upgrade will break something. I have had to handle systems like that at $WORK in the past and I prefer simpler answers for my hobbies, but that is my preference and you are of course free to enjoy the power while it works. :-)

        Dist::Zilla is complicated and has a learning curve, but actually once you get it configured the way you like you can forget most of the details and just copy the dist.ini from one project to the next, making a few changes as needed.

        (notice how in the source for FormulaEngine I just add a #VERSION comment and dzil build inserts the incremented version from the last git tag.)

        I totally agree with the sentiment you are expressing about not wanting to waste tooling time on a personal project, but this one really will pay for itself if you release a few modules.

        I wish Dist::Zilla was not written as a giant pile of heavyweight Moose roles, but the external design is absolutely correct (running "dzil test", "dzil build", "dzil release" and so on) and I have been able to make all the customizations I've needed even for some wild makefile requirements:

        • Data::TableReader dist.ini weaver.ini (example adding "Contributors" POD section auto-generated from Git)
        • VideoLAN::LibVLC dist.ini Makefile.header (example of exotic c-library detection using MakeMaker::Awesome plugin)
        • OpenGL::Sandbox dist.ini (example using Inline::Module plugin to distribute a module using Inline::C as a standard XS module not depending on Inline)