Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Open sidebar
best-practical
rt-extension-mandatoryontransition
Commits
48e8b277
Commit
48e8b277
authored
Jul 23, 2012
by
Thomas Sibley
Browse files
Add Module::Install
parent
008d0c36
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
2436 additions
and
0 deletions
+2436
-0
inc/Module/Install.pm
inc/Module/Install.pm
+470
-0
inc/Module/Install/Base.pm
inc/Module/Install/Base.pm
+83
-0
inc/Module/Install/Can.pm
inc/Module/Install/Can.pm
+154
-0
inc/Module/Install/Fetch.pm
inc/Module/Install/Fetch.pm
+93
-0
inc/Module/Install/Makefile.pm
inc/Module/Install/Makefile.pm
+418
-0
inc/Module/Install/Metadata.pm
inc/Module/Install/Metadata.pm
+722
-0
inc/Module/Install/RTx.pm
inc/Module/Install/RTx.pm
+231
-0
inc/Module/Install/ReadmeFromPod.pm
inc/Module/Install/ReadmeFromPod.pm
+138
-0
inc/Module/Install/Win32.pm
inc/Module/Install/Win32.pm
+64
-0
inc/Module/Install/WriteAll.pm
inc/Module/Install/WriteAll.pm
+63
-0
No files found.
inc/Module/Install.pm
0 → 100644
View file @
48e8b277
#line 1
package
Module::
Install
;
# For any maintainers:
# The load order for Module::Install is a bit magic.
# It goes something like this...
#
# IF ( host has Module::Install installed, creating author mode ) {
# 1. Makefile.PL calls "use inc::Module::Install"
# 2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install
# 3. The installed version of inc::Module::Install loads
# 4. inc::Module::Install calls "require Module::Install"
# 5. The ./inc/ version of Module::Install loads
# } ELSE {
# 1. Makefile.PL calls "use inc::Module::Install"
# 2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install
# 3. The ./inc/ version of Module::Install loads
# }
use
5.005
;
use
strict
'
vars
';
use
Cwd
();
use
File::
Find
();
use
File::
Path
();
use
vars
qw{$VERSION $MAIN}
;
BEGIN
{
# All Module::Install core packages now require synchronised versions.
# This will be used to ensure we don't accidentally load old or
# different versions of modules.
# This is not enforced yet, but will be some time in the next few
# releases once we can make sure it won't clash with custom
# Module::Install extensions.
$VERSION
=
'
1.06
';
# Storage for the pseudo-singleton
$MAIN
=
undef
;
*
inc::Module::Install::
VERSION
=
*VERSION
;
@
inc::Module::Install::
ISA
=
__PACKAGE__
;
}
sub
import
{
my
$class
=
shift
;
my
$self
=
$class
->
new
(
@
_
);
my
$who
=
$self
->
_caller
;
#-------------------------------------------------------------
# all of the following checks should be included in import(),
# to allow "eval 'require Module::Install; 1' to test
# installation of Module::Install. (RT #51267)
#-------------------------------------------------------------
# Whether or not inc::Module::Install is actually loaded, the
# $INC{inc/Module/Install.pm} is what will still get set as long as
# the caller loaded module this in the documented manner.
# If not set, the caller may NOT have loaded the bundled version, and thus
# they may not have a MI version that works with the Makefile.PL. This would
# result in false errors or unexpected behaviour. And we don't want that.
my
$file
=
join
(
'
/
',
'
inc
',
split
/::/
,
__PACKAGE__
)
.
'
.pm
';
unless
(
$INC
{
$file
}
)
{
die
<<
"
END_DIE
"
}
Please
invoke
$
{
\
__PACKAGE__
}
with:
use
inc::
$
{
\
__PACKAGE__
};
not
:
use
$
{
\
__PACKAGE__
};
END_DIE
# This reportedly fixes a rare Win32 UTC file time issue, but
# as this is a non-cross-platform XS module not in the core,
# we shouldn't really depend on it. See RT #24194 for detail.
# (Also, this module only supports Perl 5.6 and above).
eval
"
use Win32::UTCFileTime
"
if
$^O
eq
'
MSWin32
'
&&
$]
>=
5.006
;
# If the script that is loading Module::Install is from the future,
# then make will detect this and cause it to re-run over and over
# again. This is bad. Rather than taking action to touch it (which
# is unreliable on some platforms and requires write permissions)
# for now we should catch this and refuse to run.
if
(
-
f
$
0
)
{
my
$s
=
(
stat
(
$
0
))[
9
];
# If the modification time is only slightly in the future,
# sleep briefly to remove the problem.
my
$a
=
$s
-
time
;
if
(
$a
>
0
and
$a
<
5
)
{
sleep
5
}
# Too far in the future, throw an error.
my
$t
=
time
;
if
(
$s
>
$t
)
{
die
<<
"
END_DIE
"
}
Your
installer
$
0
has
a
modification
time
in
the
future
(
$s
>
$t
)
.
This
is
known
to
create
infinite
loops
in
make
.
Please
correct
this
,
then
run
$
0
again
.
END_DIE
}
# Build.PL was formerly supported, but no longer is due to excessive
# difficulty in implementing every single feature twice.
if
(
$
0
=~
/Build.PL$/i
)
{
die
<<
"
END_DIE
"
}
Module::
Install
no
longer
supports
Build
.
PL
.
It
was
impossible
to
maintain
duel
backends
,
and
has
been
deprecated
.
Please
remove
all
Build
.
PL
files
and
only
use
the
Makefile
.
PL
installer
.
END_DIE
#-------------------------------------------------------------
# To save some more typing in Module::Install installers, every...
# use inc::Module::Install
# ...also acts as an implicit use strict.
$^H
|=
strict::
bits
(
qw(refs subs vars)
);
#-------------------------------------------------------------
unless
(
-
f
$self
->
{
file
}
)
{
foreach
my
$key
(
keys
%INC
)
{
delete
$INC
{
$key
}
if
$key
=~
/Module\/Install/
;
}
local
$^W
;
require
"
$self
->{path}/
$self
->{dispatch}.pm
";
File::Path::
mkpath
("
$self
->{prefix}/
$self
->{author}
");
$self
->
{
admin
}
=
"
$self
->{name}::
$self
->{dispatch}
"
->
new
(
_top
=>
$self
);
$self
->
{
admin
}
->
init
;
@
_
=
(
$class
,
_self
=>
$self
);
goto
&
{"
$self
->{name}::import
"};
}
local
$^W
;
*
{"
${who}
::AUTOLOAD
"}
=
$self
->
autoload
;
$self
->
preload
;
# Unregister loader and worker packages so subdirs can use them again
delete
$INC
{'
inc/Module/Install.pm
'};
delete
$INC
{'
Module/Install.pm
'};
# Save to the singleton
$MAIN
=
$self
;
return
1
;
}
sub
autoload
{
my
$self
=
shift
;
my
$who
=
$self
->
_caller
;
my
$cwd
=
Cwd::
cwd
();
my
$sym
=
"
${who}
::AUTOLOAD
";
$sym
->
{
$cwd
}
=
sub
{
my
$pwd
=
Cwd::
cwd
();
if
(
my
$code
=
$sym
->
{
$pwd
}
)
{
# Delegate back to parent dirs
goto
&$code
unless
$cwd
eq
$pwd
;
}
unless
(
$$sym
=~
s/([^:]+)$//
)
{
# XXX: it looks like we can't retrieve the missing function
# via $$sym (usually $main::AUTOLOAD) in this case.
# I'm still wondering if we should slurp Makefile.PL to
# get some context or not ...
my
(
$package
,
$file
,
$line
)
=
caller
;
die
<<"EOT";
Unknown function is found at $file line $line.
Execution of $file aborted due to runtime errors.
If you're a contributor to a project, you may need to install
some Module::Install extensions from CPAN (or other repository).
If you're a user of a module, please contact the author.
EOT
}
my
$method
=
$
1
;
if
(
uc
(
$method
)
eq
$method
)
{
# Do nothing
return
;
}
elsif
(
$method
=~
/^_/
and
$self
->
can
(
$method
)
)
{
# Dispatch to the root M:I class
return
$self
->
$method
(
@
_
);
}
# Dispatch to the appropriate plugin
unshift
@
_
,
(
$self
,
$
1
);
goto
&
{
$self
->
can
('
call
')};
};
}
sub
preload
{
my
$self
=
shift
;
unless
(
$self
->
{
extensions
}
)
{
$self
->
load_extensions
(
"
$self
->{prefix}/
$self
->{path}
",
$self
);
}
my
@exts
=
@
{
$self
->
{
extensions
}};
unless
(
@exts
)
{
@exts
=
$self
->
{
admin
}
->
load_all_extensions
;
}
my
%seen
;
foreach
my
$obj
(
@exts
)
{
while
(
my
(
$method
,
$glob
)
=
each
%
{
ref
(
$obj
)
.
'
::
'})
{
next
unless
$obj
->
can
(
$method
);
next
if
$method
=~
/^_/
;
next
if
$method
eq
uc
(
$method
);
$seen
{
$method
}
++
;
}
}
my
$who
=
$self
->
_caller
;
foreach
my
$name
(
sort
keys
%seen
)
{
local
$^W
;
*
{"
${who}
::
$name
"}
=
sub
{
$
{"
${who}
::AUTOLOAD
"}
=
"
${who}
::
$name
";
goto
&
{"
${who}
::AUTOLOAD
"};
};
}
}
sub
new
{
my
(
$class
,
%args
)
=
@_
;
delete
$INC
{'
FindBin.pm
'};
{
# to suppress the redefine warning
local
$SIG
{
__WARN__
}
=
sub
{};
require
FindBin
;
}
# ignore the prefix on extension modules built from top level.
my
$base_path
=
Cwd::
abs_path
(
$
FindBin::
Bin
);
unless
(
Cwd::
abs_path
(
Cwd::
cwd
())
eq
$base_path
)
{
delete
$args
{
prefix
};
}
return
$args
{
_self
}
if
$args
{
_self
};
$args
{
dispatch
}
||=
'
Admin
';
$args
{
prefix
}
||=
'
inc
';
$args
{
author
}
||=
(
$^O
eq
'
VMS
'
?
'
_author
'
:
'
.author
');
$args
{
bundle
}
||=
'
inc/BUNDLES
';
$args
{
base
}
||=
$base_path
;
$class
=~
s/^\Q$args{prefix}\E:://
;
$args
{
name
}
||=
$class
;
$args
{
version
}
||=
$class
->
VERSION
;
unless
(
$args
{
path
}
)
{
$args
{
path
}
=
$args
{
name
};
$args
{
path
}
=~
s!::!/!g
;
}
$args
{
file
}
||=
"
$args
{base}/
$args
{prefix}/
$args
{path}.pm
";
$args
{
wrote
}
=
0
;
bless
(
\
%args
,
$class
);
}
sub
call
{
my
(
$self
,
$method
)
=
@_
;
my
$obj
=
$self
->
load
(
$method
)
or
return
;
splice
(
@
_
,
0
,
2
,
$obj
);
goto
&
{
$obj
->
can
(
$method
)};
}
sub
load
{
my
(
$self
,
$method
)
=
@_
;
$self
->
load_extensions
(
"
$self
->{prefix}/
$self
->{path}
",
$self
)
unless
$self
->
{
extensions
};
foreach
my
$obj
(
@
{
$self
->
{
extensions
}})
{
return
$obj
if
$obj
->
can
(
$method
);
}
my
$admin
=
$self
->
{
admin
}
or
die
<<"END_DIE";
The '$method' method does not exist in the '$self->{prefix}' path!
Please remove the '$self->{prefix}' directory and run $0 again to load it.
END_DIE
my
$obj
=
$admin
->
load
(
$method
,
1
);
push
@
{
$self
->
{
extensions
}},
$obj
;
$obj
;
}
sub
load_extensions
{
my
(
$self
,
$path
,
$top
)
=
@_
;
my
$should_reload
=
0
;
unless
(
grep
{
!
ref
$_
and
lc
$_
eq
lc
$self
->
{
prefix
}
}
@INC
)
{
unshift
@INC
,
$self
->
{
prefix
};
$should_reload
=
1
;
}
foreach
my
$rv
(
$self
->
find_extensions
(
$path
)
)
{
my
(
$file
,
$pkg
)
=
@
{
$rv
};
next
if
$self
->
{
pathnames
}{
$pkg
};
local
$@
;
my
$new
=
eval
{
local
$^W
;
require
$file
;
$pkg
->
can
('
new
')
};
unless
(
$new
)
{
warn
$@
if
$@
;
next
;
}
$self
->
{
pathnames
}{
$pkg
}
=
$should_reload
?
delete
$INC
{
$file
}
:
$INC
{
$file
};
push
@
{
$self
->
{
extensions
}},
&
{
$new
}(
$pkg
,
_top
=>
$top
);
}
$self
->
{
extensions
}
||=
[]
;
}
sub
find_extensions
{
my
(
$self
,
$path
)
=
@_
;
my
@found
;
File::Find::
find
(
sub
{
my
$file
=
$
File::Find::
name
;
return
unless
$file
=~
m!^\Q$path\E/(.+)\.pm\Z!is
;
my
$subpath
=
$
1
;
return
if
lc
(
$subpath
)
eq
lc
(
$self
->
{
dispatch
});
$file
=
"
$self
->{path}/
$subpath
.pm
";
my
$pkg
=
"
$self
->{name}::
$subpath
";
$pkg
=~
s!/!::!g
;
# If we have a mixed-case package name, assume case has been preserved
# correctly. Otherwise, root through the file to locate the case-preserved
# version of the package name.
if
(
$subpath
eq
lc
(
$subpath
)
||
$subpath
eq
uc
(
$subpath
)
)
{
my
$content
=
Module::Install::
_read
(
$subpath
.
'
.pm
');
my
$in_pod
=
0
;
foreach
(
split
//
,
$content
)
{
$in_pod
=
1
if
/^=\w/
;
$in_pod
=
0
if
/^=cut/
;
next
if
(
$in_pod
||
/^=cut/
);
# skip pod text
next
if
/^\s*#/
;
# and comments
if
(
m/^\s*package\s+($pkg)\s*;/i
)
{
$pkg
=
$
1
;
last
;
}
}
}
push
@found
,
[
$file
,
$pkg
];
},
$path
)
if
-
d
$path
;
@found
;
}
#####################################################################
# Common Utility Functions
sub
_caller
{
my
$depth
=
0
;
my
$call
=
caller
(
$depth
);
while
(
$call
eq
__PACKAGE__
)
{
$depth
++
;
$call
=
caller
(
$depth
);
}
return
$call
;
}
# Done in evals to avoid confusing Perl::MinimumVersion
eval
(
$]
>=
5.006
?
<<
'
END_NEW
'
:
<<
'
END_OLD
'
);
die
$@
if
$@
;
sub
_read
{
local
*FH
;
open
(
FH
,
'
<
',
$_
[
0
]
)
or
die
"
open(
$_
[0]): $!
";
my
$string
=
do
{
local
$/
;
<
FH
>
};
close
FH
or
die
"
close(
$_
[0]): $!
";
return
$string
;
}
END_NEW
sub
_read
{
local
*FH
;
open
(
FH
,
"
<
$_
[0]
"
)
or
die
"
open(
$_
[0]): $!
";
my
$string
=
do
{
local
$/
;
<
FH
>
};
close
FH
or
die
"
close(
$_
[0]): $!
";
return
$string
;
}
END_OLD
sub
_readperl
{
my
$string
=
Module::Install::
_read
(
$_
[
0
]);
$string
=~
s/(?:\015{1,2}\012|\015|\012)/\n/sg
;
$string
=~
s/(\n)\n*__(?:DATA|END)__\b.*\z/$1/s
;
$string
=~
s/\n\n=\w+.+?\n\n=cut\b.+?\n+/\n\n/sg
;
return
$string
;
}
sub
_readpod
{
my
$string
=
Module::Install::
_read
(
$_
[
0
]);
$string
=~
s/(?:\015{1,2}\012|\015|\012)/\n/sg
;
return
$string
if
$_
[
0
]
=~
/\.pod\z/
;
$string
=~
s/(^|\n=cut\b.+?\n+)[^=\s].+?\n(\n=\w+|\z)/$1$2/sg
;
$string
=~
s/\n*=pod\b[^\n]*\n+/\n\n/sg
;
$string
=~
s/\n*=cut\b[^\n]*\n+/\n\n/sg
;
$string
=~
s/^\n+//s
;
return
$string
;
}
# Done in evals to avoid confusing Perl::MinimumVersion
eval
(
$]
>=
5.006
?
<<
'
END_NEW
'
:
<<
'
END_OLD
'
);
die
$@
if
$@
;
sub
_write
{
local
*FH
;
open
(
FH
,
'
>
',
$_
[
0
]
)
or
die
"
open(
$_
[0]): $!
";
foreach
(
1
..
$
#_ ) {
print
FH
$_
[
$_
]
or
die
"
print(
$_
[0]): $!
";
}
close
FH
or
die
"
close(
$_
[0]): $!
";
}
END_NEW
sub
_write
{
local
*FH
;
open
(
FH
,
"
>
$_
[0]
"
)
or
die
"
open(
$_
[0]): $!
";
foreach
(
1
..
$
#_ ) {
print
FH
$_
[
$_
]
or
die
"
print(
$_
[0]): $!
";
}
close
FH
or
die
"
close(
$_
[0]): $!
";
}
END_OLD
# _version is for processing module versions (eg, 1.03_05) not
# Perl versions (eg, 5.8.1).
sub
_version
($)
{
my
$s
=
shift
||
0
;
my
$d
=
()
=
$s
=~
/(\.)/g
;
if
(
$d
>=
2
)
{
# Normalise multipart versions
$s
=~
s/(\.)(\d{1,3})/sprintf("$1%03d",$2)/
eg
;
}
$s
=~
s/^(\d+)\.?//
;
my
$l
=
$
1
||
0
;
my
@v
=
map
{
$_
.
'
0
'
x
(
3
-
length
$_
)
}
$s
=~
/(\d{1,3})\D?/g
;
$l
=
$l
.
'
.
'
.
join
'',
@v
if
@v
;
return
$l
+
0
;
}
sub
_cmp
($$)
{
_version
(
$_
[
1
])
<=>
_version
(
$_
[
2
]);
}
# Cloned from Params::Util::_CLASS
sub
_CLASS
($)
{
(
defined
$_
[
0
]
and
!
ref
$_
[
0
]
and
$_
[
0
]
=~
m/^[^\W\d]\w*(?:::\w+)*\z/s
)
?
$_
[
0
]
:
undef
;
}
1
;
# Copyright 2008 - 2012 Adam Kennedy.
inc/Module/Install/Base.pm
0 → 100644
View file @
48e8b277
#line 1
package
Module::Install::
Base
;
use
strict
'
vars
';
use
vars
qw{$VERSION}
;
BEGIN
{
$VERSION
=
'
1.06
';
}
# Suspend handler for "redefined" warnings
BEGIN
{
my
$w
=
$SIG
{
__WARN__
};
$SIG
{
__WARN__
}
=
sub
{
$w
};
}
#line 42
sub
new
{
my
$class
=
shift
;
unless
(
defined
&
{"
${class}
::call
"}
)
{
*
{"
${class}
::call
"}
=
sub
{
shift
->
_top
->
call
(
@
_
)
};
}
unless
(
defined
&
{"
${class}
::load
"}
)
{
*
{"
${class}
::load
"}
=
sub
{
shift
->
_top
->
load
(
@
_
)
};
}
bless
{
@
_
},
$class
;
}
#line 61
sub
AUTOLOAD
{
local
$@
;
my
$func
=
eval
{
shift
->
_top
->
autoload
}
or
return
;
goto
&$func
;
}
#line 75
sub
_top
{
$_
[
0
]
->
{
_top
};
}
#line 90
sub
admin
{
$_
[
0
]
->
_top
->
{
admin
}
or
Module::Install::Base::
FakeAdmin
->
new
;
}
#line 106
sub
is_admin
{
!
$_
[
0
]
->
admin
->
isa
('
Module::Install::Base::FakeAdmin
');
}
sub
DESTROY
{}
package
Module::Install::Base::
FakeAdmin
;
use
vars
qw{$VERSION}
;
BEGIN
{
$VERSION
=
$
Module::Install::Base::
VERSION
;
}
my
$fake
;
sub
new
{
$fake
||=
bless
(
\
@
_
,
$_
[
0
]);
}
sub
AUTOLOAD
{}
sub
DESTROY
{}
# Restore warning handler
BEGIN
{
$SIG
{
__WARN__
}
=
$SIG
{
__WARN__
}
->
();
}
1
;
#line 159
inc/Module/Install/Can.pm
0 → 100644
View file @
48e8b277
#line 1
package
Module::Install::
Can
;
use
strict
;
use
Config
();
use
ExtUtils::
MakeMaker
();
use
Module::Install::
Base
();
use
vars
qw{$VERSION @ISA $ISCORE}
;
BEGIN
{
$VERSION
=
'
1.06
';
@ISA
=
'
Module::Install::Base
';
$ISCORE
=
1
;
}
# check if we can load some module
### Upgrade this to not have to load the module if possible
sub
can_use
{
my
(
$self
,
$mod
,
$ver
)
=
@_
;
$mod
=~
s{::|\\}{/}g
;
$mod
.=
'
.pm
'
unless
$mod
=~
/\.pm$/i
;
my
$pkg
=
$mod
;
$pkg
=~
s{/}{::}g
;
$pkg
=~
s{\.pm$}{}i
;
local
$@
;
eval
{
require
$mod
;
$pkg
->
VERSION
(
$ver
||
0
);
1
};
}
# Check if we can run some command
sub
can_run
{
my
(
$self
,
$cmd
)
=
@_
;
my
$_cmd
=
$cmd
;
return
$_cmd
if
(
-
x
$_cmd
or
$_cmd
=
MM
->
maybe_command
(
$_cmd
));
for
my
$dir
((
split
/$Config::Config{path_sep}/
,
$ENV
{
PATH
}),
'
.
')
{
next
if
$dir
eq
'';
require
File::
Spec
;
my
$abs
=
File::
Spec
->
catfile
(
$dir
,
$cmd
);
return
$abs
if
(
-
x
$abs
or
$abs
=
MM
->
maybe_command
(
$abs
));
}
return
;
}
# Can our C compiler environment build XS files
sub
can_xs
{
my
$self
=
shift
;
# Ensure we have the CBuilder module
$self
->
configure_requires
(
'
ExtUtils::CBuilder
'
=>
0.27
);
# Do we have the configure_requires checker?
local
$@
;
eval
"
require ExtUtils::CBuilder;
";
if
(
$@
)
{
# They don't obey configure_requires, so it is
# someone old and delicate. Try to avoid hurting
# them by falling back to an older simpler test.
return
$self
->
can_cc
();
}