diff --git a/Source/MantisSourceGitBasePlugin.class.php b/Source/MantisSourceGitBasePlugin.class.php index 068e83135..bb444d0f6 100644 --- a/Source/MantisSourceGitBasePlugin.class.php +++ b/Source/MantisSourceGitBasePlugin.class.php @@ -46,6 +46,7 @@ abstract class MantisSourceGitBasePlugin extends MantisSourcePlugin * Error constants */ const ERROR_INVALID_BRANCH = 'invalid_branch'; + const ERROR_INVALID_DATE = 'invalid_date'; /** * Define plugin's Error strings @@ -54,6 +55,7 @@ abstract class MantisSourceGitBasePlugin extends MantisSourcePlugin public function errors() { $t_errors_list = array( self::ERROR_INVALID_BRANCH, + self::ERROR_INVALID_DATE, ); foreach( $t_errors_list as $t_error ) { @@ -73,6 +75,19 @@ protected function is_branch_valid( $p_branch ) return (bool)preg_match( $this->valid_branch_regex, $p_branch ); } + /** + * Determines if given string name is a valid regex. + * @param string $p_regex regex to validate + * @return bool True if valid + */ + protected function is_regex_branch_valid( $p_regex ) + { + # Trick to compile the regex + # see ReturnValues of the official doc https://www.php.net/manual/en/function.preg-match.php + return (0 === preg_match( $p_regex, "" )); + } + + /** * Triggers an error if the branch is invalid * @param string $p_branch Branch name to validate @@ -89,15 +104,20 @@ protected function ensure_branch_valid( $p_branch ) /** * Validates a comma-delimited list of git branches. * Triggers an ERROR_INVALID_BRANCH if one of the branches is invalid - * @param string $p_list Comma-delimited list of branch names (or '*') + * @param string $p_list Comma-delimited list of branch names, or a regex, or '*' * @return void */ protected function validate_branch_list( $p_list ) { + #Case '*' if( $p_list == '*' ) { return; } - + #Case regex + if( preg_match( "/^\/.+\/[a-z]*$/i", $p_list ) ) { + return; + } + #Case list of validi git branches foreach( explode( ',', $p_list ) as $t_branch ) { $this->ensure_branch_valid( trim( $t_branch ) ); } @@ -114,6 +134,21 @@ protected function get_default_primary_branches() { return $t_value; } + /** + * Validates a date + * Triggers an ERROR_INVALID_DATE if date is not valid + * @return void + */ + protected function validate_date($p_date) { + if (empty($p_date)) { + return; + } + if (! (bool)strtotime($p_date)) { + error_parameters( $p_date ); + plugin_error( self::ERROR_INVALID_DATE ); + } +} + /** * Output form elements for configuration options. */ diff --git a/Source/lang/strings_english.txt b/Source/lang/strings_english.txt index 6973b1fb1..3c08408c3 100644 --- a/Source/lang/strings_english.txt +++ b/Source/lang/strings_english.txt @@ -138,7 +138,9 @@ $s_plugin_Source_changeset_removed = 'Changeset removed'; $s_plugin_Source_ensure_delete = 'Do you really want to delete the "%s" repository and all of its history?'; $s_plugin_Source_ensure_import_full = 'This will import to a new copy of your repository, and then destroy the old repository data, and may require use of shell access. Do you wish to continue?'; +$s_plugin_Source_ensure_import__full_since = 'This will import to a new copy of your repository since "%s", and then destroy the old repository data, and may require use of shell access. Do you wish to continue?'; $s_plugin_Source_ensure_import_latest = 'This will attempt to import recent data for your repository, and may require use of shell access. Do you wish to continue?'; +$s_plugin_Source_ensure_import_latest_since = 'This will attempt to import since "%s" for yout repository, and may require use of shell access. Do you wish to continue?'; $s_plugin_Source_import_results = 'Import Results'; $s_plugin_Source_import_stats = 'Imported %s changesets, %s files, and %s bug references.'; $s_plugin_Source_import_repo_error = 'Import process produced an error.'; @@ -150,6 +152,7 @@ $s_plugin_Source_invalid_changeset = 'Changeset information could not be loaded' $s_plugin_Source_import_latest_failed = 'Repository latest data importing failed.'; $s_plugin_Source_import_full_failed = 'Full repository data importing failed.'; +$s_plugin_Source_import_since_failed = 'Repository "since date" importing failed.'; $s_plugin_Source_changeset_column_title = 'C'; diff --git a/Source/lang/strings_french.txt b/Source/lang/strings_french.txt index 398de63fc..03a6dbc79 100644 --- a/Source/lang/strings_french.txt +++ b/Source/lang/strings_french.txt @@ -70,6 +70,7 @@ $s_plugin_Source_back_repo = 'Retour au dépôt'; $s_plugin_Source_back_changeset = 'Retour au jeu de changements'; $s_plugin_Source_import_full = 'Tout importer'; $s_plugin_Source_import_latest = 'Importer les dernières données'; +$s_plugin_Source_import_since = 'Importer depuis le...'; $s_plugin_Source_related_changesets = 'Jeux de changements liés'; $s_plugin_Source_affected_issues = 'Demandes affectées'; $s_plugin_Source_attach_to_issue = 'Attacher des demandes :'; @@ -134,7 +135,9 @@ $s_plugin_Source_changeset_removed = 'Jeu de changement détaché'; $s_plugin_Source_ensure_delete = 'Voulez-vous vraiment supprimer le dépôt "%s" et tout son historique ?'; $s_plugin_Source_ensure_import_full = 'Ceci va importer une nouvelle copie de votre dépôt, puis détruira les vieilles données de dépôt et pourrait avoir besoin d\'un accès au shell. Voulez-vous continuer ?'; +$s_plugin_Source_ensure_import_full_since = 'Ceci va importer une nouvelle copie de votre dépôt depuis le "%s", puis détruira les vieilles données de dépôt et pourrait avoir besoin d\'un accès au shell. Voulez-vous continuer ?'; $s_plugin_Source_ensure_import_latest = 'Ceci va tenter d\'importer les données récentes dans votre dépôt et pourrait avoir besoin d\'un accès au shell. Voulez-vous continuer ?'; +$s_plugin_Source_ensure_import_latest_since = 'Cevi va tenter d\'importer les données depuis le "%s" dans votre dépôt et pourrait avoir besoin d\'un accès au shell. Voulez-vous continuer ?'; $s_plugin_Source_import_results = 'Résultats de l\'import'; $s_plugin_Source_import_stats = '%s jeux de changements importés, %s fichiers, et %s références de demande.'; $s_plugin_Source_import_repo_error = 'Le processus d\'import a rencontré une erreur.'; diff --git a/Source/pages/repo_import_full.php b/Source/pages/repo_import_full.php index 93c104dc3..3b602b506 100644 --- a/Source/pages/repo_import_full.php +++ b/Source/pages/repo_import_full.php @@ -6,12 +6,18 @@ form_security_validate( 'plugin_Source_repo_import_full' ); access_ensure_global_level( plugin_config_get( 'manage_threshold' ) ); -$f_repo_id = gpc_get_string( 'id' ); +$f_repo_id = gpc_get_int( 'id' ); $t_repo = SourceRepo::load( $f_repo_id ); $t_vcs = SourceVCS::repo( $t_repo ); -helper_ensure_confirmed( plugin_lang_get( 'ensure_import_full' ), plugin_lang_get( 'import_full' ) ); +if (empty( $t_repo->info['hub_oldest_commit_date'])){ + helper_ensure_confirmed( plugin_lang_get( 'ensure_import_full' ), plugin_lang_get( 'import_full' ) ); +}else{ + $t_date_since = $t_repo->info['hub_oldest_commit_date']; + helper_ensure_confirmed( sprintf( plugin_lang_get( 'ensure_import_full_since' ), $t_date_since), plugin_lang_get( 'import_full' ) ); +} + helper_begin_long_process(); layout_page_header( plugin_lang_get( 'title' ) ); diff --git a/Source/pages/repo_import_latest.php b/Source/pages/repo_import_latest.php index a84cf82d5..b553e01cd 100644 --- a/Source/pages/repo_import_latest.php +++ b/Source/pages/repo_import_latest.php @@ -7,17 +7,23 @@ form_security_validate( 'plugin_Source_repo_import_latest' ); access_ensure_global_level( plugin_config_get( 'manage_threshold' ) ); -helper_ensure_confirmed( plugin_lang_get( 'ensure_import_latest' ), plugin_lang_get( 'import_latest' ) ); -$f_repo_id = strtolower( gpc_get_string( 'id' ) ); +$f_repo_id = gpc_get_int( 'id' ); $t_repo_id = (int) $f_repo_id; $t_repos = array( SourceRepo::load( $t_repo_id ) ); - $t_repo = array_shift( $t_repos ); $t_vcs = SourceVCS::repo( $t_repo ); -$t_repo->pre_stats = $t_repo->stats(); +$t_pre_stats = $t_repo->stats(); + +if ( empty( $t_repo->info['hub_oldest_commit_date'] ) ) { + helper_ensure_confirmed( plugin_lang_get( 'ensure_import_latest' ), plugin_lang_get( 'import_latest' ) ); +}else{ + $t_date_since = $t_repo->info['hub_oldest_commit_date']; + helper_ensure_confirmed( sprintf(plugin_lang_get( 'ensure_import_latest_since' ), $t_date_since), plugin_lang_get( 'import_latest' ) ); +} + layout_page_header( plugin_lang_get( 'title' ) ); layout_page_begin(); @@ -39,7 +45,7 @@ import_error = false; +$t_import_error = false; while( true ) { # import the next batch of changesets @@ -47,7 +53,7 @@ # check for errors if ( !is_array( $t_changesets ) ) { - $t_repo->import_error = true; + $t_import_error = true; break; } @@ -59,21 +65,21 @@ Source_Process_Changesets( $t_changesets ); } -$t_repo->post_stats = $t_repo->stats(); +$t_post_stats = $t_repo->stats(); ?>
'; + protected function build_gitlab_apis($p_repo, $t_branch) { + + $t_repoid = $p_repo->info['hub_repoid']; + + /* + * Because Gitlab will return a pageg result (only the 20 first branches) + * The request for '*' should be reworked + */ + if ( $t_branch === "*" ) { + return array( "projects/$t_repoid/repository/branches/"); + } + + if ( preg_match( "/^\/.+\/[a-z]*$/i", $t_branch )) /* is a regex ? */ + { + return array("projects/$t_repoid/repository/branches/?regex=$t_branch"); + } + + $gitlab_url_by_name = function( $branch ) use ($t_repoid) { + $branch_name = urlencode($branch); + return "projects/$t_repoid/repository/branches/$branch_name/"; + }; + + $t_branches = array_map( 'trim', explode( ',', $t_branch ) ); + return array_map( $gitlab_url_by_name, $t_branches); + } + + + public function import_full( $p_repo) { + static $counter=0; + $counter = $counter + 1; + echo "'; + return array(); } + array_push( $t_json, $t_json_tmp); } + } catch (Exception $e) { + echo 'Caught exception: ', $e->getMessage(), "\n"; + echo ''; + return array(); + } + #print_r($t_json); $t_changesets = array(); $t_changeset_table = plugin_table( 'changeset', 'Source' ); - foreach( $t_branches as $t_branch ) { + foreach( $t_json as $t_branch ) { $t_query = "SELECT parent FROM $t_changeset_table WHERE repo_id=" . db_param() . ' AND branch=' . db_param() . ' ORDER BY timestamp'; $t_result = db_query( $t_query, array( $p_repo->id, $t_branch->name ), 1 ); - + echo "Process branch '$t_branch->name':\n"; $t_commits = array( $t_branch->commit->id ); if ( db_num_rows( $t_result ) > 0 ) { $t_parent = db_result( $t_result ); @@ -355,9 +415,10 @@ public function import_full( $p_repo ) { if ( !empty( $t_parent ) ) { $t_commits[] = $t_parent; - echo "Parents not empty"; + echo "Parents not empty - "; + } else { + echo "Parents empty"; } - echo "Parents empty"; } $t_changesets = array_merge( $t_changesets, $this->import_commits( $p_repo, $t_commits, $t_branch->name ) ); @@ -414,37 +475,43 @@ public function import_commits( $p_repo, $p_commit_ids, $p_branch='' ) { private function json_commit_changeset( $p_repo, $p_json, $p_branch='' ) { echo "processing $p_json->id ... "; - if ( !SourceChangeset::exists( $p_repo->id, $p_json->id ) ) { - # Message will be replaced by title in gitlab version earlier than 7.2 - $t_message = ( !property_exists( $p_json, 'message' ) ) - ? $p_json->title - : $p_json->message; - $t_changeset = new SourceChangeset( - $p_repo->id, - $p_json->id, - $p_branch, - $p_json->created_at, - $p_json->author_name, - $t_message - ); - - $t_parents = array(); - foreach( $p_json->parent_ids as $t_parent ) { - $t_parents[] = $t_parent; - } - if( $t_parents ) { - $t_changeset->parent = $t_parents[0]; - } - - $t_changeset->author_email = $p_json->author_email; - $t_changeset->save(); - - echo "saved.\n"; - return array( $t_changeset, $t_parents ); - } else { + if ( SourceChangeset::exists( $p_repo->id, $p_json->id ) ) { echo "already exists.\n"; return array( null, array() ); } + + $t_oldest_commit_date = $p_repo->info['hub_oldest_commit_date']; + if ( !empty( $t_oldest_commit_date ) && new DateTime( $p_json->created_at ) < new DateTime( $t_oldest_commit_date ) ) { + echo "commit before the oldest_commit_date.\n"; + return array( null, array() ); + } + + # Message will be replaced by title in gitlab version earlier than 7.2 + $t_message = ( !property_exists( $p_json, 'message' ) ) + ? $p_json->title + : $p_json->message; + $t_changeset = new SourceChangeset( + $p_repo->id, + $p_json->id, + $p_branch, + $p_json->created_at, + $p_json->author_name, + $t_message + ); + + $t_parents = array(); + foreach( $p_json->parent_ids as $t_parent ) { + $t_parents[] = $t_parent; + } + if( $t_parents ) { + $t_changeset->parent = $t_parents[0]; + } + + $t_changeset->author_email = $p_json->author_email; + $t_changeset->save(); + + echo "saved.\n"; + return array( $t_changeset, $t_parents ); } public static function url_post( $p_url, $p_post_data ) { diff --git a/SourceGitlab/lang/strings_english.txt b/SourceGitlab/lang/strings_english.txt index 71d36fd75..7e4dce9f4 100644 --- a/SourceGitlab/lang/strings_english.txt +++ b/SourceGitlab/lang/strings_english.txt @@ -14,6 +14,7 @@ $s_plugin_SourceGitlab_hub_repoid = 'GitLab Repository IDPass #$counter: \n"; $t_branch = $p_repo->info['master_branch']; if ( is_blank( $t_branch ) ) { $t_branch = $this->get_default_primary_branches(); } - # if we're not allowed everything, populate an array of what we are allowed - if( $t_branch != '*' ) { - $t_branches_allowed = array_map( 'trim', explode( ',', $t_branch ) ); + # Always pull back only interested branches + $t_api_names = $this->build_gitlab_apis($p_repo, $t_branch); + + $t_uris = array(); + foreach( $t_api_names as $t_api_name) + { + array_push($t_uris, $this->api_uri( $p_repo, $t_api_name)); } - # Always pull back full list of repos - $t_repoid = $p_repo->info['hub_repoid']; - $t_uri = $this->api_uri( $p_repo, "projects/$t_repoid/repository/branches" ); - - $t_member = null; - $t_json = json_url( $t_uri, $t_member ); - if( $t_json === null ) { - echo "Could not retrieve data from GitLab at '$t_uri'. Make sure your "; - print_link( - plugin_page( 'repo_update_page', null, 'Source' ) - . "&id=$p_repo->id", - 'repository settings' - ); - echo " are correct."; - echo ''; - return array(); - } + $t_json = array(); + try { - $t_branches = array(); - foreach( $t_json as $t_branch ) { - if( empty( $t_branches_allowed ) || in_array( $t_branch->name, $t_branches_allowed ) ) { - $t_branches[] = $t_branch; + foreach ($t_uris as $t_uri) + { + $t_member = null; + #print_r($t_uri); + $t_json_tmp = json_url( $t_uri, $t_member ); + #print_r($t_json_tmp); + if( $t_json_tmp === null ) { + echo "Could not retrieve data from GitLab at '$t_uri'. Make sure your "; + print_link( + plugin_page( 'repo_update_page', null, 'Source' ) + . "&id=$p_repo->id", + 'repository settings' + ); + echo " are correct."; + echo '