DCausse has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/404428 )
Change subject: Unify profiles with i18n messages ...................................................................... Unify profiles with i18n messages Add i18n_msg data to suggest profiles Unify handling of exported profiles from CirrusSearch::getProfiles Bug: T183279 Change-Id: If909d89f0afaf4e417ad60f8ef084adab454257c --- M includes/CirrusSearch.php M includes/Profile/CompletionSearchProfileRepository.php M includes/Query/CompSuggestQueryBuilder.php M profiles/SuggestProfiles.config.php M tests/unit/CompletionSuggesterTest.php M tests/unit/Profile/CompletionSearchProfileRepositoryTest.php M tests/unit/Profile/SearchProfileServiceFactoryTest.php 7 files changed, 331 insertions(+), 271 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CirrusSearch refs/changes/28/404428/1 diff --git a/includes/CirrusSearch.php b/includes/CirrusSearch.php index 6aa19a5..6a9b280 100644 --- a/includes/CirrusSearch.php +++ b/includes/CirrusSearch.php @@ -642,51 +642,43 @@ */ public function getProfiles( $profileType, User $user = null ) { $profileService = $this->config->getProfileService(); + $profileType = null; + $profileContext = SearchProfileService::CONTEXT_DEFAULT; switch ( $profileType ) { case SearchEngine::COMPLETION_PROFILE_TYPE: - if ( $this->config->get( 'CirrusSearchUseCompletionSuggester' ) == 'no' ) { - // No profile selection if completion suggester is disabled. - return []; + if ( $this->config->get( 'CirrusSearchUseCompletionSuggester' ) !== 'no' ) { + $profileType = SearchProfileService::COMPLETION; } - - $allowedProfiles = $profileService->listExposedProfiles( SearchProfileService::COMPLETION ); - // Only check user options if the user is logged to avoid loading - // default user options. - $userDefault = $profileService->getProfileNameFromContext( SearchProfileService::COMPLETION, - SearchProfileService::CONTEXT_DEFAULT ); - - $profiles = []; - foreach ( array_keys( $allowedProfiles ) as $name ) { - $profiles[] = [ - 'name' => $name, - 'desc-message' => 'cirrussearch-completion-profile-' . $name, - 'default' => $userDefault === $name, - ]; - } - return $profiles; + break; case SearchEngine::FT_QUERY_INDEP_PROFILE_TYPE: - $profiles = []; - $cirrusDefault = $profileService->getProfileNameFromContext( SearchProfileService::RESCORE, SearchProfileService::CONTEXT_DEFAULT ); - $defaultFound = false; - foreach ( $profileService->listExposedProfiles( SearchProfileService::RESCORE ) as $name => $profile ) { - $default = $cirrusDefault === $name; - $defaultFound |= $default; - $profiles[] = [ - 'name' => $name, - // @todo: decide what to with profiles we declare - // in wmf-config with no i18n messages. - // Do we want to expose them anyway, or simply - // hide them but still allow Api to pass them to us. - // It may require a change in core since ApiBase is - // strict and won't allow unknown values to be set - // here. - 'desc-message' => isset( $profile['i18n_msg'] ) ? $profile['i18n_msg'] : null, - 'default' => $default, - ]; - } - return $profiles; + $profileType = SearchProfileService::RESCORE; + break; } - return null; + + if ( $profileType === null ) { + return null; + } + + $allowedProfiles = $profileService->listExposedProfiles( $profileType ); + $default = $profileService->getProfileNameFromContext( $profileType, + $profileContext ); + + $profiles = []; + foreach ( $allowedProfiles as $name => $profile ) { + // @todo: decide what to with profiles we declare + // in wmf-config with no i18n messages. + // Do we want to expose them anyway, or simply + // hide them but still allow Api to pass them to us. + // It may require a change in core since ApiBase is + // strict and won't allow unknown values to be set + // here. + $profiles[] = [ + 'name' => $name, + 'desc-message' => isset( $profile['i18n_msg'] ) ? $profile['i18n_msg'] : null, + 'default' => $default === $name, + ]; + } + return $profiles; } /** diff --git a/includes/Profile/CompletionSearchProfileRepository.php b/includes/Profile/CompletionSearchProfileRepository.php index c0b0d5a..ea80b1a 100644 --- a/includes/Profile/CompletionSearchProfileRepository.php +++ b/includes/Profile/CompletionSearchProfileRepository.php @@ -37,7 +37,10 @@ } foreach ( $originalProfiles as $name => $settings ) { $allowed = true; - foreach ( $settings as $value ) { + if ( !isset( $settings['fst'] ) ) { + throw new SearchProfileException( "Completion profile $name must have a fst key defined" ); + } + foreach ( $settings['fst'] as $value ) { if ( empty( $allowedFields[$value['field']] ) ) { $allowed = false; break; diff --git a/includes/Query/CompSuggestQueryBuilder.php b/includes/Query/CompSuggestQueryBuilder.php index 7b54095..fe64766 100644 --- a/includes/Query/CompSuggestQueryBuilder.php +++ b/includes/Query/CompSuggestQueryBuilder.php @@ -49,7 +49,7 @@ */ public function __construct( SearchContext $context, array $profile, $limit, $offset = 0 ) { $this->searchContext = $context; - $this->profile = $profile; + $this->profile = $profile['fst']; $this->hardLimit = self::computeHardLimit( $limit, $offset, $context->getConfig() ); if ( $limit > $this->hardLimit - $offset ) { $limit = $this->hardLimit - $offset; diff --git a/profiles/SuggestProfiles.config.php b/profiles/SuggestProfiles.config.php index 2e450dd..81ece56 100644 --- a/profiles/SuggestProfiles.config.php +++ b/profiles/SuggestProfiles.config.php @@ -31,243 +31,264 @@ return [ // Strict profile (no accent squasing) 'strict' => [ - 'plain-strict' => [ - 'field' => 'suggest', - 'min_query_len' => 0, - 'discount' => 1.0, - 'fetch_limit_factor' => 2, + 'i18n_msg' => 'cirrussearch-completion-profile-strict', + 'fst' => [ + 'plain-strict' => [ + 'field' => 'suggest', + 'min_query_len' => 0, + 'discount' => 1.0, + 'fetch_limit_factor' => 2, + ], ], ], // Accent squashing and stopwords filtering 'normal' => [ - 'plain-normal' => [ - 'field' => 'suggest', - 'min_query_len' => 0, - 'discount' => 1.0, - 'fetch_limit_factor' => 2, - ], - 'plain-stop-normal' => [ - 'field' => 'suggest-stop', - 'min_query_len' => 0, - 'discount' => 0.001, - 'fetch_limit_factor' => 2, + 'i18n_msg' => 'cirrussearch-completion-profile-normal', + 'fst' => [ + 'plain-normal' => [ + 'field' => 'suggest', + 'min_query_len' => 0, + 'discount' => 1.0, + 'fetch_limit_factor' => 2, + ], + 'plain-stop-normal' => [ + 'field' => 'suggest-stop', + 'min_query_len' => 0, + 'discount' => 0.001, + 'fetch_limit_factor' => 2, + ], ], ], // Normal with subphrases 'normal-subphrases' => [ - 'plain-normal' => [ - 'field' => 'suggest', - 'min_query_len' => 0, - 'discount' => 1.0, - 'fetch_limit_factor' => 2, - ], - 'plain-stop-normal' => [ - 'field' => 'suggest-stop', - 'min_query_len' => 0, - 'discount' => 0.001, - 'fetch_limit_factor' => 2, - ], - 'plain-subphrase' => [ - 'field' => 'suggest-subphrases', - 'min_query_len' => 0, - 'discount' => 0.0001, - 'fetch_limit_factor' => 2, + 'i18n_msg' => 'cirrussearch-completion-profile-normal-subphrases', + 'fst' => [ + 'plain-normal' => [ + 'field' => 'suggest', + 'min_query_len' => 0, + 'discount' => 1.0, + 'fetch_limit_factor' => 2, + ], + 'plain-stop-normal' => [ + 'field' => 'suggest-stop', + 'min_query_len' => 0, + 'discount' => 0.001, + 'fetch_limit_factor' => 2, + ], + 'plain-subphrase' => [ + 'field' => 'suggest-subphrases', + 'min_query_len' => 0, + 'discount' => 0.0001, + 'fetch_limit_factor' => 2, + ], ], ], // Default profile 'fuzzy' => [ - // Defines the list of suggest queries to run in the same request. - // key is the name of the suggestion request - 'plain' => [ - // Field to request - 'field' => 'suggest', - // Fire the request only if the user query has min_query_len chars. - // See max_query_len to limit on max. - 'min_query_len' => 0, - // Discount result scores for this request - // Useful to discount fuzzy request results - 'discount' => 1.0, - // Fetch more results than the limit - // It's possible to have the same page multiple times - // (title and redirect suggestion). - // Requesting more than the limit helps to display the correct number - // of suggestions - 'fetch_limit_factor' => 2, - ], - 'plain_stop' => [ - 'field' => 'suggest-stop', - 'min_query_len' => 0, - 'discount' => 0.001, - 'fetch_limit_factor' => 2, - ], - // Fuzzy query for query length (3 to 4) with prefix len 1 - 'plain_fuzzy_2' => [ - 'field' => 'suggest', - 'min_query_len' => 3, - 'max_query_len' => 4, - 'discount' => 0.000001, - 'fetch_limit_factor' => 2, - 'fuzzy' => [ - 'fuzziness' => 'AUTO', - 'prefix_length' => 1, - 'unicode_aware' => true, + 'i18n_msg' => 'cirrussearch-completion-profile-fuzzy', + 'fst' => [ + // Defines the list of suggest queries to run in the same request. + // key is the name of the suggestion request + 'plain' => [ + // Field to request + 'field' => 'suggest', + // Fire the request only if the user query has min_query_len chars. + // See max_query_len to limit on max. + 'min_query_len' => 0, + // Discount result scores for this request + // Useful to discount fuzzy request results + 'discount' => 1.0, + // Fetch more results than the limit + // It's possible to have the same page multiple times + // (title and redirect suggestion). + // Requesting more than the limit helps to display the correct number + // of suggestions + 'fetch_limit_factor' => 2, + ], + 'plain_stop' => [ + 'field' => 'suggest-stop', + 'min_query_len' => 0, + 'discount' => 0.001, + 'fetch_limit_factor' => 2, + ], + // Fuzzy query for query length (3 to 4) with prefix len 1 + 'plain_fuzzy_2' => [ + 'field' => 'suggest', + 'min_query_len' => 3, + 'max_query_len' => 4, + 'discount' => 0.000001, + 'fetch_limit_factor' => 2, + 'fuzzy' => [ + 'fuzziness' => 'AUTO', + 'prefix_length' => 1, + 'unicode_aware' => true, + ] + ], + 'plain_stop_fuzzy_2' => [ + 'field' => 'suggest-stop', + 'min_query_len' => 3, + 'max_query_len' => 4, + 'discount' => 0.0000001, + 'fetch_limit_factor' => 1, + 'fuzzy' => [ + 'fuzziness' => 'AUTO', + 'prefix_length' => 2, + 'unicode_aware' => true, + ] + ], + // Fuzzy query for query length > 5 with prefix len 0 + 'plain_fuzzy_1' => [ + 'field' => 'suggest', + 'min_query_len' => 5, + 'discount' => 0.000001, + 'fetch_limit_factor' => 1, + 'fuzzy' => [ + 'fuzziness' => 'AUTO', + 'prefix_length' => 1, + 'unicode_aware' => true, + ] + ], + 'plain_stop_fuzzy_1' => [ + 'field' => 'suggest-stop', + 'min_query_len' => 5, + 'discount' => 0.0000001, + 'fetch_limit_factor' => 1, + 'fuzzy' => [ + 'fuzziness' => 'AUTO', + 'prefix_length' => 1, + 'unicode_aware' => true, + ] ] ], - 'plain_stop_fuzzy_2' => [ - 'field' => 'suggest-stop', - 'min_query_len' => 3, - 'max_query_len' => 4, - 'discount' => 0.0000001, - 'fetch_limit_factor' => 1, - 'fuzzy' => [ - 'fuzziness' => 'AUTO', - 'prefix_length' => 2, - 'unicode_aware' => true, - ] - ], - // Fuzzy query for query length > 5 with prefix len 0 - 'plain_fuzzy_1' => [ - 'field' => 'suggest', - 'min_query_len' => 5, - 'discount' => 0.000001, - 'fetch_limit_factor' => 1, - 'fuzzy' => [ - 'fuzziness' => 'AUTO', - 'prefix_length' => 1, - 'unicode_aware' => true, - ] - ], - 'plain_stop_fuzzy_1' => [ - 'field' => 'suggest-stop', - 'min_query_len' => 5, - 'discount' => 0.0000001, - 'fetch_limit_factor' => 1, - 'fuzzy' => [ - 'fuzziness' => 'AUTO', - 'prefix_length' => 1, - 'unicode_aware' => true, - ] - ] ], // Experimental profile, we fire a single suggest query per field // problem is that a fuzzy match on plain will certainly // win against a non fuzzy match on plain_stop... 'fast-fuzzy' => [ - 'plain' => [ - 'field' => 'suggest', - 'min_query_len' => 0, - 'discount' => 1.0, - 'fetch_limit_factor' => 2, - // Fuzzy is fired after 3 chars - // with auto edit distance based input length - // (see https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#fuzziness ) - 'fuzzy' => [ - 'fuzziness' => 'AUTO', - 'unicode_aware' => true, - ] - ], - 'plain_stop' => [ - 'field' => 'suggest-stop', - 'min_query_len' => 0, - 'discount' => 0.01, - 'fetch_limit_factor' => 2, - 'fuzzy' => [ - 'fuzziness' => 'AUTO', - 'unicode_aware' => true, - ] + 'i18n_msg' => 'cirrussearch-completion-profile-fast-fuzzy', + 'fst' => [ + 'plain' => [ + 'field' => 'suggest', + 'min_query_len' => 0, + 'discount' => 1.0, + 'fetch_limit_factor' => 2, + // Fuzzy is fired after 3 chars + // with auto edit distance based input length + // (see https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#fuzziness ) + 'fuzzy' => [ + 'fuzziness' => 'AUTO', + 'unicode_aware' => true, + ] + ], + 'plain_stop' => [ + 'field' => 'suggest-stop', + 'min_query_len' => 0, + 'discount' => 0.01, + 'fetch_limit_factor' => 2, + 'fuzzy' => [ + 'fuzziness' => 'AUTO', + 'unicode_aware' => true, + ] + ], ], ], 'fuzzy-subphrases' => [ - // Defines the list of suggest queries to run in the same request. - // key is the name of the suggestion request - 'plain' => [ - // Field to request - 'field' => 'suggest', - // Fire the request only if the user query has min_query_len chars. - // See max_query_len to limit on max. - 'min_query_len' => 0, - // Discount result scores for this request - // Useful to discount fuzzy request results - 'discount' => 1.0, - // Fetch more results than the limit - // It's possible to have the same page multiple times - // (title and redirect suggestion). - // Requesting more than the limit helps to display the correct number - // of suggestions - 'fetch_limit_factor' => 2, - ], - 'plain_stop' => [ - 'field' => 'suggest-stop', - 'min_query_len' => 0, - 'discount' => 0.001, - 'fetch_limit_factor' => 2, - ], - 'subphrases' => [ - 'field' => 'suggest-subphrases', - 'min_query_len' => 0, - 'discount' => 0.0001, - 'fetch_limit_factor' => 2, - ], - // Fuzzy query for query length (3 to 4) with prefix len 1 - 'plain_fuzzy_2' => [ - 'field' => 'suggest', - 'min_query_len' => 3, - 'max_query_len' => 4, - 'discount' => 0.000001, - 'fetch_limit_factor' => 2, - 'fuzzy' => [ - 'fuzziness' => 'AUTO', - 'prefix_length' => 1, - 'unicode_aware' => true, + 'i18n_msg' => 'cirrussearch-completion-profile-fuzzy-subphrases', + 'fst' => [ + // Defines the list of suggest queries to run in the same request. + // key is the name of the suggestion request + 'plain' => [ + // Field to request + 'field' => 'suggest', + // Fire the request only if the user query has min_query_len chars. + // See max_query_len to limit on max. + 'min_query_len' => 0, + // Discount result scores for this request + // Useful to discount fuzzy request results + 'discount' => 1.0, + // Fetch more results than the limit + // It's possible to have the same page multiple times + // (title and redirect suggestion). + // Requesting more than the limit helps to display the correct number + // of suggestions + 'fetch_limit_factor' => 2, + ], + 'plain_stop' => [ + 'field' => 'suggest-stop', + 'min_query_len' => 0, + 'discount' => 0.001, + 'fetch_limit_factor' => 2, + ], + 'subphrases' => [ + 'field' => 'suggest-subphrases', + 'min_query_len' => 0, + 'discount' => 0.0001, + 'fetch_limit_factor' => 2, + ], + // Fuzzy query for query length (3 to 4) with prefix len 1 + 'plain_fuzzy_2' => [ + 'field' => 'suggest', + 'min_query_len' => 3, + 'max_query_len' => 4, + 'discount' => 0.000001, + 'fetch_limit_factor' => 2, + 'fuzzy' => [ + 'fuzziness' => 'AUTO', + 'prefix_length' => 1, + 'unicode_aware' => true, + ] + ], + 'plain_stop_fuzzy_2' => [ + 'field' => 'suggest-stop', + 'min_query_len' => 3, + 'max_query_len' => 4, + 'discount' => 0.0000001, + 'fetch_limit_factor' => 1, + 'fuzzy' => [ + 'fuzziness' => 'AUTO', + 'prefix_length' => 2, + 'unicode_aware' => true, + ] + ], + // Fuzzy query for query length > 5 with prefix len 0 + 'plain_fuzzy_1' => [ + 'field' => 'suggest', + 'min_query_len' => 5, + 'discount' => 0.000001, + 'fetch_limit_factor' => 1, + 'fuzzy' => [ + 'fuzziness' => 'AUTO', + 'prefix_length' => 1, + 'unicode_aware' => true, + ] + ], + 'plain_stop_fuzzy_1' => [ + 'field' => 'suggest-stop', + 'min_query_len' => 5, + 'discount' => 0.0000001, + 'fetch_limit_factor' => 1, + 'fuzzy' => [ + 'fuzziness' => 'AUTO', + 'prefix_length' => 1, + 'unicode_aware' => true, + ] + ], + 'subphrases_fuzzy_1' => [ + 'field' => 'suggest-subphrases', + 'min_query_len' => 5, + 'discount' => 0.00000001, + 'fetch_limit_factor' => 1, + 'fuzzy' => [ + 'fuzziness' => 'AUTO', + 'prefix_length' => 1, + 'unicode_aware' => true, + ] ] ], - 'plain_stop_fuzzy_2' => [ - 'field' => 'suggest-stop', - 'min_query_len' => 3, - 'max_query_len' => 4, - 'discount' => 0.0000001, - 'fetch_limit_factor' => 1, - 'fuzzy' => [ - 'fuzziness' => 'AUTO', - 'prefix_length' => 2, - 'unicode_aware' => true, - ] - ], - // Fuzzy query for query length > 5 with prefix len 0 - 'plain_fuzzy_1' => [ - 'field' => 'suggest', - 'min_query_len' => 5, - 'discount' => 0.000001, - 'fetch_limit_factor' => 1, - 'fuzzy' => [ - 'fuzziness' => 'AUTO', - 'prefix_length' => 1, - 'unicode_aware' => true, - ] - ], - 'plain_stop_fuzzy_1' => [ - 'field' => 'suggest-stop', - 'min_query_len' => 5, - 'discount' => 0.0000001, - 'fetch_limit_factor' => 1, - 'fuzzy' => [ - 'fuzziness' => 'AUTO', - 'prefix_length' => 1, - 'unicode_aware' => true, - ] - ], - 'subphrases_fuzzy_1' => [ - 'field' => 'suggest-subphrases', - 'min_query_len' => 5, - 'discount' => 0.00000001, - 'fetch_limit_factor' => 1, - 'fuzzy' => [ - 'fuzziness' => 'AUTO', - 'prefix_length' => 1, - 'unicode_aware' => true, - ] - ] ], // Special profile to fallback to prefix search - 'classic' => [], + 'classic' => [ + 'i18n_msg' => 'cirrussearch-completion-profile-classic', + 'fst' => [], + ], ]; diff --git a/tests/unit/CompletionSuggesterTest.php b/tests/unit/CompletionSuggesterTest.php index d5dfa7c..140d139 100644 --- a/tests/unit/CompletionSuggesterTest.php +++ b/tests/unit/CompletionSuggesterTest.php @@ -79,8 +79,12 @@ ]; $profile = [ - 'test-simple' => $simpleProfile, - 'test-fuzzy' => $simpleFuzzy, + 'test-simple' => [ + 'fst' => $simpleProfile + ], + 'test-fuzzy' => [ + 'fst' => $simpleFuzzy, + ] ]; return [ @@ -205,7 +209,7 @@ $suggest = $completion->build( $query, [] )->toArray()['suggest']; $profiles = $completion->getMergedProfiles(); // Unused profiles are kept - $this->assertEquals( count( $config->getProfileService()->loadProfileByName( SearchProfileService::COMPLETION, 'fuzzy' ) ), count( $profiles ) ); + $this->assertEquals( count( $config->getProfileService()->loadProfileByName( SearchProfileService::COMPLETION, 'fuzzy' )['fst'] ), count( $profiles ) ); // Never run more than 4 suggest query (without variants) $this->assertTrue( count( $suggest ) <= 4 ); // small queries diff --git a/tests/unit/Profile/CompletionSearchProfileRepositoryTest.php b/tests/unit/Profile/CompletionSearchProfileRepositoryTest.php index 00a7db0..ff98794 100644 --- a/tests/unit/Profile/CompletionSearchProfileRepositoryTest.php +++ b/tests/unit/Profile/CompletionSearchProfileRepositoryTest.php @@ -20,22 +20,26 @@ // Without subphrases the normal-subphrases is hidden $profiles = [ 'normal' => [ - 'plain-normal' => [ - 'field' => 'suggest', - ], - 'plain-stop-normal' => [ - 'field' => 'suggest-stop' + 'fst' => [ + 'plain-normal' => [ + 'field' => 'suggest', + ], + 'plain-stop-normal' => [ + 'field' => 'suggest-stop' + ], ], ], 'normal-subphrases' => [ - 'plain-normal' => [ - 'field' => 'suggest', - ], - 'plain-stop-normal' => [ - 'field' => 'suggest-stop', - ], - 'plain-subphrase' => [ - 'field' => 'suggest-subphrases', + 'fst' => [ + 'plain-normal' => [ + 'field' => 'suggest', + ], + 'plain-stop-normal' => [ + 'field' => 'suggest-stop', + ], + 'plain-subphrase' => [ + 'field' => 'suggest-subphrases', + ], ], ], ]; diff --git a/tests/unit/Profile/SearchProfileServiceFactoryTest.php b/tests/unit/Profile/SearchProfileServiceFactoryTest.php index 0e17572..5117c03 100644 --- a/tests/unit/Profile/SearchProfileServiceFactoryTest.php +++ b/tests/unit/Profile/SearchProfileServiceFactoryTest.php @@ -122,4 +122,40 @@ ], ]; } + + /** + * @dataProvider provideExposedProfileType + * @throws \Exception + * @throws \FatalError + * @throws \MWException + */ + public function testExportedProfilesWithI18N( $type, array $must_have ) { + $factory = new SearchProfileServiceFactory(); + $service = $factory->loadService( new HashSearchConfig( [] ) ); + $profiles = $service->listExposedProfiles( $type ); + + $seen = []; + foreach( $profiles as $name => $profile ) { + $this->assertArrayHasKey( 'i18n_msg', $profile, "Profile $name in $type has i18n_msg key" ); + $this->assertTrue( wfMessage( $profile['i18n_msg'] )->exists(), + "Profile $name in $type has i18n message set" ); + $seen[] = $name; + } + $missing = array_diff( $must_have, $seen ); + $this->assertEmpty( $missing, "Profiles of type $type must include all must_have profiles" ); + } + + public static function provideExposedProfileType() { + return [ + 'rescore' => [ + SearchProfileService::RESCORE, + [ 'classic', 'empty', 'classic_noboostlinks', 'wsum_inclinks', + 'wsum_inclinks_pv', 'popular_inclinks_pv', 'popular_inclinks' ] + ], + 'completion' => [ + SearchProfileService::COMPLETION, + [ 'classic', 'fuzzy', 'normal', 'strict' ] + ] + ]; + } } -- To view, visit https://gerrit.wikimedia.org/r/404428 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: If909d89f0afaf4e417ad60f8ef084adab454257c Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/CirrusSearch Gerrit-Branch: master Gerrit-Owner: DCausse <dcau...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits