Making WordPress.org

Changeset 1121


Ignore:
Timestamp:
01/11/2015 11:00:02 AM (9 years ago)
Author:
nacin
Message:

Update Slack libraries.

Location:
sites/trunk/svn.wordpress.org/includes/slack-trac-hooks
Files:
11 added
4 moved

Legend:

Unmodified
Added
Removed
  • sites/trunk/svn.wordpress.org/includes/slack-trac-hooks/trac/comment-handler.php

    r1080 r1121  
    11<?php
    22
    3 namespace Dotorg\SlackTracHooks\Comments;
     3namespace Dotorg\Slack\Trac;
    44
    5 function process_message( $lines ) {
    6     $lines = array_map( 'rtrim', $lines );
     5class Comment_Handler {
     6
     7    function __construct( Dotorg\Slack\Send $send, array $email_message ) {
     8        $this->send  = $send;
     9        $this->lines = $email_message;
     10    }
     11
     12    function run() {
     13        $this->process_message();
     14
     15        // Don't post auto-comments for commits.
     16        if ( false !== strpos( $this->comment, '#!CommitTicketReference' ) ) {
     17            return;
     18        }
     19
     20        $this->generate_payload();
     21        $this->send->send( $trac->get_firehose_channel() );
     22    }
     23
     24    function process_message() {
     25        $lines = array_map( 'rtrim', $this->lines );
     26       
     27        // Trim off headers.
     28        while ( '' !== current( $lines ) ) {
     29            $line = array_shift( $lines );
     30            if ( 0 === strpos( $line, 'X-Trac-Ticket-URL:' ) ) {
     31                // X-Trac-Ticket-URL: https://core.trac.wordpress.org/ticket/12345#comment:1
     32                list( , $comment_url ) = explode( ': ', $line );
     33                list( $ticket_url, $comment_id ) = explode( '#comment:', $comment_url );
     34                list( $trac_url, $ticket_id ) = explode( '/ticket/', $ticket_url );
    735   
    8     // Trim off headers.
    9     while ( '' !== current( $lines ) ) {
    10         array_shift( $lines );
    11     }
    12     // Remove empty line between headers and body.
    13     array_shift( $lines );
    14    
    15     $title = '';
    16     while ( 0 !== strpos( current( $lines ), '------' ) ) {
    17         if ( '' !== $title ) {
    18             $last = substr( $title, -1 );
    19             if ( $last !== '-' && $last !== '_' ) {
    20                 $title .= ' ';
     36                $trac = Dotorg\Slack\Trac::get( $trac_url );
     37                if ( ! $trac ) {
     38                    return false;
     39                }
    2140            }
    2241        }
    23         $title .= array_shift( $lines );
     42
     43        // Remove empty line between headers and body.
     44        array_shift( $lines );
     45       
     46        $title = '';
     47        while ( 0 !== strpos( current( $lines ), '------' ) ) {
     48            if ( '' !== $title ) {
     49                $last = substr( $title, -1 );
     50                if ( $last !== '-' && $last !== '_' ) {
     51                    $title .= ' ';
     52                }
     53            }
     54            $title .= array_shift( $lines );
     55        }
     56        $title = substr( $title, strpos( $title, ': ' ) + 2 );
     57
     58        // Remove up to top of ticket properties table.
     59        while ( 0 !== strpos( current( $lines ), '------' ) ) {
     60            array_shift( $lines );
     61        }
     62        // Remove top border of table.
     63        array_shift( $lines );
     64        // Remove ticket properties table.
     65        while ( 0 !== strpos( current( $lines ), '------' ) ) {
     66            array_shift( $lines );
     67        }
     68        // Remove bottom border of table.
     69        array_shift( $lines );
     70       
     71        // Remove empty line if present. (It is when it's a comment without changes.)
     72        if ( current( $lines ) === '' ) {
     73            array_shift( $lines );
     74        }
     75       
     76        // Remove Trac email footer.
     77        while ( end( $lines ) !== '--' ) {
     78            array_pop( $lines );
     79        }
     80        // Remove -- which starts footer.
     81        array_pop( $lines );
     82        // Remove empty line before footer.
     83        array_pop( $lines );
     84       
     85        preg_match( '/^(Comment|Changes) \(by (.*)\):$/', array_shift( $lines ), $matches );
     86        $has_changes = $matches[1] === 'Changes';
     87        $author = $matches[2];
     88
     89        // Remove blank line after 'Comment|Changes (by author):'
     90        array_shift( $lines );
     91       
     92        $changes = $comment = array();
     93        if ( $has_changes ) {
     94            while ( '' !== current( $lines ) ) {
     95                $changes[] = preg_replace( '~^ \* (.*?):  ~', '_*$1:*_ ', array_shift( $lines ) );
     96            }
     97        }
     98       
     99        // Remove blank lines (should be two if it had changes).
     100        while ( '' === current( $lines ) ) {
     101            array_shift( $lines );
     102        }
     103       
     104        // Next line should start with 'Comment' if there is one.
     105        if ( $has_changes && 0 === strpos( current( $lines ), 'Comment' ) ) {
     106            array_shift( $lines ); // Remove 'Comment'
     107            array_shift( $lines ); // Remove blank line
     108        }
     109
     110        // Everything left is the comment. Remove leading space.
     111        $comment = array_map( 'ltrim', $lines );
     112
     113        $this->trac    = $trac;
     114        $this->title   = $title;
     115        $this->author  = $author;
     116        $this->comment = $comment;
     117        $this->changes = $changes;
     118        $this->ticket_id   = $ticket_id;
     119        $this->ticket_url  = $ticket_url;
     120        $this->comment_id  = $comment_id;
     121        $this->comment_url = $comment_url;
    24122    }
    25     $title = substr( $title, strpos( $title, ': ' ) + 2 );
    26    
    27     // Remove up to top of ticket properties table.
    28     while ( 0 !== strpos( current( $lines ), '------' ) ) {
    29         array_shift( $lines );
     123
     124    function format_comment_for_slack() {
     125        // Link 'Replying to [comment:1 user]:'
     126        $ticket_url = $this->ticket_url;
     127        $comment = preg_replace_callback( '/Replying to \[comment:(\d+) (.*)\]/m',
     128            function ( $matches ) use ( $ticket_url ) {
     129                $comment_url = $ticket_url . '#comment:' . $matches[1];
     130                $text = 'Replying to ' . $matches[2];
     131                return "<$comment_url|$text>";
     132            }, $this->comment );
     133
     134        $comment = Trac::format_for_slack( $comment );
     135        return $comment;
    30136    }
    31     // Remove top border of table.
    32     array_shift( $lines );
    33     // Remove ticket properties table.
    34     while ( 0 !== strpos( current( $lines ), '------' ) ) {
    35         array_shift( $lines );
    36     }
    37     // Remove bottom border of table.
    38     array_shift( $lines );
    39    
    40     // Remove empty line if present. (It is when it's a comment without changes.)
    41     if ( current( $lines ) === '' ) {
    42         array_shift( $lines );
    43     }
    44    
    45     // Remove Trac email footer.
    46     while ( end( $lines ) !== '--' ) {
    47         array_pop( $lines );
    48     }
    49     // Remove -- which starts footer.
    50     array_pop( $lines );
    51     // Remove empty line before footer.
    52     array_pop( $lines );
    53    
    54     preg_match( '/^(Comment|Changes) \(by (.*)\):$/', array_shift( $lines ), $matches );
    55     $has_changes = $matches[1] === 'Changes';
    56     $author = $matches[2];
    57    
    58     // Remove blank line after 'Comment|Changes (by author):'
    59     array_shift( $lines );
    60    
    61     $changes = $comment = array();
    62     if ( $has_changes ) {
    63         while ( '' !== current( $lines ) ) {
    64             $changes[] = preg_replace( '~^ \* (.*?):  ~', '_*$1:*_ ', array_shift( $lines ) );
     137
     138    function generate_payload() {
     139        $this->send->set_icon( $this->trac->get_icon() );
     140        $this->send->set_username( $this->trac->get_ticket_username() );
     141           
     142        $comment         = $this->format_comment_for_slack();
     143        $main_attachment = $this->changes ? $this->changes : $comment;
     144        $fallback        = trim( $pretext, '*' ) . "\n" . $main_attachment;
     145        $pretext         = sprintf( '*%s updated <%s|#%s %s>*', $this->author, $this->comment_url, $this->ticket_id, $this->title );
     146
     147        $attachment = array(
     148            'pretext'   => $pretext,
     149            'fallback'  => $fallback,
     150            'text'      => $main_attachment,
     151            'mrkdwn_in' => array( 'pretext', 'fallback', 'text' ),
     152        );
     153
     154        // Ensure the comment uses a darker gray color, even when alone.   
     155        if ( ! $this->changes ) {
     156            $attachment['color'] = '#999';
     157        }
     158
     159        $this->send->add_attachment( $attachment );
     160
     161        // If we have both changes and a comment, append the comment.
     162        if ( $this->changes && $comment ) {
     163            $this->send->add_attachment( array(
     164                'fallback'  => $comment,
     165                'text'      => $comment,
     166                'mrkdwn_in' => array( 'fallback', 'text' ),
     167                'color'     => '#999',
     168            ) );
    65169        }
    66170    }
    67    
    68     // Remove blank lines (should be two if it had changes).
    69     while ( '' === current( $lines ) ) {
    70         array_shift( $lines );
    71     }
    72    
    73     // Next line should start with 'Comment' if there is one.
    74     if ( $has_changes && 0 === strpos( current( $lines ), 'Comment' ) ) {
    75         array_shift( $lines ); // Remove 'Comment'
    76         array_shift( $lines ); // Remove blank line
    77     }
    78    
    79     // Everything left is the comment. Remove leading space.
    80     $comment = array_map( 'ltrim', $lines );
    81    
    82     $changes = implode( "\n", $changes );
    83     $comment = implode( "\n", $comment );
    84 
    85     return compact( 'author', 'title', 'changes', 'comment' );
    86171}
    87 
    88 function format_comment( $comment, $ticket_url ) {
    89     // Link 'Replying to [comment:1 user]:'
    90     $comment = preg_replace_callback( '/^Replying to \[comment:(\d+) (.*)\]/m',
    91         function ( $matches ) use ( $ticket_url ) {
    92             $comment_url = $ticket_url . '#comment:' . $matches[1];
    93             $text = 'Replying to ' . $matches[2];
    94             return "<$comment_url|$text>";
    95         }, $comment );
    96 
    97     // Replace {{{ and }}} with ``` or `
    98     $comment = trim( str_replace(
    99         array( "\n{{{\n", "\n}}}\n", '{{{', '}}}' ),
    100         array( "\n```\n", "\n```\n", '`',   '`' ),
    101         "\n$comment\n"
    102     ), "\n" );
    103 
    104     return $comment;
    105 }
    106 
    107 function send( $slack_hook, $args ) {
    108     // Don't post auto-comments for commits.
    109     if ( false !== strpos( $args['comment'], '#!CommitTicketReference' ) ) {
    110         return;
    111     }
    112 
    113     $trac_class = '\\Dotorg\\SlackTracHooks\\' . $args['trac'] . '_Trac';
    114     $trac = new $trac_class;
    115 
    116        
    117     $args['comment'] = format_comment( $args['comment'], $args['ticket_url'] );
    118     $main_attachment = $args['changes'] ? $args['changes'] : $args['comment'];
    119 
    120     $pretext = sprintf( '*%s updated <%s|#%s %s>*', $args['author'], $args['comment_url'], $args['ticket'], $args['title'] );
    121     $fallback = trim( $pretext, '*' ) . "\n" . $main_attachment;
    122 
    123     $payload = array(
    124         'channel'     => $trac->get_firehose_channel(),
    125         'icon_emoji'  => $trac->get_emoji(),
    126         'username'    => $trac->get_ticket_username(),
    127         'attachments' => array(
    128             array(
    129                 'pretext'   => $pretext,
    130                 'fallback'  => $fallback,
    131                 'text'      => $main_attachment,
    132                 'mrkdwn_in' => array( 'pretext', 'fallback', 'text' ),
    133             ),
    134         ),
    135     );
    136 
    137     // If we have both changes and a comment, append the comment.
    138     // Ensure the comment uses a darker gray color, even when alone.   
    139     if ( $args['changes'] && $args['comment'] ) {
    140         $payload['attachments'][] = array(
    141             'fallback'  => $args['comment'],
    142             'text'      => $args['comment'],
    143             'mrkdwn_in' => array( 'fallback', 'text' ),
    144             'color'     => '#999',
    145         );
    146     } elseif ( ! $args['changes'] ) {
    147         $payload['attachments'][0]['color'] = '#999';
    148     }
    149    
    150     $payload = json_encode( $payload );
    151    
    152     $context = stream_context_create( array(
    153         'http' => array(
    154             'method'  => 'POST',
    155             'header'  => 'Content-Type: application/x-www-form-urlencoded' . PHP_EOL,
    156             'content' => http_build_query( compact( 'payload' ) ),
    157         ),
    158     ) );
    159    
    160     file_get_contents( $slack_hook, false, $context );
    161 }
    162 
  • sites/trunk/svn.wordpress.org/includes/slack-trac-hooks/trac/commit-handler.php

    r1080 r1121  
    11<?php
    22
    3 namespace Dotorg\SlackTracHooks;
     3namespace Dotorg\Slack\Trac;
     4use Dotorg\Slack\Send;
    45
    5 class Commits {
     6class Commit_Handler {
    67    protected $trac;
    78    protected $repo;
    89    protected $rev;
    9     protected $slack_hook;
     10    protected $send;
    1011
    1112    protected $test_mode = false;
    1213    protected $svnlook = '/usr/bin/svnlook';
    1314
    14     public function __construct( $trac, $repo, $rev, $slack_hook ) {
    15         $this->set_trac( $trac );
     15    public function __construct( Send $send, $trac, $repo, $rev ) {
     16        $this->send = $send;
     17        $this->trac = Trac::get( $trac );
    1618        $this->repo = $repo;
    17         $this->rev = $rev;
    18         $this->slack_hook = $slack_hook;
     19        $this->rev  = $rev;
    1920    }
    2021
    21     public function use_test_channel( $enabled ) {
    22         $this->test_mode = (bool) $enabled;
     22    public function run() {
     23        $this->generate_payload();
     24        foreach ( $this->trac->get_commit_channels( $this->svnlook( 'changed' ) ) as $channel ) {
     25            $this->send->send( $channel );
     26        }
     27    }
     28
     29    public function testing( $enabled ) {
     30        $this->send->testing( (bool) $enabled );
    2331    }
    2432
     
    2735    }
    2836
    29     public function run() {
    30         $payload = $this->generate_payload();
    31         foreach ( $this->trac->get_commit_channels( $this->svnlook( 'changed' ) ) as $channel ) {
    32             $this->send( $channel, $payload );
    33         }
    34     }
    35 
    36     protected function set_trac( $trac ) {
    37         $class = __NAMESPACE__ . '\\' . $trac . '_Trac';
    38         $this->trac = new $class;
    39     }
    40 
    4137    protected function generate_payload() {
    4238        $author = $this->svnlook( 'author' );
    43         $log = $this->format_log_for_slack( $this->svnlook( 'log' ) );
     39        $log = Commit::format_commit_for_slack( $this->trac, $this->svnlook( 'log' ) );
    4440
    4541        $url = $this->trac->get_commit_template( $this->rev );
     
    4743
    4844        $username = $this->trac->get_commit_username();
    49         $emoji    = $this->trac->get_emoji();
     45        $icon     = $this->trac->get_icon();
    5046        $color    = $this->trac->get_color();
    5147
     
    5349        $fallback = "$revision by $author: $log";
    5450
    55         return array(
    56             'channel'     => '#test',
    57             'username'    => $username,
    58             'icon_emoji'  => $emoji,
    59             'attachments' => array( array(
    60                 'color'     => $color,
    61                 'pretext'   => $pretext,
    62                 'text'      => $log,
    63                 'fallback'  => $fallback,
    64                 'mrkdwn_in' => array( 'text', 'pretext' ),
    65             ) ),
    66         );
    67     }
    68 
    69     protected function format_log_for_slack( $log ) {
    70         foreach ( $this->trac->get_log_replacements() as $find => $replace ) {
    71             $log = preg_replace( $find, '<' . $replace . '|$0>', $log );
    72         }
    73         return $log;
     51        $this->send->set_username( $username );
     52        $this->send->set_icon( $icon );
     53        $this->send->add_attachment( array(
     54            'color'     => $color,
     55            'pretext'   => $pretext,
     56            'text'      => $log,
     57            'fallback'  => $fallback,
     58            'mrkdwn_in' => array( 'text', 'pretext', 'fallback' ),
     59        ) );
    7460    }
    7561
     
    8167        );
    8268        $args = array_map( 'escapeshellarg', $args );
    83         $command = escapeshellcmd( $this->svnlook ) . ' ' . implode( ' ', $args );
     69        $command = escapeshellcmd( $this->svnlook . ' ' . implode( ' ', $args ) );
    8470
    8571        if ( $subcommand === 'changed' ) {
     
    9884        exit( 1 );
    9985    }
    100 
    101     protected function send( $channel, $payload ) {
    102         if ( $this->test_mode ) {
    103             $payload['attachments'][0]['pretext']  = "[$channel] " . $payload['attachments'][0]['pretext'];
    104             $payload['attachments'][0]['fallback'] = "[$channel] " . $payload['attachments'][0]['fallback'];
    105         } else {
    106             $payload['channel'] = $channel;
    107         }
    108 
    109         $context = stream_context_create( array(
    110             'http' => array(
    111                 'method'  => 'POST',
    112                 'header'  => 'Content-Type: application/x-www-form-urlencoded' . PHP_EOL,
    113                 'content' => http_build_query( array( 'payload' => json_encode( $payload ) ) ),
    114             ),
    115         ) );
    116 
    117         file_get_contents( $this->slack_hook, false, $context );
    118     }
    11986}
  • sites/trunk/svn.wordpress.org/includes/slack-trac-hooks/trac/config.php

    r1080 r1121  
    11<?php
    22
    3 namespace Dotorg\SlackTracHooks;
     3namespace Dotorg\Slack\Trac\Tracs;
     4use Dotorg\Slack\Trac\Trac;
    45
    5 class Core_Trac extends Trac {
    6     protected $commit_channels = array( '#core', '#core-commits' );
    7     protected $commit_username = 'WordPress commit';
    8     protected $commit_range = array( 3, 5 );
    9     protected $ticket_range = array( 3, 5 );
     6class Core extends Trac {
     7    protected $name = 'WordPress';
     8    protected $primary_channel  = '#core';
     9    protected $commits_channel  = '#core-commits';
     10    protected $tickets_channel  = '#core-newtickets';
     11    protected $firehose_channel = '#core-firehose';
    1012
    11     protected $ticket_channels  = array( '#core', '#core-newtickets' );
    12     protected $ticket_username  = 'WordPress Trac';
    13     protected $firehose_channel = '#core-firehose';
     13    protected $primary_channel_ticket_format = 'title';
    1414
    1515    /**
     
    1818     */
    1919    protected $commit_path_filters = array(
    20         'wp-content/themes'       => '#core-themes',
     20        'wp-content/themes'       => array( '#core-themes' => true, '#core' => false ),
    2121        'customize'               => '#core-customize',
    2222        'editor-expand.js'        => '#feature-focus',
     
    3030     */
    3131    protected $ticket_component_filters = array(
     32        'Bundled Theme' => array( '#core-themes' => true, '#core' => false ),
    3233        'Customize'     => '#core-customize',
    33         'Bundled Theme' => '#core-themes',
    3434        'Press This'    => '#feature-pressthis',
    3535    );
    3636}
    3737
    38 class Meta_Trac extends Trac {
    39     protected $commit_channels = array( '#meta', '#meta-commits' );
    40     protected $commit_username = 'WordPress.org Meta commit';
     38class Meta extends Trac {
     39    protected $name = 'WordPress.org Meta';
     40    protected $primary_channel  = '#meta';
     41    protected $commits_channel  = '#meta-commits';
     42    protected $tickets_channel  = '$meta-newtickets';
     43    protected $firehose_channel = '#meta-firehose';
    4144
    42     protected $ticket_channels = array( '#meta-newtickets' );
     45    protected $bypass_primary_channel_for_commit_filter_matches = true;
     46    protected $bypass_primary_channel_for_ticket_filter_matches = true;
    4347
    4448    protected $commit_path_filters = array(
     
    5862}
    5963
    60 class bbPress_Trac extends Trac {
    61     protected $commit_channels = array( '#bbpress', '#bbpress-commits' );
    62     protected $commit_username = 'bbPress commit';
    63     protected $ticket_channels = array( '#bbpress', '#bbpress-newtickets' );
    64     protected $color    = '#080';
    65     protected $emoji    = ':bbpress:';
     64class bbPress extends Trac {
     65    protected $primary_channel  = '#bbpress';
     66    protected $commits_channel  = '#bbpress-commits';
     67    protected $tickets_channel  = '#bbpress-newtickets';
     68    protected $firehose_channel = '#bbpress-firehose';
     69
     70    protected $color = '#080';
     71    protected $icon  = ':bbpress:';
    6672}
    6773
    68 class BuddyPress_Trac extends Trac {
    69     protected $commit_channels = array( '#buddypress', '#buddypress-commits' );
    70     protected $commit_username = 'BuddyPress commit';
    71     protected $ticket_channels = array( '#buddypress', '#buddypress-newtickets' );
    72     protected $color    = '#d84800';
    73     protected $emoji    = ':buddypress:';
     74class BuddyPress extends Trac {
     75    protected $primary_channel  = '#buddypress';
     76    protected $commits_channel  = '#buddypress-commits';
     77    protected $tickets_channel  = '#buddypress-newtickets';
     78    protected $firehose_channel = '#buddypress-firehose';
     79
     80    protected $color = '#d84800';
     81    protected $icon  = ':buddypress:';
    7482}
    7583
    76 class Dotorg_Trac extends Trac {
    77     protected $commit_channels = 'dotorg';
    78     protected $commit_username = 'Private dotorg commit';
    79     protected $ticket_channels = 'dotorg';
     84class Dotorg extends Trac {
     85    protected $name = 'Private Dotorg';
     86    protected $public = false;
     87    protected $primary_channel = 'dotorg';
    8088}
    8189
    82 class Deploy_Trac extends Trac {
    83     protected $commit_channels = 'dotorg';
    84     protected $commit_username = 'Deploy commit';
    85     protected $ticket_channels = 'dotorg';
     90class Deploy extends Trac {
     91    protected $public = false;
     92    protected $tickets = false;
     93
     94    protected $primary_channel = 'dotorg';
    8695}
    8796
    88 class GlotPress_Trac extends Trac {
    89     protected $commit_channels = '#glotpress';
    90     protected $commit_username = 'GlotPress commit';
    91     protected $ticket_channels = '#glotpress';
     97class GlotPress extends Trac {
     98    protected $primary_channel = '#glotpress';
    9299}
     100
     101class Build extends Trac {
     102    protected $name = 'WordPress Build';
     103    protected $tickets = false;
     104}
     105
     106class BackPress extends Trac {
     107}
     108
     109class SupportPress extends Trac {
     110}
     111
     112class Design extends Trac {
     113    protected $commit_template = 'https://core.trac.wordpress.org/changeset/design/%s';
     114    protected $commit_info_template = 'https://core.trac.wordpress.org/log/%s?rev=%s&format=changelog&limit=1&verbose=on';
     115}
     116
     117class Plugins extends Trac {
     118}
     119
     120class Themes extends Trac {
     121}
     122
     123class i18n extends Trac {
     124    protected $name = 'WordPress i18n';
     125    protected $tickets = false;
     126}
     127
     128class Unit_Tests extends Trac {
     129    protected $dormant = true;
     130    protected $slug = 'unit-tests';
     131    protected $name = 'Unit Tests (Old)';
     132}
     133
     134class MU extends Trac {
     135    protected $dormant = true;
     136    protected $name = 'WordPress MU';
     137}
     138
     139class OpenAtd extends Trac {
     140    protected $dormant = true;
     141    protected $name = 'After the Deadline';
     142}
     143
     144class Code extends Trac {
     145    protected $dormant = true;
     146    protected $name = 'Code Repo';
     147}
     148
     149class GSoC extends Trac {
     150    protected $dormant = true;
     151}
     152
     153class Security extends Trac {
     154    protected $public = false;
     155    protected $commits = false;
     156}
     157
     158class WordCamp extends Trac {
     159    protected $name = 'Private WordCamp.org';
     160    protected $public = false;
     161}
     162
  • sites/trunk/svn.wordpress.org/includes/slack-trac-hooks/trac/trac.php

    r1080 r1121  
    11<?php
    22
    3 namespace Dotorg\SlackTracHooks;
    4 
    5 abstract class Trac {
    6     protected $commit_channels = '#test';
    7     protected $commit_username = 'Commit';
    8     protected $ticket_channels = '#test';
     3namespace Dotorg\Slack\Trac;
     4use Dotorg\Slack\User;
     5
     6class Trac implements User {
     7    protected $public = true;
     8    protected $commits = true;
     9    protected $tickets = true;
     10
     11    protected $primary_channel  = '#test';
     12    protected $tickets_channel  = false;
     13    protected $commits_channel  = false;
     14    protected $firehose_channel = false;
     15    protected $commit_username;
    916    protected $ticket_username;
    1017
    11     protected $firehose_channel = false;
    12 
    13     protected $color    = '#21759b';
    14     protected $emoji    = ':wordpress:';
     18    // 'title', 'fields', 'description'
     19    protected $primary_channel_ticket_format = 'description';
     20
     21    protected $bypass_primary_channel_for_commit_filter_matches = false;
     22    protected $bypass_primary_channel_for_ticket_filter_matches = false;
     23
     24    protected $commit_path_filters = array();
     25    protected $ticket_component_filters = array();
     26
     27    protected $color = '#21759b';
     28    protected $icon  = ':wordpress:';
    1529
    1630    protected $ticket_template = 'https://%s.trac.wordpress.org/ticket/%s';
    1731    protected $commit_template = 'https://%s.trac.wordpress.org/changeset/%s';
    18     protected $ticket_range = array( 1, 5 );
    19     protected $commit_range = array( 1, 5 );
    20 
    21     function __construct() {
    22         // 'Dotorg\SlackTracHooks\Core_Trac' => 'Core_Trac'
    23         $class = str_replace( __NAMESPACE__ . '\\', '', get_class( $this ) );
    24 
    25         // 'Core_Trac' => 'core'
    26         $this->trac = strtolower( str_replace( '_Trac', '', $class ) );
     32    protected $commit_info_template = 'https://%s.trac.wordpress.org/log/?rev=%s&format=changelog&limit=1&verbose=on';
     33
     34    const min_digits = 2;
     35    const max_digits = 5;
     36
     37    static protected $shorthands = array(
     38        'wp'        => 'core',
     39        'wordpress' => 'core',
     40        'develop'   => 'core',
     41        'bb'        => 'bbpress',
     42    );
     43
     44    protected function __construct() {
     45        if ( isset( $this->trac, $this->name ) ) {
     46            return;
     47        }
     48
     49        // 'Dotorg\Slack\Trac\Tracs\Core' => 'Core'
     50        $class = str_replace( __NAMESPACE__ . '\\Tracs\\', '', get_class( $this ) );
     51
     52        if ( ! isset( $this->trac ) ) {
     53            $this->trac = strtolower( $class );
     54        }
     55
     56        if ( ! isset( $this->name ) ) {
     57            $this->name = str_replace( '_', ' ', $class );
     58        }
    2759
    2860        if ( ! isset( $this->ticket_username ) ) {
    29             // 'Core_Trac' => 'Core Trac'
    30             $this->ticket_username = str_replace( '_', ' ', $class );
    31         }
     61            $this->ticket_username = $this->name . ' Trac';
     62        }
     63
     64        if ( ! isset( $this->commit_username ) ) {
     65            $this->commit_username = $this->name . ' commit';
     66        }
     67
     68        foreach ( $this->commit_path_filters as $path => $channel ) {
     69            if ( is_string( $channel ) ) {
     70                $this->commit_path_filters[ $path ] = array( $channel => true );
     71            }
     72            if ( $this->bypass_primary_channel_for_commit_filter_matches && empty( $this->commit_path_filters[ $path ][ $this->primary_channel ] ) ) {
     73                $this->commit_path_filters[ $path ][ $this->primary_channel ] = false;
     74            }
     75        }
     76
     77        foreach ( $this->ticket_component_filters as $component => $channel ) {
     78            if ( is_string( $channel ) ) {
     79                $this->ticket_component_filters[ $component ] = array( $channel => true );
     80            }
     81            if ( $this->bypass_primary_channel_for_ticket_filter_matches && empty( $this->ticket_component_filters[ $path ][ $this->primary_channel ] ) ) {
     82                $this->ticket_component_filters[ $path ][ $this->primary_channel ] = false;
     83            }
     84        }
     85    }
     86
     87    static function get( $trac ) {
     88        require_once __DIR__ . '/config.php';
     89        if ( $trac instanceof Trac ) {
     90            return $trac;
     91        }
     92
     93        $ns = __NAMESPACE__ . '\\Tracs\\';
     94
     95        $class = $ns . $trac;   
     96        if ( class_exists( $class ) ) {
     97            return new $class;
     98        }
     99
     100        if ( isset( self::$shorthands[ $trac ] ) ) {
     101            $class = $ns . self::$shorthands[ $trac ];
     102            return new $class;
     103        }
     104       
     105        if ( preg_match( '~([a-z]+).trac.wordpress.org~', $url, $match ) ) {
     106            $class = $ns . $match[1];
     107            if ( class_exists( $class ) ) {
     108                return new $class;
     109            }
     110        }
     111
     112        return false;
     113    }
     114
     115    static function get_regex() {
     116        return implode( '|', array_merge( self::get_registered_tracs(), array_keys( self::$shorthands ) ) );
     117    }
     118
     119    static function get_registered_tracs() {
     120        require_once __DIR__ . '/config.php';
     121        $classes = get_declared_classes();
     122        $tracs = array();
     123
     124        foreach ( $classes as $key => $class ) {
     125            if ( 0 !== strpos( $class, __NAMESPACE__ . '\\Tracs\\' ) ) {
     126                continue;
     127            }
     128
     129            $tracs[] = strtolower( str_replace( array( __NAMESPACE__ . '\\Tracs\\', '_' ), array( '', '-' ), $class ) );
     130        }
     131
     132        return $tracs;
     133    }
     134
     135    function get_slug() {
     136        return $this->trac;
    32137    }
    33138
     
    44149    }
    45150
    46     function get_emoji() {
    47         return $this->emoji;
     151    function get_name() {
     152        return $this->name . ' Trac';
     153    }
     154
     155    function get_icon() {
     156        return $this->icon;
     157    }
     158
     159    function get_ticket_url( $ticket ) {
     160        return $this->get_ticket_template( $ticket );
    48161    }
    49162
     
    52165    }
    53166
     167    function get_commit_url( $commit ) {
     168        return $this->get_commit_template( $commit );
     169    }
     170
    54171    function get_commit_template( $template = '%s' ) {
    55172        return sprintf( $this->commit_template, $this->trac, $template );
    56173    }
    57174
    58     function get_digit_capture( $range ) {
    59         $min = $range[0] - 1;
    60         $max = $range[1] - 1;
    61         return '[0-9]\d{' . $min . ',' . $max . '}';
     175    function get_commit_info_url( $commit ) {
     176        return sprintf( $this->commit_info_template, $this->trac, $commit );
     177    }
     178
     179    function is_public() {
     180        return (bool) $this->public;
     181    }
     182
     183    function has_tickets() {
     184        return (bool) $this->tickets;
     185    }
     186
     187    function has_commits() {
     188        return (bool) $this->commits;
     189    }
     190
     191    static function get_digit_capture() {
     192        $min = self::min_digits - 1;
     193        $max = self::max_digits - 1;
     194        return '[1-9][0-9]{' . $min . ',' . $max . '}';
    62195    }
    63196
    64197    function get_log_replacements() {
    65198        $commit_template = $this->get_commit_template( '$1' );
    66         $ticket_digits = $this->get_digit_capture( $this->ticket_range );
    67         $commit_digits = $this->get_digit_capture( $this->commit_range );
     199        $digits = self::get_digit_capture();
    68200
    69201        return array(
    70             "/#($ticket_digits)\b/"   => $this->get_ticket_template( '$1' ),
    71             "/\[($commit_digits)\]/"  => $commit_template,
    72             "/\br($commit_digits)\b/" => $commit_template,
     202            "/#($digits)\b/"   => $this->get_ticket_template( '$1' ),
     203            "/\[($digits)\]/"  => $commit_template,
     204            "/\br($digits)\b/" => $commit_template,
    73205        );
    74206    }
    75207
    76208    function get_commit_channels( $changed_files = null ) {
    77         $channels = (array) $this->commit_channels;
    78 
    79         if ( ! empty( $this->firehose_channel ) ) {
    80             $channels[] = $this->firehose_channel;
    81         }
    82 
    83         if ( empty( $this->commit_path_filters ) || empty( $changed_files ) ) {
    84             return $channels;
     209        $channels = array();
     210
     211        if ( $this->primary_channel ) {
     212            $channels[ $this->primary_channel ] = true;
     213        }
     214
     215        if ( $this->commits_channel ) {
     216            $channels[ $this->commits_channel ] = true;
    85217        }
    86218
     
    95227            }
    96228        }
    97    
    98         return $channels;
     229
     230        if ( $this->firehose_channel ) {
     231            $channels[ $this->firehose_channel ] = true;
     232        }
     233
     234        return array_keys( array_filter( $channels ) );
    99235    }
    100236
    101237    function get_ticket_channels( $ticket = null ) {
    102         $channels = (array) $this->ticket_channels;
    103 
    104         if ( ! empty( $this->firehose_channel ) ) {
    105             $channels[] = $this->firehose_channel;
    106         }
    107 
    108         if ( empty( $this->ticket_component_filters ) || empty( $ticket ) ) {
    109             return $channels;
     238        $channels = array();
     239
     240        if ( $this->primary_channel ) {
     241            $channels[ $this->primary_channel ] = true;
     242        }
     243
     244        if ( $this->tickets_channel ) {
     245            $channels[ $this->tickets_channel ] = true;
    110246        }
    111247
     
    121257            }
    122258        }
    123         return $channels;
     259
     260        if ( $this->firehose_channel ) {
     261            $channels[ $this->firehose_channel ] = true;
     262        }
     263
     264        return array_keys( array_filter( $channels ) );
    124265    }
    125266
     
    127268        return $this->firehose_channel;
    128269    }
     270
     271    function get_ticket_format( $channel ) {
     272        if ( $channel === $this->primary_channel ) {
     273            return $this->primary_channel_ticket_format;
     274        }       
     275        return 'description';
     276    }
     277
     278    function format_for_slack( $text ) {
     279        $text = str_replace( "\r\n", "\n", $text );
     280        $text = trim( str_replace(
     281            array( "\n{{{\n", "\n}}}\n", '{{{', '}}}' ),   
     282            array( "\n```\n", "\n```\n", '`',   '`' ),
     283            "\n$text\n"
     284        ), "\n" );
     285
     286        // TODO: bold, italic, links
     287
     288        return $text;
     289    }
    129290}
    130 
Note: See TracChangeset for help on using the changeset viewer.