While we don't know the state of pobj in portcheck, here in portgen we can assume that it's freshly extracted and so whatever permissions are on the files came from the archive.
It was pointed out by cwen@ that with PORTS_PRIVSEP=Yes, portgen fails to update devel/p5-Moose because of the permission to the extracted files and that we could detect that, set FIX_EXTRACT_PERMISSIONS and then clean and re-extract to be able to continue. It isn't entirely true that we know the state, because if you cancel a portgen run partway through and rm -r /usr/ports/mystuff there is cruft still in /usr/ports/pobj another run will find the old WRKSRC from the previous run, which had FIX_EXTRACT_PERMISSIONS applied, so this check now succeeds and we don't reset it the next time through. We could add a $self->make_clean just before the other $self->make_extract, but is it would slow things down slightly. (Sadly File::Find doesn't have a "stop finding" feature, so we just have to stop checking and prune to avoid possible permission failures inside a directory) Thoughts? OK? Index: lib/OpenBSD/PortGen/Port.pm =================================================================== RCS file: /cvs/ports/infrastructure/lib/OpenBSD/PortGen/Port.pm,v retrieving revision 1.18 diff -u -p -r1.18 Port.pm --- lib/OpenBSD/PortGen/Port.pm 12 Jun 2019 19:25:53 -0000 1.18 +++ lib/OpenBSD/PortGen/Port.pm 23 Nov 2019 21:54:24 -0000 @@ -21,6 +21,8 @@ use 5.012; use warnings; use Cwd; +use Fcntl qw( :mode ); +use File::Find qw(); use File::Path qw( make_path ); use JSON::PP; use Text::Wrap; @@ -222,6 +224,37 @@ sub set_test_deps $self->{TEST_DEPENDS} = $test_deps; } +sub set_fix_extract_permissions +{ + my ($self, $value) = @_; + + return $self->{FIX_EXTRACT_PERMISSIONS} = $value + if @_ == 2; + + my $perm_file = S_IRUSR | S_IRGRP | S_IROTH; + my $perm_dir = S_IXUSR | S_IXGRP | S_IXOTH | $perm_file; + + # Assume a cached stat on whatever mode we are checking + my $perm_ok = sub { + my $mode = ( stat _ )[2]; + return S_ISDIR($mode) + ? ($mode & $perm_dir ) == $perm_dir + : ($mode & $perm_file) == $perm_file; + }; + + my $wrksrc = $self->make_show('WRKSRC'); + + # Look through WRKSRC for files that don't have + # the necessary permissions. + my $needs_fix; + File::Find::find({ no_chdir => 1, wanted => sub { + $needs_fix = $File::Find::prune = 1 + if $needs_fix or not $perm_ok->(); + } }, $wrksrc ); + + return $self->{FIX_EXTRACT_PERMISSIONS} = $needs_fix ? 'Yes' : undef; +} + sub set_other { my ( $self, $var, $value ) = @_; @@ -536,6 +569,12 @@ sub make_port $self->make_makesum(); $self->make_checksum(); $self->make_extract(); + + if ( $self->set_fix_extract_permissions() ) { + $self->write_makefile(); + $self->make_clean(); + $self->make_extract(); + } my $wrksrc = $self->make_show('WRKSRC');