rjbs / Config-MVP

multivalue property config section state machine
9 stars 7 forks source link

Localizing @INC in read_config reverts my desired changes #14

Open chazmcgarvey opened 6 years ago

chazmcgarvey commented 6 years ago

Localizing @INC (3966df41) breaks this Dist::Zilla use case:

[lib]
lib = inc

[PodWeaver]
config_plugin = @MyBundle       ; uh oh

since munging happens after read_config.

# dzil build
...
Pod::Weaver::PluginBundle::MyBundle (for section @MyBundle) does not appear to be installed
...
kentfredric commented 4 years ago

Just hit this on a seperate usecase.

  1. You're trying to bundle copies of system @INC in a path ( eg: ./dev-inc/ )
  2. This includes, non-dzil dependencies, and .... sharedir contents provisioned into ./dev-inc/auto/share/dist/
  3. You're employing some @INC tweaking plugin, or you're employing dist.pl with a more explicit and literal @INC modification.

This is somewhat "fine" as long as all dependencies and assets are resolved during plugin loading, inside this block:

https://github.com/rjbs/Config-MVP/blob/3966df4193d20ac8aaa639d2a6b65875431eba3f/lib/Config/MVP/Reader.pm#L70-L77

However, any dependency/sharedir loading that occurs outside the plugin loading phase becomes utterly broken.

Which makes bundling libraries in an "only non-XS deps, local lib" impossible.

kentfredric commented 4 years ago

I have a seeming workaround, but its a bit obscene and I doubt many can utilize it...

my $libdir;
my $devlibdir;
BEGIN {
    $libdir = path('./lib')->realpath->stringify;
    $devlibdir = path('./dev-inc')->realpath->stringify;
    *_ensure_devel_inc = sub {
        require lib;
        if ( not grep { $_ eq $libdir } @INC ) {
          lib->import($libdir);
        }
        if ( not grep { $_ eq $devlibdir } @INC ) {
          lib->import($devlibdir);
        }
    };
    _ensure_devel_inc();
}

BEGIN {
  # Oh god: https://github.com/rjbs/Config-MVP/issues/14
  require Config::MVP::Assembler;
  my $old = \&Config::MVP::Assembler::sequence;
  my $replacement = sub {
    _ensure_devel_inc();
    my $guard = guard { _ensure_devel_inc(); undef };
    $old->(@_)
  };
  { 
    no strict 'refs';
    no warnings 'redefine';
    *Config::MVP::Assembler::sequence = $replacement;
  }
}