On Tue, Nov 05, 2024 at 07:44:59PM +0100, Matthieu Herrb wrote:
> On Sun, Nov 03, 2024 at 02:11:12PM +0100, Marc Espie wrote:
> > Here's a second version that actually works with multiple parameters,
> > is way more specific at telling you where badly-placed variables should be,
> > and also knows a heck of a lot more about existing variables.
> 
> Hmm
> 
> Makefile: SITES late (should be before SITES)
> 
> with the following (ugly) Makefile from my xenoport project
> 
> 
> COMMENT = library providing the VESA CVT standard modelines generator
> 
> DISTNAME =      libxcvt-0.1.1
> 
> SHARED_LIBS =           xcvt 0.0
> CATEGORIES =    devel x11
> HOMEPAGE =      https://gitlab.freedesktop.org/xorg/lib/libxfont
> 
> MAINTAINER =    xenoc...@openbsd.org
> 
> # MIT
> PERMIT_PACKAGE =        Yes
> 
> WANTLIB =      c m
> 
> EXTRACT_SUFX = .tar.xz
> 
> MODULES =    devel/meson xenocara
> 
> SITES =         ${SITE_XORG:=lib/}
> 
> .include <bsd.port.mk>
> 
> -- 
> Matthieu Herrb
> 
> 

Funny !!! SITES is mentioned several times in Makefile.template

Here's a version of port-var-check that fixes this (twice)
deduplicating Makefile.template variables AND protecting against issues.

It also figures out Makefile.inc and checks it for the right order as well

Along with a manpage.

I believe this could be useful for "trivial" ports and hence should be
committed

(Obviously with a + in the share/man/man1/Makefile as well
#! /usr/bin/perl
# ex:ts=8 sw=4:
# $OpenBSD$
#
# Copyright (c) 2024 Marc Espie <es...@openbsd.org>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
use v5.36;
use File::Basename;

my $portsdir = $ENV{PORTSDIR} // '/usr/ports';
my $rc = 0;

# all variables we know that don't appear in Makefile.template
my @unreg = (qw(GH_ACCOUNT GH_COMMIT GH_PROJECT GH_TAGNAME V
    REVISION EPOCH REVISION-* EPOCH-* TEST_ENV
    FIX_EXTRACT_PERMISSIONS CFLAGS CXXFLAGS LDSTATIC
    PORTROACH MULTI_PACKAGES));

my $unreg = {map {($_, 1)} @unreg};

my @wantdash = (qw(BROKEN WANTLIB LIB_DEPENDS RUN_DEPENDS
    PERMIT_PACKAGE PKG_ARCH ONLY_FOR_ARCHS NOT_FOR_ARCHS));
my $wantdash = {map {($_, 1)} @wantdash};

sub read_order($file)
{
        my @list;
        open my $f, "<", $file or return;
        while (<$f>) {
                chomp;
                if (m/^([A-Z0-9_]+(:?\-[a-zA-Z0-9_]*)?)\s*\+?\=/) {
                        push(@list, $1);
                } elsif (m/^\#\s*([A-Z0-9_]+(:?\-[a-zA-Z0-9_]*)?)\s*\+?\=/) {
                        push(@list, $1);
                }
        }
        for my $i (@list) {
                $i =~ s/\-.*/\-\*/;
        }
        return \@list;
}

sub find_closest($e, $seen, $ref)
{
        my $f = 0;
        for my $i (@$ref) {
                if ($f == 0) {
                        if ($i eq $e) {
                                $f = 1;
                                next;
                        }
                } elsif ($i ne $e) {
                        if ($seen->{$i}) {
                                return " (should be before $i)";
                        }
                }
        }
        return "";
}

# some variables don't appear with their '-' form in the template
sub fix_template($ref)
{
        my @list;
        # XXX need to dedup the ref (SITES and friends)
        my $done = {};
        for my $i (@$ref) {
                next if $done->{$i};
                push(@list, $i);
                if ($wantdash->{$i}) {
                        push(@list, "$i-*");
                }
                $done->{$i} = 1;
        }
        return \@list;
}

sub port_var_check($name, $ref, $all, $rrc)
{
        my $port = read_order($name);
        if (!defined $port) {
                say STDERR "$name: Couldn't read";
                $$rrc = 2;
                return;
        }

        my @new = @$ref;

        my $old = {};
        my $seen = {};
        while (my $e = shift @$port) {
                $seen->{$e} = 1;
                if (!$all->{$e}) {
                        if ($unreg->{$e}) {
                                next;
                        }
                        say "$name: $e unknown";
                        next;
                }
                if ($old->{$e}) {
                        say "$name: $e late".
                            find_closest($e, $seen, $ref);
                        $$rrc = 1 if !$rrc;
                        next;
                }
                while ($e ne $new[0]) {
                        $old->{$new[0]} = 1;
                        shift @new;
                        if (@new == 0) {
                                say "$name: $e ? (unknown error)";
                                last;
                                $$rrc = 1 if !$rrc;
                        }
                }
        }
}

my $ref = read_order("${portsdir}/infrastructure/templates/Makefile.template");
if (!defined $ref) {
        say STDERR "Couldn't read reference template";
        exit 2;
}

$ref = fix_template($ref);

my $all = {};
for my $i (@$ref) {
        $all->{$i} = 1;
}

for my $name (@ARGV) {
        my $inc = dirname($name)."/../Makefile.inc";
        if (-e $inc) {
                port_var_check($name, $ref, $all, \$rc);
        }
        port_var_check($name, $ref, $all, \$rc)
}
exit $rc;
.\"     $OpenBSD$
.\"
.\" Copyright (c) 2024 Marc Espie <es...@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd $Mdocdate$
.Dt PORT-VAR-CHECK 1
.Os
.Sh NAME
.Nm port-var-check
.Nd check variables order against 
.Pa Makefile.template
.Sh SYNOPSIS
.Nm
.Ar filename ...
.Sh DESCRIPTION
.Nm
compares the order of variables in Makefile against
.Pa Makefile.template
and issues warnings and recommendations.
.Pp
.Nm
will also check
.Pa Makefile.inc .
.Pp
Note that these are only recommendations, and there can be lots of valid
reasons to not follow the order in
.Pa Makefile.template
exactly.
.Sh ENVIRONMENT
.Bl -tag -width PORTSDIR
.It Ev PORTSDIR
Location of the ports tree.
.El
.Sh FILES
.Bl -tag -width PORTSDIR
.It Pa ${PORSTDIR}/infrastructure/templates/Makefile.template
Default order of variables in Makefiles.
.El

Reply via email to