ACME-2026

 view release on metacpan or  search on metacpan

META.json  view on Meta::CPAN

   },
   "name" : "ACME-2026",
   "no_index" : {
      "directory" : [
         "t",
         "inc"
      ]
   },
   "prereqs" : {
      "build" : {
         "requires" : {
            "ExtUtils::MakeMaker" : "0"
         }
      },
      "configure" : {
         "requires" : {
            "ExtUtils::MakeMaker" : "0"
         }
      },
      "runtime" : {
         "requires" : {
            "JSON::PP" : "0",
            "perl" : "5.008003"
         }
      },
      "test" : {
         "requires" : {
            "Test::More" : "0"
         }
      }
   },
   "release_status" : "stable",
   "version" : "0.01",
   "x_serialization_backend" : "JSON::PP version 4.16"
}

META.yml  view on Meta::CPAN

---
abstract: 'Checklists for glorious 2026 goals'
author:
  - 'Will Willis <wwillis@cpan.org>'
build_requires:
  ExtUtils::MakeMaker: '0'
  Test::More: '0'
configure_requires:
  ExtUtils::MakeMaker: '0'
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010'
license: artistic_2
meta-spec:
  url: http://module-build.sourceforge.net/META-spec-v1.4.html
  version: '1.4'
name: ACME-2026
no_index:
  directory:
    - t
    - inc
requires:
  JSON::PP: '0'
  perl: '5.008003'
version: '0.01'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'

Makefile.PL  view on Meta::CPAN

    },
    PREREQ_PM => {
        'JSON::PP' => '0',
    },
    dist  => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
    clean => { FILES => 'ACME-2026-*' },
);

# Compatibility with old versions of ExtUtils::MakeMaker
unless (eval { ExtUtils::MakeMaker->VERSION('6.64'); 1 }) {
    my $test_requires = delete $WriteMakefileArgs{TEST_REQUIRES} || {};
    @{$WriteMakefileArgs{PREREQ_PM}}{keys %$test_requires} = values %$test_requires;
}

unless (eval { ExtUtils::MakeMaker->VERSION('6.55_03'); 1 }) {
    my $build_requires = delete $WriteMakefileArgs{BUILD_REQUIRES} || {};
    @{$WriteMakefileArgs{PREREQ_PM}}{keys %$build_requires} = values %$build_requires;
}

delete $WriteMakefileArgs{CONFIGURE_REQUIRES}
    unless eval { ExtUtils::MakeMaker->VERSION('6.52'); 1 };
delete $WriteMakefileArgs{MIN_PERL_VERSION}
    unless eval { ExtUtils::MakeMaker->VERSION('6.48'); 1 };
delete $WriteMakefileArgs{LICENSE}
    unless eval { ExtUtils::MakeMaker->VERSION('6.31'); 1 };

WriteMakefile(%WriteMakefileArgs);

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

    priority => 2,
  );

  complete_item($plan, $id, note => 'Signed up for NYC');
  my @open = items($plan, status => 'todo', list => 'Health', sort => 'due');

  plan_save($plan);

=head1 DESCRIPTION

ACME::2026 is a tiny functional API for keeping 2026 checklists. It stores
plans as plain Perl hashrefs and can persist them to JSON.

=head1 DATA MODEL

Plan hashref:

  {
    title       => '2026',
    items       => [ ... ],
    next_id     => 1,

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

        updated_at => $now,
        storage    => $opts{storage},
        autosave   => $opts{autosave} ? 1 : 0,
    };

    return $plan;
}

sub plan_load {
    my ($path, %opts) = @_;
    croak 'plan_load requires a path' unless defined $path && length $path;

    my $json = _read_file($path);
    my $data = eval { JSON::PP->new->decode($json) };
    croak "Failed to decode JSON from $path: $@" if $@;

    _normalize_plan($data);

    $data->{storage} = $path;
    $data->{title} = $opts{title} if exists $opts{title};
    $data->{autosave} = $opts{autosave} ? 1 : 0 if exists $opts{autosave};

    return $data;
}

sub plan_save {
    my ($plan, $path) = @_;
    _ensure_plan($plan);

    $path ||= $plan->{storage};
    croak 'plan_save requires a path or plan storage' unless defined $path && length $path;

    _normalize_plan($plan);

    my $encoder = JSON::PP->new->canonical(1)->pretty(1);
    my $json = $encoder->encode($plan);
    _write_file_atomic($path, $json);

    return 1;
}

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


    my ($title, %opts);
    if (@args % 2 == 1) {
        $title = shift @args;
        %opts = @args;
    } else {
        %opts = @args;
        $title = $opts{title};
    }

    croak 'add_item requires a title' unless defined $title && length $title;
    _reject_unknown('add_item', \%opts, qw(title list tags tag priority due note));

    my $now = _now();
    my $item = {
        id         => $plan->{next_id}++,
        title      => $title,
        status     => 'todo',
        list       => defined $opts{list} ? $opts{list} : 'General',
        tags       => _normalize_tags($opts{tags}, $opts{tag}),
        priority   => defined $opts{priority} ? $opts{priority} : 3,

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


sub get_item {
    my ($plan, $id) = @_;
    _ensure_plan($plan);
    return _find_item($plan, $id);
}

sub add_note {
    my ($plan, $id, $note) = @_;
    _ensure_plan($plan);
    croak 'add_note requires a note' unless defined $note && length $note;

    my $item = _find_item($plan, $id);
    croak "No item with id $id" unless $item;

    _add_note($plan, $item, $note);
    _maybe_autosave($plan);

    return $item;
}

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

}

=head1 AUTHOR

Will Willis <wwillis@cpan.org>

=head1 BUGS

Please report any bugs or feature requests to C<bug-acme-2026 at rt.cpan.org>, or through
the web interface at L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=ACME-2026>.  I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.

=head1 SUPPORT

You can find documentation for this module with the perldoc command.

  perldoc ACME::2026

You can also look for information at:

=over 4

script/acme2026  view on Meta::CPAN

        'list|l=s'     => \$list,
        'tag|t=s@'     => \@tags,
        'priority|p=i' => \$priority,
        'due|d=s'      => \$due,
        'note|n=s'     => \$note,
        'help|h'       => \$help,
    ) or usage('Invalid options for add');
    usage() if $help;

    my $title = shift @ARGV;
    usage('add requires a title') unless defined $title && length $title;

    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);

script/acme2026  view on Meta::CPAN

    my ($note, $help);
    GetOptionsFromArray(
        \@ARGV,
        'file|f=s' => \$file,
        'note|n=s' => \$note,
        'help|h'   => \$help,
    ) 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') {



( run in 0.697 second using v1.01-cache-2.11-cpan-0a27d97929d )