]> git.vpit.fr Git - perl/modules/Mac-NSGetExecutablePath.git/commitdiff
This is 0.01 v0.01
authorVincent Pit <vince@profvince.com>
Mon, 29 Oct 2012 19:55:40 +0000 (17:55 -0200)
committerVincent Pit <vince@profvince.com>
Mon, 29 Oct 2012 19:55:40 +0000 (17:55 -0200)
19 files changed:
.gitignore [new file with mode: 0644]
Changes [new file with mode: 0644]
MANIFEST [new file with mode: 0644]
META.json [new file with mode: 0644]
META.yml [new file with mode: 0644]
Makefile.PL [new file with mode: 0644]
NSGetExecutablePath.xs [new file with mode: 0644]
README [new file with mode: 0644]
lib/Mac/NSGetExecutablePath.pm [new file with mode: 0644]
samples/perl_path.pl [new file with mode: 0755]
t/00-load.t [new file with mode: 0644]
t/01-import.t [new file with mode: 0644]
t/10-base.t [new file with mode: 0644]
t/91-pod.t [new file with mode: 0644]
t/92-pod-coverage.t [new file with mode: 0644]
t/93-pod-spelling.t [new file with mode: 0644]
t/95-portability-files.t [new file with mode: 0644]
t/99-kwalitee.t [new file with mode: 0644]
t/lib/VPIT/TestHelpers.pm [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..e2a9f70
--- /dev/null
@@ -0,0 +1,28 @@
+blib*
+pm_to_blib*
+
+Makefile
+Makefile.old
+Build
+_build*
+
+MYMETA.json
+MYMETA.yml
+
+*.tar.gz
+Mac-NSGetExecutablePath-*
+
+core.*
+*.[co]
+*.so
+*.bs
+*.out
+*.def
+*.exp
+
+cover_db
+*.gcda
+*.gcov
+*.gcno
+
+Debian_CPANTS.txt*
diff --git a/Changes b/Changes
new file mode 100644 (file)
index 0000000..a72ba10
--- /dev/null
+++ b/Changes
@@ -0,0 +1,5 @@
+Revision history for Mac-NSGetExecutablePath
+
+0.01    2012-10-29 19:55 UTC
+        First version, released on an unsuspecting world.
+
diff --git a/MANIFEST b/MANIFEST
new file mode 100644 (file)
index 0000000..a77e496
--- /dev/null
+++ b/MANIFEST
@@ -0,0 +1,18 @@
+Changes
+MANIFEST
+META.json
+META.yml
+Makefile.PL
+NSGetExecutablePath.xs
+README
+lib/Mac/NSGetExecutablePath.pm
+samples/perl_path.pl
+t/00-load.t
+t/01-import.t
+t/10-base.t
+t/91-pod.t
+t/92-pod-coverage.t
+t/93-pod-spelling.t
+t/95-portability-files.t
+t/99-kwalitee.t
+t/lib/VPIT/TestHelpers.pm
diff --git a/META.json b/META.json
new file mode 100644 (file)
index 0000000..8222885
--- /dev/null
+++ b/META.json
@@ -0,0 +1,60 @@
+{
+   "abstract" : "Perl interface to the _NSGetExecutablePath darwin (OS X) system call.",
+   "author" : [
+      "Vincent Pit <perl@profvince.com>"
+   ],
+   "dynamic_config" : 1,
+   "generated_by" : "ExtUtils::MakeMaker version 6.6302, CPAN::Meta::Converter version 2.120921",
+   "license" : [
+      "perl_5"
+   ],
+   "meta-spec" : {
+      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
+      "version" : "2"
+   },
+   "name" : "Mac-NSGetExecutablePath",
+   "no_index" : {
+      "directory" : [
+         "t",
+         "inc"
+      ]
+   },
+   "prereqs" : {
+      "build" : {
+         "requires" : {
+            "Exporter" : "0",
+            "ExtUtils::MakeMaker" : "0",
+            "Test::More" : "0",
+            "XSLoader" : "0",
+            "base" : "0"
+         }
+      },
+      "configure" : {
+         "requires" : {
+            "ExtUtils::MakeMaker" : "0"
+         }
+      },
+      "runtime" : {
+         "requires" : {
+            "Exporter" : "0",
+            "XSLoader" : "0",
+            "base" : "0",
+            "perl" : "5.006"
+         }
+      }
+   },
+   "release_status" : "stable",
+   "resources" : {
+      "bugtracker" : {
+         "web" : "http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Mac-NSGetExecutablePath"
+      },
+      "homepage" : "http://search.cpan.org/dist/Mac-NSGetExecutablePath/",
+      "license" : [
+         "http://dev.perl.org/licenses/"
+      ],
+      "repository" : {
+         "url" : "http://git.profvince.com/?p=perl%2Fmodules%2FMac-NSGetExecutablePath.git"
+      }
+   },
+   "version" : "0.01"
+}
diff --git a/META.yml b/META.yml
new file mode 100644 (file)
index 0000000..8f7c092
--- /dev/null
+++ b/META.yml
@@ -0,0 +1,34 @@
+---
+abstract: 'Perl interface to the _NSGetExecutablePath darwin (OS X) system call.'
+author:
+  - 'Vincent Pit <perl@profvince.com>'
+build_requires:
+  Exporter: 0
+  ExtUtils::MakeMaker: 0
+  Test::More: 0
+  XSLoader: 0
+  base: 0
+configure_requires:
+  ExtUtils::MakeMaker: 0
+dynamic_config: 1
+generated_by: 'ExtUtils::MakeMaker version 6.6302, CPAN::Meta::Converter version 2.120921'
+license: perl
+meta-spec:
+  url: http://module-build.sourceforge.net/META-spec-v1.4.html
+  version: 1.4
+name: Mac-NSGetExecutablePath
+no_index:
+  directory:
+    - t
+    - inc
+requires:
+  Exporter: 0
+  XSLoader: 0
+  base: 0
+  perl: 5.006
+resources:
+  bugtracker: http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Mac-NSGetExecutablePath
+  homepage: http://search.cpan.org/dist/Mac-NSGetExecutablePath/
+  license: http://dev.perl.org/licenses/
+  repository: http://git.profvince.com/?p=perl%2Fmodules%2FMac-NSGetExecutablePath.git
+version: 0.01
diff --git a/Makefile.PL b/Makefile.PL
new file mode 100644 (file)
index 0000000..4f54c99
--- /dev/null
@@ -0,0 +1,62 @@
+use 5.006;
+
+use strict;
+use warnings;
+use ExtUtils::MakeMaker;
+
+die 'OS unsupported' unless $^O and $^O eq 'darwin';
+
+my $dist = 'Mac-NSGetExecutablePath';
+
+(my $name = $dist) =~ s{-}{::}g;
+
+(my $file = $dist) =~ s{-}{/}g;
+$file = "lib/$file.pm";
+
+my %PREREQ_PM = (
+ 'Exporter' => 0,
+ 'XSLoader' => 0,
+ 'base'     => 0,
+);
+
+my %BUILD_REQUIRES = (
+ 'ExtUtils::MakeMaker' => 0,
+ 'Test::More'          => 0,
+ %PREREQ_PM,
+);
+
+my %META = (
+ configure_requires => {
+  'ExtUtils::MakeMaker' => 0,
+ },
+ build_requires => {
+  %BUILD_REQUIRES,
+ },
+ dynamic_config => 1,
+ resources => {
+  bugtracker => "http://rt.cpan.org/NoAuth/ReportBug.html?Queue=$dist",
+  homepage   => "http://search.cpan.org/dist/$dist/",
+  license    => 'http://dev.perl.org/licenses/',
+  repository => "http://git.profvince.com/?p=perl%2Fmodules%2F$dist.git",
+ },
+);
+
+WriteMakefile(
+ NAME             => $name,
+ AUTHOR           => 'Vincent Pit <perl@profvince.com>',
+ LICENSE          => 'perl',
+ VERSION_FROM     => $file,
+ ABSTRACT_FROM    => $file,
+ PL_FILES         => {},
+ BUILD_REQUIRES   => \%BUILD_REQUIRES,
+ PREREQ_PM        => \%PREREQ_PM,
+ MIN_PERL_VERSION => '5.006',
+ META_MERGE       => \%META,
+ dist             => {
+  PREOP    => "pod2text -u $file > \$(DISTVNAME)/README",
+  COMPRESS => 'gzip -9f', SUFFIX => 'gz',
+ },
+ clean            => {
+  FILES => "$dist-* *.gcov *.gcda *.gcno cover_db Debian_CPANTS.txt*"
+ },
+);
diff --git a/NSGetExecutablePath.xs b/NSGetExecutablePath.xs
new file mode 100644 (file)
index 0000000..c0a3a93
--- /dev/null
@@ -0,0 +1,44 @@
+/* This file is part of the Mac::NSGetExecutablePath Perl module.
+ * See http://search.cpan.org/dist/Mac-NSGetExecutablePath/ */
+
+#define PERL_NO_GET_CONTEXT
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+#include <mach-o/dyld.h>
+
+
+static const char nsgep_too_long[] = "NSGetExecutablePath() wants to return a path too large";
+
+/* --- XS ------------------------------------------------------------------ */
+
+MODULE = Mac::NSGetExecutablePath        PACKAGE = Mac::NSGetExecutablePath
+
+PROTOTYPES: ENABLE
+
+void
+NSGetExecutablePath()
+PROTOTYPE:
+PREINIT:
+ char      buf[1];
+ uint32_t  size = sizeof buf;
+ SV       *dst;
+ char     *buffer;
+PPCODE:
+ _NSGetExecutablePath(buf, &size);
+ if (size >= MAXPATHLEN * MAXPATHLEN)
+  croak(nsgep_too_long);
+#ifdef newSV_type
+ dst = newSV_type(SVt_PV);
+#else
+ dst = sv_newmortal();
+ (void) SvUPGRADE(dst, SVt_PV);
+#endif
+ buffer = SvGROW(dst, size);
+ if (_NSGetExecutablePath(buffer, &size))
+  croak(nsgep_too_long);
+ SvCUR_set(dst, size - 1);
+ SvPOK_on(dst);
+ XPUSHs(dst);
+ XSRETURN(1);
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..5f0836c
--- /dev/null
+++ b/README
@@ -0,0 +1,80 @@
+NAME
+    Mac::NSGetExecutablePath - Perl interface to the _NSGetExecutablePath
+    darwin (OS X) system call.
+
+VERSION
+    Version 0.01
+
+SYNOPSIS
+        sub get_perl_path {
+         if ($^O eq 'darwin') {
+          require Cwd;
+          require Mac::NSGetExecutablePath;
+          return Cwd::abs_path(Mac::NSGetExecutablePath::NSGetExecutablePath());
+         } else {
+          return $^X;
+         }
+        }
+
+DESCRIPTION
+    This module provides a Perl interface to the "_NSGetExecutablePath"
+    darwin system call. It will only build on darwin systems.
+
+    Note that if you are using perl 5.16 or greater, then the value of $^X
+    is already computed from the return value of "_NSGetExecutablePath",
+    making this module mostly irrelevant.
+
+FUNCTIONS
+  "NSGetExecutablePath"
+        my $path = NSGetExecutablePath();
+
+    Returns a string representing the path to the current executable. This
+    path may rightfully point to a symlink.
+
+    This function may throw exceptions, see "DIAGNOSTICS" for details.
+
+DIAGNOSTICS
+  "NSGetExecutablePath() wants to return a path too large"
+    This exception is thrown when "_NSGetExecutablePath" requires an
+    outrageously large buffer to return the path to the current executable.
+
+EXPORT
+    The function "NSGetExecutablePath" is only exported on request, either
+    individually or by the tags ':funcs' and ':all'.
+
+DEPENDENCIES
+    perl 5.6.
+
+    A C compiler. This module may happen to build with a C++ compiler as
+    well, but don't rely on it, as no guarantee is made in this regard.
+
+    Exporter (core since perl 5), XSLoader (since 5.006), base (since
+    5.004_05).
+
+SEE ALSO
+    dyld(3).
+
+AUTHOR
+    Vincent Pit, "<perl at profvince.com>", <http://www.profvince.com>.
+
+    You can contact me by mail or on "irc.perl.org" (vincent).
+
+BUGS
+    Please report any bugs or feature requests to
+    "bug-mac-nsgetexecutablepath at rt.cpan.org", or through the web
+    interface at
+    <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Mac-NSGetExecutablePath>
+    . I will be notified, and then you'll automatically be notified of
+    progress on your bug as I make changes.
+
+SUPPORT
+    You can find documentation for this module with the perldoc command.
+
+        perldoc Mac::NSGetExecutablePath
+
+COPYRIGHT & LICENSE
+    Copyright 2012 Vincent Pit, all rights reserved.
+
+    This program is free software; you can redistribute it and/or modify it
+    under the same terms as Perl itself.
+
diff --git a/lib/Mac/NSGetExecutablePath.pm b/lib/Mac/NSGetExecutablePath.pm
new file mode 100644 (file)
index 0000000..dcb9f88
--- /dev/null
@@ -0,0 +1,120 @@
+package Mac::NSGetExecutablePath;
+
+use 5.006;
+
+use strict;
+use warnings;
+
+=head1 NAME
+
+Mac::NSGetExecutablePath - Perl interface to the _NSGetExecutablePath darwin (OS X) system call.
+
+=head1 VERSION
+
+Version 0.01
+
+=cut
+
+our $VERSION;
+BEGIN {
+ $VERSION = '0.01';
+}
+
+=head1 SYNOPSIS
+
+    sub get_perl_path {
+     if ($^O eq 'darwin') {
+      require Cwd;
+      require Mac::NSGetExecutablePath;
+      return Cwd::abs_path(Mac::NSGetExecutablePath::NSGetExecutablePath());
+     } else {
+      return $^X;
+     }
+    }
+
+=head1 DESCRIPTION
+
+This module provides a Perl interface to the C<_NSGetExecutablePath> darwin system call.
+It will only build on darwin systems.
+
+Note that if you are using L<perl> 5.16 or greater, then the value of C<$^X> is already computed from the return value of C<_NSGetExecutablePath>, making this module mostly irrelevant.
+
+=cut
+
+BEGIN {
+ require XSLoader;
+ XSLoader::load(__PACKAGE__, $VERSION);
+}
+
+=head1 FUNCTIONS
+
+=head2 C<NSGetExecutablePath>
+
+    my $path = NSGetExecutablePath();
+
+Returns a string representing the path to the current executable.
+This path may rightfully point to a symlink.
+
+This function may throw exceptions, see L</DIAGNOSTICS> for details.
+
+=head1 DIAGNOSTICS
+
+=head2 C<NSGetExecutablePath() wants to return a path too large>
+
+This exception is thrown when C<_NSGetExecutablePath> requires an outrageously large buffer to return the path to the current executable.
+
+=head1 EXPORT
+
+The function L</NSGetExecutablePath> is only exported on request, either individually or by the tags C<':funcs'> and C<':all'>.
+
+=cut
+
+use base qw<Exporter>;
+
+our @EXPORT         = ();
+our %EXPORT_TAGS    = (
+ 'funcs' => [ qw<NSGetExecutablePath> ],
+);
+our @EXPORT_OK      = map { @$_ } values %EXPORT_TAGS;
+$EXPORT_TAGS{'all'} = [ @EXPORT_OK ];
+
+=head1 DEPENDENCIES
+
+L<perl> 5.6.
+
+A C compiler.
+This module may happen to build with a C++ compiler as well, but don't rely on it, as no guarantee is made in this regard.
+
+L<Exporter> (core since perl 5), L<XSLoader> (since 5.006), L<base> (since 5.004_05).
+
+=head1 SEE ALSO
+
+C<dyld(3)>.
+
+=head1 AUTHOR
+
+Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
+
+You can contact me by mail or on C<irc.perl.org> (vincent).
+
+=head1 BUGS
+
+Please report any bugs or feature requests to C<bug-mac-nsgetexecutablepath at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Mac-NSGetExecutablePath>.
+I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
+
+=head1 SUPPORT
+
+You can find documentation for this module with the perldoc command.
+
+    perldoc Mac::NSGetExecutablePath
+
+=head1 COPYRIGHT & LICENSE
+
+Copyright 2012 Vincent Pit, all rights reserved.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=cut
+
+1; # End of Mac::NSGetExecutablePath
diff --git a/samples/perl_path.pl b/samples/perl_path.pl
new file mode 100755 (executable)
index 0000000..60e12d5
--- /dev/null
@@ -0,0 +1,19 @@
+#!perl
+
+use strict;
+use warnings;
+
+use blib;
+
+use Cwd 'abs_path';
+
+my $path;
+
+if ($^O eq 'darwin') {
+ require Mac::NSGetExecutablePath;
+ $path = Mac::NSGetExecutablePath::NSGetExecutablePath();
+} else {
+ $path = $^X;
+}
+
+print abs_path($path), "\n";
diff --git a/t/00-load.t b/t/00-load.t
new file mode 100644 (file)
index 0000000..a96da09
--- /dev/null
@@ -0,0 +1,12 @@
+#!perl -T
+
+use strict;
+use warnings;
+
+use Test::More tests => 1;
+
+BEGIN {
+       use_ok( 'Mac::NSGetExecutablePath' );
+}
+
+diag( "Testing Mac::NSGetExecutablePath $Mac::NSGetExecutablePath::VERSION, Perl $], $^X" );
diff --git a/t/01-import.t b/t/01-import.t
new file mode 100644 (file)
index 0000000..ff37b44
--- /dev/null
@@ -0,0 +1,18 @@
+#!perl -T
+
+use strict;
+use warnings;
+
+use Test::More tests => 2 * 1;
+
+require Mac::NSGetExecutablePath;
+
+my %syms = (
+ 'NSGetExecutablePath' => '',
+);
+
+for (sort keys %syms) {
+ eval { Mac::NSGetExecutablePath->import($_) };
+ is $@,            '',        "import $_";
+ is prototype($_), $syms{$_}, "prototype $_";
+}
diff --git a/t/10-base.t b/t/10-base.t
new file mode 100644 (file)
index 0000000..c2f2e32
--- /dev/null
@@ -0,0 +1,24 @@
+#!perl
+
+use strict;
+use warnings;
+
+use Test::More tests => 6;
+
+use Mac::NSGetExecutablePath 'NSGetExecutablePath';
+
+my $path = NSGetExecutablePath();
+
+ok defined($path), 'NSGetExecutablePath() does not return undef';
+cmp_ok length($path), '>', 0,
+                   'NSGetExecutablePath() returns something of positive length';
+
+my $v = `$path -v`;
+
+ok   defined($v), '`NSGetExecutablePath() -v` returns something';
+like $v, qr/This is perl\b/, 'NSGetExecutablePath() points to a perl';
+
+$v = `$path -le 'print "\$]"'`;
+ok defined($v), q{`NSGetExecutablePath() -le 'print "$]"'` returns something};
+1 while chomp $v;
+is $v, "$]", 'NSGetExecutablePath() points to the same perl version';
diff --git a/t/91-pod.t b/t/91-pod.t
new file mode 100644 (file)
index 0000000..c2d16af
--- /dev/null
@@ -0,0 +1,16 @@
+#!perl -T
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use lib 't/lib';
+use VPIT::TestHelpers;
+
+load_or_skip('Test::Pod', '1.22', [ ],
+             'required for testing POD syntax');
+
+eval 'use Test::Pod'; # Make Kwalitee test happy
+
+all_pod_files_ok();
diff --git a/t/92-pod-coverage.t b/t/92-pod-coverage.t
new file mode 100644 (file)
index 0000000..2ef490e
--- /dev/null
@@ -0,0 +1,18 @@
+#!perl -T
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use lib 't/lib';
+use VPIT::TestHelpers;
+
+my $desc = 'required for testing POD coverage';
+
+load_or_skip('Test::Pod::Coverage', '1.08', [ ],   $desc);
+load_or_skip('Pod::Coverage',       '0.18', undef, $desc);
+
+eval 'use Test::Pod::Coverage'; # Make Kwalitee test happy
+
+all_pod_coverage_ok();
diff --git a/t/93-pod-spelling.t b/t/93-pod-spelling.t
new file mode 100644 (file)
index 0000000..acb2587
--- /dev/null
@@ -0,0 +1,14 @@
+#!perl -T
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use lib 't/lib';
+use VPIT::TestHelpers;
+
+load_or_skip('Test::Pod::Spelling::CommonMistakes', '1.0', [ ],
+             'required for testing POD spelling');
+
+all_pod_files_ok();
diff --git a/t/95-portability-files.t b/t/95-portability-files.t
new file mode 100644 (file)
index 0000000..55a9005
--- /dev/null
@@ -0,0 +1,14 @@
+#!perl -T
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use lib 't/lib';
+use VPIT::TestHelpers;
+
+load_or_skip('Test::Portability::Files', undef, [ ],
+             'required for testing filenames portability');
+
+run_tests();
diff --git a/t/99-kwalitee.t b/t/99-kwalitee.t
new file mode 100644 (file)
index 0000000..796fe61
--- /dev/null
@@ -0,0 +1,31 @@
+#!perl
+
+use strict;
+use warnings;
+
+use Test::More;
+
+use lib 't/lib';
+use VPIT::TestHelpers;
+
+my $guard = VPIT::TestHelpers::Guard->new(
+ sub { unlink for glob 'Debian_CPANTS.txt*' }
+);
+
+my $desc = 'required to test kwalitee';
+
+load_or_skip('Parse::RecDescent',  '1.967006', undef, $desc);
+load_or_skip('Module::ExtractUse', '0.24',     undef, $desc);
+load_or_skip('Test::Kwalitee',     '1.01',     undef, $desc);
+
+SKIP: {
+ eval { Test::Kwalitee->import(); };
+ if (my $err = $@) {
+  1 while chomp $err;
+  require Test::Builder;
+  my $Test = Test::Builder->new;
+  my $plan = $Test->has_plan;
+  $Test->skip_all($err) if not defined $plan or $plan eq 'no_plan';
+  skip $err => $plan - $Test->current_test;
+ }
+}
diff --git a/t/lib/VPIT/TestHelpers.pm b/t/lib/VPIT/TestHelpers.pm
new file mode 100644 (file)
index 0000000..42ff189
--- /dev/null
@@ -0,0 +1,79 @@
+package VPIT::TestHelpers;
+
+use strict;
+use warnings;
+
+my %exports = (
+ load_or_skip => \&load_or_skip,
+ skip_all     => \&skip_all,
+);
+
+sub import {
+ my $pkg = caller;
+ while (my ($name, $code) = each %exports) {
+  no strict 'refs';
+  *{$pkg.'::'.$name} = $code;
+ }
+}
+
+my $test_sub = sub {
+ my $sub = shift;
+ my $stash;
+ if ($INC{'Test/Leaner.pm'}) {
+  $stash = \%Test::Leaner::;
+ } else {
+  require Test::More;
+  $stash = \%Test::More::;
+ }
+ my $glob = $stash->{$sub};
+ return $glob ? *$glob{CODE} : undef;
+};
+
+sub skip_all { $test_sub->('plan')->(skip_all => $_[0]) }
+
+sub diag {
+ my $diag = $test_sub->('diag');
+ $diag->($_) for @_;
+}
+
+our $TODO;
+local $TODO;
+
+sub load_or_skip {
+ my ($pkg, $ver, $imports, $desc) = @_;
+ my $spec = $ver && $ver !~ /^[0._]*$/ ? "$pkg $ver" : $pkg;
+ local $@;
+ if (eval "use $spec (); 1") {
+  $ver = do { no strict 'refs'; ${"${pkg}::VERSION"} };
+  $ver = 'undef' unless defined $ver;
+  if ($imports) {
+   my @imports = @$imports;
+   my $caller  = (caller 0)[0];
+   local $@;
+   my $res = eval <<"IMPORTER";
+package
+        $caller;
+BEGIN { \$pkg->import(\@imports) }
+1;
+IMPORTER
+   skip_all "Could not import '@imports' from $pkg $ver: $@" unless $res;
+  }
+  diag "Using $pkg $ver";
+ } else {
+  (my $file = "$pkg.pm") =~ s{::}{/}g;
+  delete $INC{$file};
+  skip_all "$spec $desc";
+ }
+}
+
+package VPIT::TestHelpers::Guard;
+
+sub new {
+ my ($class, $code) = @_;
+
+ bless { code => $code }, $class;
+}
+
+sub DESTROY { $_[0]->{code}->() }
+
+1;