On 8/8/21 4:26 PM, Dan Book wrote:
On Sun, Aug 8, 2021 at 3:35 PM Diab Jerius <djer...@cpan.org <mailto:djer...@cpan.org>> wrote:

    Howdy!

    I've a module
    (https://metacpan.org/release/DJERIUS/Data-Record-Serialize-0.27-TRIAL
    <https://metacpan.org/release/DJERIUS/Data-Record-Serialize-0.27-TRIAL>)
    which may use JSON and YAML writers.

    For JSON, I use JSON::MaybeXS.  Cpanel::JSON::XS >= 3.0236 is
    required.

    My code can use either YAML::XS or YAML::PP.  YAML::XS >= 0.67 is
    required.

    Since JSON & YAML output are optional, I've encoded the XS
    dependencies as runtime recommendations, rather than requirements.
    JSON::MaybeXS is specified as a runtime dependency (as is
    YAML::PP, but that's a mistake; it should also be a runtime
    recommendation).

    Here are the relevant bits of  META.json
    
(https://metacpan.org/release/DJERIUS/Data-Record-Serialize-0.27-TRIAL/source/META.json#L98
    
<https://metacpan.org/release/DJERIUS/Data-Record-Serialize-0.27-TRIAL/source/META.json#L98>)

           "runtime" : {         "recommends" : {            "Cpanel::JSON::XS" : "3.0236",            "JSON::PP" : "0",            
"YAML::XS" : "0.67"         },         "requires" : {            "JSON::MaybeXS" : "0",            "YAML::PP" : "0",         }      },

    Here's the problem, illustrated by this CPAN testers failure:

        
http://www.cpantesters.org/cpan/report/2f961e48-6bf6-1014-90df-a468c69b7236
        
<http://www.cpantesters.org/cpan/report/2f961e48-6bf6-1014-90df-a468c69b7236>

    The smoker has versions of Cpanel::JSON::XS and YAML::XS which are
    older than my required versions. Since the ::XS versions are
    prioritized over the ::PP versions, the code uses those and thus
    fails the tests.   I presume that because the ::XS versions are
    recommendations rather than requirements, they weren't updated to
    the versions that the code requires.

    Is there some way of triggering an update to the required versions
    via the metadata, or should I put a runtime version check into the
    tests and skip if the appropriate versions aren't installed?

    For production runs, I'll have to add a runtime check in the code
    which falls back to YAML::PP if the version of YAML::XS is too
    old, but I don't see how I can do that with JSON::MaybeXS, as
    there are no hooks to indicate acceptable versions of the
    backend.  I think my only option is to take the same approach as
    for YAML, namely manually specifying which backend libraries are
    acceptable.  I don't like this, as now I can't automatically take
    advantage of JSON::MaybeXS's list of backends.

    Any advice on how to gracefully handle this situation?


There's only two real options, and you might want to do both:

Dynamically add a runtime requires on the required version if you detect that the optional module is installed but too old. With dzil you can do this with https://metacpan.org/pod/Dist::Zilla::Plugin::DynamicPrereqs <https://metacpan.org/pod/Dist::Zilla::Plugin::DynamicPrereqs>.

At runtime, ensure that the module satisfies your minimum version if it is present, and if not treat it as if it was not installed.

I'll take a look at DynamicPrereqs. My concern is that if a user isn't interested in the optional component, this adds an unwanted dependency.

To get this out  the door I've added the runtime fallback checks in the code and made the tests conditional on the runtime checks succeeding.

As I mentioned in my response to David Cantrell's email, the real solution is to split the distribution into core and optional components.

Thanks!

Diab


Reply via email to