summaryrefslogtreecommitdiff
path: root/ciabot/run-libreoffice-ciabot.pl
blob: 4cb1bdb3208e013f89842f6ab9b105072b1e09b6 (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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
#!/usr/bin/perl -w

use POSIX;
use File::Basename;

open STDOUT, '>', dirname($0) . "/ciabot.out";
open STDERR, '>', dirname($0) . "/ciabot.err";

my $suffix = "";
my $cwd;

$cwd = `pwd`;
chomp $cwd;

if ( ! -d 'core' && ! -d 'core.git' ) {
    print STDERR "Not a directory with libreoffice repos!\n";
    exit 1;
}
if ( -d 'core.git' ) {
    $suffix=".git"
}
sub error($) {
    my ( $message ) = @_;
    print STDERR "$message\n";
}

#
# Get a list of filtered branch HEADs
#
# Gets all branches, except HEAD.
#
# @returns \%{ branch name => git branch head hashval }
#
sub get_branches() {
    my %branches;
    if ( open REFS, "git show-ref |" ) {
        while ( <REFS> ) {
            chomp;
            if ( /^([^ ]*) refs\/remotes\/origin\/(.*)/ ) {
                if ( $2 ne 'HEAD' ) {
                    $branches{$2} = $1;
                }
            }
        }
        close REFS;
    }
    else {
        error( "Cannot call git show-ref." );
    }

    return \%branches;
}

#
# Should we generate Bugzilla comments?
#
# Report all commits for all repositories except 'core'. For 'core'
# just report libreoffice-* and master branches to Bugzilla.
#
# @returns true, if this commit should be reported to Bugzilla.
#
sub is_valid_bugzilla_commit($$) {
   my ( $repo, $branch ) = @_;
   return 1 if ( $repo ne 'core' );
   return ( $branch =~ /^(libreoffice-[^\/]*|master)$/ );
}

sub timestamp() {
        return strftime("[%Y-%m-%d %H:%M:%S]", localtime);
}

#
# Report all branch changes to IRC and bugzilla.
#
# We just report changes filtered by is_valid_bugzilla_report to Bugzilla
# but inform IRC off all changes.
#
# $1 = repository name
# $2 = hashref of old branch heads (@see get_branches).
# $3 = hashref of new branch heads (@see get_branches).
#
sub report($$$) {
    my ( $repo, $old_ref, $new_ref ) = @_;
    my %old = %{$old_ref};
    my %new = %{$new_ref};
    my $ciabot = "timeout 60 $cwd/libreoffice-ciabot.pl";
    my $ciaproxy = "| ( cd $cwd && python irker-cia-proxy.py -s )";

    foreach my $key ( keys %new ) {
        my $branch_name = $key;
        $branch_name = '' if ( $branch_name eq 'master' );
        if ($branch_name =~ /aoo\//) {
            next;
        }

        my $old_head = $old{$key};
        my $new_head = $new{$key};

        if ( defined( $old_head ) ) {
            if ( $old_head ne $new_head ) {
                my $ret = system("git rev-parse -q --verify $new_head^2 >/dev/null");
                if ($ret != 0) {
                    # not a merge commit, announce every commit

                    # limit the number of commits we report
                    my $limit = 25;
                    if ( `git rev-list $new_head ^$old_head | wc -l` > 25 ) {
                        # something is wrong - probably a big rebase,
                        # or something, report just 1 commit
                        $limit = 1;
                    }
                    if ( open COMMITS, "git rev-list -n $limit $new_head ^$old_head | tac |" ) {
                        while ( <COMMITS> ) {
                            chomp;
                            print timestamp() . " Sending report about $_ in $key\n";
                            if (!$test) {
                                if ($repo eq "si-gui")
                                {
                                    qx(perl -I $cwd $cwd/sigui-bugzilla.pl $repo $_ $branch_name);
                                } else {
                                    qx($ciabot $repo $_ $branch_name $ciaproxy);
                                    next if ( ! is_valid_bugzilla_commit( $repo, $branch_name ) );
                                    qx(perl -I $cwd $cwd/libreoffice-bugzilla.pl $repo $_ $branch_name);
                                }
                            } else {
                                print "$ciabot '$repo' '$_' '$branch_name' $ciaproxy\n";
                                next if ( ! is_valid_bugzilla_commit( $repo, $branch_name ) );
                                print "perl -I $cwd $cwd/libreoffice-bugzilla.pl '$repo' '$_' '$branch_name'\n";
                            }
                        }
                        close COMMITS;
                    }
                    else {
                        error( "Cannot call git rev-list." );
                    }
                } else {
                    # just process the merge commit itself
                    print timestamp() . " Sending report about $new_head in $key\n";
                    if (!$test) {
                        qx($ciabot $repo $new_head $branch_name $ciaproxy);
                        # no libreoffice-bugzilla.pl call for the merge commit
                    } else {
                        print "$ciabot '$repo' '$new_head' '$branch_name' $ciaproxy\n";
                    }
                }
            }
        }
        else {
            # Report the newest commit which is not in master
            if ( open COMMITS, "git rev-list -n 1 $new_head ^refs/remotes/origin/master |" ) {
                while ( <COMMITS> ) {
                    chomp;
                    print timestamp() . " Sending report about $_ in $key (newly created branch)\n";
                    if (!$test) {
                        qx($ciabot $repo $_ $branch_name $ciaproxy);
                        # no libreoffice-bugzilla.pl call for newly created branch
                    } else {
                        print "$ciabot '$repo' '$_' '$branch_name' $ciaproxy\n";
                    }
                }
                close COMMITS;
            }
            else {
                error( "Cannot call git rev-list." );
            }
        }
    }
}

print timestamp() . " Checking for changes in the libreoffice repo & sending reports to CIA.vc.\n";

@all_repos = (
    "core",
    "dictionaries",
    "help",
    "si-gui",
);

$test = 0;

if ($test) {
    @all_repos = ("test");
}


my %old_ref;
foreach $repo (@all_repos) {
    chdir "$cwd/$repo$suffix";
    qx(git fetch origin);
    qx(git fetch --tags origin);
    $old_ref{$repo} = get_branches();
}

while ( 1 ) {
    foreach $repo (@all_repos) {
        chdir "$cwd/$repo$suffix";

        # update
        qx(git fetch origin);
        qx(git fetch --tags origin);
        my $new_ref = get_branches();

        # report
        report( $repo, $old_ref{$repo}, $new_ref );
        $old_ref{$repo} = $new_ref;
    }

    if (!$test) {
        # check every 5 minutes
        print timestamp() . " Sleeping for 1 minute...\n";
        sleep 1*60;
    } else {
        print "Hit enter to report...\n";
        <STDIN>;
    }
}

# vim:set shiftwidth=4 softtabstop=4 expandtab: