]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 530746: Create a script that converts extensions from the old format to the new...
authormkanat%bugzilla.org <>
Wed, 25 Nov 2009 01:46:35 +0000 (01:46 +0000)
committermkanat%bugzilla.org <>
Wed, 25 Nov 2009 01:46:35 +0000 (01:46 +0000)
Patch by Max Kanat-Alexander <mkanat@bugzilla.org> (module owner) a=mkanat

Bugzilla/Extension.pm
contrib/extension-convert.pl [new file with mode: 0644]
extensions/BmpConvert/Extension.pm
extensions/Example/Extension.pm

index 08d5c86c3adef4b8be806a864a7d7b5eb7ffc78f..48efd76f610b272ebff44acd619b4507b2c4e1b4 100644 (file)
@@ -281,8 +281,8 @@ For example, here's an implementation of a hook named C<foo_start>
 that gets an argument named C<bar>:
 
  sub foo_start {
-     my ($self, $params) = @_;
-     my $bar = $params->{bar};
+     my ($self, $args) = @_;
+     my $bar = $args->{bar};
      print "I got $bar!\n";
  }
 
diff --git a/contrib/extension-convert.pl b/contrib/extension-convert.pl
new file mode 100644 (file)
index 0000000..1f29db3
--- /dev/null
@@ -0,0 +1,304 @@
+#!/usr/bin/perl -w
+#
+# The contents of this file are subject to the Mozilla Public
+# License Version 1.1 (the "License"); you may not use this file
+# except in compliance with the License. You may obtain a copy of
+# the License at http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS
+# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# rights and limitations under the License.
+#
+# The Original Code is the Bugzilla Bug Tracking System.
+#
+# The Initial Developer of the Original Code is Everything Solved, Inc.
+# Portions created by the Initial Developer are Copyright (C) 2009 the
+# Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#   Max Kanat-Alexander <mkanat@bugzilla.org>
+
+use strict;
+use warnings;
+use lib qw(. lib);
+
+use Bugzilla;
+use Bugzilla::Constants;
+use Bugzilla::Util qw(trim);
+
+use File::Basename;
+use File::Copy qw(move);
+use File::Find;
+use File::Path qw(mkpath rmtree);
+
+my $from = $ARGV[0]
+  or die <<END;
+You must specify the name of the extension you are converting from,
+as the first argument.
+END
+my $extension_name = ucfirst($from);
+
+my $extdir = bz_locations()->{'extensionsdir'};
+
+my $from_dir = "$extdir/$from";
+if (!-d $from_dir) {
+    die "$from_dir does not exist.\n";
+}
+
+my $to_dir = "$extdir/$extension_name";
+if (-d $to_dir) {
+    die "$to_dir already exists, not converting.\n";
+}
+
+if (ON_WINDOWS) {
+    # There's no easy way to recursively copy a directory on Windows.
+    print "WARNING: This will modify the contents of $from_dir.\n",
+          "Press Ctrl-C to stop or any other key to continue...\n";
+    getc;
+    move($from_dir, $to_dir) 
+        || die "rename of $from_dir to $to_dir failed: $!";
+}
+else {
+    print "Copying $from_dir to $to_dir...\n";
+    system("cp", "-r", $from_dir, $to_dir);
+}
+
+# Make sure we don't accidentally modify the $from_dir anywhere else 
+# in this script.
+undef $from_dir;
+
+if (!-d $to_dir) {
+    die "$to_dir was not created.\n";
+}
+
+my $version = get_version($to_dir);
+move_template_hooks($to_dir);
+rename_module_packages($to_dir, $extension_name);
+my $install_requirements = get_install_requirements($to_dir);
+my ($modules, $subs) = code_files_to_subroutines($to_dir);
+
+my $config_pm = <<END;
+package Bugzilla::Extension::$extension_name;
+use strict;
+use constant NAME => '$extension_name';
+$install_requirements
+__PACKAGE__->NAME;
+END
+
+my $extension_pm = <<END;
+package Bugzilla::Extension::$extension_name;
+use strict;
+use base qw(Bugzilla::Extension);
+
+$modules
+
+our \$VERSION = '$version';
+
+$subs
+
+__PACKAGE__->NAME;
+END
+
+open(my $config_fh, '>', "$to_dir/Config.pm") || die "$to_dir/Config.pm: $!";
+print $config_fh $config_pm;
+close($config_fh);
+open(my $extension_fh, '>', "$to_dir/Extension.pm") 
+  || die "$to_dir/Extension.pm: $!";
+print $extension_fh $extension_pm;
+close($extension_fh);
+
+rmtree("$to_dir/code");
+unlink("$to_dir/info.pl");
+
+###############
+# Subroutines #
+###############
+
+sub rename_module_packages {
+    my ($dir, $name) = @_;
+    my $lib_dir = "$dir/lib";
+
+    # We don't want things like Bugzilla::Extension::Testopia::Testopia.
+    if (-d "$lib_dir/$name") {
+        print "Moving contents of $lib_dir/$name into $lib_dir...\n";
+        foreach my $file (glob("$lib_dir/$name/*")) {
+            my $dirname = dirname($file);
+            my $basename = basename($file);
+            rename($file, "$dirname/../$basename") || warn "$file: $!\n";
+        }
+    }
+
+    my @modules;
+    find({ wanted   => sub { $_ =~ /\.pm$/i and push(@modules, $_) }, 
+           no_chdir => 1 }, $lib_dir);
+    my %module_rename;
+    foreach my $file (@modules) {
+        open(my $fh, '<', $file) || die "$file: $!";
+        my $content = do { local $/ = undef; <$fh> };
+        close($fh);
+        if ($content =~ /^package (\S+);/m) {
+            my $package = $1;
+            my $new_name = $file;
+            $new_name =~ s/^$lib_dir\///;
+            $new_name =~ s/\.pm$//;
+            $new_name = join('::', File::Spec->splitdir($new_name));
+            $new_name = "Bugzilla::Extension::${name}::$new_name";
+            print "Renaming $package to $new_name...\n";
+            $content =~ s/^package \Q$package\E;/package \Q$new_name\E;/;
+            open(my $write_fh, '>', $file) || die "$file: $!";
+            print $write_fh $content;
+            close($write_fh);
+            $module_rename{$package} = $new_name;
+        }
+    }
+
+    print "Renaming module names inside of library and code files...\n";
+    my @code_files = glob("$dir/code/*.pl");
+    rename_modules_internally(\%module_rename, [@modules, @code_files]);
+}
+
+sub rename_modules_internally {
+    my ($rename, $files) = @_;
+
+    # We can't use \b because :: matches \b.
+    my $break = qr/^|[^\w:]|$/;
+    foreach my $file (@$files) {
+        open(my $fh, '<', $file) || die "$file: $!";
+        my $content = do { local $/ = undef; <$fh> };
+        close($fh);
+        foreach my $old_name (keys %$rename) {
+            my $new_name = $rename->{$old_name};
+            $content =~ s/($break)\Q$old_name\E($break)/$1$new_name$2/gms;
+        }
+        open(my $write_fh, '>', $file) || die "$file: $!";
+        print $write_fh $content;
+        close($write_fh);
+    }
+}
+
+sub get_version {
+    my ($dir) = @_;
+    print "Getting version info from info.pl...\n";
+    my $info;
+    {
+        local @INC = ("$dir/lib", @INC);
+        $info = do "$dir/info.pl"; die $@ if $@;
+    }
+    return $info->{version};
+}
+
+sub get_install_requirements {
+    my ($dir) = @_;
+    my $file = "$dir/code/install-requirements.pl";
+    return '' if !-f $file;
+
+    print "Moving install-requirements.pl code into Config.pm...\n";
+    my ($modules, $code) = process_code_file($file);
+    $modules = join('', @$modules);
+    $code = join('', @$code);
+    if ($modules) {
+        return "$modules\n\n$code";
+    }
+    return $code;
+}
+
+sub process_code_file {
+    my ($file) = @_;
+    open(my $fh, '<', $file) || die "$file: $!";
+    my $stuff_started;
+    my (@modules, @code);
+    foreach my $line (<$fh>) {
+        $stuff_started = 1 if $line !~ /^#/;
+        next if !$stuff_started;
+        next if $line =~ /^use (warnings|strict|lib|Bugzilla)[^\w:]/;
+        if ($line =~ /^(?:use|require)\b/) {
+            push(@modules, $line);
+        }
+        else {
+            push(@code, $line);
+        }
+    }
+    close $fh;
+    return (\@modules, \@code);
+}
+
+sub code_files_to_subroutines {
+    my ($dir) = @_;
+
+    my @dir_files = glob("$dir/code/*.pl");
+    my (@all_modules, @subroutines);
+    foreach my $file (@dir_files) {
+        next if $file =~ /install-requirements/;
+        print "Moving $file code into Extension.pm...\n";
+        my ($modules, $code) = process_code_file($file);
+        my @code_lines = map { "    $_" } @$code;
+        my $code_string = join('', @code_lines);
+        $code_string =~ s/Bugzilla->hook_args/\$args/g;
+        $code_string =~ s/my\s+\$args\s+=\s+\$args;//gs;
+        chomp($code_string);
+        push(@all_modules, @$modules);
+        my $name = basename($file);
+        $name =~ s/-/_/;
+        $name =~ s/\.pl$//;
+
+        my $subroutine = <<END;
+sub $name {
+    my (\$self, \$args) = \@_;
+$code_string
+}
+END
+        push(@subroutines, $subroutine);
+    }
+
+    my %seen_modules = map { trim($_) => 1 } @all_modules;
+    my $module_string = join("\n", sort keys %seen_modules);
+    my $subroutine_string = join("\n", @subroutines);
+    return ($module_string, $subroutine_string);
+}
+
+sub move_template_hooks {
+    my ($dir) = @_;
+    foreach my $lang (glob("$dir/template/*")) {
+        next if !_file_matters($lang);
+        mkpath("$lang/hook") || die "$lang/hook: $!";
+        # Hooks can be in all sorts of weird places, including
+        # template/default/hook.
+        foreach my $hooks_container ($lang, "$lang/default/hook") {
+            foreach my $file (glob("$hooks_container/*")) {
+                next if !_file_matters($file, 1);
+                my $dirname = basename($file);
+                print "Moving $file to $lang/hook/$dirname...\n";
+                rename($file, "$lang/hook/$dirname") || die "move failed: $!";
+            }
+        }
+    }
+}
+
+sub _file_matters {
+     my ($path, $tmpl) = @_;
+     my @ignore = qw(default custom CVS hook);
+     my $file = basename($path);
+     return 0 if grep(lc($_) eq lc($file), @ignore);
+      # Hidden files
+     return 0 if $file =~ /^\./;
+     if ($tmpl) {
+         return 1 if $file =~ /\.tmpl$/;
+     }
+     return 0 if !-d $path;
+     return 1;
+}
+
+__END__
+
+=head1 NAME
+
+extension-convert.pl - Convert extensions from the pre-3.6 format to the 
+3.6 format.
+
+=head1 SYNOPSIS
+
+ contrib/extension-convert.pl name
+
+ Converts an extension in the F<extensions/> directory into the new
+ extension layout for Bugzilla 3.6.
index 29113bd08071e2d5f55be259c438de1c7f74894e..ee08e04f079d47bf190e07b7ede75ed940323730 100644 (file)
@@ -29,10 +29,10 @@ use Image::Magick;
 our $VERSION = '1.0';
 
 sub attachment_process_data {
-    my ($self, $params) = @_;
-    return unless $params->{attributes}->{mimetype} eq 'image/bmp';
+    my ($self, $args) = @_;
+    return unless $args->{attributes}->{mimetype} eq 'image/bmp';
 
-    my $data = ${$params->{data}};
+    my $data = ${$args->{data}};
     my $img = Image::Magick->new(magick => 'bmp');
 
     # $data is a filehandle.
@@ -49,9 +49,9 @@ sub attachment_process_data {
     }
     undef $img;
 
-    ${$params->{data}} = $data;
-    $params->{attributes}->{mimetype} = 'image/png';
-    $params->{attributes}->{filename} =~ s/^(.+)\.bmp$/$1.png/i;
+    ${$args->{data}} = $data;
+    $args->{attributes}->{mimetype} = 'image/png';
+    $args->{attributes}->{filename} =~ s/^(.+)\.bmp$/$1.png/i;
 }
 
  __PACKAGE__->NAME;
