Skip to content

Commit

Permalink
Got makestub and autostub working with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ingydotnet committed Dec 5, 2014
1 parent a518bff commit e39b5f7
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 68 deletions.
15 changes: 4 additions & 11 deletions doc/Inline/Module.swim
Expand Up @@ -73,25 +73,18 @@ Arguments are key/value pairs.

During development, [Inline::Module] needs to generate /stub/ modules. For the
case in the synopsis, it would need to generate `Acme::Math::XS::Inline`.
Depending on your development / testing style, it can either go into `lib/` or
`blib/` (even if `blib/` doesn't exist yet). There a few similar but different
ways to do this:
There a few similar but different ways to do this:

PERL5OPT='-MInline::Module=blib' prove -blv t/
perl -MInline::Module=makestub,Acme::Math::XS::Inline

or:

export PERL5OPT='-MInline::Module=lib'
export PERL5OPT='-MInline::Module=autostub'
prove -lv t/


or:

perl -MInline::Module=blib -MAcme::Math::XS -e1

or (temporarily) in your code:

use Inline::Module 'blib';
perl Makefile.PL

= TPF Grant

Expand Down
144 changes: 95 additions & 49 deletions lib/Inline/Module.pm
Expand Up @@ -18,7 +18,7 @@ sub new {

#------------------------------------------------------------------------------
# This import serves multiple roles:
# - bin/perl-inline-module
# - -MInline::Module=autostub
# - ::Inline module's proxy to Inline.pm
# - Makefile.PL postamble
# - Makefile rule support
Expand All @@ -27,52 +27,33 @@ sub import {
my $class = shift;

my ($inline_module, $program) = caller;
if (@_ == 1 and $_[0] =~ /^b?lib$/) {
if (-d 'lib') {
unshift @INC, 'lib';
push @INC, $class->module_maker(@_);
}
return;
}
elsif ($program eq 'Makefile.PL') {

if ($program eq 'Makefile.PL') {
no warnings 'once';
*MY::postamble = \&postamble;
return;
}

if (@_ == 1) {
my ($cmd) = @_;
if ($cmd =~ /^(distdir|fixblib)$/) {
my $method = "handle_$cmd";
$class->$method();
}
else {
die "Unknown argument '$cmd'"
}
return unless @_;
my $cmd = shift;

return $class->handle_makestub(@_)
if $cmd eq 'makestub';
return $class->handle_autostub(@_)
if $cmd eq 'autostub';
return $class->handle_distdir(@_)
if $cmd eq 'distdir';
return $class->handle_fixblib(@_)
if $cmd eq 'fixblib';

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

return unless @_;

# XXX 'exit' is used to get a cleaner error msg.
# Try to redo this without 'exit'.
$class->check_api_version($inline_module, @_)
or exit 1;

my $importer = sub {
require File::Path;
File::Path::mkpath('./blib') unless -d './blib';
# TODO try to not use eval here:
eval "use Inline Config => " .
"directory => './blib', " .
"using => 'Inline::C::Parser::RegExp', " .
"name => '$inline_module'";

my $class = shift;
Inline->import_heavy(@_);
};
no strict 'refs';
*{"${inline_module}::import"} = $importer;
die "Unknown argument '$cmd'"
}

sub check_api_version {
Expand All @@ -85,12 +66,30 @@ You have Inline::Module version '$VERSION' installed.
Make sure you have the latest version of Inline::Module installed, then run:
perl-inline-module generate $inline_module
perl -MInline::Module=makestub,$inline_module
...
return;
# XXX 'exit' is used to get a cleaner error msg.
# Try to redo this without 'exit'.
exit 1;
}
return 1;
}

sub importer {
my ($class, $inline_module) = @_;
return sub {
require File::Path;
File::Path::mkpath('./blib') unless -d './blib';
require Inline;
Inline->import(
Config =>
directory => './blib',
using => 'Inline::C::Parser::RegExp',
name => $inline_module,
);
my $class = shift;
Inline->import_heavy(@_);
};
}

#------------------------------------------------------------------------------
Expand Down Expand Up @@ -155,11 +154,59 @@ sub included_modules {
#------------------------------------------------------------------------------
# Class methods.
#------------------------------------------------------------------------------
sub module_maker {
my ($class, $dest) = @_;
$dest = 'blib/lib' if $dest eq 'blib';
sub handle_makestub {
my ($class, @args) = @_;

my $dest;
my @modules;
for my $arg (@args) {
if ($arg eq 'blib') {
$dest = 'blib/lib';
}
elsif ($arg =~ m!/!) {
$dest = $arg;
}
elsif ($arg =~ /::/) {
push @modules, $arg;
}
else {
croak "Unknown 'makestub' argument: '$arg'";
}
}
$dest ||= 'lib';


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

exit 0;
}

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;
for my $arg (@args) {
if ($arg eq 'blib') {
$dest = 'blib/lib';
}
elsif ($arg =~ m!/!) {
$dest = $arg;
}
else {
croak "Unknown 'autostub' argument: '$arg'";
}
}
$dest ||= 'lib';

sub {
push @INC, sub {
my ($self, $module) = @_;

# TODO This asserts that we are really building a ::Inline stub.
Expand All @@ -169,10 +216,10 @@ sub module_maker {

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

open my $fh, '<', $path or die "Can't open '$path' for input:\n$!";
Expand Down Expand Up @@ -255,7 +302,6 @@ sub write_proxy_module {
use strict; use warnings;
package $module;
use base 'Inline';
use Inline::Module 'v1' => '$VERSION';
1;
Expand Down
2 changes: 1 addition & 1 deletion note/UX-Spec
Expand Up @@ -34,7 +34,7 @@ These are the steps that a user goes through to make a Inline module and get it

3) Author generates `lib/Foo/Bar/Inline.pm` with this tool:

perl-inline-module generate Foo::Bar::Inline
perl -MInline::Module=makestub,Foo::Bar::Inline

4) Author codes and tests with one of the following:
- `perl Makefile.PL; make test`
Expand Down
27 changes: 24 additions & 3 deletions test/devel/generate-stub.t
Expand Up @@ -7,10 +7,31 @@ BAIL_ON_FAIL
# lib must exist (Sanity check)
mkdir lib

# Generate a Foo::Inline stub
perl -MInline::Module=blib -MFoo::Inline -e1
# 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

ok "`[ -d blib ]`" "The blib directory exists"
# 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

done_testing
teardown
Expand Down
4 changes: 2 additions & 2 deletions test/devel/setup
Expand Up @@ -8,7 +8,7 @@ PATH="$BASHLIB:$PATH"
source bash+ :std

TMP=$PWD/tmp
BEGIN_PWD=$PWD
TEST_HOME=$PWD

rm -fr $TMP
mkdir $TMP
Expand All @@ -17,7 +17,7 @@ export PERL5LIB="$PWD/lib:$PERL5LIB"
cd $TMP

teardown() {
cd $BEGIN_PWD
cd $TEST_HOME
rm -fr $TMP
return 0
}
23 changes: 21 additions & 2 deletions test/devel/test-acme-math-xs.t
@@ -1,5 +1,24 @@
use Test::More;
#!/bin/bash

pass 'Development testing';
source "`dirname $0`/setup"
use Test::More
BAIL_ON_FAIL

git clone $TEST_HOME/../acme-math-xs-pm/.git -b eumm
cd acme-math-xs-pm
perl -MInline::Module=autostub -MAcme::Math::XS::Inline -e1
ok "`[ -f lib/Acme/Math/XS/Inline.pm ]`" "The stub file exists"

cat lib/Acme/Math/XS/Inline.pm

prove -lv t &> out
pass "Acme::Math::XS passes its tests"

perl Makefile.PL
ok "`[ -f Makefile ]`" "The Makefile exists after 'perl Makefile.PL'"

make
ok "`[ -d blib ]`" "The 'blib' dir exists after 'make'"

done_testing;
teardown

0 comments on commit e39b5f7

Please sign in to comment.