Acrux

 view release on metacpan or  search on metacpan

lib/Acme/Crux.pm  view on Meta::CPAN

    my $tempdir = $app->tempdir;

Default: /tmp/<MONIKER>

=head2 test

    test => 1
    test => 'on'
    test => 'yes'

Test mode

Default: 0

=head2 verbose

    verbose => 1
    verbose => 'on'
    verbose => 'yes'

Verbose mode

Default: 0

=head2 webdir

    webdir => '/var/www/myapp'

Web dir for project web files (DocumentRoot)

    $app = $app->webdir( "/path/to/webdoc/dir" );
    my $webdirr = $app->webdir;

Default: /var/www/<MONIKER>

=head1 METHODS

This class implements the following methods

=head2 startup

This is your main hook into the application, it will be called at application startup.
Meant to be overloaded in a subclass.

This method is called immediately after creating the instance and returns it

B<NOTE:> Please use only in your subclasses!

    sub startup {
        my $self = shift;

        . . .

        return $self; # REQUIRED!
    }

=head2 debugmode

    $app->debugmode;

Returns debug flag. 1 - on, 0 - off

=head2 begin

    my $timing_begin = $app->begin;

This method sets timestamp for L</elapsed>

    my $timing_begin = $app->begin;
    # ... long operations ...
    my $elapsed = $app->elapsed( $timing_begin );

=head2 elapsed

    my $elapsed = $app->elapsed;

    my $timing_begin = [gettimeofday];
    # ... long operations ...
    my $elapsed = $app->elapsed( $timing_begin );

Return fractional amount of time in seconds since unnamed timstamp has been created while start application

    my $elapsed = $app->elapsed;
    $app->log->debug("Database stuff took $elapsed seconds");

For formatted output:

    $app->log->debug(sprintf("%+.*f sec", 4, $app->elapsed));

=head2 error

    my $error = $app->error;

Returns error string if occurred any errors while working with application

    $app = $app->error( "error text" );

Sets new error message and returns object

=head2 exedir

    my $exedir = $app->exedir;

Gets exedir value

=head2 handlers

    my @names = $app->handlers;

Returns list of names of registered handlers

    my @names_and_aliases = $app->handlers(1);

Returns list of aliases and names of registered handlers

=head2 lookup_handler

    my $handler = $app->lookup_handler($name)
        or die "Handler not found";

Lookup handler by name or aliase. Returns handler or undef while error

lib/Acme/Crux.pm  view on Meta::CPAN

    }

Sets code oh handler

=item description

    description => 'Short description, abstract or synopsis'

=item handler, name

    handler => 'version'
    name => 'version'

Sets handler name. Default to 'default'

=item params, parameters

    params => { foo => 'bar' }

List of handler parameters. All handler parameters will passed to $meta

=back

=head2 register_method

    $app->register_method($namespace, $method, sub { 1 });
    $app->register_method($method => sub { 1 });
    __PACKAGE__->register_method($namespace, $method, sub { 1 });

This method performs register the new method in your namespace

By default use current application namespace

=head2 register_plugin

    $app->register_plugin('foo', 'MyApp::Plugin::Foo');
    $app->register_plugin('foo', 'MyApp::Plugin::Foo', {bar => 123});
    $app->register_plugin('foo', 'MyApp::Plugin::Foo', bar => 123);

Load a plugin and run C<register> method, optional arguments are passed through

=head2 run

By default this method is alias for L</run_handler> method.

This method meant to be overloaded in a subclass

=head2 run_handler

    my $result = $app->run_handler("foo",
        foo => "one",
        bar => 1
    ) or die $app->error;

Runs handler by name and returns result of it handler running

=head2 silentmode

    $app->silentmode;

Returns the verbose flag in the opposite value. 0 - verbose, 1 - silent.

See L</verbosemode>

=head2 testmode

    $app->testmode;

Returns test flag. 1 - on, 0 - off

=head2 verbosemode

    $app->verbosemode;

Returns verbose flag. 1 - on, 0 - off

See L</silentmode>

=head1 PLUGINS

The following plugins are included in the Acrux distribution

=over 4

=item L<Acme::Crux::Plugin::Config>

    Config => Acme::Crux::Plugin::Config

L<Acrux::Config> configuration plugin

=item L<Acme::Crux::Plugin::Log>

    Log => Acme::Crux::Plugin::Log

L<Acrux::Log> logging plugin

=back

=head1 TO DO

See C<TODO> file

=head1 SEE ALSO

L<CTK>, L<CTK::App>

=head1 AUTHOR

Serż Minus (Sergey Lepenkov) L<https://www.serzik.com> E<lt>abalama@cpan.orgE<gt>

=head1 COPYRIGHT

Copyright (C) 1998-2026 D&D Corporation

=head1 LICENSE

This program is distributed under the terms of the Artistic License Version 2.0

See the C<LICENSE> file or L<https://opensource.org/license/artistic-2-0> for details

=cut

use Carp qw/carp croak/;
use Time::HiRes qw/gettimeofday tv_interval/;
use FindBin qw/$RealBin $Script/;
use File::Spec qw//;
use Cwd qw/getcwd/;
use Sub::Util qw/set_subname/;
use Acrux::RefUtil qw/
        as_hash_ref is_hash_ref
        as_array_ref is_array_ref
        is_value is_code_ref is_true_flag
    /;
use Acrux::Const qw/:dir/;
use Acrux::Util qw/load_class trim words/;

use constant {
    WIN             => !!($^O =~ /mswin/i),
    ALOWED_MODES    => [qw/debug test verbose/],
    PRELOAD_PLUGINS => [qw/Config Log/], # Order is very important!
    DEFAULT_PLUGINS => {
        Config  => "Acme::Crux::Plugin::Config",
        Log     => "Acme::Crux::Plugin::Log",
    },
};

sub new {
    my $class = shift;
    my $args = @_ ? @_ > 1 ? {@_} : {%{$_[0]}} : {};

    # Get project name and moniker
    my $project = $args->{project} || $args->{name}
      || ($Script =~ /^(.+?)\.(pl|t|pm|cgi)$/ ? $1 : $Script)
      || $class || scalar(caller(0));
    my $moniker = $args->{moniker} || _project2moniker($project)
      || _project2moniker($class || scalar(caller(0)));

    # Current dir
    my $pwd = getcwd();

    # Create
    my $self = bless {
        # Common
        error       => "",
        script      => $Script,
        invocant    => scalar(caller(0)),
        project     => $project,
        moniker     => $moniker,
        pid         => $$,
        running     => 0,

        # General
        orig        => {%$args},
        created     => Time::HiRes::time,
        hitime      => [gettimeofday],
        options     => as_hash_ref($args->{options}), # Options of command line
        plugins     => {},
        preload_plugins => $args->{preload} || $args->{preload_plugins} || PRELOAD_PLUGINS,

        # Modes (defaults)
        debugmode   => 0,
        testmode    => 0,
        verbosemode => 0,

        # Dirs
        pwd         => $pwd,
        exedir      => $RealBin, # Script dir
        root        => $args->{root}, # Root dir of project. Default: /etc/moniker
        tempdir     => $args->{tempdir}, # Temp dir of project. Default: /tmp/moniker
        datadir     => $args->{datadir}, # Data dir of project. Defaut: /var/lib/moniker
        logdir      => $args->{logdir}, # Log dir of project. Default: /var/log/moniker
        sharedir    => $args->{sharedir}, # Share dir. Default: /usr/share/moniker
        docdir      => $args->{docdir}, # Share dir. Default: /usr/share/doc/moniker
        cachedir    => $args->{cachedir}, # Cache dir. Default: /var/cache/moniker
        spooldir    => $args->{spooldir}, # Spool dir. Default: /var/spool/moniker
        rundir      => $args->{rundir}, # Run dir. Default: /var/run/moniker
        lockdir     => $args->{lockdir}, # Lock dir. Default: /var/lock/moniker
        webdir      => $args->{webdir}, # Web dir. Default: /var/www/moniker

        # Files
        logfile     => $args->{logfile}, # Log file of project. Default: /var/log/moniker/moniker.log
        configfile  => $args->{configfile}, # Config file of project. Default: /etc/moniker/moniker.conf
        pidfile     => $args->{pidfile}, # PID file of project. Default: /var/run/moniker.pid

    }, $class;

    # Modes
    foreach my $mode ( @{(ALOWED_MODES)}) {
        $self->{$mode."mode"} = 1 if is_true_flag($args->{$mode});
    }

    # Root dir
    my $root = $self->{root};
    $root = $self->{root} = $pwd if defined($root) && $root eq '.'; # Set root to cwd if specified as '.'
    unless (defined($root) && length($root)) {
        $root = $self->{root} = File::Spec->catdir(SYSCONFDIR, $moniker);
    }

    # Temp dir
    my $temp = $self->{tempdir};
    unless (defined($temp) && length($temp)) {
        $temp = $self->{tempdir} = File::Spec->catdir(File::Spec->tmpdir(), $moniker);
    }

    # Data dir
    my $datadir = $self->{datadir};
    unless (defined($datadir) && length($datadir)) {
        $datadir = $self->{datadir} = File::Spec->catdir(SHAREDSTATEDIR, $moniker);
    }

    # Log dir
    my $logdir = $self->{logdir};
    unless (defined($logdir) && length($logdir)) {
        $logdir = $self->{logdir} = File::Spec->catdir(LOGDIR, $moniker);
    }

    # Share dir
    my $sharedir = $self->{sharedir};
    unless (defined($sharedir) && length($sharedir)) {
        $self->{sharedir} = File::Spec->catdir(DATADIR, $moniker);
    }

    # Doc dir
    my $docdir = $self->{docdir};
    unless (defined($docdir) && length($docdir)) {
        $self->{docdir} = File::Spec->catdir(DOCDIR, $moniker);
    }

    # Cache dir
    my $cachedir = $self->{cachedir};
    unless (defined($cachedir) && length($cachedir)) {
        $self->{cachedir} = File::Spec->catdir(CACHEDIR, $moniker);
    }

    # Spool dir
    my $spooldir = $self->{spooldir};
    unless (defined($spooldir) && length($spooldir)) {
        $self->{spooldir} = File::Spec->catdir(SPOOLDIR, $moniker);
    }

    # Run dir
    my $rundir = $self->{rundir};
    unless (defined($rundir) && length($rundir)) {
        $rundir = $self->{rundir} = File::Spec->catdir(RUNDIR, $moniker);
    }

    # Lock dir
    my $lockdir = $self->{lockdir};
    unless (defined($lockdir) && length($lockdir)) {



( run in 2.424 seconds using v1.01-cache-2.11-cpan-cdf2f3d4e48 )