package inc::Installer::OutPaths; use strict; use base qw( inc::Installer inc::Installer::Logger inc::Installer::OptionsProviderI inc::Installer::EnvObservableI inc::Installer::EUMMArgProviderI ); use inc::Installer; use inc::Installer::CPAN; use inc::Config; our $AUTOLOAD; use Config (); use File::Path (); { my $SINGLETON; my $DEFAULT_PREFIX = __PACKAGE__->FixSlashes( $Config::Config{'installprefix'} ); my %DEFAULTS = ( 'installstyle' => 'site', 'installbin' => __PACKAGE__->FixSlashes( $Config::Config{ 'installbin' } ), 'installprefix' => __PACKAGE__->FixSlashes( $Config::Config{ 'installprefix' } ), 'installprefixexp' => __PACKAGE__->FixSlashes( $Config::Config{ 'installprefixexp' } ), 'installscript' => __PACKAGE__->FixSlashes( $Config::Config{ 'installscript' } ), 'installsitearch' => __PACKAGE__->FixSlashes( $Config::Config{ 'installsitearch' } ), 'installsitebin' => __PACKAGE__->FixSlashes( $Config::Config{ 'installsitebin' } ), 'installsitelib' => __PACKAGE__->FixSlashes( $Config::Config{ 'installsitelib' } ), 'installvendorarch' => __PACKAGE__->FixSlashes( $Config::Config{ 'installvendorarch' } ) || "$DEFAULT_PREFIX/lib/", 'installvendorbin' => __PACKAGE__->FixSlashes( $Config::Config{ 'installvendorbin' } ) || "$DEFAULT_PREFIX/bin/", 'installvendorlib' => __PACKAGE__->FixSlashes( $Config::Config{ 'installvendorlib' } ) || "$DEFAULT_PREFIX/lib/", 'installhtmldir' => __PACKAGE__->FixSlashes( $Config::Config{ 'installhtmldir' } ) || "$DEFAULT_PREFIX/html/", 'installhtmlhelpdir' => __PACKAGE__->FixSlashes( $Config::Config{ 'installhtmlhelpdir' } ) || "$DEFAULT_PREFIX/html/", 'installman1dir' => __PACKAGE__->FixSlashes( $Config::Config{ 'installman1dir' } ) || "$DEFAULT_PREFIX/man/man1/", 'installman3dir' => __PACKAGE__->FixSlashes( $Config::Config{ 'installman3dir' } ) || "$DEFAULT_PREFIX/man/man3/", 'installsiteman1dir' => __PACKAGE__->FixSlashes( $Config::Config{ 'installsiteman1dir' } ) || "$DEFAULT_PREFIX/man/man1/", 'installsiteman3dir' => __PACKAGE__->FixSlashes( $Config::Config{ 'installsiteman3dir' } ) || "$DEFAULT_PREFIX/man/man3/", 'configdir' => "$DEFAULT_PREFIX/etc/", 'sharedir' => "$DEFAULT_PREFIX/share/", ); sub new { my ( $class, %paths ) = @_; if ( $SINGLETON ) { my $current_prefix = $SINGLETON->Prefix; my $new_prefix; # first update prefix for all defaults... if ( exists $paths{'installprefix'} or exists $paths{'prefix'} ) { $new_prefix = $paths{'installprefix'} ? $paths{'installprefix'} : $paths{'prefix'} ? $paths{'prefix'} : $DEFAULTS{'installprefix'}; $new_prefix = $SINGLETON->FixSlashes( $new_prefix ); } for my $path ( keys %{ $SINGLETON } ) { $SINGLETON->{$path} =~ s/^\Q$current_prefix\E/$new_prefix/ if $new_prefix; } # ...then overwrite with custom paths $SINGLETON->{$_} = $SINGLETON->FixSlashes( $paths{$_} ) for ( keys %paths ); } else { my $self = {}; my $current_prefix = $DEFAULTS{'installprefix'}; my $new_prefix; # first update prefix for all defaults... if ( exists $paths{'installprefix'} or exists $paths{'prefix'} ) { $new_prefix = $paths{'installprefix'} ? $paths{'installprefix'} : $paths{'prefix'} ? $paths{'prefix'} : $DEFAULTS{'installprefix'}; $new_prefix = __PACKAGE__->FixSlashes( $new_prefix ); } for my $default ( keys %DEFAULTS ) { my $default_path = $DEFAULTS{$default}; $default_path =~ s/^\Q$current_prefix\E/$new_prefix/ if $new_prefix; $self->{$default} = $default_path; } # ...then overwrite with custom paths $self->{$_} = __PACKAGE__->FixSlashes( $paths{$_} ) for ( keys %paths ); bless $self, $class; $SINGLETON = $self; } return $SINGLETON; } } sub Options { my $self = shift; my %options; for my $path ( keys %$self ) { next if $path =~ qr/^(?:installprefix|prefix)$/; $options{"$path=s"} = \$self->{$path}; } $options{'prefix=s'} = sub { my ( $flag, $prefix ) = @_; inc::Installer::OutPaths->new( 'prefix' => $prefix ); inc::Installer::CPAN->new( $prefix ); }; $self->debug("Returning custom options"); return %options; } sub MakePERL5LIB { my $self = shift; return join $Config::Config{'path_sep'}, $self->Installsitelib, $self->Installvendorlib; } sub OptionsHelp { my $self = shift; my $help = " Destination paths:\n"; my $prefix = $self->Prefix; $help .= " --prefix=[PATH]\n"; $help .= " Specify this default before defining any of the custom paths below.\n"; $help .= " Current setting: $prefix\n\n"; for my $path ( sort { $a cmp $b } keys %$self ) { next if $path =~ qr/^(?:installprefix|prefix)$/; my $abs_path = $self->{$path}; $help .= " --$path=[PATH]\n Current setting: $abs_path\n\n"; } return $help; } sub Check { my ( $self, $key ) = @_; if ( $key ne 'installstyle' ) { my $path = ucfirst( $key ); $path = $self->$path; $self->debug("Inspecting '$path' ($key)"); eval { File::Path::mkpath( [ $path ], 0, 0711 ); }; if ( not $@ ) { return [ $path, 1 ]; } else { $self->fatal( $@ ); return [ 0, 1 ]; } } else { return [ "Installing as '" . $self->{'installstyle'} . "'", 1 ]; } } sub Keys { my $self = shift; return sort { $a cmp $b } keys %$self; } sub GetEUMMArgs { my $self = shift; my %prefix; $prefix{'PREFIX'} = $self->Prefix; $prefix{'INSTALLSCRIPT'} = $self->Installscript; $prefix{'INSTALLSITEBIN'} = $self->Installsitebin; $prefix{'INSTALLSITELIB'} = $self->Installsitelib; $prefix{'INSTALLSITEARCH'} = $self->Installsitearch; $prefix{'INSTALLSITEMAN1DIR'} = $self->Installsiteman1dir; $prefix{'INSTALLSITEMAN3DIR'} = $self->Installsiteman3dir; $prefix{'INSTALLDIRS'} = 'site'; return %prefix; } sub Prefix { my ( $self, $new_prefix ) = @_; if ( $new_prefix ) { my $current_prefix = $self->{'installprefix'}; $new_prefix = $self->FixSlashes( $new_prefix ); for my $path ( keys %$self ) { $self->{$path} =~ s/^\Q$current_prefix\E/$new_prefix/; } } return $self->{'installprefix'}; } sub ToGlobalConfig { my $self = shift; my $sysconfig = $inc::Config::Config; for my $path ( %$self ) { if ( exists $sysconfig->{$path} ) { my $newval = $self->{$path}; $self->debug("To global config: '$path' => '$newval'"); $sysconfig->{$path} = $newval; } } } sub FixSlashes { my ( $self, $path ) = @_; if ( $path ) { $path =~ tr/\\/\//; $path =~ s/\/+/\//g; return $path; } else { return ''; } } sub AUTOLOAD { my $path = $AUTOLOAD; $path =~ s/^.+::([^:]+)$/$1/; return if $path =~ qr/^[A-Z]+$/; $path = lc $path; my ( $self, $newval ) = @_; if ( exists $self->{$path} ) { if ( $newval ) { $self->{$path} = $self->FixSlashes( $newval ); $self->debug("Setting path '$path' to '". $self->{$path} . "'"); } return $self->{$path}; } else { $self->fatal("Path '$path' is not defined!"); } } 1;