Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
We now generate in-mem stubs by default!
  • Loading branch information
ingydotnet committed Dec 6, 2014
1 parent e8d4a0f commit c7d9e8b
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 107 deletions.
11 changes: 6 additions & 5 deletions doc/Inline/Module/Tutorial.swim
Expand Up @@ -111,19 +111,20 @@ extension libraries. As long the shared library stuff gets built into the
If you don't want to keep the generated stub code around, there is a way to
have it autogenerated. Just set `PERL5OPT` like this:

export PERL5OPT='-MInline::Module=autostub'
export PERL5OPT='-MInline::Module=autostub,Acme::Math::XS::Inline'

This will add a CODE ref to @INC that will generate stub modules just in time,
and put them under `lib`. For instance if you just run your tests with:
as in-memory files. For instance if you just run your tests with:

prove -l t/

the stub modules will be autogenerated. If you'd rather see the stubs be
generated under the `blib` directory, use this:
generated as real files under the `lib` or `blib` directory, use one of these:

export PERL5OPT='-MInline::Module=autostub,blib'
export PERL5OPT='-MInline::Module=autostub,lib,Acme::Math::XS::Inline'
export PERL5OPT='-MInline::Module=autostub,blib,Acme::Math::XS::Inline'

Then you'll need to add the `-b` flag for testing:
Then you'll need to add the `-b` flag for `blib` testing:

prove -lb t/

Expand Down
86 changes: 45 additions & 41 deletions lib/Inline/Module.pm
Expand Up @@ -34,7 +34,7 @@ sub import {
my $class = shift;
DEBUG "Inline::Module::import(@_)";

my ($inline_module, $program) = caller;
my ($stub_module, $program) = caller;

if ($program eq 'Makefile.PL') {
no warnings 'once';
Expand All @@ -55,26 +55,26 @@ sub import {
if $cmd eq 'fixblib';

if ($cmd =~ /^v[0-9]$/) {
$class->check_api_version($inline_module, $cmd => @_);
$class->check_api_version($stub_module, $cmd => @_);
no strict 'refs';
*{"${inline_module}::import"} = $class->importer($inline_module);
*{"${stub_module}::import"} = $class->importer($stub_module);
return;
}

die "Unknown Inline::Module::import argument '$cmd'"
}

sub check_api_version {
my ($class, $inline_module, $api_version, $inline_module_version) = @_;
my ($class, $stub_module, $api_version, $inline_module_version) = @_;
if ($api_version ne 'v1' or $inline_module_version ne $VERSION) {
warn <<"...";
It seems that '$inline_module' is out of date.
It seems that '$stub_module' is out of date.
It is using Inline::Module version '$inline_module_version'.
You have Inline::Module version '$VERSION' installed.
Make sure you have the latest version of Inline::Module installed, then run:
perl -MInline::Module=makestub,$inline_module
perl -MInline::Module=makestub,$stub_module
...
# XXX 'exit' is used to get a cleaner error msg.
Expand All @@ -84,7 +84,7 @@ Make sure you have the latest version of Inline::Module installed, then run:
}

sub importer {
my ($class, $inline_module) = @_;
my ($class, $stub_module) = @_;
return sub {
require File::Path;
File::Path::mkpath($inline_build_path)
Expand All @@ -94,7 +94,7 @@ sub importer {
Config =>
directory => $inline_build_path,
using => 'Inline::C::Parser::RegExp',
name => $inline_module,
name => $stub_module,
);
my $class = shift;
DEBUG "Inline::Module proxy to Inline::%s", @_;
Expand Down Expand Up @@ -187,7 +187,8 @@ sub handle_makestub {


for my $module (@modules) {
my $path = $class->write_proxy_module($dest, $module);
my $code = $class->proxy_module($module);
my $path = $class->write_module($dest, $module, $code);
print "Created stub module '$path' (Inline::Module $VERSION)\n";
}

Expand All @@ -196,40 +197,45 @@ sub handle_makestub {

sub handle_autostub {
my ($class, @args) = @_;
croak "The 'autostub' directive used but no './lib' dir present"
unless -d 'lib';

require lib;
lib->import('lib');

my $dest;
my @modules;
my ($dest, %autostub_modules);
for my $arg (@args) {
if ($arg eq 'blib') {
$dest = 'blib/lib';
if ($arg =~ m!::!) {
$autostub_modules{$arg} = 1;
}
elsif ($arg =~ m!/!) {
$dest = $arg;
elsif ($arg =~ m!(^(b?lib$|mem)$|/)!) {
croak "Invalid arg '$arg'. Dest path already set to '$dest'"
if $dest;
$dest = $arg eq 'blib' ? 'blib/lib' : $arg;
}
else {
croak "Unknown 'autostub' argument: '$arg'";
}
}
$dest ||= 'lib';
$dest ||= 'mem';

push @INC, sub {
my ($self, $module) = @_;
my ($self, $module_path) = @_;
delete $ENV{PERL5OPT};

# TODO This asserts that we are really building a ::Inline stub.
# We might need to be more forgiving on naming here at some point:
$module =~ m!/Inline\w*\.pm$!
or return;
my $module = $module_path;
$module =~ s!\.pm$!!;
$module =~ s!/!::!g;
$autostub_modules{$module} or return;

if ($dest eq 'mem') {
my $code = $class->proxy_module($module);
open my $fh, '<', \$code;
return $fh;
}

my $path = "$dest/$module";
my $path = "$dest/$module_path";
if (not -e $path) {
$module =~ s!\.pm$!!;
$module =~ s!/!::!g;
my $path = $class->write_proxy_module($dest, $module);
my $code = $class->proxy_module($module);
$class->write_module($dest, $module, $code);
print "Created stub module '$path' (Inline::Module $VERSION)\n";
}

Expand All @@ -251,8 +257,10 @@ sub handle_distdir {
}

for my $module (@inlined_modules) {
$class->write_dyna_module("$distdir/lib", $module);
$class->write_proxy_module("$distdir/inc", $module);
my $code = $class->dyna_module($module);
$class->write_module("$distdir/lib", $module, $code);
$code = $class->proxy_module($module);
$class->write_module("$distdir/inc", $module, $code);
}
for my $module (@included_modules) {
$class->write_included_module("$distdir/inc", $module);
Expand Down Expand Up @@ -299,10 +307,10 @@ sub read_local_module {
return $code;
}

sub write_proxy_module {
my ($class, $dest, $module) = @_;
sub proxy_module {
my ($class, $module) = @_;

my $code = <<"...";
return <<"...";
# DO NOT EDIT
#
# GENERATED BY: Inline::Module $Inline::Module::VERSION
Expand All @@ -317,13 +325,11 @@ use Inline::Module 'v1' => '$VERSION';
1;
...

$class->write_module($dest, $module, $code);
}

sub write_dyna_module {
my ($class, $dest, $module) = @_;
my $code = <<"...";
sub dyna_module {
my ($class, $module) = @_;
return <<"...";
# DO NOT EDIT
#
# GENERATED BY: Inline::Module $Inline::Module::VERSION
Expand All @@ -339,12 +345,10 @@ bootstrap $module;
# XXX - think about this later:
# our \$VERSION = '0.0.5';
# bootstrap $module \$VERSION;

$class->write_module($dest, $module, $code);
}

sub write_module {
my ($class, $dest, $module, $text) = @_;
my ($class, $dest, $module, $code) = @_;

my $filepath = $module;
$filepath =~ s!::!/!g;
Expand All @@ -356,7 +360,7 @@ sub write_module {
unlink $filepath;
open OUT, '>', $filepath
or die "Can't open '$filepath' for output:\n$!";
print OUT $text;
print OUT $code;
close OUT;

return $filepath;
Expand Down
35 changes: 13 additions & 22 deletions note/ToDo
@@ -1,38 +1,21 @@
== To Do Next

- Use IO::String for autostub handle by default

== Soon

- Add tests
+ Bash test setup
- Write a test/devel test for making a full module like Acme::Math::XS

- Add new plugin sections to the tutorial

- Refactor Dist-Zilla-Plugin-InlineModule to use postamble
- and Alt-Acme-Math-XS-DistZilla
- Look at ZillaDist too

- Try putting ::Inline module into author time blib
- This would simplify everything greatly
== Soon

- Issue #9. Fix this `make` time bug:
> make
Can't opendir(blib/lib/auto/Alt): No such file or directory
at inc/Inline/Module.pm line 227.
- Happens on:
- make
- make test
- make install
- Add tests
+ Bash test setup
- Write a test/devel test for making a full module like Acme::Math::XS

- Think of a way to make sure Inline::Module version does not regress.
- From release to release with comaintainers
- Not sure how important this is

- Change the 'inline' meta keyword to 'loader' or 'stub'
- This might go away altogether so let's wait and see

== Done

+ Switch Inline::Module to the postamble model
Expand All @@ -46,4 +29,12 @@
+ The ::Inline module can be generated by the Makefile.PL etc
+ It should likely never be committed. (We commit it now)
+ Change 'inline' config key to 'stub'

+ Use IO::String for autostub handle by default
+ Try putting ::Inline module into author time blib
+ This would simplify everything greatly
+ Change the 'inline' meta keyword to 'loader' or 'stub'
+ This might go away altogether so let's wait and see
+ Issue #9. Fix this `make` time bug:
> make
Can't opendir(blib/lib/auto/Alt): No such file or directory
at inc/Inline/Module.pm line 227.
68 changes: 39 additions & 29 deletions test/devel/generate-stub.t
@@ -1,37 +1,47 @@
#!/bin/bash
#!/usr/bin/env bash

source "`dirname $0`/setup"
use Test::More
BAIL_ON_FAIL

# lib must exist (Sanity check)
mkdir lib

# Generate a stub
perl -MInline::Module=makestub,Foo::Inline
ok "`[ -f lib/Foo/Inline.pm ]`" "The stub file exists in lib"
rm -fr lib/Foo

# Auto-generate a stub
(
export PERL5OPT=-MInline::Module=autostub
perl -e 'use Foo::Inline'
)
ok "`[ -f lib/Foo/Inline.pm ]`" "The stub file exists in lib"
rm -fr lib/Foo

# Generate into blib
perl -MInline::Module=makestub,Foo::Inline,blib
ok "`[ -f blib/lib/Foo/Inline.pm ]`" "The stub file exists in blib"
rm -fr blib

# Auto-generate into blib
(
export PERL5OPT=-MInline::Module=autostub,blib
perl -e 'use Foo::Inline'
)
ok "`[ -f blib/lib/Foo/Inline.pm ]`" "The stub file exists in blib"
rm -fr blib
{
perl -MInline::Module=makestub,Foo::Bar
ok "`[ -f lib/Foo/Bar.pm ]`" "Stub file was generated into lib"
rm -fr lib
}

{
(
export PERL5OPT=-MInline::Module=autostub,Foo::Bar
perl -e 'use Foo::Bar'
)
pass "Stub was auto-generated as IO::String object"
# ok "`[ ! -e lib ] && [ ! -e blib ]`" "Neither lib nor blib exist"
}

{
(
export PERL5OPT=-MInline::Module=autostub,lib,Foo::Bar
perl -e 'use Foo::Bar'
)
ok "`[ -f lib/Foo/Bar.pm ]`" "Stub file auto-generated into lib"
rm -fr lib
}

{
perl -MInline::Module=makestub,Foo::Bar,blib
ok "`[ -f blib/lib/Foo/Bar.pm ]`" "Stub file generated into blib"
rm -fr blib
}

{
(
export PERL5OPT=-MInline::Module=autostub,Foo::Bar,blib
perl -e 'use Foo::Bar'
)
ok "`[ -f blib/lib/Foo/Bar.pm ]`" "Stub file auto-generated into blib"
rm -fr blib
}

done_testing
teardown
Expand Down

0 comments on commit c7d9e8b

Please sign in to comment.