#!/usr/bin/perl -w # dgit repos policy hook script for Debian # # usages: # dgit-repos-policy-debian DISTRO DGIT-REPOS-DIR ACTION... # ie. # dgit-repos-policy-debian ... check-list # dgit-repos-policy-debian ... check-package PACKAGE # dgit-repos-policy-debian ... push PACKAGE \ # VERSION SUITE TAGNAME DELIBERATELIES [...] # # exit status is bitmap; bit weights (values) as follows # 1 failure; operation must be rejected; other bits will be ignored # 2 suppress dgit-repos-server's ff check ("push" only) # 4 blow away repo away right away (ie before push or fetch) # ("check-package" only) # # cwd for push is a temporary repo where the to-be-pushed objects have # been received; TAGNAME is the version-based tag # # policy hook for a particular package will be invoked only once at # a time use strict; use POSIX; use JSON; use Debian::Dgit; our $distro = shift @ARGV // die "need DISTRO"; our $repos = shift @ARGV // die "need DGIT-REPOS-DIR"; our $action = shift @ARGV // die "need ACTION"; our $pkg = shift @ARGV; # We assume that it is not possible for NEW to have a version older # than sid. # Whenever pushing, we check for # source-package-local tainted history # global tainted history # can be overridden by --deliberately except for an admin prohib taint # # ALL of the following apply only if history is secret: # # if NEW has no version, or a version which is not in our history[1] # (always) # check all suites # if any suite's version is in our history[1], publish our history # otherwise discard our history, # tainting --deliberately-include-questionable-history # # if NEW has a version which is in our history[1] # (on push only) # require explicit specification of one of # --deliberately-include-questionable-history # --deliberately-not-fast-forward # (latter will taint old NEW version --d-i-q-h) # (otherwise) # leave it be # # [1] looking for the relevant git tag for the version number and not # caring what that tag refers to. sub apiquery ($) { my ($subpath) = @_; local $/=undef; $!=0; $?=0; my $json = `dgit -d $distro archive-api-query $subpath`; defined $json or die "$subpath $! $?"; return decode_json $json; } sub new_has_vsn_in_our_history () { my $in_new = apiquery "/dsc_in_suite/new/$pkg"; foreach my $entry (@$in_new) { my $vsn = $entry->{version}; die "$pkg ?" unless defined $vsn; my $tag = debiantag $vsn; $?=0; my $r = system qw(git show-ref --verify --quiet), $tag; return 1 if !$r; next if $r==256; die "$pkg tag $tag $? $!"; } return 0; } sub selectpackage () { die if $pkg =~ m#^-#; die if $pkg =~ m#[^-+.0-9a-z]#; if (!chdir "$repos/$pkg") { die "$pkg $!" unless $!==ENOENT; # something } stat "." or die $!; if (~(stat _)[2] & 05) { # secret history } } if (defined $pkg) { selectpackage; } sub action_push () { } my $fn = ${*::}{"action_$cmd"}; $fn or die "unknown ACTION"; $fn->();