package Dist::Zilla::Plugin::UploadToCPAN::OnePassword 5.027;
# ABSTRACT: upload the dist to CPAN, credentials in 1Password

use Moose;
extends 'Dist::Zilla::Plugin::UploadToCPAN';

use v5.36.0;

use Password::OnePassword::OPCLI;

has op_item_id => (
  is  => 'ro',
  isa => 'Str',
  default => sub {
    my $item_id = $ENV{DZIL_PAUSE_1P_ITEM_ID};

    confess "no op_item_id given and no DZIL_PAUSE_1P_ITEM_ID env var"
      unless length $item_id;

    confess "bogus-looking 1Password item id in DZIL_PAUSE_1P_ITEM_ID"
      unless $item_id =~ /\A\p{PosixAlnum}+\z/;

    $item_id;
  },
);

has _op_item_fields => (
  is => 'ro',
  isa => 'HashRef',
  lazy    => 1,
  default => sub ($self) {
    my $item_id = $self->op_item_id;

    confess "bogus-looking 1Password item id"
      unless $item_id =~ /\A\p{PosixAlnum}+\z/;

    my $struct = Password::OnePassword::OPCLI->new->get_item($item_id);

    my $field_aref = $struct->{fields};
    my %fields = map {; $_->{id} => $_->{value} } @$field_aref;

    return \%fields;
  },
);

sub username ($self) {
  $self->_op_item_fields->{username}
    // Carp::croak("no username field in 1Password credential")
}

sub password ($self) {
  $self->_op_item_fields->{password}
    // Carp::croak("no password field in 1Password credential")
}

# Overriding this method is just more of a show of how this plugin is kind of a
# grody hack.  The version of this method in UploadToCPAN does the checks in a
# try block with no catch, so it wasn't saying "getting pw from 1P is throwing
# an error, it was saying "you need to supply a password".  Ugh.
#
# I think the real solution is to use the normal UploadToCPAN but with a
# smarter stash. -- rjbs, 2024-05-25
sub before_release {
  my $self = shift;

  my $problem;

  for my $attr (qw(username password)) {
    unless (length $self->$attr) {
      $self->log_fatal(['You need to supply a %s', $attr]);
    }
  }
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Dist::Zilla::Plugin::UploadToCPAN::OnePassword - upload the dist to CPAN, credentials in 1Password

=head1 VERSION

version 5.027

=head1 PERL VERSION

This module is shipped with no promise about what version of perl it will
require in the future.  In practice, this tends to mean "you need a perl from
the last three years," but you can't rely on that.  If a new version of perl
ship, this software B<may> begin to require it for any reason, and there is
no promise that patches will be accepted to lower the minimum required perl.

=head1 AUTHOR

Ricardo Signes <cpan@semiotic.systems>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2024 by Ricardo Signes.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
