App-Music-ChordPro

 view release on metacpan or  search on metacpan

lib/ChordPro/Paths.pm  view on Meta::CPAN

#! perl

use v5.26;
use Object::Pad;
use utf8;
use Carp;

class ChordPro::Paths;

my $instance;

# Work around Object::Pad 0.817 breakage.
#method get :common ( $reset = 0 ) {
#    undef $instance if $reset;
#    $instance //= $class->new;
#}

sub get( $class, $reset = 0 ) {
    undef $instance if $reset;
    $instance //= $class->new;
}

use Cwd qw(realpath);
use File::HomeDir;
use ChordPro::Files;

field $home      :reader;	# dir
field $configdir :reader;	# dir
field $privlib   :reader;	# dir
field $resdirs   :reader;	# [ dir, ... ]
field $configs   :reader;	# { config => dir, ... }
field $pathsep   :reader;	# : or ;

field $packager  :reader;

# Cwd::realpath always returns forward slashes.
# On Windows, Cwd::realpath always returns a volume.

BUILD {
    my $app = "ChordPro";
    my $app_lc = lc($app);

    $pathsep = is_msw ? ';' : ':';

    $home     = realpath( $ENV{HOME} = File::HomeDir->my_home );

#    $desktop  = File::HomeDir->my_desktop;
#    $docs     = File::HomeDir->my_documents;
#    $music    = File::HomeDir->my_music;
#    $pics     = File::HomeDir->my_pictures;
#    $videos   = File::HomeDir->my_videos;
#    $data     = File::HomeDir->my_data;
#    $dist     = File::HomeDir->my_dist_data('ChordPro');
#    $dist     = File::HomeDir->my_dist_config('ChordPro');

    # Establish config files. Global config is easy.
    for ( $self->normalize("/etc/$app_lc.json") ) {
	next unless $_ && -f;
	$configs->{sysconfig} = $_;
    }

    $configs = {};
    # The user specific config requires some alternatives.
    # -d $XDG_CONFIG_HOME/$app_lc
    # -d ~/.config/$app_lc
    # -d ~/.$app_lc
    # -d my_dist_config
    my @try;
    if ( defined( $ENV{XDG_CONFIG_HOME} ) && $ENV{XDG_CONFIG_HOME} ne "" ) {
	push( @try,
	      # See https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
	      # fn_catdir( $ENV{XDG_CONFIG_HOME}, ".config", $app_lc ),
	      # fn_catdir( $ENV{XDG_CONFIG_HOME}, ".config" ),
	      # fn_catdir( $ENV{XDG_CONFIG_HOME}, ".$app_lc" ) );
	      fn_catdir( $ENV{XDG_CONFIG_HOME}, "$app_lc" ) );
    }
    else {
	push( @try,
	      fn_catdir( $home, ".config", $app_lc ),
	      fn_catdir( $home, ".$app_lc" ),
	      File::HomeDir->my_dist_config($app) );
    }

    for ( @try ) {
	next unless $_ && fs_test( d => $_);
	my $path = $self->normalize($_);
	warn("Paths: configdir try $_ => $path\n") if $self->debug > 1;
	next unless $path && fs_test( d => $path);
	$configdir = $path;
	for ( $self->normalize( fn_catfile( $path, "$app_lc.prp" ) ),
	      $self->normalize( fn_catfile( $path, "$app_lc.json" ) ) ) {
	    next unless $_ && fs_test( f => $_ );
	    $configs->{userconfig} = $_;
	    last;
	}
	last if $configdir;
    }
    warn("Paths: configdir = ", $configdir // "<undef>", "\n") if $self->debug;

    for ( $self->normalize(".$app_lc.json"),
	  $self->normalize("$app_lc.json") ) {
	    next unless $_ && fs_test( f => $_ );
	$configs->{config} = $_;
	last;
    }
    if ( $self->debug ) {
	for ( qw( sysconfig userconfig config ) ) {
	    warn(sprintf("Paths: %-10s = %s\n",
			 $_, $configs->{$_} // "<undef>" ) );
	}
    }

    # Private lib.
    $privlib = $INC{'ChordPro.pm'} =~ s/\.pm$/\/lib/r;

    # Now for the resources.
    $self->setup_resdirs;

    # Check for packaged image.
    for ( qw( OCI Docker AppImage PPL ) ) {
	next unless exists $ENV{uc($_)."_PACKAGED"}
	  && $ENV{uc($_)."_PACKAGED"};
	$packager = $_;
	last;
    }

};

# We need this to be able to re-establish the resdirs, e.g. after a change
# of CHORDPRO_LIB.
method setup_resdirs {



( run in 1.057 second using v1.01-cache-2.11-cpan-22024b96cdf )