ACME-2026

 view release on metacpan or  search on metacpan

lib/ACME/2026.pm  view on Meta::CPAN

sub _read_file {
    my ($path) = @_;
    open my $fh, '<', $path or croak "Unable to read $path: $!";
    local $/;
    return <$fh>;
}

sub _write_file_atomic {
    my ($path, $content) = @_;
    my ($fh, $tmp) = tempfile('acme2026-XXXXXX', DIR => _temp_dir($path));
    print {$fh} $content or croak "Unable to write $tmp: $!";
    close $fh or croak "Unable to close $tmp: $!";
    rename $tmp, $path or croak "Unable to move $tmp to $path: $!";
}

sub _temp_dir {
    my ($path) = @_;
    return '.' unless defined $path && length $path;
    if ($path =~ /[\/\\]/) {
        $path =~ s/[\/\\][^\/\\]+$//;
        return length $path ? $path : '.';

script/acme2026  view on Meta::CPAN

use warnings;

use Getopt::Long qw(GetOptionsFromArray);
use ACME::2026 qw(plan_new plan_load plan_save add_item complete_item items);

sub usage {
    my ($msg) = @_;
    if ($msg) {
        warn "$msg\n";
    }
    print <<'USAGE';
Usage:
  acme2026 add "Title" [--list NAME] [--tag TAG ...] [--priority N] [--due YYYY-MM-DD] [--note TEXT] [--file PATH]
  acme2026 complete ID [--note TEXT] [--file PATH]
  acme2026 list [--status todo|done|skipped] [--list NAME] [--tag TAG ...] [--sort FIELD] [--file PATH]

Options:
  --file, -f     Path to JSON storage (default: 2026.json or $ACME_2026_FILE)
  --sort         One of: due, -due, priority, -priority, created, updated, title, -title
  --help, -h     Show this help
USAGE

script/acme2026  view on Meta::CPAN

    my $plan = load_plan($file);
    my %opts;
    $opts{list} = $list if defined $list;
    $opts{priority} = $priority if defined $priority;
    $opts{due} = $due if defined $due;
    $opts{note} = $note if defined $note;
    $opts{tags} = \@tags if @tags;

    my $id = add_item($plan, $title, %opts);
    plan_save($plan, $file);
    print "Added [$id] $title\n";
    exit 0;
}

if ($cmd eq 'complete') {
    my $file = default_file();
    my ($note, $help);
    GetOptionsFromArray(
        \@ARGV,
        'file|f=s' => \$file,
        'note|n=s' => \$note,

script/acme2026  view on Meta::CPAN

    ) or usage('Invalid options for complete');
    usage() if $help;

    my $id = shift @ARGV;
    usage('complete requires an ID') unless defined $id && $id =~ /^\d+$/;
    die "Plan file not found: $file\n" unless -e $file;

    my $plan = plan_load($file);
    complete_item($plan, $id, (defined $note ? (note => $note) : ()));
    plan_save($plan, $file);
    print "Completed [$id]\n";
    exit 0;
}

if ($cmd eq 'list') {
    my $file = default_file();
    my ($status, $list, $sort, $help);
    my @tags;
    GetOptionsFromArray(
        \@ARGV,
        'file|f=s' => \$file,

script/acme2026  view on Meta::CPAN


    my $plan = load_plan($file);
    my %filters;
    $filters{status} = $status if defined $status;
    $filters{list} = $list if defined $list;
    $filters{tags} = \@tags if @tags;
    $filters{sort} = $sort if defined $sort;

    my @items = items($plan, %filters);
    if (!@items) {
        print "No items\n";
        exit 0;
    }

    for my $item (@items) {
        my $tags = $item->{tags} && @{ $item->{tags} } ? join(',', @{ $item->{tags} }) : '-';
        my $due = defined $item->{due} && length $item->{due} ? $item->{due} : '-';
        my $line = join("\t",
            $item->{id},
            $item->{status},
            $item->{list} || 'General',
            $due,
            'p' . ($item->{priority} || 0),
            $tags,
            $item->{title},
        );
        print "$line\n";
    }
    exit 0;
}

usage("Unknown command: $cmd");

__END__

=head1 NAME

t/00-load.t  view on Meta::CPAN

#!perl
use 5.008003;
use strict;
use warnings;
use Test::More;

plan tests => 1;

BEGIN {
    use_ok( 'ACME::2026' ) || print "Bail out!\n";
}

diag( "Testing ACME::2026 $ACME::2026::VERSION, Perl $], $^X" );



( run in 0.865 second using v1.01-cache-2.11-cpan-c966e8aa7e8 )