[Bps-public-commit] RT-Extension-MandatoryOnTransition branch, support-coreroles-and-customroles, updated. 0.17-4-g1ecb623
Craig Kaiser
craig at bestpractical.com
Mon Jan 7 08:49:25 EST 2019
The branch, support-coreroles-and-customroles has been updated
via 1ecb623d131fe5d4530d0b6dfb172deda91f1b30 (commit)
from 9b18d2564f6b96ae363610f60f4129677e4ba0e6 (commit)
Summary of changes:
README | 14 ++-
inc/Module/Install/Can.pm | 163 ------------------------------
inc/Module/Install/Fetch.pm | 93 -----------------
inc/Module/Install/Substitute.pm | 131 ------------------------
inc/Module/Install/Win32.pm | 64 ------------
inc/Module/Install/WriteAll.pm | 63 ------------
lib/RT/Extension/MandatoryOnTransition.pm | 18 +++-
7 files changed, 29 insertions(+), 517 deletions(-)
delete mode 100644 inc/Module/Install/Can.pm
delete mode 100644 inc/Module/Install/Fetch.pm
delete mode 100644 inc/Module/Install/Substitute.pm
delete mode 100644 inc/Module/Install/Win32.pm
delete mode 100644 inc/Module/Install/WriteAll.pm
- Log -----------------------------------------------------------------
commit 1ecb623d131fe5d4530d0b6dfb172deda91f1b30
Author: Craig Kaiser <craig at bestpractical.com>
Date: Mon Jan 7 08:47:46 2019 -0500
Update README and inc files
diff --git a/README b/README
index ad7e034..80db750 100644
--- a/README
+++ b/README
@@ -96,7 +96,7 @@ CONFIGURATION
Set( %MandatoryOnTransition,
'QueueName' => {
- 'from -> to' => [ 'BasicField', 'CF.MyField', ],
+ 'from -> to' => [ 'BasicField', 'CF.MyField', 'CustomRole.MyRole' ],
},
);
@@ -125,6 +125,18 @@ CONFIGURATION
The transition syntax is similar to that found in RT's Lifecycles. See
perldoc /opt/rt4/etc/RT_Config.pm.
+ Requiring role values
+ You can require any core or custom role on a RT::Ticket object, further
+ more you can require a 'group' category to check that at least one value
+ for that role is a member of the required group. In the below example we
+ require that the custom role 'customer' have a user value who is a
+ member of the group 'Customers' and the owner of the ticket must be a
+ member of the group 'Helpdesk'.
+
+ Set( %MandatoryOnTransition, 'General' => { 'CustomRole.customer' => {
+ transition => 'open -> *', group => 'Customers' }, 'Owner' => {
+ transition => 'open -> *', group => 'Helpdesk' }, }, );
+
Restrictions on Queue Transitions
The default behavior for MandatoryOnTransition operates on status
transitions, so a change from new to open or from open to resolved. It
diff --git a/inc/Module/Install/Can.pm b/inc/Module/Install/Can.pm
deleted file mode 100644
index d65c753..0000000
--- a/inc/Module/Install/Can.pm
+++ /dev/null
@@ -1,163 +0,0 @@
-#line 1
-package Module::Install::Can;
-
-use strict;
-use Config ();
-use ExtUtils::MakeMaker ();
-use Module::Install::Base ();
-
-use vars qw{$VERSION @ISA $ISCORE};
-BEGIN {
- $VERSION = '1.19';
- @ISA = 'Module::Install::Base';
- $ISCORE = 1;
-}
-
-# check if we can load some module
-### Upgrade this to not have to load the module if possible
-sub can_use {
- my ($self, $mod, $ver) = @_;
- $mod =~ s{::|\\}{/}g;
- $mod .= '.pm' unless $mod =~ /\.pm$/i;
-
- my $pkg = $mod;
- $pkg =~ s{/}{::}g;
- $pkg =~ s{\.pm$}{}i;
-
- local $@;
- eval { require $mod; $pkg->VERSION($ver || 0); 1 };
-}
-
-# Check if we can run some command
-sub can_run {
- my ($self, $cmd) = @_;
-
- my $_cmd = $cmd;
- return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd));
-
- for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') {
- next if $dir eq '';
- require File::Spec;
- my $abs = File::Spec->catfile($dir, $cmd);
- return $abs if (-x $abs or $abs = MM->maybe_command($abs));
- }
-
- return;
-}
-
-# Can our C compiler environment build XS files
-sub can_xs {
- my $self = shift;
-
- # Ensure we have the CBuilder module
- $self->configure_requires( 'ExtUtils::CBuilder' => 0.27 );
-
- # Do we have the configure_requires checker?
- local $@;
- eval "require ExtUtils::CBuilder;";
- if ( $@ ) {
- # They don't obey configure_requires, so it is
- # someone old and delicate. Try to avoid hurting
- # them by falling back to an older simpler test.
- return $self->can_cc();
- }
-
- # Do we have a working C compiler
- my $builder = ExtUtils::CBuilder->new(
- quiet => 1,
- );
- unless ( $builder->have_compiler ) {
- # No working C compiler
- return 0;
- }
-
- # Write a C file representative of what XS becomes
- require File::Temp;
- my ( $FH, $tmpfile ) = File::Temp::tempfile(
- "compilexs-XXXXX",
- SUFFIX => '.c',
- );
- binmode $FH;
- print $FH <<'END_C';
-#include "EXTERN.h"
-#include "perl.h"
-#include "XSUB.h"
-
-int main(int argc, char **argv) {
- return 0;
-}
-
-int boot_sanexs() {
- return 1;
-}
-
-END_C
- close $FH;
-
- # Can the C compiler access the same headers XS does
- my @libs = ();
- my $object = undef;
- eval {
- local $^W = 0;
- $object = $builder->compile(
- source => $tmpfile,
- );
- @libs = $builder->link(
- objects => $object,
- module_name => 'sanexs',
- );
- };
- my $result = $@ ? 0 : 1;
-
- # Clean up all the build files
- foreach ( $tmpfile, $object, @libs ) {
- next unless defined $_;
- 1 while unlink;
- }
-
- return $result;
-}
-
-# Can we locate a (the) C compiler
-sub can_cc {
- my $self = shift;
-
- if ($^O eq 'VMS') {
- require ExtUtils::CBuilder;
- my $builder = ExtUtils::CBuilder->new(
- quiet => 1,
- );
- return $builder->have_compiler;
- }
-
- my @chunks = split(/ /, $Config::Config{cc}) or return;
-
- # $Config{cc} may contain args; try to find out the program part
- while (@chunks) {
- return $self->can_run("@chunks") || (pop(@chunks), next);
- }
-
- return;
-}
-
-# Fix Cygwin bug on maybe_command();
-if ( $^O eq 'cygwin' ) {
- require ExtUtils::MM_Cygwin;
- require ExtUtils::MM_Win32;
- if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) {
- *ExtUtils::MM_Cygwin::maybe_command = sub {
- my ($self, $file) = @_;
- if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) {
- ExtUtils::MM_Win32->maybe_command($file);
- } else {
- ExtUtils::MM_Unix->maybe_command($file);
- }
- }
- }
-}
-
-1;
-
-__END__
-
-#line 245
diff --git a/inc/Module/Install/Fetch.pm b/inc/Module/Install/Fetch.pm
deleted file mode 100644
index 3072b08..0000000
--- a/inc/Module/Install/Fetch.pm
+++ /dev/null
@@ -1,93 +0,0 @@
-#line 1
-package Module::Install::Fetch;
-
-use strict;
-use Module::Install::Base ();
-
-use vars qw{$VERSION @ISA $ISCORE};
-BEGIN {
- $VERSION = '1.19';
- @ISA = 'Module::Install::Base';
- $ISCORE = 1;
-}
-
-sub get_file {
- my ($self, %args) = @_;
- my ($scheme, $host, $path, $file) =
- $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return;
-
- if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) {
- $args{url} = $args{ftp_url}
- or (warn("LWP support unavailable!\n"), return);
- ($scheme, $host, $path, $file) =
- $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return;
- }
-
- $|++;
- print "Fetching '$file' from $host... ";
-
- unless (eval { require Socket; Socket::inet_aton($host) }) {
- warn "'$host' resolve failed!\n";
- return;
- }
-
- return unless $scheme eq 'ftp' or $scheme eq 'http';
-
- require Cwd;
- my $dir = Cwd::getcwd();
- chdir $args{local_dir} or return if exists $args{local_dir};
-
- if (eval { require LWP::Simple; 1 }) {
- LWP::Simple::mirror($args{url}, $file);
- }
- elsif (eval { require Net::FTP; 1 }) { eval {
- # use Net::FTP to get past firewall
- my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600);
- $ftp->login("anonymous", 'anonymous at example.com');
- $ftp->cwd($path);
- $ftp->binary;
- $ftp->get($file) or (warn("$!\n"), return);
- $ftp->quit;
- } }
- elsif (my $ftp = $self->can_run('ftp')) { eval {
- # no Net::FTP, fallback to ftp.exe
- require FileHandle;
- my $fh = FileHandle->new;
-
- local $SIG{CHLD} = 'IGNORE';
- unless ($fh->open("|$ftp -n")) {
- warn "Couldn't open ftp: $!\n";
- chdir $dir; return;
- }
-
- my @dialog = split(/\n/, <<"END_FTP");
-open $host
-user anonymous anonymous\@example.com
-cd $path
-binary
-get $file $file
-quit
-END_FTP
- foreach (@dialog) { $fh->print("$_\n") }
- $fh->close;
- } }
- else {
- warn "No working 'ftp' program available!\n";
- chdir $dir; return;
- }
-
- unless (-f $file) {
- warn "Fetching failed: $@\n";
- chdir $dir; return;
- }
-
- return if exists $args{size} and -s $file != $args{size};
- system($args{run}) if exists $args{run};
- unlink($file) if $args{remove};
-
- print(((!exists $args{check_for} or -e $args{check_for})
- ? "done!" : "failed! ($!)"), "\n");
- chdir $dir; return !$?;
-}
-
-1;
diff --git a/inc/Module/Install/Substitute.pm b/inc/Module/Install/Substitute.pm
deleted file mode 100644
index 56af7fe..0000000
--- a/inc/Module/Install/Substitute.pm
+++ /dev/null
@@ -1,131 +0,0 @@
-#line 1
-package Module::Install::Substitute;
-
-use strict;
-use warnings;
-use 5.008; # I don't care much about earlier versions
-
-use Module::Install::Base;
-our @ISA = qw(Module::Install::Base);
-
-our $VERSION = '0.03';
-
-require File::Temp;
-require File::Spec;
-require Cwd;
-
-#line 89
-
-sub substitute
-{
- my $self = shift;
- $self->{__subst} = shift;
- $self->{__option} = {};
- if( UNIVERSAL::isa( $_[0], 'HASH' ) ) {
- my $opts = shift;
- while( my ($k,$v) = each( %$opts ) ) {
- $self->{__option}->{ lc( $k ) } = $v || '';
- }
- }
- $self->_parse_options;
-
- my @file = @_;
- foreach my $f (@file) {
- $self->_rewrite_file( $f );
- }
-
- return;
-}
-
-sub _parse_options
-{
- my $self = shift;
- my $cwd = Cwd::getcwd();
- foreach my $t ( qw(from to) ) {
- $self->{__option}->{$t} = $cwd unless $self->{__option}->{$t};
- my $d = $self->{__option}->{$t};
- die "Couldn't read directory '$d'" unless -d $d && -r _;
- }
-}
-
-sub _rewrite_file
-{
- my ($self, $file) = @_;
- my $source = File::Spec->catfile( $self->{__option}{from}, $file );
- $source .= $self->{__option}{sufix} if $self->{__option}{sufix};
- unless( -f $source && -r _ ) {
- print STDERR "Couldn't find file '$source'\n";
- return;
- }
- my $dest = File::Spec->catfile( $self->{__option}{to}, $file );
- return $self->__rewrite_file( $source, $dest );
-}
-
-sub __rewrite_file
-{
- my ($self, $source, $dest) = @_;
-
- my $mode = (stat($source))[2];
-
- open my $sfh, "<$source" or die "Couldn't open '$source' for read";
- print "Open input '$source' file for substitution\n";
-
- my ($tmpfh, $tmpfname) = File::Temp::tempfile('mi-subst-XXXX', UNLINK => 1);
- $self->__process_streams( $sfh, $tmpfh, ($source eq $dest)? 1: 0 );
- close $sfh;
-
- seek $tmpfh, 0, 0 or die "Couldn't seek in tmp file";
-
- open my $dfh, ">$dest" or die "Couldn't open '$dest' for write";
- print "Open output '$dest' file for substitution\n";
-
- while( <$tmpfh> ) {
- print $dfh $_;
- }
- close $dfh;
- chmod $mode, $dest or "Couldn't change mode on '$dest'";
-}
-
-sub __process_streams
-{
- my ($self, $in, $out, $replace) = @_;
-
- my @queue = ();
- my $subst = $self->{'__subst'};
- my $re_subst = join('|', map {"\Q$_"} keys %{ $subst } );
-
- while( my $str = <$in> ) {
- if( $str =~ /^###\s*(before|replace|after)\:\s?(.*)$/s ) {
- my ($action, $nstr) = ($1,$2);
- $nstr =~ s/\@($re_subst)\@/$subst->{$1}/ge;
-
- die "Replace action is bad idea for situations when dest is equal to source"
- if $replace && $action eq 'replace';
- if( $action eq 'before' ) {
- die "no line before 'before' action" unless @queue;
- # overwrite prev line;
- pop @queue;
- push @queue, $nstr;
- push @queue, $str;
- } elsif( $action eq 'replace' ) {
- push @queue, $nstr;
- } elsif( $action eq 'after' ) {
- push @queue, $str;
- push @queue, $nstr;
- # skip one line;
- <$in>;
- }
- } else {
- push @queue, $str;
- }
- while( @queue > 3 ) {
- print $out shift(@queue);
- }
- }
- while( scalar @queue ) {
- print $out shift(@queue);
- }
-}
-
-1;
-
diff --git a/inc/Module/Install/Win32.pm b/inc/Module/Install/Win32.pm
deleted file mode 100644
index f7aa615..0000000
--- a/inc/Module/Install/Win32.pm
+++ /dev/null
@@ -1,64 +0,0 @@
-#line 1
-package Module::Install::Win32;
-
-use strict;
-use Module::Install::Base ();
-
-use vars qw{$VERSION @ISA $ISCORE};
-BEGIN {
- $VERSION = '1.19';
- @ISA = 'Module::Install::Base';
- $ISCORE = 1;
-}
-
-# determine if the user needs nmake, and download it if needed
-sub check_nmake {
- my $self = shift;
- $self->load('can_run');
- $self->load('get_file');
-
- require Config;
- return unless (
- $^O eq 'MSWin32' and
- $Config::Config{make} and
- $Config::Config{make} =~ /^nmake\b/i and
- ! $self->can_run('nmake')
- );
-
- print "The required 'nmake' executable not found, fetching it...\n";
-
- require File::Basename;
- my $rv = $self->get_file(
- url => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe',
- ftp_url => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe',
- local_dir => File::Basename::dirname($^X),
- size => 51928,
- run => 'Nmake15.exe /o > nul',
- check_for => 'Nmake.exe',
- remove => 1,
- );
-
- die <<'END_MESSAGE' unless $rv;
-
--------------------------------------------------------------------------------
-
-Since you are using Microsoft Windows, you will need the 'nmake' utility
-before installation. It's available at:
-
- http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe
- or
- ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe
-
-Please download the file manually, save it to a directory in %PATH% (e.g.
-C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to
-that directory, and run "Nmake15.exe" from there; that will create the
-'nmake.exe' file needed by this module.
-
-You may then resume the installation process described in README.
-
--------------------------------------------------------------------------------
-END_MESSAGE
-
-}
-
-1;
diff --git a/inc/Module/Install/WriteAll.pm b/inc/Module/Install/WriteAll.pm
deleted file mode 100644
index 2db861a..0000000
--- a/inc/Module/Install/WriteAll.pm
+++ /dev/null
@@ -1,63 +0,0 @@
-#line 1
-package Module::Install::WriteAll;
-
-use strict;
-use Module::Install::Base ();
-
-use vars qw{$VERSION @ISA $ISCORE};
-BEGIN {
- $VERSION = '1.19';
- @ISA = qw{Module::Install::Base};
- $ISCORE = 1;
-}
-
-sub WriteAll {
- my $self = shift;
- my %args = (
- meta => 1,
- sign => 0,
- inline => 0,
- check_nmake => 1,
- @_,
- );
-
- $self->sign(1) if $args{sign};
- $self->admin->WriteAll(%args) if $self->is_admin;
-
- $self->check_nmake if $args{check_nmake};
- unless ( $self->makemaker_args->{PL_FILES} ) {
- # XXX: This still may be a bit over-defensive...
- unless ($self->makemaker(6.25)) {
- $self->makemaker_args( PL_FILES => {} ) if -f 'Build.PL';
- }
- }
-
- # Until ExtUtils::MakeMaker support MYMETA.yml, make sure
- # we clean it up properly ourself.
- $self->realclean_files('MYMETA.yml');
-
- if ( $args{inline} ) {
- $self->Inline->write;
- } else {
- $self->Makefile->write;
- }
-
- # The Makefile write process adds a couple of dependencies,
- # so write the META.yml files after the Makefile.
- if ( $args{meta} ) {
- $self->Meta->write;
- }
-
- # Experimental support for MYMETA
- if ( $ENV{X_MYMETA} ) {
- if ( $ENV{X_MYMETA} eq 'JSON' ) {
- $self->Meta->write_mymeta_json;
- } else {
- $self->Meta->write_mymeta_yaml;
- }
- }
-
- return 1;
-}
-
-1;
diff --git a/lib/RT/Extension/MandatoryOnTransition.pm b/lib/RT/Extension/MandatoryOnTransition.pm
index 425999c..3eb01b2 100644
--- a/lib/RT/Extension/MandatoryOnTransition.pm
+++ b/lib/RT/Extension/MandatoryOnTransition.pm
@@ -146,17 +146,31 @@ Category selection before resolving tickets in every other queue.
Set( %MandatoryOnTransition,
Helpdesk => {
- '* -> resolved' => ['TimeWorked', 'CF.Resolution', 'CustomRole.Analyst'],
+ '* -> resolved' => ['TimeWorked', 'CF.Resolution'],
},
'*' => {
'* -> resolved' => ['CF.Category'],
- 'CustomRole.Analyst' => {transition => '* -> open', group => 'Engineering'},
},
);
The transition syntax is similar to that found in RT's Lifecycles. See
C<perldoc /opt/rt4/etc/RT_Config.pm>.
+=head2 Requiring role values
+
+You can require any core or custom role on a RT::Ticket object, further more
+you can require a 'group' category to check that at least one value for that
+role is a member of the required group. In the below example we require that
+the custom role 'customer' have a user value who is a member of the group 'Customers'
+and the owner of the ticket must be a member of the group 'Helpdesk'.
+
+Set( %MandatoryOnTransition,
+ 'General' => {
+ 'CustomRole.customer' => { transition => 'open -> *', group => 'Customers' },
+ 'Owner' => { transition => 'open -> *', group => 'Helpdesk' },
+ },
+);
+
=head2 Restrictions on Queue Transitions
The default behavior for C<MandatoryOnTransition> operates on status transitions,
-----------------------------------------------------------------------
More information about the Bps-public-commit
mailing list