App-AppSpec

 view release on metacpan or  search on metacpan

lib/App/AppSpec.pm  view on Meta::CPAN


sub _read_spec {
    my ($self, $run) = @_;
    my $parameters = $run->parameters;

    my $spec_file = $parameters->{spec_file};
    my $spec = App::Spec->read($spec_file);
    return $spec;
}

sub cmd_completion {
    my ($self, $run) = @_;
    my $options = $run->options;
    my $parameters = $run->parameters;
    my $name = $options->{name};

    my $shell = $options->{zsh} ? "zsh" : $options->{bash} ? "bash" : '';
    die "Specify which shell" unless $shell;

    my $spec = $self->_read_spec($run);
    if (defined $name) {
        $spec->name($name);
    }
    my $completion = $spec->generate_completion(
        shell => $shell,
    );
    say $completion;
}

sub generate_pod {
    my ($self, $run) = @_;
    my $parameters = $run->parameters;

    my $spec = $self->_read_spec($run);

    require App::Spec::Pod;
    my $generator = App::Spec::Pod->new(
        spec => $spec,
    );
    my $pod = $generator->generate;

    say $pod;
}

sub cmd_validate {
    my ($self, $run) = @_;
    my $options = $run->options;
    my $parameters = $run->parameters;

    my @errors;
    require App::AppSpec::Schema::Validator;
    my $validator = App::AppSpec::Schema::Validator->new;
    my $spec_file = $parameters->{spec_file};
    if (ref $spec_file eq 'SCALAR') {
        my $spec = YAML::PP::Load($$spec_file);
        @errors = $validator->validate_spec($spec);
    }
    else {
        @errors = $validator->validate_spec_file($spec_file);
    }
    binmode STDOUT, ":encoding(utf-8)";
    if (@errors) {
        print $validator->format_errors(\@errors);
        say $run->colored(out => red => "Not valid!");
    }
    else {
        say $run->colored(out => [qw/ bold green /] => "Validated ✓");
    }
}

sub cmd_new {
    my ($self, $run) = @_;
    my $options = $run->options;
    my $params = $run->parameters;
    my $dist_path = $params->{path};
    require File::Path;

    my $name = $options->{name};
    my $class = $options->{class};
    my $overwrite = $options->{overwrite};
    unless ($name =~ m/^\w[\w+-]*/) {
        die "Option name '$name': invalid app name";
    }
    unless ($class =~ m/^[a-zA-Z]\w*(::\w+)+$/) {
        die "Option class '$class': invalid classname";
    }
    my $dist = $class;
    $dist =~ s/::/-/g;
    $dist = $dist_path // $dist;
    if (-d $dist and not $overwrite) {
        die "Directory $dist already exists";
    }
    elsif (-d $dist) {
        say "Removing old $dist directory first";
        File::Path::remove_tree($dist);
    }
    my $spec = <<"EOM";
name: $name
appspec: { version: '0.001' }
class: $class
title: 'app title'
description: 'app description'
options:
- name: some-flag
  type: flag
  summary: option summary
- spec: other-option=s --another option
EOM
    my $subname = $options->{"with-subcommands"} ? "mycommand" : "execute";
    my $module = <<"EOM";
package $class;
use strict;
use warnings;
use feature qw/ say /;
use base 'App::Spec::Run::Cmd';

sub $subname \{
    my (\$self, \$run) = \@_;
    my \$options = \$run->options;
    my \$parameters = \$run->parameters;



( run in 1.095 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )