Kent Fredric > File-ShareDir-ProjectDistDir > File::ShareDir::ProjectDistDir

Download:
File-ShareDir-ProjectDistDir-1.000004.tar.gz

Dependencies

Annotate this POD

Website

View/Report Bugs
Module Version: 1.000004   Source  

NAME ^

File::ShareDir::ProjectDistDir - Simple set-and-forget using of a '/share' directory in your projects root

VERSION ^

version 1.000004

SYNOPSIS ^

  package An::Example::Package;

  use File::ShareDir::ProjectDistDir;

  # during development, $dir will be $projectroot/share
  # but once installed, it will be wherever File::Sharedir thinks it is.
  my $dir = dist_dir('An-Example')

Project layout requirements:

  $project/
  $project/lib/An/Example/Package.pm
  $project/share/   # files for package 'An-Example' go here.

You can use a directory name other than 'share' ( Assuming you make sure when you install that, you specify the different directory there also ) as follows:

  use File::ShareDir::ProjectDistDir ':all', defaults => {
    projectdir => 'templates',
  };

METHODS ^

import

    use File::ShareDir::ProjectDistDir (@args);

This uses Sub::Exporter to do the heavy lifting, so most usage of this module can be maximized by understanding that first.

Sub::Exporter tricks of note.

Make your own sharedir util

    package Foo::Util;

    sub import {
        my ($caller_class, $caller_file, $caller_line )  = caller();
        if ( grep { /share/ } @_ ) {
            require File::ShareDir::ProjectDistDir;
            File::ShareDir::ProjectDistDir->import(
                filename => $caller_file,
                dist_dir => { distname => 'myproject' , -as => 'share' },
                dist_dir => { distname => 'otherproject' , -as => 'other_share' , projectdir => 'share2' },
                -into => $caller_class,
            );
        }
    }

    ....

    package Foo;
    use Foo::Util qw( share );

    my $dir = share();
    my $other_dir => other_share();

build_dist_dir

    use File::ShareDir::ProjectDirDir ( : all );

    #  this calls
    my $coderef = File::ShareDir::ProjectDistDir->build_dist_dir(
      'dist_dir' => {},
      { defaults => { filename => 'path/to/yourcallingfile.pm', projectdir => 'share' } }
    );

    use File::ShareDir::ProjectDirDir ( qw( :all ), distname => 'example-dist' );

    #  this calls
    my $coderef = File::ShareDir::ProjectDistDir->build_dist_dir(
      'dist_dir' => {},
      { distname => 'example-dist', defaults => { filename => 'path/to/yourcallingfile.pm', projectdir => 'share' } }
    );

    use File::ShareDir::ProjectDirDir
      dist_dir => { distname => 'example-dist', -as => 'mydistdir' },
      dist_dir => { distname => 'other-dist',   -as => 'otherdistdir' };

    # This calls
    my $coderef = File::ShareDir::ProjectDistDir->build_dist_dir(
      'dist_dir',
      { distname => 'example-dist' },
      { defaults => { filename => 'path/to/yourcallingfile.pm', projectdir => 'share' } },
    );
    my $othercoderef = File::ShareDir::ProjectDistDir->build_dist_dir(
      'dist_dir',
      { distname => 'other-dist' },
      { defaults => { filename => 'path/to/yourcallingfile.pm', projectdir => 'share' } },
    );

    # And leverages Sub::Exporter to create 2 subs in your package.

Generates the exported 'dist_dir' method. In development environments, the generated method will return a path to the development directories 'share' directory. In non-development environments, this simply returns File::ShareDir::dist_dir.

As a result of this, specifying the Distribution name is not required during development ( unless in strict mode ), however, it will start to matter once it is installed. This is a potential avenues for bugs if you happen to name it wrong.

In strict mode, the distribution name is ALWAYS REQUIRED, either at least at import or dist_dir() time.

build_dist_file

    use File::ShareDir::ProjectDirDir ( : all );

    #  this calls
    my $coderef = File::ShareDir::ProjectDistDir->build_dist_file(
      'dist_file' => {},
      { defaults => { filename => 'path/to/yourcallingfile.pm', projectdir => 'share' } }
    );

    use File::ShareDir::ProjectDirDir ( qw( :all ), distname => 'example-dist' );

    #  this calls
    my $coderef = File::ShareDir::ProjectDistDir->build_dist_file(
      'dist_file' => {},
      { distname => 'example-dist', defaults => { filename => 'path/to/yourcallingfile.pm', projectdir => 'share' } }
    );

    use File::ShareDir::ProjectDirDir
      dist_file => { distname => 'example-dist', -as => 'mydistfile' },
      dist_file => { distname => 'other-dist',   -as => 'otherdistfile' };

    # This calls
    my $coderef = File::ShareDir::ProjectDistDir->build_dist_file(
      'dist_file',
      { distname => 'example-dist' },
      { defaults => { filename => 'path/to/yourcallingfile.pm', projectdir => 'share' } },
    );
    my $othercoderef = File::ShareDir::ProjectDistDir->build_dist_file(
      'dist_file',
      { distname => 'other-dist' },
      { defaults => { filename => 'path/to/yourcallingfile.pm', projectdir => 'share' } },
    );

    # And leverages Sub::Exporter to create 2 subs in your package.

