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   2  
  1         29  
  1         5  
  1         2  
  1         25  
4 1     1   5 use Data::Hopen::Base;
  1         2  
  1         8  
5              
6 1     1   1276 use Import::Into;
  1         2  
  1         23  
7 1     1   546 use Package::Alias ();
  1         556  
  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   8 use App::hopen::BuildSystemGlobals;
  1         2  
  1         104  
12 1     1   436 use App::hopen::Util::BasedPath ();
  1         3  
  1         28  
13 1     1   6 use Path::Class ();
  1         2  
  1         18  
14              
15 1     1   4 use App::hopen::Phases ();
  1         2  
  1         20  
16 1     1   5 use Data::Hopen qw(:default loadfrom);
  1         2  
  1         130  
17              
18              
19             our $VERSION = '0.000012'; # TRIAL
20              
21 1     1   7 use parent 'Exporter'; # Exporter-exported symbols {{{1
  1         2  
  1         6  
22             our (@EXPORT, @EXPORT_OK, %EXPORT_TAGS);
23             BEGIN {
24 1     1   132 @EXPORT = qw($__R_on_result *FILENAME);
25             # ^ for Phases::on()
26             # ^ glob so it can be localized
27 1         3 @EXPORT_OK = qw();
28 1         317 %EXPORT_TAGS = (
29             default => [@EXPORT],
30             all => [@EXPORT, @EXPORT_OK]
31             );
32             } # }}}1
33              
34             # Docs {{{1
35              
36             =head1 NAME
37              
38             Data::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<Data::Hopen::App/_run_phase>. Usage:
44              
45             use Data::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 4     4   16 my $target = caller;
72             #say "language invoked from $target";
73 4         8 shift; # Drop our package name
74 4 50       15 croak "I need at least one language name" unless @_;
75              
76 4 50       13 die "TODO permit aliases" if ref $_[0]; # TODO take { alias => name }
77              
78 4         13 foreach my $language (@_) {
79 4 100       800 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       6 $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       27 $dest_package = ($src_package =~ m/::([^:]+)$/) ? $1 : $src_package;
94 1         11 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         633 $_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 6 100   6   26 return if %language::; #idempotent
112              
113             {
114 1     1   8 no strict 'refs';
  1         2  
  1         200  
  1         2  
115 1         3 *{'language::import'} = \&_language_import;
  1         5  
116             }
117              
118 1         3 $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 6     6   16 my $target = caller;
130 6 50       22 my $target_friendly_name = $_[1] or croak "Need a filename";
131             # 0=__PACKAGE__, 1=filename
132 6         18 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 6         426 __PACKAGE__->export_to_level(1, @args);
137              
138             # Re-export packages
139 6         61 $_->import::into($target) foreach qw(
140             Data::Hopen::Base
141             App::hopen::BuildSystemGlobals
142             App::hopen::Util::BasedPath
143             Path::Class
144             );
145              
146 6         12424 App::hopen::Phases->import::into($target, qw(:all :hopenfile));
147 6         1630 Data::Hopen->import::into($target, ':all');
148              
149             # Initialize data in the caller
150             {
151 1     1   8 no strict 'refs';
  1         2  
  1         161  
  6         1704  
152 6         432 *{ $target . '::FILENAME' } = eval("\\\"\Q$target_friendly_name\E\"");
  6         27  
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 6         39 _create_language();
160             Package::Alias->import::into($target, 'H' => 'App::hopen::H')
161 6 100       9 unless eval { scalar keys %H:: };
  6         171  
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: #