<commit_before>package JIP::LockFile;

use 5.006;
use strict;
use warnings;
use IO::File;
use JIP::ClassField;
use Carp qw(croak);
use Fcntl qw(LOCK_EX LOCK_NB);
use English qw(-no_match_vars);

our $VERSION = '0.05';

has lock_file => (get => '+', set => '-');
has is_locked => (get => '+', set => '-');

has fh => (get => '-', set => '-');

sub new {
    my ($class, %param) = @ARG;

    # Mandatory options
    croak qq{Mandatory argument "lock_file" is missing\n}
        unless exists $param{'lock_file'};

    # Check "lock_file"
    my $lock_file = $param{'lock_file'};
    croak qq{Bad argument "lock_file"\n}
        unless defined $lock_file and length $lock_file;

    # Class to object
    return bless({}, $class)
        ->_set_is_locked(0)
        ->_set_lock_file($lock_file)
        ->_set_fh(undef);
}

# Lock or raise an exception
sub lock {
    my $self = shift;

    # Re-locking changes nothing
    return $self if $self->is_locked;

    my $fh = IO::File->new($self->lock_file, O_RDWR|O_CREAT)
        or croak(sprintf qq{Can't open "%s": %s\n}, $self->lock_file, $OS_ERROR);

    flock $fh, LOCK_EX|LOCK_NB
        or croak(sprintf qq{Can't lock "%s": %s\n}, $self->lock_file, $OS_ERROR);

    truncate $fh, 0
        or croak(sprintf qq{Can't truncate "%s": %s\n}, $self->lock_file, $OS_ERROR);

    autoflush $fh 1;

    $fh->print($self->_lock_message())
        or croak(sprintf qq{Can't write message to file: %s\n}, $OS_ERROR);

    return $self->_set_fh($fh)->_set_is_locked(1);
}

# Or just return undef
sub try_lock {
    my $self = shift;

    # Re-locking changes nothing
    return $self if $self->is_locked;

    my $fh = IO::File->new($self->lock_file, O_RDWR|O_CREAT);

    if ($fh and flock $fh, LOCK_EX|LOCK_NB) {
        truncate $fh, 0
            or croak(sprintf qq{Can't truncate "%s": %s\n}, $self->lock_file, $OS_ERROR);

        autoflush $fh 1;

        $fh->print($self->_lock_message())
            or croak(sprintf qq{Can't write message to file: %s\n}, $OS_ERROR);

        return $self->_set_fh($fh)->_set_is_locked(1);
    }
    else {
        return;
    }
}

# You can manually unlock
sub unlock {
    my $self = shift;

    # Re-unlocking changes nothing
    return $self if not $self->is_locked;

    # Close filehandle before file removing
    unlink $self->_set_fh(undef)->lock_file
        or croak(sprintf qq{Can't unlink "%s": %s\n}, $self->lock_file, $OS_ERROR);
<commit_msg>Small fixes<commit_after>package JIP::LockFile;

use 5.006;
use strict;
use warnings;
use IO::File;
use JIP::ClassField;
use Carp qw(croak);
use Fcntl qw(LOCK_EX LOCK_NB);
use English qw(-no_match_vars);

our $VERSION = '0.05';

has lock_file => (get => '+', set => '-');
has is_locked => (get => '+', set => '-');

has fh => (get => '-', set => '-');

sub new {
    my ($class, %param) = @ARG;

    # Mandatory options
    croak q{Mandatory argument "lock_file" is missing}
        unless exists $param{'lock_file'};

    # Check "lock_file"
    my $lock_file = $param{'lock_file'};
    croak q{Bad argument "lock_file"}
        unless defined $lock_file and length $lock_file;

    # Class to object
    return bless({}, $class)
        ->_set_is_locked(0)
        ->_set_lock_file($lock_file)
        ->_set_fh(undef);
}

# Lock or raise an exception
sub lock {
    my $self = shift;

    # Re-locking changes nothing
    return $self if $self->is_locked;

    my $fh = IO::File->new($self->lock_file, O_RDWR|O_CREAT)
        or croak(sprintf q{Can't open "%s": %s}, $self->lock_file, $OS_ERROR);

    flock $fh, LOCK_EX|LOCK_NB
        or croak(sprintf q{Can't lock "%s": %s}, $self->lock_file, $OS_ERROR);

    truncate $fh, 0
        or croak(sprintf q{Can't truncate "%s": %s}, $self->lock_file, $OS_ERROR);

    autoflush $fh 1;

    $fh->print($self->_lock_message())
        or croak(sprintf q{Can't write message to file: %s}, $OS_ERROR);

    return $self->_set_fh($fh)->_set_is_locked(1);
}

# Or just return undef
sub try_lock {
    my $self = shift;

    # Re-locking changes nothing
    return $self if $self->is_locked;

    my $fh = IO::File->new($self->lock_file, O_RDWR|O_CREAT);

    if ($fh and flock $fh, LOCK_EX|LOCK_NB) {
        truncate $fh, 0
            or croak(sprintf q{Can't truncate "%s": %s}, $self->lock_file, $OS_ERROR);

        autoflush $fh 1;

        $fh->print($self->_lock_message())
            or croak(sprintf q{Can't write message to file: %s}, $OS_ERROR);

        return $self->_set_fh($fh)->_set_is_locked(1);
    }
    else {
        return;
    }
}

# You can manually unlock
sub unlock {
    my $self = shift;

    # Re-unlocking changes nothing
    return $self if not $self->is_locked;

    # Close filehandle before file removing
    unlink $self->_set_fh(undef)->lock_file
        or croak(sprintf q{Can't unlink "%s": %s}, $self->lock_file, $OS_ERROR);

{'fraction_non_alphanumeric': 0.15928291778281475, 'fraction_numerical': 0.00576962703482382, 'mean_word_length': 3.0148883374689825, 'pattern_counts': {'":': 10, '<': 3, '<?xml version=': 0, '>': 71, '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': '2714595', 'n_tokens_mistral': 1876, 'n_tokens_neox': 1758, 'n_words': 461}