One Hat Cyber Team
Your IP :
172.16.0.254
Server IP :
58.26.163.33
Server :
Windows NT DGPENSV2LPKMN 10.0 build 14393 (Windows Server 2016) AMD64
Server Software :
Apache/2.4.46 (Win64) OpenSSL/1.1.1h PHP/7.3.25
PHP Version :
7.3.25
Buat File
|
Buat Folder
Eksekusi
Dir :
C:
/
xampp7
/
perl
/
vendor
/
lib
/
Test
/
View File Name :
CleanNamespaces.pm
use strict; use warnings; package Test::CleanNamespaces; # git description: v0.23-5-gf8e88b1 # ABSTRACT: Check for uncleaned imports # KEYWORDS: testing namespaces clean dirty imports exports subroutines methods our $VERSION = '0.24'; use Module::Runtime (); use Sub::Identify (); use Package::Stash 0.14; use Test::Builder; use File::Find (); use File::Spec; use Exporter 5.57 'import'; our @EXPORT = qw(namespaces_clean all_namespaces_clean); #pod =head1 SYNOPSIS #pod #pod use strict; #pod use warnings; #pod use Test::CleanNamespaces; #pod #pod all_namespaces_clean; #pod #pod =head1 DESCRIPTION #pod #pod This module lets you check your module's namespaces for imported functions you #pod might have forgotten to remove with L<namespace::autoclean> or #pod L<namespace::clean> and are therefore available to be called as methods, which #pod usually isn't want you want. #pod #pod =head1 FUNCTIONS #pod #pod All functions are exported by default. #pod #pod =head2 namespaces_clean #pod #pod namespaces_clean('YourModule', 'AnotherModule'); #pod #pod Tests every specified namespace for uncleaned imports. If the module couldn't #pod be loaded it will be skipped. #pod #pod =head2 all_namespaces_clean #pod #pod all_namespaces_clean; #pod #pod Runs L</namespaces_clean> for all modules in your distribution. #pod #pod =cut sub namespaces_clean { my (@namespaces) = @_; local $@; my $builder = builder(); my $result = 1; for my $ns (@namespaces) { unless (eval { Module::Runtime::require_module($ns); 1 }) { $builder->skip("failed to load ${ns}: $@"); next; } my $imports = _remaining_imports($ns); my $ok = $builder->ok(!keys(%$imports), "${ns} contains no imported functions"); $ok or $builder->diag($builder->explain('remaining imports: ' => $imports)); $result &&= $ok; } return $result; } sub all_namespaces_clean { my @modules = find_modules(@_); builder()->plan(tests => scalar @modules); namespaces_clean(@modules); } # given a package name, returns a hashref of all remaining imports sub _remaining_imports { my $ns = shift; my $symbols = Package::Stash->new($ns)->get_all_symbols('CODE'); my @imports; my $meta; if ($INC{ Module::Runtime::module_notional_filename('Class::MOP') } and $meta = Class::MOP::class_of($ns) and $meta->can('get_method_list')) { my %subs = %$symbols; delete @subs{ $meta->get_method_list }; @imports = keys %subs; } elsif ($INC{ Module::Runtime::module_notional_filename('Mouse::Util') } and Mouse::Util->can('class_of') and $meta = Mouse::Util::class_of($ns)) { warn 'Mouse class detected - chance of false negatives is high!'; my %subs = %$symbols; # ugh, this returns far more than the true list of methods delete @subs{ $meta->get_method_list }; @imports = keys %subs; } else { @imports = grep { my $stash = Sub::Identify::stash_name($symbols->{$_}); $stash ne $ns and $stash ne 'Role::Tiny' and not eval { require Role::Tiny; Role::Tiny->is_role($stash) } } keys %$symbols; } my %imports; @imports{@imports} = map { Sub::Identify::sub_fullname($symbols->{$_}) } @imports; # these subs are special-cased - they are often provided by other # modules, but cannot be wrapped with Sub::Name as the call stack # is important delete @imports{qw(import unimport)}; my @overloads = grep { $imports{$_} eq 'overload::nil' || $imports{$_} eq 'overload::_nil' } keys %imports; delete @imports{@overloads} if @overloads; if ("$]" < 5.020) { # < haarg> 5.10+ allows sticking a readonly scalar ref directly in the symbol table, rather than a glob. when auto-promoted to a sub, it will have the correct name. # < haarg> but that only works if the symbol table entry is empty # < haarg> if it exists, it has to use the *$const = sub () { $val } method, so the name is __ANON__ # < haarg> newer versions don't use that method # < haarg> rather, newer versions of constant.pm don't use that method # < haarg> and then the name ends up being YourPackage::__ANON__ my @constants = grep { $imports{$_} eq 'constant::__ANON__' } keys %imports; delete @imports{@constants} if @constants; } return \%imports; } #pod =head2 find_modules #pod #pod my @modules = Test::CleanNamespaces->find_modules; #pod #pod Returns a list of modules in the current distribution. It'll search in #pod C<blib/>, if it exists. C<lib/> will be searched otherwise. #pod #pod =cut sub find_modules { my @modules; for my $top (-e 'blib' ? ('blib/lib', 'blib/arch') : 'lib') { File::Find::find({ no_chdir => 1, wanted => sub { my $file = $_; return unless $file =~ s/\.pm$//; push @modules, join '::' => File::Spec->splitdir( File::Spec->abs2rel(File::Spec->rel2abs($file, '.'), $top) ); }, }, $top); } return @modules; } #pod =head2 builder #pod #pod my $builder = Test::CleanNamespaces->builder; #pod #pod Returns the C<Test::Builder> used by the test functions. #pod #pod =cut { my $Test = Test::Builder->new; sub builder { $Test } } 1; __END__ =pod =encoding UTF-8 =head1 NAME Test::CleanNamespaces - Check for uncleaned imports =head1 VERSION version 0.24 =head1 SYNOPSIS use strict; use warnings; use Test::CleanNamespaces; all_namespaces_clean; =head1 DESCRIPTION This module lets you check your module's namespaces for imported functions you might have forgotten to remove with L<namespace::autoclean> or L<namespace::clean> and are therefore available to be called as methods, which usually isn't want you want. =head1 FUNCTIONS All functions are exported by default. =head2 namespaces_clean namespaces_clean('YourModule', 'AnotherModule'); Tests every specified namespace for uncleaned imports. If the module couldn't be loaded it will be skipped. =head2 all_namespaces_clean all_namespaces_clean; Runs L</namespaces_clean> for all modules in your distribution. =head2 find_modules my @modules = Test::CleanNamespaces->find_modules; Returns a list of modules in the current distribution. It'll search in C<blib/>, if it exists. C<lib/> will be searched otherwise. =head2 builder my $builder = Test::CleanNamespaces->builder; Returns the C<Test::Builder> used by the test functions. =head1 KNOWN ISSUES Uncleaned imports from L<Mouse> classes are incompletely detected, due to its lack of ability to return the correct method list -- it assumes that all subs are meant to be callable as methods unless they originated from (were imported by) one of: L<Mouse>, L<Mouse::Role>, L<Mouse::Util>, L<Mouse::Util::TypeConstraints>, L<Carp>, L<Scalar::Util>, or L<List::Util>. =head1 SEE ALSO =over 4 =item * L<namespace::clean> =item * L<namespace::autoclean> =item * L<namespace::sweep> =item * L<Sub::Exporter::ForMethods> =item * L<Test::API> =item * L<Sub::Name> =item * L<Sub::Install> =item * L<MooseX::MarkAsMethods> =item * L<Dist::Zilla::Plugin::Test::CleanNamespaces> =back =head1 SUPPORT Bugs may be submitted through L<the RT bug tracker|https://rt.cpan.org/Public/Dist/Display.html?Name=Test-CleanNamespaces> (or L<bug-Test-CleanNamespaces@rt.cpan.org|mailto:bug-Test-CleanNamespaces@rt.cpan.org>). There is also a mailing list available for users of this distribution, at L<http://lists.perl.org/list/perl-qa.html>. There is also an irc channel available for users of this distribution, at L<C<#perl> on C<irc.perl.org>|irc://irc.perl.org/#perl-qa>. =head1 AUTHOR Florian Ragwitz <rafl@debian.org> =head1 CONTRIBUTORS =for stopwords Karen Etheridge Graham Knop =over 4 =item * Karen Etheridge <ether@cpan.org> =item * Graham Knop <haarg@haarg.org> =back =head1 COPYRIGHT AND LICENCE This software is copyright (c) 2009 by Florian Ragwitz. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut