App-Fetchware

 view release on metacpan or  search on metacpan

lib/App/Fetchware/CreateConfigOptions.pm  view on Meta::CPAN

#=cut

sub _create_config_options {
    my ($callers_package, %opts) = @_;

    for my $value_key (keys %opts) {
        for my $sub_name (@{$opts{$value_key}}) {

        # IMPORT subroutines are not actually "imported." Instead, they are
        # "made" in the correct package by App::Fetchware's config subroutine
        # function factory, _make_config_sub().
        if ($value_key ne 'IMPORT') {
            App::Fetchware::_make_config_sub($sub_name, $value_key,
                $callers_package);
        } else {
            die <<EOD unless grep {$INC{$_} =~ /App.Fetchware/} keys %INC;
App-Fetchware-Util: App::Fetchware has not been loaded. How can you import a
subroutine from App::Fetchware if you have not yet loaded it yet? Please load
App::Fetchware [use App::Fetchware;] and try again.
EOD
            clone($sub_name => (from => 'App::Fetchware', to => $callers_package))
                or die <<EOD;
App-Fetchware-Util: Failed to clone the specified subroutine [$sub_name] from
App::Fetchware into your namespace [$callers_package]. You probably just need to
load fetchware [use App::Fetchware;] inside your fetchware extension.
EOD
        }

    # Be sure to @EXPORT the newly minted subroutine.
    _add_export($sub_name, $callers_package);



        }
    }
}


# Hide it's POD since it's an '_' hidden subroutine I don't want fetchware
# extensions to use.
#=head2 _add_export()
#
#    _add_export(start => caller);
#
#Adds the specified subroutine to the specified caller's @EXPORT variable, so
#that when the specified package is imported the specified subroutine is imported
#as well.
#
#=cut

sub _add_export {
    my ($sub_to_export, $caller) = @_;

    {
        no strict 'refs';

        # If the $caller has not declared @EXPORT for us, then we'll do it here
        # ourselves, so you don't need to declare a variable in your fetchware
        # extension that you never even use yourself.
        #
        #The crazy *{...} contraption looks up @$caller::EXPORT up in the stash,
        #and checks if it's defined in the stash, and if there's a stash entry,
        #then it has been defined, and if not, then the variable is undeclared,
        #so then delare it using the crazy eval.
        #
        #Also, note that use vars is used in favor of our, because our variables
        #are bizarrely lexically scoped, which is insane. Why would a global be
        #lexically scoped it's a global isn't it. But if you think that's
        #bizarre, check this out, use vars is file scoped. Again, how is a
        #global file scoped? Perhaps just the variable you declare with our or
        #use vars is lexical or file scoped, but the stash entry it creates
        #actually is global???
        unless (defined *{ $caller . '::EXPORT' }{ARRAY}) {
            my $eval = 'use vars @$caller::EXPORT; 1;';
            $eval =~ s/\$caller/$caller/;
            eval $eval or die <<EOD;
App-Fetchware-Util: Huh?!? For some reason fetchware failed to create the
necessary \@EXPORT variable in the specified caller's package [$caller]. This
just shouldn't happen, and is probably an internal bug in fetchware. Perhaps
the package specified in [$caller] has not been defined. Exception:
[$@]
EOD
        }
        
        # export *all* @api_subs.
        push @{"${caller}::EXPORT"}, $sub_to_export;
    }
}



1;

=pod

=head1 NAME

App::Fetchware::CreateConfigOptions - Used by fetchware extensions to create their configuration options.

=head1 VERSION

version 1.016

=head1 SYNOPSIS

    use App::Fetchware::ExportAPI KEEP => [qw(start end)],
        OVERRIDE =>
            [qw(lookup download verify unarchive build install uninstall)];

=head1 DESCRIPTION

App::Fetchware::ExportAPI is a utility helper class for fetchware extensions. It
makes it easy to ensure that your fetchware extension implements or imports all
of App::Fetchware's required API subroutines.

See section L<App::Fetchware/CREATING A FETCHWARE EXTENSION> in App::Fetchware's
documentation for more information on how to create your very own fetchware
extension.

=head1 CREATECONFIGOPTIONS'S API METHODS



( run in 0.616 second using v1.01-cache-2.11-cpan-39bf76dae61 )