From a35e8376553924b35d97a5648f5910da843eab49 Mon Sep 17 00:00:00 2001 From: Heavenfighter <33938595+Heavenfighter@users.noreply.github.com> Date: Wed, 15 Oct 2025 10:38:10 +0200 Subject: [PATCH] pre-commit checking adopted for current version --- Source/lang/strings_english.txt | 23 ++ Source/lang/strings_german.txt | 20 ++ Source/pages/pre_commit_check.php | 231 ++++++++++++++++++ Source/pages/repo_update.php | 19 ++ Source/pages/repo_update_page.php | 62 +++++ Source/pages/si_common.php | 8 + SourceHgWeb/lang/strings_english.txt | 11 + SourceHgWeb/lang/strings_german.txt | 32 +++ .../pre_commit.py.tmpl.mantis-checks-commit | 117 +++++++++ .../pre-commit.tmpl.mantis-checks-commit | 77 ++++++ 10 files changed, 600 insertions(+) create mode 100644 Source/pages/pre_commit_check.php create mode 100644 Source/pages/si_common.php create mode 100644 SourceHgWeb/lang/strings_german.txt create mode 100644 SourceHgWeb/pre_commit.py.tmpl.mantis-checks-commit create mode 100644 SourceSVN/pre-commit.tmpl.mantis-checks-commit diff --git a/Source/lang/strings_english.txt b/Source/lang/strings_english.txt index 6973b1fb1..464768021 100644 --- a/Source/lang/strings_english.txt +++ b/Source/lang/strings_english.txt @@ -35,6 +35,19 @@ $s_plugin_Source_filename = 'Filename'; $s_plugin_Source_ported = 'Ported'; $s_plugin_Source_vcs_username = 'Source Control Username'; +$s_plugin_Source_pre_commit_checks = 'Pre-Commit Checks'; +$s_plugin_Source_commit_needs_issue = 'Commit Requires Issue Reference(s)'; +$s_plugin_Source_commit_issues_must_exist = 'Referenced Issue(s) Must Exist'; +$s_plugin_Source_commit_ownership_must_match = 'Referenced Issue(s) Must Be Owned By Committer'; +$s_plugin_Source_commit_committer_must_be_member = 'Committer must be a member of the Mantis project'; +$s_plugin_Source_commit_committer_must_be_level = 'Committer must be a'; +$s_plugin_Source_commit_status_restricted = 'Referenced Issue(s) must be at a particular status'; +$s_plugin_Source_commit_status_restricted_list = 'Only allow commits when ticket is'; +$s_plugin_Source_commit_project_restricted = 'Referenced Issue(s) must be within a particular project'; +$s_plugin_Source_commit_project_restricted_list = 'Only allow commits when ticket is within'; +$s_plugin_Source_commit_on = 'On'; +$s_plugin_Source_commit_off = 'Off'; + $s_plugin_Source_issue = 'Issue'; $s_plugin_Source_issues = 'Issues'; $s_plugin_Source_actions = 'Actions'; @@ -147,6 +160,7 @@ $s_plugin_Source_invalid_checkin_url = 'Invalid remote check-in address'; $s_plugin_Source_invalid_import_url = 'Invalid remote import address'; $s_plugin_Source_invalid_repo = 'Invalid repository name'; $s_plugin_Source_invalid_changeset = 'Changeset information could not be loaded'; +$s_plugin_Source_invalid_key = 'Invalid API Key. Please check that you have set the API_KEY variable correctly in the hook script'; $s_plugin_Source_import_latest_failed = 'Repository latest data importing failed.'; $s_plugin_Source_import_full_failed = 'Full repository data importing failed.'; @@ -162,3 +176,12 @@ $s_plugin_Source_error_invalid_branch = 'Invalid characters in Branch name "%1$s $s_plugin_Source_error_productmatrix_not_loaded = 'Product Matrix integration is enabled, but the plugin is not loaded.'; $s_plugin_Source_error_repo_missing = 'Repository "%1$s" not found.'; $s_plugin_Source_error_repo_missing_changeset = 'No repositories found for Changeset "%1$s".'; + +$s_plugin_Source_error_commit_needs_issue = 'Commit comments needs to reference one or more issues'; +$s_plugin_Source_error_commit_nonexistent_issue = 'Commit comment references non-existent issue'; +$s_plugin_Source_error_commit_issue_ownership = 'Issue referenced in commit need to be assigned to the committer'; +$s_plugin_Source_error_commit_committer_not_member = 'Committing user is not a member of the Mantis project'; +$s_plugin_Source_error_commit_committer_not_fount = 'Committing user could not be found in Mantis'; +$s_plugin_Source_error_commit_committer_wrong_level = 'Committing user does not have appropriate access level in project'; +$s_plugin_Source_error_commit_issue_wrong_status = 'Issue referenced in commit is not at correct status to be committed against'; +$s_plugin_Source_error_commit_issue_wrong_project = 'Issue referenced in commit is within appropriate project'; \ No newline at end of file diff --git a/Source/lang/strings_german.txt b/Source/lang/strings_german.txt index 5c18aeae5..1135aedaa 100644 --- a/Source/lang/strings_german.txt +++ b/Source/lang/strings_german.txt @@ -25,6 +25,18 @@ $s_plugin_Source_username = 'Benutzer'; $s_plugin_Source_timestamp = 'Datum'; $s_plugin_Source_parent = 'Vorgänger'; $s_plugin_Source_url = 'URL'; +$s_plugin_Source_pre_commit_checks = 'Pre-Commit Checks'; +$s_plugin_Source_commit_needs_issue = 'Committext benötigt Beziehung zu mindestens einem Eintrag'; +$s_plugin_Source_commit_issues_must_exist = 'Eintrag muss existieren'; +$s_plugin_Source_commit_ownership_must_match = 'Eintrag muss Autor/Comitter gehören'; +$s_plugin_Source_commit_committer_must_be_member = 'Benutzer muss dem Projekt in Mantis angehören'; +$s_plugin_Source_commit_committer_must_be_level = 'Benutzer muss Rolle haben'; +$s_plugin_Source_commit_status_restricted = 'Referenzierte Einträge müssen einen bestimmten Status haben'; +$s_plugin_Source_commit_status_restricted_list = 'Commit nur zulassen für Einträge mit folgendem Status'; +$s_plugin_Source_commit_project_restricted = 'Referenzierte Einträge müssen zu einem bestimmten Projekt gehören'; +$s_plugin_Source_commit_project_restricted_list = 'Commit nur zulassen, wenn Eintrag aus Projekt'; +$s_plugin_Source_commit_on = 'An'; +$s_plugin_Source_commit_off = 'Aus'; $s_plugin_Source_info = 'Zusatzinfos'; $s_plugin_Source_revision = 'Revision'; $s_plugin_Source_date_begin = 'Beginn'; @@ -144,6 +156,14 @@ $s_plugin_Source_invalid_changeset = 'Die Informationen zu dem Änderungssatz ko $s_plugin_Source_import_latest_failed = 'Partieller Import des Projektarchivs fehlgeschlagen.'; $s_plugin_Source_import_full_failed = 'Vollständiger Import des Projektarchivs fehlgeschlagen.'; +$s_plugin_Source_error_commit_needs_issue = 'Kommentar muss einen oder mehrere Verweise auf Einträge enthalten'; +$s_plugin_Source_error_commit_nonexistent_issue = 'Committext verweist auf nicht existenten Eintrag'; +$s_plugin_Source_error_commit_issue_ownership = 'Verwiesener Eintrag muss dem Benutzer gehören'; +$s_plugin_Source_error_commit_committer_not_member = 'Benutzer ist nicht Mitglied des Mantisprojektes'; +$s_plugin_Source_error_commit_committer_not_found = 'Benutzer konnte nicht gefunden werden in Mantis'; +$s_plugin_Source_error_commit_committer_wrong_level = 'Benutzer hat unzureichende Rechte im Projekt'; +$s_plugin_Source_error_commit_issue_wrong_status = 'Verwiesener Eintrag hat nicht den korrekten Status'; +$s_plugin_Source_error_commit_issue_wrong_project = 'Verwiesener Eintrag ist nicht im zugelassenen Projekt'; $s_plugin_Source_changeset_column_title = 'C'; $s_plugin_Source_error_invalid_branch = 'Ungültige Zeichen in der Zweige "%1$s"'; diff --git a/Source/pages/pre_commit_check.php b/Source/pages/pre_commit_check.php new file mode 100644 index 000000000..39cf621a5 --- /dev/null +++ b/Source/pages/pre_commit_check.php @@ -0,0 +1,231 @@ +info['repo_commit_needs_issue'] ) ? $t_repo->info['repo_commit_needs_issue'] : false; +$t_repo_commit_issues_must_exist = isset( $t_repo->info['repo_commit_issues_must_exist'] ) ? $t_repo->info['repo_commit_issues_must_exist'] : false; +$t_repo_commit_ownership_must_match = isset( $t_repo->info['repo_commit_ownership_must_match'] ) ? $t_repo->info['repo_commit_ownership_must_match'] : false; +$t_repo_commit_status_restricted = isset( $t_repo->info['repo_commit_status_restricted'] ) ? $t_repo->info['repo_commit_status_restricted'] : false; +$t_repo_commit_status_allowed = isset( $t_repo->info['repo_commit_status_allowed'] ) ? $t_repo->info['repo_commit_status_allowed'] : ''; +$t_repo_commit_project_restricted = isset( $t_repo->info['repo_commit_project_restricted'] ) ? $t_repo->info['repo_commit_project_restricted'] : ''; +$t_repo_commit_project_allowed = isset( $t_repo->info['repo_commit_project_allowed'] ) ? $t_repo->info['repo_commit_project_allowed'] : ''; +$t_repo_commit_committer_must_be_member = isset( $t_repo->info['repo_commit_committer_must_be_member'] ) ? $t_repo->info['repo_commit_committer_must_be_member'] : ''; +$t_repo_commit_committer_must_be_level = isset( $t_repo->info['repo_commit_committer_must_be_level'] ) ? $t_repo->info['repo_commit_committer_must_be_level'] : MantisEnum::getValues( config_get( 'access_levels_enum_string' ) ) ; + +$t_all_ok = true; + +# Check number of bugs referenced in the commit comment +if(( sizeof( $t_bug_list ) == 0 ) && $t_repo_commit_needs_issue ) { + + # It was expected that the commit comment would reference one of more bug + # IDs but this was not the case + + printf( "Check-Message: '%s'\r\n",plugin_lang_get( 'error_commit_needs_issue' ) ); + $t_all_ok = false; + +} else { + + # Loop all the bug IDs referenced in the commit comment + foreach( $t_bug_list as $t_bug_id ) { + + # Check existence first to prevent API throwing an error + if( bug_exists( $t_bug_id ) ) { + + $t_bug = bug_get( $t_bug_id ); + + # Ownership of ticket must match committer? + if( $t_repo_commit_ownership_must_match ) { + + if( 0 == $t_bug->handler_id ) { + $t_user_name = 'none'; + $t_user_email = 'none'; + } else { + $t_user_name = user_get_name( $t_bug->handler_id ); + $t_user_email = user_get_email( $t_bug->handler_id ); + } + + # Check that the username of the committer matches the user name + # or e-mail address of the owner of the ticket + if( !( strlen( $f_committer_name ) && + (( $t_user_name == $f_committer_name ) || + ( $t_user_email == $f_committer_name )))) { + + printf( "Check-Message: '%s : %s %d", + plugin_lang_get( 'error_commit_issue_ownership' ), + plugin_lang_get( 'issue' ), + $t_bug_id ); + + if( $t_informational_errors ) { + + # Informative errors turned on so display the user to whom + # the ticket is assigned + printf( " (%s/%s vs %s)", + $t_user_name, $t_user_email, $f_committer_name ); + } + + printf( "'\r\n" ); + $t_all_ok = false; + } + } # End ownership must match ticket + + # Only allowed to commit against tickets with a specific status? + if( $t_repo_commit_status_restricted ) { + + # Check that the bug's status is at a level for which a commit + # is allowed + if( !in_array( $t_bug->status, $t_repo_commit_status_allowed )) { + + printf( "Check-Message: '%s : %s %d", + plugin_lang_get( 'error_commit_issue_wrong_status' ), + plugin_lang_get( 'issue' ), + $t_bug_id ); + + if( $t_informational_errors ) { + + # Informative errors turned on so display a list of statuses for which + # a commit would be accepted + + # Get an array of the names of the statuses for which commit is allowed + $t_statuses = array_map( function( $p_status ) { return get_enum_element( 'status', $p_status ); }, $t_repo_commit_status_allowed ); + + printf( " (%s vs %s)", + get_enum_element( 'status', $t_bug->status ), + implode( ", ", $t_statuses )); + } + printf( "'\r\n" ); + $t_all_ok = false; + } + } # End only allowed to commit against tickets with a specific status + + # Only allowed to commit against Mantis tickets within specific project(s) + if( $t_repo_commit_project_restricted ) { + + if( !in_array( 0, $t_repo_commit_project_allowed ) && + !in_array( $t_bug->project_id, $t_repo_commit_project_allowed )) { + + printf( "Check-Message: '%s : %s %d", + plugin_lang_get( 'error_commit_issue_wrong_project' ), + plugin_lang_get( 'issue' ), + $t_bug_id ); + + if( $t_informational_errors ) { + + # Informative errors turned on so display a list of Mantis projects to + # which referenced tickets must belong + + # Get an array of the names of all the projects + $t_projects = array_map( function( $p_proj ) { return project_get_field( $p_proj, 'name' ); }, $t_repo_commit_project_allowed ); + + printf( " (%s vs %s)", + project_get_field( $t_bug->project_id, 'name' ), + implode( $t_projects, ", " )); + } + + printf( "'\r\n" ); + $t_all_ok = false; + } + } # End only allowed to commit against tickets within specific projects + + # Committer must belong to the Mantis project? + if( $t_repo_commit_committer_must_be_member ) { + + $t_user_id = user_get_id_by_name( $f_committer_name ); + + # Didn't find the username? Try the e-mail address + if( $t_user_id == false ) { + + $t_user_id = user_get_id_by_email( $f_committer_name ); + } + + /* Check that the user exists in Mantis */ + if( $t_user_id == false ) { + + printf( "Check-Message: '%s : %s %d (%s)'\r\n", + plugin_lang_get( 'error_commit_committer_not_found' ), + plugin_lang_get( 'issue' ), + $t_bug_id, $f_committer_name ); + $t_all_ok = false; + + /* Check that the user is assigned to the project */ + } elseif( ! project_includes_user( $t_bug->project_id, $t_user_id )) { + printf( "Check-Message: '%s : %s %d (%s)'\r\n", + plugin_lang_get( 'error_commit_committer_not_member' ), + plugin_lang_get( 'issue' ), + $t_bug_id, $f_committer_name ); + $t_all_ok = false; + + } else { + + $t_user_access_level = access_get_local_level( $t_user_id, $t_bug->project_id ); + if( in_array( $t_user_access_level, $t_repo_commit_committer_must_be_level )) { + + printf( "Check-Message: '%s : %s %d", + plugin_lang_get( 'error_commit_committer_wrong_level' ), + plugin_lang_get( 'issue' ), + $t_bug_id ); + + if( $t_informational_errors ) { + + # Informative errors turned on so display a list of access levels + # for which commit is allowed + + $t_levels = MantisEnum::getAssocArrayIndexedByValues( config_get( 'access_levels_enum_string' ) ); + $t_allowed_levels = array_intersect_key( $t_levels, array_flip( $t_repo_commit_committer_must_be_level )); + + printf( " (%s vs %s)", + $t_levels[ $t_user_access_level ], + implode( ", ", array_values( $t_allowed_levels ) ) ); + } + printf( "'\r\n" ); + $t_all_ok = false; + } + } + } # End committer must belong to mantis project + } else { + + /* If the issue doesn't exist, then can't perform the checks */ + if( $t_repo_commit_issues_must_exist || + $t_repo_commit_ownership_must_match || + $t_repo_commit_status_restricted || + $t_repo_commit_project_restricted || + $t_repo_commit_committer_must_be_member ) { + + printf( "Check-Message: '%s : %s %d'\r\n", + plugin_lang_get( 'error_commit_nonexistent_issue' ), + plugin_lang_get( 'issue' ), + $t_bug_id ); + $t_all_ok = false; + } + } + } +} +printf( "Check-OK: %d\r\n",$t_all_ok ); + +?> \ No newline at end of file diff --git a/Source/pages/repo_update.php b/Source/pages/repo_update.php index f3d265a93..de172c7bf 100644 --- a/Source/pages/repo_update.php +++ b/Source/pages/repo_update.php @@ -10,12 +10,31 @@ $f_repo_name = gpc_get_string( 'repo_name' ); $f_repo_url = gpc_get_string( 'repo_url' ); +f_repo_commit_needs_issue = gpc_get_bool( 'repo_commit_needs_issue', false ); +$f_repo_commit_issues_must_exist = gpc_get_bool( 'repo_commit_issues_must_exist', false ); +$f_repo_commit_ownership_must_match = gpc_get_bool( 'repo_commit_ownership_must_match', false ); +$f_repo_commit_status_restricted = gpc_get_bool( 'repo_commit_status_restricted', false ); +$f_repo_commit_status_allowed = gpc_get_int_array( 'repo_commit_status_allowed', MantisEnum::getValues( config_get( 'status_enum_string' ) )); +$f_repo_commit_project_restricted = gpc_get_bool( 'repo_commit_project_restricted', false ); +$f_repo_commit_project_allowed = gpc_get_int_array( 'repo_commit_project_allowed', Array( 0 ) ); +$f_repo_commit_committer_must_be_member = gpc_get_bool( 'repo_commit_committer_must_be_member', false ); +$f_repo_commit_committer_must_be_level = gpc_get_int_array( 'repo_commit_committer_must_be_level', MantisEnum::getValues( config_get( 'access_levels_enum_string' ) )); + $t_repo = SourceRepo::load( $f_repo_id ); $t_vcs = SourceVCS::repo( $t_repo ); $t_type = SourceType($t_repo->type); $t_repo->name = $f_repo_name; $t_repo->url = $f_repo_url; +$t_repo->info['repo_commit_needs_issue'] = $f_repo_commit_needs_issue; +$t_repo->info['repo_commit_issues_must_exist'] = $f_repo_commit_issues_must_exist; +$t_repo->info['repo_commit_ownership_must_match'] = $f_repo_commit_ownership_must_match; +$t_repo->info['repo_commit_status_restricted'] = $f_repo_commit_status_restricted; +$t_repo->info['repo_commit_status_allowed'] = $f_repo_commit_status_allowed; +$t_repo->info['repo_commit_project_restricted'] = $f_repo_commit_project_restricted; +$t_repo->info['repo_commit_project_allowed'] = $f_repo_commit_project_allowed; +$t_repo->info['repo_commit_committer_must_be_member'] = $f_repo_commit_committer_must_be_member; +$t_repo->info['repo_commit_committer_must_be_level'] = $f_repo_commit_committer_must_be_level; /** @var SourceRepo $t_updated_repo */ $t_updated_repo = $t_vcs->update_repo( $t_repo ); diff --git a/Source/pages/repo_update_page.php b/Source/pages/repo_update_page.php index 19a16b120..893a8c002 100644 --- a/Source/pages/repo_update_page.php +++ b/Source/pages/repo_update_page.php @@ -12,6 +12,16 @@ $t_vcs = SourceVCS::repo( $t_repo ); $t_type = SourceType($t_repo->type); +$t_repo_commit_needs_issue = isset( $t_repo->info['repo_commit_needs_issue'] ) ? $t_repo->info['repo_commit_needs_issue'] : false; +$t_repo_commit_issues_must_exist = isset( $t_repo->info['repo_commit_issues_must_exist'] ) ? $t_repo->info['repo_commit_issues_must_exist'] : false; +$t_repo_commit_ownership_must_match = isset( $t_repo->info['repo_commit_ownership_must_match'] ) ? $t_repo->info['repo_commit_ownership_must_match'] : false; +$t_repo_commit_committer_must_be_member = isset( $t_repo->info['repo_commit_committer_must_be_member'] ) ? $t_repo->info['repo_commit_committer_must_be_member'] : false; +$t_repo_commit_committer_must_be_level = isset( $t_repo->info['repo_commit_committer_must_be_level'] ) ? $t_repo->info['repo_commit_committer_must_be_level'] : MantisEnum::getValues( config_get( 'access_levels_enum_string' ) ) ; +$t_repo_commit_status_restricted = isset( $t_repo->info['repo_commit_status_restricted'] ) ? $t_repo->info['repo_commit_status_restricted'] : false; +$t_repo_commit_status_allowed = isset( $t_repo->info['repo_commit_status_allowed'] ) ? $t_repo->info['repo_commit_status_allowed'] : MantisEnum::getValues( config_get( 'status_enum_string' )); +$t_repo_commit_project_restricted = isset( $t_repo->info['repo_commit_project_restricted'] ) ? $t_repo->info['repo_commit_project_restricted'] : false; +$t_repo_commit_project_allowed = isset( $t_repo->info['repo_commit_project_allowed'] ) ? $t_repo->info['repo_commit_project_allowed'] : Array( 0 ); + layout_page_header( plugin_lang_get( 'title' ) ); layout_page_begin(); @@ -69,6 +79,58 @@ update_repo_form( $t_repo ) ?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
/>
/>
/>
/>
/>
/>
+ + diff --git a/Source/pages/si_common.php b/Source/pages/si_common.php new file mode 100644 index 000000000..66b98bb01 --- /dev/null +++ b/Source/pages/si_common.php @@ -0,0 +1,8 @@ + \ No newline at end of file diff --git a/SourceHgWeb/lang/strings_english.txt b/SourceHgWeb/lang/strings_english.txt index 015bd2a46..02db7efcf 100644 --- a/SourceHgWeb/lang/strings_english.txt +++ b/SourceHgWeb/lang/strings_english.txt @@ -19,3 +19,14 @@ $s_plugin_SourceHgWeb_description = 'Adds HgWeb integration to the Source Integr $s_plugin_SourceHgWeb_hgweb_root = 'HgWeb Root URL'; $s_plugin_SourceHgWeb_hgweb_project = 'HgWeb Project
(name only)'; $s_plugin_SourceHgWeb_master_branch = 'Primary Branches
(comma-separated list)'; + +$s_plugin_SourceHgWeb_repo_commit_needs_issue = 'Commit Requires Issue Reference(s)'; +$s_plugin_SourceHgWeb_repo_commit_issues_must_exist = 'Referenced Issue(s) Must Exist'; +$s_plugin_SourceHgWeb_repo_commit_ownership_must_match = 'Referenced Issue(s) Must Be Owned By Committer'; +$s_plugin_SourceHgWeb_repo_commit_committer_must_be_member = 'Committer must be a member of the Mantis project'; +$s_plugin_SourceHgWeb_repo_commit_committer_must_be_level = 'Committer must be a:'; +$s_plugin_SourceHgWeb_repo_commit_status_restricted = 'Referenced Issue(s) must be at a particular status'; +$s_plugin_SourceHgWeb_repo_commit_status_allowed = 'Only allow commits when ticket is'; +$s_plugin_SourceHgWeb_repo_commit_project_restricted = 'Referenced Issue(s) must be within a particular project'; +$s_plugin_SourceHgWeb_repo_commit_project_allowed = 'Only allow commits when ticket is within'; + diff --git a/SourceHgWeb/lang/strings_german.txt b/SourceHgWeb/lang/strings_german.txt new file mode 100644 index 000000000..d80f2b806 --- /dev/null +++ b/SourceHgWeb/lang/strings_german.txt @@ -0,0 +1,32 @@ +(nur Bezeichner)'; +$s_plugin_SourceHgWeb_master_branch = 'Hauptzweige
(kommaseparierte Liste)'; + +$s_plugin_SourceHgWeb_repo_commit_needs_issue = 'Committext benötigt Beziehung zu mindestens einem Eintrag'; +$s_plugin_SourceHgWeb_repo_commit_issues_must_exist = 'Eintrag muss existieren'; +$s_plugin_SourceHgWeb_repo_commit_ownership_must_match = 'Eintrag muss Autor/Comitter gehören'; +$s_plugin_SourceHgWeb_repo_commit_committer_must_be_member = 'Benutzer muss dem Projekt in Mantis angehören'; +$s_plugin_SourceHgWeb_repo_commit_committer_must_be_level = 'Benutzer muss Rolle haben'; +$s_plugin_SourceHgWeb_repo_commit_status_restricted = 'Referenzierte Einträge müssen einen bestimmten Status haben'; +$s_plugin_SourceHgWeb_repo_commit_status_allowed = 'Commit nur zulassen für Einträge mit folgendem Status'; +$s_plugin_SourceHgWeb_repo_commit_project_restricted = 'Referenzierte Einträge müssen zu einem bestimmten Projekt gehören'; +$s_plugin_SourceHgWeb_repo_commit_project_allowed = 'Commit nur zulassen, wenn Eintrag aus Projekt'; + diff --git a/SourceHgWeb/pre_commit.py.tmpl.mantis-checks-commit b/SourceHgWeb/pre_commit.py.tmpl.mantis-checks-commit new file mode 100644 index 000000000..ca4d76a76 --- /dev/null +++ b/SourceHgWeb/pre_commit.py.tmpl.mantis-checks-commit @@ -0,0 +1,117 @@ +# -*- coding: utf-8 -*- +"""check_commit_message_hook + +Calls pre-commit extension of mantis source plugin for evaluation. +Inactive during merges. + +Intagrate into mercurial via + +[hooks] +pretxncommit.bug_id_required=python://pre_commit.py:check_commit_message_hook +""" +import re,os,sys,urllib,tempfile,mercurial + +if sys.version_info[0] < 3: + import urllib2 + +#only edit these variables +URL = 'http://localhost/mantis/plugin.php?page=Source/pre_commit_check' +API_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx' + +# for testing +bounce_commits = 0 +debug_mode = False + + +def check_commit_message_hook(ui, repo, node, **kwargs): + + global bounce_commits + + ctx = repo[node] + commit_message = ctx.description() + repo_name = os.path.basename(repo.root) + user = ctx.user() + + if debug_mode: + ui.warn( b'\n\nDEBUG MODE IS ACTIVATED!\n\n' ) + bounce_commits = 1 + + # not at merges + if len( ctx.parents() ) >= 2: + if debug_mode: + ui.warn( b'possible merge found, cancelling\n' ) + return bounce_commits + + # not at tagging + try: + idx = ctx.files().index( '.hgtags' ) + except ValueError: + idx = -1 + + if idx >= 0: + if debug_mode: + ui.warn( b'tag found, cancelling\n' ) + return bounce_commits + + + if debug_mode: + ui.warn( b'sending data:\n\n' ) + ui.warn( b'repo name ">%s<".\n' % repo_name ) + ui.warn( b'comitter ">%s<".\n' % user ) + ui.warn( b'message ">%s<".\n\n' % commit_message ) + + values = { + 'repo_name' : repo_name, + 'committer' : user, + 'api_key' : API_KEY, + 'commit_comment' : commit_message + } + + if sys.version_info[0] > 2: + data = urllib.parse.urlencode( values ) + data = data.encode('ascii') #to bytes + + req = urllib.request.Request(URL, data) + response = urllib.request.urlopen(req) + else: + data = urllib.urlencode( values ) + + # disable proxy + proxy_support = urllib2.ProxyHandler( {} ) + opener = urllib2.build_opener( proxy_support ) + urllib2.install_opener( opener) + + req = urllib2.Request( URL, data ) + response = urllib2.urlopen( req ) + + response_msg = response.read() + + # plugin serving utf8, encode as iso-8859-15 + response_msg = response_msg.decode('utf8').encode('iso-8859-15') + + #for testing + if debug_mode: + ui.warn( b'getting response:\n\n' ) + ui.warn( b'>%s<\n' % response_msg ) + + match = re.search( b'Check-OK: ([0-9]+)', response_msg, re.IGNORECASE ) + if not match: + ui.warn( b'Didnt receive a valid response from Mantis SourceIntegration\n' ) + ui.warn( b'Received:\n' ) + ui.warn( b'-----------8<--------------------\n' ) + ui.warn( b'>' + response_msg + b'<\n' ) + ui.warn( b'-----------8<--------------------\n' ) + return 1 + elif match.group(1) == b'0': + match = re.search( b"^Check-Message: '(.+)(?=')", response_msg ) + if not match: + ui.warn( b'Mantis SourceIntegration bounced the commit but didnt report why\n' ) + return 1 + + else: + #output bounce message + ui.warn( match.group(1) + b'\n\n' ) + + return 1 + + return bounce_commits diff --git a/SourceSVN/pre-commit.tmpl.mantis-checks-commit b/SourceSVN/pre-commit.tmpl.mantis-checks-commit new file mode 100644 index 000000000..14c89d006 --- /dev/null +++ b/SourceSVN/pre-commit.tmpl.mantis-checks-commit @@ -0,0 +1,77 @@ +#!/bin/sh + +# Copyright (c) 2014 John Bailey +# Licensed under the MIT license +# +# Requires GNU grep with PCRE + +# Customise the following settings based on your Mantis installation +URL="http://localhost/mantis/plugin.php?page=Source/pre_commit_check" +PROJECT="RepoName" +API_KEY="dd" + +SVNLOOK=/usr/bin/svnlook +CURL=/usr/bin/curl + +# Set this to 1 during testing so that even commits which pass the +# mantis checks will be halted +BOUNCE_ALL_COMMITS=0 + +# Deal with hook parameters +REPOS="$1" +TXN="$2" + +LOG_FILE=`mktemp /tmp/svn_log.XXX` +COMMENT_FILE=`mktemp /tmp/svn_comment.XXX` + +# Exit as soon as an error is encountered +#set -e + +# Check for tools + +if [ ! -x "$SVNLOOK" ]; then + echo "You need to update the script at $0 to point to svnlook" 1>&2 + exit 1 +fi + +if [ ! -x "$CURL" ]; then + echo "You need to update the script at $0 to point to curl" 1>&2 + exit 1 +fi + +COMMITTING_USER=$("${SVNLOOK}" author -t "${TXN}" "${REPOS}") + +# Put the commit comment into a file which we can pass to curl +echo 'commit_comment="' >> ${COMMENT_FILE} +"${SVNLOOK}" log -t "${TXN}" "${REPOS}" >> ${COMMENT_FILE} +echo '"' >> ${COMMENT_FILE} + +# Fire off the query to Mantis (-s -S to prevent progress bar but keep error +# reporting +"${CURL}" -s -S -d "repo_name=${PROJECT}" -d "committer=${COMMITTING_USER}" -d @${COMMENT_FILE} -d "api_key=${API_KEY}" ${URL} >> ${LOG_FILE} + +# Try and extract the result from the response +RESULT=$(grep -oP 'Check-OK: \K([0-9]+)' ${LOG_FILE}) + +if [ "x$RESULT" = "x" ]; then + echo "Didn't receive a valid response from Mantis SourceIntegration" 1>&2 + echo "Received:" 1>&2 + echo "-----------8<--------------------" 1>&2 + cat ${LOG_FILE} 1>&2 + echo 1>&2 + echo "-----------8<--------------------" 1>&2 + exit 1; +elif [ $RESULT -eq 0 ]; then + CHECK_MESSAGE=$(grep -oP "Check-Message: '\K(.+)(?=')" ${LOG_FILE}) + if [ "x$CHECK_MESSAGE" = "x" ]; then + echo "Mantis SourceIntegration bounced the commit but didn't report why" 1>&2 + else + echo "$CHECK_MESSAGE" 1>&2 + fi + exit 1 +else + # Success! + exit $BOUNCE_ALL_COMMITS +fi + +exit 1