summaryrefslogtreecommitdiff
path: root/infra/dgit-repos-policy-debian
blob: db15310314234c90bc67f39f44b4504f258f2d15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#!/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->();