1 ##############################################################################
2 # $URL: http://perlcritic.tigris.org/svn/perlcritic/trunk/Perl-Critic/lib/Perl/Critic/UserProfile.pm $
3 # $Date: 2008-07-03 10:19:10 -0500 (Thu, 03 Jul 2008) $
6 ##############################################################################
8 package Perl::Critic::UserProfile;
14 use English qw(-no_match_vars);
17 use Config::Tiny qw();
20 use Perl::Critic::OptionsProcessor qw();
21 use Perl::Critic::Utils qw{ :characters policy_long_name policy_short_name };
22 use Perl::Critic::Exception::Fatal::Internal qw{ throw_internal };
23 use Perl::Critic::Exception::Configuration::Generic qw{ throw_generic };
24 use Perl::Critic::PolicyConfig;
26 our $VERSION = '1.088';
28 #-----------------------------------------------------------------------------
32 my ( $class, %args ) = @_;
33 my $self = bless {}, $class;
34 $self->_init( %args );
38 #-----------------------------------------------------------------------------
42 my ( $self, %args ) = @_;
43 # The profile can be defined, undefined, or an empty string.
44 my $profile = defined $args{-profile} ? $args{-profile} : _find_profile_path();
45 $self->_load_profile( $profile );
46 $self->_set_options_processor();
50 #-----------------------------------------------------------------------------
52 sub options_processor {
55 return $self->{_options_processor};
58 #-----------------------------------------------------------------------------
62 my ( $self, $policy ) = @_;
64 my $short_name = policy_short_name($policy);
66 return Perl::Critic::PolicyConfig->new(
68 $self->raw_policy_params($policy),
72 #-----------------------------------------------------------------------------
74 sub raw_policy_params {
76 my ( $self, $policy ) = @_;
77 my $profile = $self->{_profile};
78 my $long_name = ref $policy || policy_long_name( $policy );
79 my $short_name = policy_short_name( $long_name );
82 $profile->{$short_name}
83 || $profile->{$long_name}
84 || $profile->{"-$short_name"}
85 || $profile->{"-$long_name"}
89 #-----------------------------------------------------------------------------
91 sub policy_is_disabled {
93 my ( $self, $policy ) = @_;
94 my $profile = $self->{_profile};
95 my $long_name = ref $policy || policy_long_name( $policy );
96 my $short_name = policy_short_name( $long_name );
98 return exists $profile->{"-$short_name"}
99 || exists $profile->{"-$long_name"};
102 #-----------------------------------------------------------------------------
104 sub policy_is_enabled {
106 my ( $self, $policy ) = @_;
107 my $profile = $self->{_profile};
108 my $long_name = ref $policy || policy_long_name( $policy );
109 my $short_name = policy_short_name( $long_name );
111 return exists $profile->{$short_name}
112 || exists $profile->{$long_name};
115 #-----------------------------------------------------------------------------
117 sub listed_policies {
119 my ( $self, $policy ) = @_;
120 my @normalized_policy_names = ();
122 for my $policy_name ( sort keys %{$self->{_profile}} ) {
123 $policy_name =~ s/\A - //mxo; #Chomp leading "-"
124 my $policy_long_name = policy_long_name( $policy_name );
125 push @normalized_policy_names, $policy_long_name;
128 return @normalized_policy_names;
131 #-----------------------------------------------------------------------------
136 return $self->{_source};
140 my ( $self, $source ) = @_;
142 $self->{_source} = $source;
147 #-----------------------------------------------------------------------------
148 # Begin PRIVATE methods
150 Readonly::Hash my %LOADER_FOR => (
151 ARRAY => \&_load_profile_from_array,
152 DEFAULT => \&_load_profile_from_file,
153 HASH => \&_load_profile_from_hash,
154 SCALAR => \&_load_profile_from_string,
159 my ( $self, $profile ) = @_;
161 my $ref_type = ref $profile || 'DEFAULT';
162 my $loader = $LOADER_FOR{$ref_type};
165 throw_internal qq{Can't load UserProfile from type "$ref_type"};
168 $self->{_profile} = $loader->($self, $profile);
172 #-----------------------------------------------------------------------------
174 sub _set_options_processor {
177 my $profile = $self->{_profile};
178 my $defaults = delete $profile->{__defaults__} || {};
179 $self->{_options_processor} =
180 Perl::Critic::OptionsProcessor->new( %{ $defaults } );
184 #-----------------------------------------------------------------------------
186 sub _load_profile_from_file {
187 my ( $self, $file ) = @_;
189 # Handle special cases.
190 return {} if not defined $file;
191 return {} if $file eq $EMPTY;
192 return {} if $file eq 'NONE';
194 $self->_set_source( $file );
196 my $profile = Config::Tiny->read( $file );
197 if (not defined $profile) {
198 my $errstr = Config::Tiny::errstr();
200 message => qq{Could not parse profile "$file": $errstr},
204 _fix_defaults_key( $profile );
209 #-----------------------------------------------------------------------------
211 sub _load_profile_from_array {
212 my ( $self, $array_ref ) = @_;
213 my $joined = join qq{\n}, @{ $array_ref };
214 my $profile = Config::Tiny->read_string( $joined );
216 if (not defined $profile) {
217 throw_generic 'Profile error: ' . Config::Tiny::errstr();
220 _fix_defaults_key( $profile );
225 #-----------------------------------------------------------------------------
227 sub _load_profile_from_string {
228 my ( $self, $string ) = @_;
229 my $profile = Config::Tiny->read_string( ${ $string } );
231 if (not defined $profile) {
232 throw_generic 'Profile error: ' . Config::Tiny::errstr();
235 _fix_defaults_key( $profile );
240 #-----------------------------------------------------------------------------
242 sub _load_profile_from_hash {
243 my ( $self, $hash_ref ) = @_;
247 #-----------------------------------------------------------------------------
249 sub _find_profile_path {
251 #Define default filename
252 my $rc_file = '.perlcriticrc';
254 #Check explicit environment setting
255 return $ENV{PERLCRITIC} if exists $ENV{PERLCRITIC};
257 #Check current directory
258 return $rc_file if -f $rc_file;
260 #Check home directory
261 if ( my $home_dir = _find_home_dir() ) {
262 my $path = File::Spec->catfile( $home_dir, $rc_file );
263 return $path if -f $path;
270 #-----------------------------------------------------------------------------
274 # Try using File::HomeDir
275 if ( eval { require File::HomeDir } ) {
276 return File::HomeDir->my_home();
279 # Check usual environment vars
280 for my $key (qw(HOME USERPROFILE HOMESHARE)) {
281 next if not defined $ENV{$key};
282 return $ENV{$key} if -d $ENV{$key};
285 # No home directory defined
289 #-----------------------------------------------------------------------------
291 # !$%@$%^ Config::Tiny uses a completely non-descriptive name for global
293 sub _fix_defaults_key {
294 my ( $profile ) = @_;
296 my $defaults = delete $profile->{_};
298 $profile->{__defaults__} = $defaults;
308 #-----------------------------------------------------------------------------
312 =for stopwords UserProfile
316 Perl::Critic::UserProfile - The contents of the user's profile, often F<.perlcriticrc>.
321 This is a helper class that encapsulates the contents of the user's
322 profile, which is usually stored in a F<.perlcriticrc> file. There are
323 no user-serviceable parts here.
330 =item C< new( -profile => $p ) >
332 B<-profile> is the path to the user's profile. If -profile is not
333 defined, then it looks for the profile at F<./.perlcriticrc> and then
334 F<$HOME/.perlcriticrc>. If neither of those files exists, then the
335 UserProfile is created with default values.
337 This object does not take into account any command-line overrides;
338 L<Perl::Critic::Config> does that.
348 =item C< options_processor() >
350 Returns the L<Perl::Critic::OptionsProcessor> object for this UserProfile.
353 =item C< policy_is_disabled( $policy ) >
355 Given a reference to a L<Perl::Critic::Policy> object or the name of
356 one, returns true if the user has disabled that policy in their
360 =item C< policy_is_enabled( $policy ) >
362 Given a reference to a L<Perl::Critic::Policy> object or the name of
363 one, returns true if the user has explicitly enabled that policy in
367 =item C< policy_params( $policy ) >
369 Given a reference to a L<Perl::Critic::Policy> object or the name of
370 one, returns a L<Perl::Critic::PolicyConfig> for the user's
371 configuration parameters for that policy.
374 =item C< raw_policy_params( $policy ) >
376 Given a reference to a L<Perl::Critic::Policy> object or the name of
377 one, returns a reference to a hash of the user's configuration
378 parameters for that policy.
381 =item C< listed_policies() >
383 Returns a list of the names of all the Policies that are mentioned in
384 the profile. The Policy names will be fully qualified (e.g.
390 The place where the profile information came from, if available.
391 Usually the path to a F<.perlcriticrc>.
399 L<Perl::Critic::Config>, L<Perl::Critic::OptionsProcessor>
404 Jeffrey Ryan Thalhammer <thaljef@cpan.org>
409 Copyright (c) 2005-2008 Jeffrey Ryan Thalhammer. All rights reserved.
411 This program is free software; you can redistribute it and/or modify
412 it under the same terms as Perl itself. The full text of this license
413 can be found in the LICENSE file included with this module.
419 # cperl-indent-level: 4
421 # indent-tabs-mode: nil
422 # c-indentation-style: bsd
424 # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :