Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F20190660
ports-hook
No One
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Authored By
mat
Apr 16 2021, 2:23 PM
2021-04-16 14:23:32 (UTC+0)
Size
7 KB
Referenced Files
None
Subscribers
None
ports-hook
View Options
#!/usr/local/bin/perl
# vim:sts=4 sw=4 et
# perltidy -bext=/ -se -i=4 -it=2 -ci=2 -xci -l=132 -pt=2 -ce -cti=1 -cab=4 -cb -cbo=0 -wbb="% + - * / x != == >= <= =~ !~ < > | &" -enc=utf8 -wn -sot -sct -asc -tqw -sbq=0 -csc -csct=30
use
strict
;
use
warnings
;
use
5.024
;
use
Git
;
################################################################
# Helper functions
################################################################
my
$git
=
Git
->
repository
;
my
$branch_main
=
'refs/heads/main'
;
my
$re_quarterlies
=
qr{^refs/heads/20\d\dQ\d\z}
oms
;
{
# sub context to avoid leaking @push_options
my
@push_options
;
for
(
my
$i
=
0
;
$i
<
$ENV
{
GIT_PUSH_OPTION_COUNT
}
;
++
$i
)
{
push
@push_options
,
$ENV
{
"GIT_PUSH_OPTION_${i}"
};
}
sub
has_option
{
my
(
$opt
)
=
@_
;
for
(
@push_options
)
{
return
1
if
$opt
eq
$_
;
}
return
0
;
}
## end sub has_option
}
my
@quarterlies
;
for
(
$git
->
command
(
'show-ref'
,
'--heads'
))
{
my
(
$hash
,
$ref
)
=
split
/ /
;
next
if
$ref
!~
m{refs/heads/\d\d\d\dQ\d\z}oms
;
push
@quarterlies
,
$ref
;
}
@quarterlies
=
sort
@quarterlies
;
my
$latest_quarterly
=
$quarterlies
[
-
1
];
sub
do_die
{
die
"\n================================================================\n"
.
join
(
"\n"
,
@_
)
.
"\n================================================================\n\n"
;
}
sub
short_ref
{
my
(
$ref
)
=
@_
;
$ref
=~
s{refs/heads/}{}oms
;
return
$ref
;
}
################################################################
# Here starts actual hooks
################################################################
# Some filenames are forbidden in the repo.
sub
deny_filenames
{
my
(
$rev
,
@changed
)
=
@_
;
for
my
$line
(
@changed
)
{
if
(
$line
=~
m{\A(?:CVS|[.](?:svn|git))\z}oms
# cvs/svn/git
||
$line
=~
m{[.](?:rej|orig)\z}oms
# patch
||
$line
=~
m{[.]core\z}oms
# core file
)
{
do_die
'This file in your commit look suspiciously like core file,'
,
'patch leftover, CVS, Subversion or git directory:'
,
$line
,
'Please double-check your commit and try committing again.'
;
}
## end if ($line =~ m{\A(?:CVS|[.](?:svn|git))\z}oms...)
if
(
$line
=~
m{(?:\A|/)Makefile.local\z}oms
)
{
do_die
'Makefile.local is a user file and MUST NOT be committed:'
,
$line
;
}
}
## end for my $line (@changed)
}
## end sub deny_filenames
################################################################
# Empty files forbidden
sub
empty
{
my
(
$rev
,
@changed
)
=
@_
;
for
my
$file
(
@changed
)
{
my
$content
=
$git
->
command
(
'show'
,
"$rev:$file"
);
next
if
length
(
$content
)
>
0
;
do_die
"Some files in your commit are empty: $file"
,
"Please fix this and try committing again."
;
}
## end for my $file (@changed)
}
## end sub empty
################################################################
# vulm.xml has to be committed alone, as it is never merged back to the
# quarterly branches.
sub
vuxml_unique
{
my
(
$ref
,
$rev
,
@changed
)
=
@_
;
my
(
$seen
,
$other
)
=
(
0
,
0
);
for
my
$line
(
@changed
)
{
if
(
$line
=~
m{\Asecurity/vuxml/vuln(?:-\d{4}
)?
.
xml
\
z
}
oms
)
{
$seen
=
1
;
}
else
{
$other
=
1
;
}
}
## end for my $line (@changed)
if
(
$seen
&&
$branch_main
ne
$ref
)
{
do_die
"Commits to security/vuxml/vuln.xml are only allowed on main"
;
}
if
(
$seen
&&
$other
)
{
do_die
"Commit to security/vuxml/vuln.xml first, and then other files"
;
}
}
## end sub vuxml_unique
################################################################
# Check git cherry-pick ran with `-x`
sub
cherry_pick
{
my
(
$ref
,
$log
)
=
@_
;
# Only do this on quarterlies
return
if
$ref
!~
$re_quarterlies
;
# Gave the magic push option
return
if
has_option
(
'direct-quarterly-commit'
);
# Found the actual magic words
return
if
$log
=~
m{
^ # Start of line
[(] # A litteral opening parenthesis
cherry[ ]picked[ ]from[ ]commit # The magic words
[0-9a-fA-F]{30,}
# A commit hash
[)]
# A litteral closing parenthesis
$
#
End
of
line
}
omsx
;
do_die
# Comments
"$ENV{GL_USER}, you are pushing a commit to ${\(short_ref($ref))} which does"
,
# to get this
'not seems to be a cherry-pick.'
,
# indented
''
,
# properly
'If you did a cherry-pick, you probably forgot to add `-x`,'
,
# by
'make sure you do run `git cherry-pick -x <hash>`.'
,
# perltidy
''
,
#
'If you did a direct commit, make sure it was approved first, and then run:'
,
#
"\tgit push --push-option=direct-quarterly-commit"
;
}
## end sub cherry_pick
################################################################
# Check that commits only go to the latest quarterly branch
sub
unsupported_quarterly
{
my
(
$ref
)
=
@_
;
# Only applies to quarterlies
return
if
$ref
!~
$re_quarterlies
;
# Gave the magic push option
return
if
has_option
(
'direct-quarterly-commit'
);
do_die
# Comments
"$ENV{GL_USER}, you are pushing a commit to ${\(short_ref($ref))} which is not"
,
# for
"the latest quarterly branch. The latest is ${\(short_ref($latest_quarterly))}."
,
# indentation
''
,
#
'Please check that you really mean to do this, and got approval, use:'
,
#
"\tgit push --push-option=unsupported-quarterly"
;
}
## end sub unsupported_quarterly
################################################################
# Check log does not contains stuff generated by phabricator
sub
stomp_bad_formatting
{
my
(
$log
)
=
@_
;
if
(
$log
=~
m
|\
n
\
nReviewers:
[
\
t
]
+|
oms
)
{
do_die
"Non-standard/badly formatted template - found 'Reviewers:' instead of 'Reviewed by:'."
;
}
if
(
$log
=~
m
|\
n
\
nSubscribers:
[
\
t
]
+|
oms
)
{
do_die
"Non-standard/badly formatted template - found 'Subscribers:'."
;
}
}
## end sub stomp_bad_formatting
################################################################
# Main loop, everything called in here.
for
(
<STDIN>
)
{
chomp
;
my
(
$old
,
$new
,
$ref
)
=
split
/ /
;
unsupported_quarterly
(
$ref
);
for
my
$rev
(
$git
->
command
(
'log'
,
'--format=%H'
,
$new
,
'--not'
,
'--all'
))
{
my
@changed
=
$git
->
command
(
'diff'
,
'--name-only'
,
"$rev~1..$rev"
);
my
$log
=
$git
->
command
(
'show'
,
'-s'
,
'--format=%B'
,
$rev
);
deny_filenames
(
$rev
,
@changed
);
vuxml_unique
(
$ref
,
$rev
,
@changed
);
cherry_pick
(
$ref
,
$log
);
stomp_bad_formatting
(
$log
);
empty
(
$rev
,
@changed
);
}
## end for my $rev ($git->command('log',...))
}
## end for (<STDIN>)
exit
1
;
File Metadata
Details
Attached
Mime Type
text/plain; charset=utf-8
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3601241
Default Alt Text
ports-hook (7 KB)
Attached To
Mode
P497 ports-hook
Attached
Detach File
Event Timeline
Log In to Comment