App-Env

 view release on metacpan or  search on metacpan

script/appexec  view on Meta::CPAN

    sh   => 'bourne',
    csh  => 'c',
);

# program options; see parse_args();
my %opt;

eval { main() } // do {
    say STDERR "# $prog: $_" foreach split /\n/, $@;    ## no critic(InputOutput::RequireCheckedSyscalls)
    exit 1;
};

exit 0;

sub main {
    parse_args();

    help( 1 ) if $opt{help};
    help( 2 ) if $opt{usage};

    return ( print "$prog $VERSION\n" )
      if $opt{version};

    die "please specify an environment\n"
      unless defined $opt{env};

    if ( $opt{clear} ) {
        ## no critic( Variables::RequireLocalizedPunctuationVars )
        %ENV = map { $_ => $ENV{$_} }
          grep { exists $ENV{$_} } qw[ HOME LOGNAME SHELL ];
    }

    my @envs = split( /,/, $opt{env} );

    # if more than one environment, sort out possible environment specific appopts
    my %appopts;
    @appopts{@envs} = map { {} } 1 .. @envs;

    if ( @envs > 1 ) {

        for my $k ( keys %{ $opt{appopts} } ) {
            my ( $env, $key ) = $k =~ /^([^:]*):(.*)$/;

            die( "appopts ($key) not specific to one of the specified environments" )
              unless exists $appopts{$env};

            $appopts{$env}{$key} = $opt{appopts}->{$k};
        }
    }

    else {
        $appopts{ $envs[0] } = $opt{appopts};
    }

    my $env = eval {
        App::Env->new(
            ( map { [ $_ => { AppOpts => $appopts{$_} } ] } @envs ),
            { ( defined $opt{site} ? ( Site => $opt{site} ) : () ), } );
    } // die( "error setting up environment `$opt{env}': $@\n" );

    $env->setenv( $_ ) for @{ $opt{delete} };
    $env->setenv( $_, $opt{define}{$_} ) for keys %{ $opt{define} };

    dumpenv( $env, $opt{dumpenv}, $opt{dumpvar} ) if $opt{dumpenv};

    if ( @ARGV ) {
        say join( q{ }, @ARGV )    ## no critic(InputOutput::RequireCheckedSyscalls)
          if $opt{verbose};

        %ENV = %$env;              ## no critic( Variables::RequireLocalizedPunctuationVars )

        die( "$ARGV[0] does not exist, is not executable, or is not in PATH\n" )
          unless ( file_name_is_absolute( $ARGV[0] ) && -e $ARGV[0] )
          || defined which( $ARGV[0] );

        exec { $ARGV[0] } @ARGV
          or die( "can't exec $ARGV[0]: not in path?\n" );
    }

    return !!1;
}

sub _is_valid_env_name {
    my $name = shift;
    return $name !~ /\P{IsWord}/ && substr( $name, 0, 1 ) =~ /\P{IsDigit}/;
}

sub dumpenv {
    my ( $env, $fmt, $vars ) = @_;

    $vars = [ keys %$env ] unless @$vars;

    ## no critic (InputOutput::RequireCheckedSyscalls)
    ## no critic (ControlStructures::ProhibitCascadingIfElse)
    if ( $fmt eq 'raw' ) {
        say "$_=",
          (
            length $env->{$_}
            ? App::Env::_Util::shell_escape( $env->{$_} )
            : q{}
          ) for @$vars;
    }

    elsif ( $fmt eq 'unquoted' ) {
        say "$_=$env->{$_}" for @$vars;
    }

    elsif ( $fmt eq 'values' ) {
        say $env->{$_} for @$vars;
    }

    elsif ( $fmt eq 'json' ) {
        require JSON::PP;
        say JSON::PP::encode_json( { map { $_ => $env->{$_} } @$vars } );
    }

    elsif ( $fmt eq 'delta-json' ) {
        my ( $delete, $add ) = delta( $env );
        require JSON::PP;
        say JSON::PP::encode_json( {
            delete => $delete,
            add    => { map { $_ => $env->{$_} } @$add },



( run in 0.452 second using v1.01-cache-2.11-cpan-39bf76dae61 )