package File::ShareDir::Dist;

use strict;
use warnings;
use 5.008001;
use base qw( Exporter );
use File::Spec;

our @EXPORT_OK = qw( dist_share dist_config );

# ABSTRACT: Locate per-dist shared files
our $VERSION = '0.07'; # VERSION

# TODO: Works with PAR

our %over;

sub dist_share ($)
  my($dist_name) = @_;
  $dist_name =~ s/::/-/g;

  local $over{$1} = $2
    if defined $ENV{PERL_FILE_SHAREDIR_DIST} && $ENV{PERL_FILE_SHAREDIR_DIST} =~ /^(.*?)=(.*)$/;

  return File::Spec->rel2abs($over{$dist_name}) if $over{$dist_name};

  my @pm = split /-/, $dist_name;
  $pm[-1] .= ".pm";

  foreach my $inc (@INC)
    my $pm = File::Spec->catfile( $inc, @pm );
    if(-f $pm)
      my $share = File::Spec->catdir( $inc, qw( auto share dist ), $dist_name );
      if(-d $share)
        return File::Spec->rel2abs($share);
        my($v,$dir) = File::Spec->splitpath( File::Spec->rel2abs($inc), 1 );
        my @dirs = File::Spec->splitdir($dir);
        if(defined $dirs[-1] && $dirs[-1] eq 'lib')
          pop @dirs; # pop off the 'lib';
          # put humpty dumpty back together again
          my $share = File::Spec->catdir(
          if(-d $share)
            return $share;


sub dist_config
  my($dist_name) = @_;
  my $dir = dist_share $dist_name;
  return {} unless defined $dir && -d $dir;
  my $fn = File::Spec->catfile($dir, '');
  return {} unless -f $fn;
  my $fh;
  open($fh, '<', $fn) || die "unable to read $fn $!";
  my $pl = do { local $/; <$fh> };
  close $fh;
  my $config = eval $pl;
  die $@ if $@;

sub import
  my($class, @args) = @_;

  my @modify;
  foreach my $arg (@args)
    if($arg =~ /^-(.*?)=(.*)$/)
      $over{$1} = $2;
      push @modify, $arg;
  @_ = ($class, @modify);
  goto \&Exporter::import;




=encoding UTF-8

=head1 NAME

File::ShareDir::Dist - Locate per-dist shared files

=head1 VERSION

version 0.07


 use File::ShareDir::Dist qw( dist_share );
 my $dir = dist_share 'Foo-Bar-Baz';


L<File::ShareDir::Dist> finds share directories for distributions.  It is similar to L<File::ShareDir>
with a few differences:

=over 4

=item Only supports distribution directories.

It doesn't support perl modules or perl class directories.  I have never really needed anything
other than a per-dist share directory.

=item Doesn't compute filenames.

Doesn't compute files in the share directory for you.  This is what L<File::Spec> or L<Path::Tiny>
are for.

=item Doesn't support old style shares.

For some reason there are two types.  I have never seen or needed the older type.

=item Hopefully doesn't find the wrong directory.

It doesn't blindly go finding the first share directory in @INC that matches the dist name.  It actually
checks to see that it matches the .pm file that goes along with it.

That does mean that you need to have a .pm that corresponds to your dist name.  This is not
always the case for some older historical distributions, but it has been the recommended convention
for quite some time.

=item No non-core dependencies.

L<File::ShareDir> only has L<Class::Inspector>, but since we are only doing per-dist share
directories we don't even need that.

The goal of this project is to have no non-core dependencies for the two most recent production
versions of Perl.  As of this writing that means Perl 5.26 and 5.24.  In the future, we C<may> add
dependencies on modules that are not part of the Perl core on older Perls.

=item Works in your development tree.

Uses the heuristic, for determining if you are in a development tree, and if so, uses the common
convention to find the directory named C<share>.  If you are using a relative path in C<@INC>,
if the directory C<share> is a sibling of that relative entry in C<@INC> and if the last element
in that relative path is C<lib>.

Example, if you have the directory structure:


and you invoke perl with

 % perl -Ilib -MFoo::Bar::Baz -MFile::ShareDir::Dist=dist_share -E 'say dist_share("Foo-Bar-Baz")'

C<dist_share> will return the (absolute) path to ./share/data.  If you invoked it with:

 % export PERL5LIB `pwd`/lib
 perl -MFoo::Bar::Baz -MFile::ShareDir::Dist=dist_share -E 'say dist_share("Foo-Bar-Baz")'

it would not.  For me this covers most of my needs when developing a Perl module with a share

L<prove> foils this heuristic by making C<@INC> absolute paths.  To get around that you can use

=item Built in override.

The hash C<%File::ShareDir::Dist::over> can be used to override what C<dist_share> returns.
You can also override behavior on the command line using a dash followed by a key value pair
joined by the equal sign.  In other words:

 % perl -MFile::ShareDir::Dist=-Foo-Bar-Baz=./share -E 'say File::ShareDir::Dist::dist_share("Foo-Bar-Baz")'

If neither of those work then you can set PERL_FILE_SHAREDIR_DIST to a dist name, directory pair

 % env PERL_FILE_SHAREDIR_DIST=Foo-Bar-Baz=`pwd`/share perl -MFile::ShareDir::Dist -E 'say File::ShareDir::Dist::dist_share("Foo-Bar-Baz")'

For L<File::ShareDir> you have to either mock the C<dist_dir> function or install
L<File::ShareDir::Override>.  For testing you can use L<Test::File::ShareDir>.  I have never
understood why such a simple concept needs three modules to do all of this.



Functions must be explicitly exported.  They are not exported by default.

=head2 dist_share

 my $dir = dist_share $dist_name;
 my $dir = dist_share $module_name;

Returns the absolute path to the share directory of the given distribution.

As a convenience you can also use the "main" module name associated with the
distribution.  That means if you want the share directory for the dist
C<Foo-Bar-Baz> you may use either C<Foo-Bar-Baz> or C<Foo::Bar::Baz> to find

Returns nothing if no share directory could be found.

=head2 dist_config

[version 0.07]

 my $config = dist_config $dist_name;

Returns the config at runtime as created by L<File::ShareDir::Dist::Install> and install time.


=over 4


Can be used to set a single dist directory override.


=head1 CAVEATS

All the stuff that is in L<File::ShareDir> but not in this module could be considered either
caveats or features depending on your perspective I suppose.

=head1 SEE ALSO


=item L<File::ShareDir::Dist::Install>

=item L<App::Prove::Plugin::ShareDirDist>

=item L<App::Yath::Plugin::ShareDirDist>


=head1 AUTHOR

Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>


Yanick Champoux (yanick)


This software is copyright (c) 2017,2018 by Graham Ollis.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.