File Coverage

blib/lib/App/hopen/HopenFileKit.pm
Criterion Covered Total %
statement 71 71 100.0
branch 11 16 68.7
condition n/a
subroutine 17 17 100.0
pod n/a
total 99 104 95.1


line stmt bran cond sub pod time code
1             # App::hopen::HopenFileKit - set up a hopen file
2             package App::hopen::HopenFileKit;
3 1     1   7 use strict; use warnings;
  1     1   3  
  1         29  
  1         5  
  1         2  
  1         27  
4 1     1   5 use Data::Hopen::Base;
  1         2  
  1         7  
5              
6 1     1   1281 use Import::Into;
  1         3  
  1         22  
7 1     1   498 use Package::Alias ();
  1         512  
  1         26  
8              
9             # Imports. Note: `()` marks packages we export to the caller but
10             # don't use ourselves. These are in the same order as in import().
11 1     1   12 use App::hopen::BuildSystemGlobals;
  1         3  
  1         126  
12 1     1   434 use App::hopen::Util::BasedPath ();
  1         5  
  1         22  
13 1     1   6 use Path::Class ();
  1         4  
  1         55  
14              
15 1     1   8 use App::hopen::Phases ();
  1         2  
  1         19  
16 1     1   7 use Data::Hopen qw(:default loadfrom);
  1         2  
  1         142  
17              
18              
19             our $VERSION = '0.000013'; # TRIAL
20              
21 1     1   13 use parent 'Exporter'; # Exporter-exported symbols {{{1
  1         2  
  1         15  
22             our (@EXPORT, @EXPORT_OK, %EXPORT_TAGS);
23             BEGIN {
24 1     1   122 @EXPORT = qw($__R_on_result *FILENAME);
25             # ^ for Phases::on()
26             # ^ glob so it can be localized
27 1         2 @EXPORT_OK = qw();
28 1         264 %EXPORT_TAGS = (
29             default => [@EXPORT],
30             all => [@EXPORT, @EXPORT_OK]
31             );
32             } # }}}1
33              
34             # Docs {{{1
35              
36             =head1 NAME
37              
38             App::hopen::HopenFileKit - Kit to be used by a hopen file
39              
40             =head1 SYNOPSIS
41              
42             This is a special-purpose test kit used for interpreting hopen files.
43             See L<App::hopen/_run_phase>. Usage:
44              
45             use App::hopen::HopenFileKit "<filename>"[, other args]
46              
47             C<< <filename> >> is the name you want to use for the package using
48             this module, and will be loaded into constant C<$FILENAME> in that
49             package.
50              
51             C<[other args]> are per Exporter, and should be omitted unless you
52             really know what you're doing!
53              
54             =head1 FUNCTIONS
55              
56             =cut
57              
58             # }}}1
59              
60             # Which languages we've loaded
61             my %_loaded_languages;
62              
63             sub _language_import { # {{{1
64              
65             =head2 _language_import
66              
67             C<import()> routine for the fake "language" package
68              
69             =cut
70              
71 6     6   21 my $target = caller;
72             #say "language invoked from $target";
73 6         16 shift; # Drop our package name
74 6 50       22 croak "I need at least one language name" unless @_;
75              
76 6 50       22 die "TODO permit aliases" if ref $_[0]; # TODO take { alias => name }
77              
78 6         20 foreach my $language (@_) {
79 6 100       1217 next if $_loaded_languages{$language};
80             # Only load any given language once. This avoids cowardly warnings
81             # from Package::Alias, but still causes warnings if a language
82             # overrides an unrelated package. (For example, saying
83             # `use language "Graph"` would be a Bad Idea :) .)
84              
85             # Find the package for the given language
86 1         3 my ($src_package, $dest_package);
87 1 50       7 $src_package = loadfrom($language, "${Toolset}::", '')
88             or croak "Can't find a package for language ``$language'' " .
89             "in toolset ``$Toolset''";
90              
91             # Import the given language into the root namespace.
92             # Use only the last ::-separated component if :: are present.
93 1 50       73 $dest_package = ($src_package =~ m/::([^:]+)$/) ? $1 : $src_package;
94 1         10 Package::Alias->import::into($target, $dest_package => $src_package);
95             # TODO add to Package::Alias the ability to pass parameters
96             # to the package being loaded.
97              
98 1         619 $_loaded_languages{$language} = true;
99             } #foreach requested language
100             } #_language_import }}}1
101              
102             sub _create_language { # {{{1
103              
104             =head2 _create_language
105              
106             Create a package "language" so that the calling package can invoke it.
107              
108             =cut
109              
110             #say "_create_language";
111 9 100   9   34 return if %language::; #idempotent
112              
113             {
114 1     1   7 no strict 'refs';
  1         3  
  1         177  
  1         3  
115 1         3 *{'language::import'} = \&_language_import;
  1         6  
116             }
117              
118 1         5 $INC{'language.pm'} = 1;
119             } #_create_language() }}}1
120              
121             sub import { # {{{1
122              
123             =head2 import
124              
125             Set up the calling package. See L</SYNOPSIS> for usage.
126              
127             =cut
128              
129 9     9   25 my $target = caller;
130 9 50       31 my $target_friendly_name = $_[1] or croak "Need a filename";
131             # 0=__PACKAGE__, 1=filename
132 9         34 my @args = splice @_, 1, 1;
133             # Remove the filename; leave the rest of the args for Exporter's use
134              
135             # Export our stuff
136 9         630 __PACKAGE__->export_to_level(1, @args);
137              
138             # Re-export packages
139 9         98 $_->import::into($target) foreach qw(
140             Data::Hopen::Base
141             App::hopen::BuildSystemGlobals
142             App::hopen::Util::BasedPath
143             Path::Class
144             );
145              
146 9         19287 App::hopen::Phases->import::into($target, qw(:all :hopenfile));
147 9         2456 Data::Hopen->import::into($target, ':all');
148              
149             # Initialize data in the caller
150             {
151 1     1   7 no strict 'refs';
  1         2  
  1         142  
  9         2474  
152 9         709 *{ $target . '::FILENAME' } = eval("\\\"\Q$target_friendly_name\E\"");
  9         65  
153             # Need `eval` to make it read-only - even \"$target..." isn't RO.
154             # \Q and \E since, on Windows, $friendly_name is likely to
155             # include backslashes.
156             }
157              
158             # Create packages at the top level
159 9         57 _create_language();
160             Package::Alias->import::into($target, 'H' => 'App::hopen::H')
161 9 100       16 unless eval { scalar keys %H:: };
  9         271  
162             # Don't import twice, but without the need to set Package::Alias::BRAVE
163             # TODO permit handling the situation in which an actual package H is
164             # loaded, and the hopenfile needs to use something else.
165             } #import() # }}}1
166              
167             1;
168             __END__
169             # vi: set fdm=marker: #