jhthorsen / mojolicious-plugin-webpack

Integrate your mojo app with webpack
13 stars 6 forks source link

Builder.pm breaks CPANPLUS #5

Closed voegelas closed 3 years ago

voegelas commented 4 years ago

Builder.pm causes Module::Metadata, which is used by CPANPLUS, to fail. The below command reproduces the problem.

perl -MModule::Metadata -E 'say Module::Metadata->new_from_module("Mojolicious::Plugin::Webpack::Builder")->version'

Module::Metadata works fine if $VERSION is set at the top of Builder.pm. Below is a patch. The "use" and "our" declarations need to be put on the same line. See Exporter::Heavy for similar code.

--- Mojolicious/Plugin/Webpack/Builder.pm.orig  2019-12-11 15:45:15.274762479 +0100
+++ Mojolicious/Plugin/Webpack/Builder.pm       2019-12-11 15:55:41.979559821 +0100
@@ -9 +9,2 @@
-use Mojolicious::Plugin::Webpack;
+# On one line so MakeMaker will see it.
+use Mojolicious::Plugin::Webpack; our $VERSION = $Mojolicious::Plugin::Webpack::VERSION;
jhthorsen commented 4 years ago

I don't get when this is an issue. How do you get yourself into this situation?

voegelas commented 4 years ago

If Mojolicious::Plugin::Webpack is installed CPANPLUS can no longer find modules that have been updated on CPAN. I've built hundreds of Perl modules with CPANPLUS. Mojolicious::Plugin::Webpack is the only distribution on CPAN, that I know, that breaks Module::Metadata and CPANPLUS.

$ cpanp
CPANPLUS::Shell::Default -- CPAN exploration and module installation (v0.9902)
CPAN Terminal> o

[ERROR] Could not get version from /usr/share/perl5/5.30/Mojolicious/Plugin/Webpack/Builder.pm by executing:
 my $dummy = q#  Hide from _packages_inside()
    #; package Module::Metadata::_version::p25; [...]
jhthorsen commented 4 years ago

I still don't get it. Why doesn't this happen with any of the Mojolicious modules? Only Mojolicious.pm has $VERSION declared.

voegelas commented 4 years ago

Module::Metadata searches modules textually for $VERSION statements. In Mojolicious::Plugin::Webpack::Builder, Module::Metadata currently finds and tries to execute the line state $VERSION = $Mojolicious::Plugin::Webpack::VERSION from the subroutine _render_to_file():

The fatal error was: Can't call method "state" on an undefined value at (eval 1443) line 6, <GEN1611> line 213.

If a version assignment is put at the top of Builder.pm, Module::Metadata finds that assignment instead of the unrelated code in _render_to_file(). Exporter::Heavy, which comes with Perl, has similar code at the top of Heavy.pm:

# On one line so MakeMaker will see it.
require Exporter;  our $VERSION = $Exporter::VERSION;

CPANPLUS uses Module::Metadata to show modules that can be updated. An example:

$ cpanp
CPANPLUS::Shell::Default -- CPAN exploration and module installation (v0.9906)
CPAN Terminal> o
    1     4.033        4.05     DBD::mysql                           DVEEDEN   
    2     1.636        1.643    DBI                                  TIMB      
    3     0.15009      0.17029  Error                                SHLOMIF   
    4     1.12         1.14     IO::Pty                              TODDR     
    5     0.4229       0.4231   Module::Build                        LEONT     
    6     2.33         2.38     Term::ReadKey                        JSTOWE    
    7     1.71         1.76     URI                                  OALDERS   
    8     2.44         2.46     XML::Parser                          TODDR     
    9     2.22         2.25     XML::Simple                          GRANTM    

If Mojolicious::Plugin::Webpack is installed Module::Metadata throws an exception and the command "o" does no longer work for any module. Of course, it would be better if Module::Metadata caught exceptions. But Module::Metadata comes with Perl and won't be fixed in older Perl versions that are still provided by various Linux distributions.

jhthorsen commented 3 years ago

Thanks for the details, and sorry for not fixing this earlier. Should be fixed in the next release.