File: Assert.pm

package info (click to toggle)
env-assert 0.015-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 424 kB
  • sloc: perl: 1,877; makefile: 8; sh: 7
file content (162 lines) | stat: -rw-r--r-- 4,088 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
## no critic (ControlStructures::ProhibitPostfixControls)
## no critic (ValuesAndExpressions::ProhibitConstantPragma)
package Env::Assert;
use strict;
use warnings;
use 5.010;

# ABSTRACT: Ensure that the environment variables match what you need, or abort.

our $VERSION = '0.015';

# We define our own import routine because
# this is the point (when `use Env::Assert` is called)
# when we do our magic.

use Carp;

use English qw( -no_match_vars );    # Avoids regex performance penalty in perl 5.18 and earlier
use open ':std', IO => ':encoding(UTF-8)';

use Env::Assert::Functions qw( :all );

use constant { ENV_DESC_FILENAME => '.envdesc', };

# Handle exports
{
    no warnings 'redefine';    ## no critic [TestingAndDebugging::ProhibitNoWarnings]

    sub import {
        my ( $class, $cmd, $args ) = @_;

        # We also allow only: 'use Env::Assert;'
        croak "Unknown argument '$cmd'" if ( $cmd && $cmd ne 'assert' );

        if ( !assert_env( %{$args} ) ) {
            croak 'Errors in environment detected.';
        }
        return;
    }
}

sub assert_env {
    my (%args) = @_;
    local $OUTPUT_AUTOFLUSH = 1;

    my $break_at_first_error = $args{'break_at_first_error'} // 0;
    my $exact                = $args{'exact'}                // 0;

    my @env_desc_rows;
    if ( $args{'envdesc'} ) {
        my $content = $args{'envdesc'};
        open my $fh, q{<}, \$content
          or croak 'Cannot open scalar envdesc content';
        @env_desc_rows = <$fh>;
        close $fh or croak 'Cannot close scalar envdesc content';
    }
    else {
        my $env_desc_filename = $args{'envdesc_file'} // ENV_DESC_FILENAME;
        open my $fh, q{<}, $env_desc_filename or croak "Cannot open file '$env_desc_filename'";
        @env_desc_rows = <$fh>;
        close $fh or croak "Cannot close file '$env_desc_filename'";
    }

    my $desc = file_to_desc(@env_desc_rows);
    my %parameters;
    $parameters{'break_at_first_error'} = $break_at_first_error
      if defined $break_at_first_error;
    $desc->{'options'}->{'exact'} = $exact
      if defined $exact;
    my $r = assert( \%ENV, $desc, \%parameters );
    if ( !$r->{'success'} ) {
        print {*STDERR} report_errors( $r->{'errors'} )
          or croak 'Cannot print errors to STDERR';
        return 0;
    }
    return 1;
}

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Env::Assert - Ensure that the environment variables match what you need, or abort.

=head1 VERSION

version 0.015

=head1 SYNOPSIS

=for :stopwords env filepath filepaths

=for test_synopsis BEGIN { die 'SKIP: no .envdesc file here' }

    use Env::Assert 'assert';
    # or:
    use Env::Assert assert => {
        envdesc_file => 'another-envdesc',
        break_at_first_error => 1,
    };

    # .envdesc file:
    # MY_VAR=.+

    # use any verified environment variable
    say $ENV{MY_VAR};

    # You can inline the envdesc file:
    use Env::Assert assert => {
        exact => 1,
        envdesc => <<'EOF'
    NUMERIC_VAR=^[[:digit:]]+$
    TIME_VAR=^\d{2}:\d{2}:\d{2}$
    EOF
    };

=head1 STATUS

Package Env::Assert is currently being developed so changes in the API are possible,
though not likely.

=head1 NOTES

Functionality of L<Env::Assert> has been moved to module L<Env::Assert::Functions> since version 0.013.
L<Env::Assert> has a different API now.

=head1 METHODS

=head2 assert_env

Read environment description, F<.envdesc> by default,
and compare current environment.

=head1 DEPENDENCIES

No external dependencies outside Perl's standard distribution.

=head1 SEE ALSO

L<Env::Dot> is a "sister" to Env::Assert.
Read environment variables from a F<.env> file directly into you program.
There is also script F<envdot> which can turn F<.env> file's content
into environment variables for different shells.

=head1 AUTHOR

Mikko Koivunalho <mikkoi@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2023 by Mikko Koivunalho.

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