index 290867e0dfdb1970726dc19a5c032cea84ab6796..425fdfb18667c6da0b5032837b52a079d14466af 100644 (file)
@@ -35,9 +35,9 @@ use Data::Dumper;
 our $VERSION = '1.0';
 
 sub attachment_process_data {
-    my ($self, $params) = @_;
-    my $type     = $params->{attributes}->{mimetype};
-    my $filename = $params->{attributes}->{filename};
+    my ($self, $args) = @_;
+    my $type     = $args->{attributes}->{mimetype};
+    my $filename = $args->{attributes}->{filename};
 
     # Make sure images have the correct extension.
     # Uncomment the two lines below to make this check effective.
@@ -45,44 +45,44 @@ sub attachment_process_data {
         my $format = $1;
         if ($filename =~ /^(.+)(:?\.[^\.]+)$/) {
             my $name = $1;
-            #$params->{attributes}->{filename} = "${name}.$format";
+            #$args->{attributes}->{filename} = "${name}.$format";
         }
         else {
             # The file has no extension. We append it.
-            #$params->{attributes}->{filename} .= ".$format";
+            #$args->{attributes}->{filename} .= ".$format";
         }
     }
 }
 
 sub auth_login_methods {
-    my ($self, $params) = @_;
-    my $modules = $params->{modules};
+    my ($self, $args) = @_;
+    my $modules = $args->{modules};
     if (exists $modules->{Example}) {
         $modules->{Example} = 'Bugzilla/Extension/Example/Auth/Login.pm';
     }
 }
 
 sub auth_verify_methods {
-    my ($self, $params) = @_;
-    my $modules = $params->{modules};
+    my ($self, $args) = @_;
+    my $modules = $args->{modules};
     if (exists $modules->{Example}) {
         $modules->{Example} = 'Bugzilla/Extension/Example/Auth/Verify.pm';
     }
 }
 
 sub bug_columns {
-    my ($self, $params) = @_;
-    my $columns = $params->{'columns'};
+    my ($self, $args) = @_;
+    my $columns = $args->{'columns'};
     push (@$columns, "delta_ts AS example")
 }
 
 sub bug_end_of_create {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
 
     # This code doesn't actually *do* anything, it's just here to show you
     # how to use this hook.
-    my $bug = $params->{'bug'};
-    my $timestamp = $params->{'timestamp'};
+    my $bug = $args->{'bug'};
+    my $timestamp = $args->{'timestamp'};
     
     my $bug_id = $bug->id;
     # Uncomment this line to see a line in your webserver's error log whenever
@@ -91,11 +91,11 @@ sub bug_end_of_create {
 }
 
 sub bug_end_of_create_validators {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
     # This code doesn't actually *do* anything, it's just here to show you
     # how to use this hook.
-    my $bug_params = $params->{'params'};
+    my $bug_params = $args->{'params'};
     
     # Uncomment this line below to see a line in your webserver's error log
     # containing all validated bug field values every time you file a bug.
@@ -107,11 +107,11 @@ sub bug_end_of_create_validators {
 }
 
 sub bug_end_of_update {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
     # This code doesn't actually *do* anything, it's just here to show you
     # how to use this hook.
-    my ($bug, $timestamp, $changes) = @$params{qw(bug timestamp changes)};
+    my ($bug, $timestamp, $changes) = @$args{qw(bug timestamp changes)};
     
     foreach my $field (keys %$changes) {
         my $used_to_be = $changes->{$field}->[0];
@@ -140,19 +140,19 @@ sub bug_end_of_update {
 }
 
 sub bug_fields {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
 
-    my $fields = $params->{'fields'};
+    my $fields = $args->{'fields'};
     push (@$fields, "example")
 }
 
 sub bug_format_comment {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
     # This replaces every occurrence of the word "foo" with the word
     # "bar"
     
-    my $regexes = $params->{'regexes'};
+    my $regexes = $args->{'regexes'};
     push(@$regexes, { match => qr/\bfoo\b/, replace => 'bar' });
     
     # And this links every occurrence of the word "bar" to example.com,
@@ -168,48 +168,48 @@ sub bug_format_comment {
 
 # Used by bug_format_comment--see its code for an explanation.
 sub _replace_bar {
-    my $params = shift;
+    my $args = shift;
     # $match is the first parentheses match in the $bar_match regex 
     # in bug-format_comment.pl. We get up to 10 regex matches as 
     # arguments to this function.
-    my $match = $params->{matches}->[0];
+    my $match = $args->{matches}->[0];
     # Remember, you have to HTML-escape any data that you are returning!
     $match = html_quote($match);
     return qq{<a href="http://example.com/">$match</a>};
 };
 
 sub buglist_columns {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my $columns = $params->{'columns'};
+    my $columns = $args->{'columns'};
     $columns->{'example'} = { 'name' => 'bugs.delta_ts' , 'title' => 'Example' };
 }
 
 sub colchange_columns {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my $columns = $params->{'columns'};
+    my $columns = $args->{'columns'};
     push (@$columns, "example")
 }
 
 sub config {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
 
-    my $config = $params->{config};
+    my $config = $args->{config};
     $config->{Example} = "Bugzilla::Extension::Example::Config";
 }
 
 sub config_add_panels {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my $modules = $params->{panel_modules};
+    my $modules = $args->{panel_modules};
     $modules->{Example} = "Bugzilla::Extension::Example::Config";
 }
 
 sub config_modify_panels {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my $panels = $params->{panels};
+    my $panels = $args->{panels};
     
     # Add the "Example" auth methods.
     my $auth_params = $panels->{'auth'}->{params};
@@ -221,11 +221,11 @@ sub config_modify_panels {
 }
 
 sub flag_end_of_update {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
     # This code doesn't actually *do* anything, it's just here to show you
     # how to use this hook.
-    my $flag_params = $params;
+    my $flag_params = $args;
     my ($object, $timestamp, $old_flags, $new_flags) =
         @$flag_params{qw(object timestamp old_flags new_flags)};
     my ($removed, $added) = diff_arrays($old_flags, $new_flags);
@@ -244,14 +244,14 @@ sub flag_end_of_update {
 }
 
 sub install_before_final_checks {
-    my ($self, $params) = @_;
-    print "Install-before_final_checks hook\n" unless $params->{silent};
+    my ($self, $args) = @_;
+    print "Install-before_final_checks hook\n" unless $args->{silent};
 }
 
 sub mailer_before_send {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my $email = $params->{email};
+    my $email = $args->{email};
     # If you add a header to an email, it's best to start it with
     # 'X-Bugzilla-<Extension>' so that you don't conflict with
     # other extensions.
@@ -259,10 +259,10 @@ sub mailer_before_send {
 }
 
 sub object_before_create {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my $class = $params->{'class'};
-    my $object_params = $params->{'params'};
+    my $class = $args->{'class'};
+    my $object_params = $args->{'params'};
     
     # Note that this is a made-up class, for this example.
     if ($class->isa('Bugzilla::ExampleObject')) {
@@ -273,9 +273,9 @@ sub object_before_create {
 }
 
 sub object_before_set {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my ($object, $field, $value) = @$params{qw(object field value)};
+    my ($object, $field, $value) = @$args{qw(object field value)};
     
     # Note that this is a made-up class, for this example.
     if ($object->isa('Bugzilla::ExampleObject')) {
@@ -285,10 +285,10 @@ sub object_before_set {
 }
 
 sub object_end_of_create_validators {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my $class = $params->{'class'};
-    my $object_params = $params->{'params'};
+    my $class = $args->{'class'};
+    my $object_params = $args->{'params'};
     
     # Note that this is a made-up class, for this example.
     if ($class->isa('Bugzilla::ExampleObject')) {
@@ -299,10 +299,10 @@ sub object_end_of_create_validators {
 }
 
 sub object_end_of_set_all {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my $object = $params->{'class'};
-    my $object_params = $params->{'params'};
+    my $object = $args->{'class'};
+    my $object_params = $args->{'params'};
     
     # Note that this is a made-up class, for this example.
     if ($object->isa('Bugzilla::ExampleObject')) {
@@ -314,10 +314,10 @@ sub object_end_of_set_all {
 }
 
 sub object_end_of_update {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
     my ($object, $old_object, $changes) = 
-        @$params{qw(object old_object changes)};
+        @$args{qw(object old_object changes)};
     
     # Note that this is a made-up class, for this example.
     if ($object->isa('Bugzilla::ExampleObject')) {
@@ -329,9 +329,9 @@ sub object_end_of_update {
 }
 
 sub page_before_template {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my ($vars, $page) = @$params{qw(vars page_id)};
+    my ($vars, $page) = @$args{qw(vars page_id)};
     
     # You can see this hook in action by loading page.cgi?id=example.html
     if ($page eq 'example.html') {
@@ -340,19 +340,19 @@ sub page_before_template {
 }
 
 sub product_confirm_delete {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my $vars = $params->{vars};
+    my $vars = $args->{vars};
     $vars->{'example'} = 1;
 }
 
 sub sanitycheck_check {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
     my $dbh = Bugzilla->dbh;
     my $sth;
     
-    my $status = $params->{'status'};
+    my $status = $args->{'status'};
     
     # Check that all users are Australian
     $status->('example_check_au_user');
@@ -374,12 +374,12 @@ sub sanitycheck_check {
 }
 
 sub sanitycheck_repair {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
     my $cgi = Bugzilla->cgi;
     my $dbh = Bugzilla->dbh;
     
-    my $status = $params->{'status'};
+    my $status = $args->{'status'};
     
     if ($cgi->param('example_repair_au_user')) {
         $status->('example_repair_au_user_start');
@@ -393,9 +393,9 @@ sub sanitycheck_repair {
 }
 
 sub template_before_create {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my $config = $params->{'config'};
+    my $config = $args->{'config'};
     # This will be accessible as "example_global_variable" in every
     # template in Bugzilla. See Bugzilla/Template.pm's create() function
     # for more things that you can set.
@@ -403,9 +403,9 @@ sub template_before_create {
 }
 
 sub template_before_process {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my ($vars, $file, $template) = @$params{qw(vars file template)};
+    my ($vars, $file, $template) = @$args{qw(vars file template)};
     
     $vars->{'example'} = 1;
     
@@ -415,16 +415,16 @@ sub template_before_process {
 }
 
 sub webservice {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
 
-    my $dispatch = $params->{dispatch};
+    my $dispatch = $args->{dispatch};
     $dispatch->{Example} = "Bugzilla::Extension::Example::WebService";
 }
 
 sub webservice_error_codes {
-    my ($self, $params) = @_;
+    my ($self, $args) = @_;
     
-    my $error_map = $params->{error_map};
+    my $error_map = $args->{error_map};
     $error_map->{'example_my_error'} = 10001;
 }