Generates the 'dist_file' method.

In development environments, the generated method will return a path to the development directories 'share' directory. In non-development environments, this simply returns File::ShareDir::dist_file.

Caveats as a result of package-name as stated in "build_dist_dir" also apply to this method.

SIGNIFICANT CHANGES ^

1.000000

Strict Mode.

Using Strict Mode

    use File::ShareDir::ProjectDistDir ':all', strict => 1;
    use File::ShareDir::ProjectDistDir 'dist_dir' => { defaults => { strict => 1 }};

Why you should use strict mode

Starting with 1.000000, there is a parameter strict that changes how sharedir resolution performs.

Without strict:

    lib/...
    share/...

With strict

    lib/...
    share/dist/Dist-Name-Here/...

This technique greatly builds resilience to the long standing problem with "develop" vs "install" heuristic ambiguity.

Here at least,

    dist_dir('Dist-Name')

Will instead fall back to

    @INC/auto/share/dist/Dist-Name

When

    share/dist/Dist-Name

Does not exist.

This means if you have a layout like this:

    <DEVROOT>/inc/<a local::lib path here>
    <DEVROOT>/lib/<development files here>

Then when Foo-Bar-Baz is installed as:

    <DEVROOT>/inc/lib/Foo/Bar/Baz.pm
    <DEVROOT>/inc/lib/auto/share/dist/Foo-Bar-Baz

Then Baz.pm will not see the DEVROOT and assume "Hey, this is development" and then proceed to try finding files in DEVROOT/share

Instead, DEVROOT must have DEVROOT/share/dist/Foo-Bar-Baz too, otherwise it reverts to DEVROOT/inc/lib/auto...

Path::Class interfaces deprecated and dependency dropped.

If you have any dependence on this function, now is the time to get yourself off it.

Minimum Changes to stay with Path::Class short term.

As the dependency has been dropped on Path::Class, if you have CPAN modules relying on Path::Class interface, you should now at a very minimum start declaring

    { requires => "Path::Class" }

This will keep your dist working, but will not be future proof against further changes.

Staying with Path::Class long term.

Recommended approach if you want to stay using the Path::Class interface:

    use File::ShareDir::... etc
    use Path::Class qw( dir file );

    my $dir = dir( dist_dir('Dist-Name') );

This should future-proof you against anything File::ShareDir may do in the future.

Versioning Scheme arbitrary converted to float

This change is a superficial one, and should have no bearing on how significant you think this release is.

It is a significant release, but the primary reason for the version change is simply to avoid compatibility issues in versions themselves.

However, outside that, x.y.z semantics are still intended to be semi-meaningful, just with less . and more 0

dev path determination now deferred to call time instead of use

This was essentially a required change to make strict mode plausible, because strict mode _requires_ the distname to be known, even in the development environment.

This should not have any user visible effects, but please, if you have any problems, file a bug.

file component determination wrested from File::ShareDir.

    dist_file('foo','bar')

Is now simply sugar syntax for

    path(dist_dir('foo'))->child('bar')

This should have no side effects in your code, but please file any bugs you experience.

( return value is still undef if the file does not exist, and still croak's if the file is not a file, or unreadable, but these may both be subject to change )

0.5.0 - Heuristics and Return type changes

New devdir heuristic

Starting with 0.5.0, instead of using our simple lib/../share pattern heuristic, a more advanced heuristic is used from the new Path::FindDev and Path::IsDev.

This relies on a more "concrete" marker somewhere at the top of your development tree, and more importantly, checks for the existence of specific files that are not likely to occur outside a project root.

lib and share based heuristics were a little fragile, for a few reasons:

So instead, as of 0.5.0, the heuristic revolves around certain specific files being in the dev directory.

Which is hopefully a more fault resilient mechanism.

New Return Types

Starting with 0.5.0, the internals are now based on Path::Tiny instead of Path::Class, and as a result, there may be a few glitches in transition.

Also, previously you could get a Path::Class::* object back from dist_dir and dist_file by importing it as such:

    use File::ShareDir::ProjectDistDir
        qw( dist_dir dist_file ),
        defaults => { pathclass => 1 };

Now you can also get Path::Tiny objects back, by passing:

    use File::ShareDir::ProjectDistDir
        qw( dist_dir dist_file ),
        defaults => { pathtiny => 1 };

For the time being, you can still get Path::Class objects back, it is deprecated since 1.000000

( In fact, I may even make 2 specific sub-classes of PDD for people who want objects back, as it will make the API and the code much cleaner )

AUTHOR ^

Kent Fredric <kentnl@cpan.org>

COPYRIGHT AND LICENSE ^

This software is copyright (c) 2014 by Kent Fredric <kentnl@cpan.org>.

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

syntax highlighting: