<commit_before>package App::Module::Template;

use 5.016;

use strict;
use warnings;

our $VERSION = '0.01';

use base qw(Exporter);

use Carp;
use Config::General;
use Cwd;
use File::Basename;
use File::Copy;
use File::HomeDir;
use File::Path;
use File::Spec;
use Getopt::Std;
use POSIX qw(strftime);
use Readonly;
use Template;
use Try::Tiny;

Readonly::Scalar my $MAX_ARGS => 3;

our (@EXPORT_OK, %EXPORT_TAGS);
@EXPORT_OK = qw(
    validate_module_name
);
%EXPORT_TAGS = (
    ALL => [ @EXPORT_OK ],
);

my $cwd;
my $tt2;
my $tmpl_vars;

#-------------------------------------------------------------------------------
sub run {
    my $class = shift;

    my %opt;
    # -t template dir, location of template files
    # -c config file
    getopts('t:c:', \%opt);

    my $module = $ARGV[0] || prompt();
    my $dist   = $module; $dist =~ s/::/-/gmsx;
    my $file   = $module; $file =~ s/.*:://msx; $file .= '.pm';
    $cwd       = File::Spec->catfile( cwd(), $dist );

    try {
        validate_module_name($module);
    } catch {
        say "$_\n\nmodule-template exiting...";
        exit();
    }

    my $template_dir;

    if (( exists $opt{t} ) and ( defined $opt{t} )) {
        $template_dir = $opt{t};
    }
    else {
        $template_dir  = join q{/}, File::HomeDir->my_home(), '.module-template/templates';
    }

    die "Template directory $template_dir does not exist\n"
        unless -d $template_dir;

    my $config_file;

    if ((exists $opt{c}) and (defined $opt{c} )) {
        $config_file = $opt{c};
    }
    else {
        $config_file = join q{/}, $template_dir, '/../config';
    }

    die "Could not locate configuration file $config_file\n"
        unless -f $config_file;

    my %cfg = Config::General->new(
            -ConfigFile            => $config_file,
            -MergeDuplicateBlocks  => 1,
            -MergeDuplicateOptions => 1,
            -AutoLaunder           => 1,
            -SplitPolicy           => 'equalsign',
            -InterPolateVars       => 1,
            -UTF8                  => 1,
    )->getall() or croak "could not read configuration file $config_file\n";

    my $tt_conf = $cfg{template_toolkit};

    delete $cfg{template_toolkit};

    $tt2 = Template->new( $tt_conf ) or croak Template->error();

    # Template Vars
    $tmpl_vars = \%cfg;
    $tmpl_vars->{module} = $module;
    $tmpl_vars->{today} = strftime('%Y-%m-%d', localtime());
    $tmpl_vars->{year} = strftime('%Y', localtime());

    unless ( (defined $cwd) and (-d $cwd) ) {
        mkpath($cwd);

    if ( -d $cwd ) {
        chdir $cwd;
    }
    else {
        croak "Could not chdir to $cwd\n";
    }
    }
    else {
        print "Destination directory $cwd exists\n";
        print "exiting...\n";
        exit();
    }

    dir_walk($template_dir, \&process_files, \&process_dirs);

    fix_module_path($module, $file);

    return 1;
}

#-------------------------------------------------------------------------------
# Fixup the module filename and path.
#-------------------------------------------------------------------------------
sub fix_module_path {
    my ($module, $file) = @_;

    my @dirs = split( /::/msx, $module );

    # remove the last part of the module name because that will be the filename
    pop @dirs;

    unshift @dirs, 'lib';

    mkpath( File::Spec->catdir( @dirs ) );

    my $dest_file = File::Spec->catfile( @dirs, $file );

    move( File::Spec->catfile( 'lib', 'Module.pm' ), $dest_file );

    return $dest_file;
}

#-------------------------------------------------------------------------------
# callback to pass to dir_walk to handle files
#-------------------------------------------------------------------------------
sub process_files {
    my ($src_file) = @_;

    # grab the directory name to be handled by dir_sub()
    # This also ensures the directory exists before we write the file
    my ($template, $src_directory, $suffix) =
#        fileparse($src_file, qr/\.swp/msx);
        fileparse($src_file, qr/[.]{1,1}swp\Z/msx);

    # skip swap files
    return if $suffix eq '.swp';

    # call process_dirs() to create the destination directory
    my $dest_dir = process_dirs($src_directory);

    # $dest_dir will be undef if it is the parent template directory so,
    # we set it to the current working directory
    $dest_dir = $cwd unless defined $dest_dir;

    my $dest_file = join q{/}, $dest_dir, $template;

    # process the template and write the output
    process_template($src_file, $tmpl_vars, $dest_file);

    return;
}

#-------------------------------------------------------------------------------
# callback to pass to dir_walk() to handle directories
#
# Create destination directories that do not exist
#-------------------------------------------------------------------------------<commit_msg>Fix regex anchor in process_files()<commit_after>package App::Module::Template;

use 5.016;

use strict;
use warnings;

our $VERSION = '0.01';

use base qw(Exporter);

use Carp;
use Config::General;
use Cwd;
use File::Basename;
use File::Copy;
use File::HomeDir;
use File::Path;
use File::Spec;
use Getopt::Std;
use POSIX qw(strftime);
use Readonly;
use Template;
use Try::Tiny;

Readonly::Scalar my $MAX_ARGS => 3;

our (@EXPORT_OK, %EXPORT_TAGS);
@EXPORT_OK = qw(
    validate_module_name
);
%EXPORT_TAGS = (
    ALL => [ @EXPORT_OK ],
);

my $cwd;
my $tt2;
my $tmpl_vars;

#-------------------------------------------------------------------------------
sub run {
    my $class = shift;

    my %opt;
    # -t template dir, location of template files
    # -c config file
    getopts('t:c:', \%opt);

    my $module = $ARGV[0] || prompt();
    my $dist   = $module; $dist =~ s/::/-/gmsx;
    my $file   = $module; $file =~ s/.*:://msx; $file .= '.pm';
    $cwd       = File::Spec->catfile( cwd(), $dist );

    try {
        validate_module_name($module);
    } catch {
        say "$_\n\nmodule-template exiting...";
        exit();
    }

    my $template_dir;

    if (( exists $opt{t} ) and ( defined $opt{t} )) {
        $template_dir = $opt{t};
    }
    else {
        $template_dir  = join q{/}, File::HomeDir->my_home(), '.module-template/templates';
    }

    die "Template directory $template_dir does not exist\n"
        unless -d $template_dir;

    my $config_file;

    if ((exists $opt{c}) and (defined $opt{c} )) {
        $config_file = $opt{c};
    }
    else {
        $config_file = join q{/}, $template_dir, '/../config';
    }

    die "Could not locate configuration file $config_file\n"
        unless -f $config_file;

    my %cfg = Config::General->new(
            -ConfigFile            => $config_file,
            -MergeDuplicateBlocks  => 1,
            -MergeDuplicateOptions => 1,
            -AutoLaunder           => 1,
            -SplitPolicy           => 'equalsign',
            -InterPolateVars       => 1,
            -UTF8                  => 1,
    )->getall() or croak "could not read configuration file $config_file\n";

    my $tt_conf = $cfg{template_toolkit};

    delete $cfg{template_toolkit};

    $tt2 = Template->new( $tt_conf ) or croak Template->error();

    # Template Vars
    $tmpl_vars = \%cfg;
    $tmpl_vars->{module} = $module;
    $tmpl_vars->{today} = strftime('%Y-%m-%d', localtime());
    $tmpl_vars->{year} = strftime('%Y', localtime());

    unless ( (defined $cwd) and (-d $cwd) ) {
        mkpath($cwd);

    if ( -d $cwd ) {
        chdir $cwd;
    }
    else {
        croak "Could not chdir to $cwd\n";
    }
    }
    else {
        print "Destination directory $cwd exists\n";
        print "exiting...\n";
        exit();
    }

    dir_walk($template_dir, \&process_files, \&process_dirs);

    fix_module_path($module, $file);

    return 1;
}

#-------------------------------------------------------------------------------
# Fixup the module filename and path.
#-------------------------------------------------------------------------------
sub fix_module_path {
    my ($module, $file) = @_;

    my @dirs = split( /::/msx, $module );

    # remove the last part of the module name because that will be the filename
    pop @dirs;

    unshift @dirs, 'lib';

    mkpath( File::Spec->catdir( @dirs ) );

    my $dest_file = File::Spec->catfile( @dirs, $file );

    move( File::Spec->catfile( 'lib', 'Module.pm' ), $dest_file );

    return $dest_file;
}

#-------------------------------------------------------------------------------
# callback to pass to dir_walk to handle files
#-------------------------------------------------------------------------------
sub process_files {
    my ($src_file) = @_;

    # grab the directory name to be handled by dir_sub()
    # This also ensures the directory exists before we write the file
    my ($template, $src_directory, $suffix) =
        fileparse($src_file, qr/[.]{1,1}swp\z/msx);

    # skip swap files
    return if $suffix eq '.swp';

    # call process_dirs() to create the destination directory
    my $dest_dir = process_dirs($src_directory);

    # $dest_dir will be undef if it is the parent template directory so,
    # we set it to the current working directory
    $dest_dir = $cwd unless defined $dest_dir;

    my $dest_file = join q{/}, $dest_dir, $template;

    # process the template and write the output
    process_template($src_file, $tmpl_vars, $dest_file);

    return;
}

#-------------------------------------------------------------------------------
# callback to pass to dir_walk() to handle directories
#
# Create destination directories that do not exist
#-------------------------------------------------------------------------------
{'fraction_non_alphanumeric': 0.24649859943977592, 'fraction_numerical': 0.0041498080713766984, 'mean_word_length': 1.7332010206974766, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '784118', 'n_tokens_mistral': 3052, 'n_tokens_neox': 2915, 'n_words': 816}