The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

package FindApp;
use v5.10;
use strict;
use mro "c3";
our $VERSION = "v0.0.7";
use FindApp::Vars qw(:all);
use FindApp::Utils qw(:package);
use FindApp::Utils <tracing debugging>;
use parent subpackage Object => with "Exporter";
# Don't do this here!!!
#__PACKAGE__->renew();
1;
=encoding utf8
=head1 NAME
FindApp - find your application home and config your process for it
=head1 SYNOPSIS
use FindApp; # defaults to "lib" argument
use FindApp "lib"; # explicit
That guarantees that this will always src, presuming there is
a "lib" above you that has the "MyCorp::CorpApp" module under it:
use FindApp "MyCorp::CorpApp";
Or load-and-go:
use FindApp -root => "lib/", -use "MyCorp::CorpApp";
AKA:
use applib "MyCorp::CorpApp";
=head1 DESCRIPTION
When you have a application directory with its own installation
instructure, setting up its @INC path for its scripts to use
can be troublesome. You can't just say:
use lib "lib";
or
use lib "../lib";
because that requires that the program be run from a particular
directory. The normal approach is something like this:
use FindBin;
use lib "$FindBin::Bin/../lib";
Even when possible in a few cases, it doesn't src for scripts that
you want to move around your application tree, such as test files,
support tools that may be in a prod-vs-nonprod directory, cron scripts,
and all the rest.
When you say C<use FindApp>, the first enclosing directory that matches
the selection criteria is used. The default selection criterion is that
the root application directory contain a directory called "lib", which
will be added to your @INC. You can also look at the current selection
criteria this way:
bash$ perl -MFindApp -le 'print FindApp->constraint_text'
lib/ in root
What it actually does is something like this:
bash$ perl -MFindApp -e 'print FindApp->shell_settings'
export APP_ROOT="/home/tchrist/src/corp-app";
export PERL5LIB="/home/tchrist/src/corp-app/lib:$PERL5LIB";
export PATH-"/home/tchrist/src/corp-app/bin:$PATH";
Except that it only does a C<use lib> on the library directory it found; it doesn't
actually muck with your PERL5LIB variable.
That's something you could eval directly from your shell. This even
srcs for I<csh> and I<tcsh> users, because they see something different:
tcsh% perl -MFindApp -e 'print FindApp->shell_settings'
setenv APP_ROOT "/home/tchrist/src/corp-app";
setenv PERL5LIB "/home/tchrist/src/corp-app/lib:$PERL5LIB";
setenv PATH "/home/tchrist/src/corp-app/bin:$PATH";
You can add constraints to the root directory itself or the bin set, the lib set,
or the man set. For example,
use FindApp -LIB "t/lib", # add new lib possibility
-BIN "bin/utils", # add new bin possibility
-bin "app.fcgi", # add new bin requirement
qw(MyCorp::CorpApp MyCorp::CorpApp::Test); # add two lib requirements
The constraint text after that would be:
lib/ in root, app.fcgi in bin or bin/utils, and MyCorp::CorpApp and MyCorp::CorpApp::Test in lib or t/lib
=head2 Public Methods
=over
=back
=head2 Exports
=over
=back
=head1 EXAMPLES
=head1 ENVIRONMENT
=head1 SEE ALSO
=over
=item L<FindApp>
=back
=head1 CAVEATS AND PROVISOS
=head1 BUGS AND LIMITATIONS
=head1 HISTORY
=head1 AUTHOR
Tom Christiansen C<< <tchrist@perl.com> >>
=head1 LICENCE AND COPYRIGHT
Copyright (c) 2016, Tom Christiansen C<< <tchrist@perl.com> >>.
All Rights Reserved.
This module is free software; you can redistribute it and/or
modify it under the same terms as Perl itself. See L<perlartistic>.