From c3db193efc07f1d74668cd9cf1daf55a25f436db Mon Sep 17 00:00:00 2001 From: Lars Hvam Date: Sat, 8 Sep 2018 08:04:09 +0200 Subject: [PATCH] parse branch list, skip first pkt-line (#1898) * add unit tests and fix some code inspector * branch parsing: skip first pkt-line #1897 --- src/git/zcl_abapgit_git_branch_list.clas.abap | 64 +++++++++------ ...pgit_git_branch_list.clas.testclasses.abap | 77 +++++++++++++++++++ src/git/zcl_abapgit_git_branch_list.clas.xml | 1 + 3 files changed, 120 insertions(+), 22 deletions(-) create mode 100644 src/git/zcl_abapgit_git_branch_list.clas.testclasses.abap diff --git a/src/git/zcl_abapgit_git_branch_list.clas.abap b/src/git/zcl_abapgit_git_branch_list.clas.abap index 7ba75d484..2ebe3a4eb 100644 --- a/src/git/zcl_abapgit_git_branch_list.clas.abap +++ b/src/git/zcl_abapgit_git_branch_list.clas.abap @@ -3,6 +3,7 @@ CLASS zcl_abapgit_git_branch_list DEFINITION CREATE PUBLIC . PUBLIC SECTION. + METHODS constructor IMPORTING !iv_data TYPE string @@ -15,7 +16,7 @@ CLASS zcl_abapgit_git_branch_list DEFINITION VALUE(rs_branch) TYPE zif_abapgit_definitions=>ty_git_branch RAISING zcx_abapgit_exception . - METHODS get_head " For potential future use + METHODS get_head " For potential future use RETURNING VALUE(rs_branch) TYPE zif_abapgit_definitions=>ty_git_branch RAISING @@ -28,11 +29,11 @@ CLASS zcl_abapgit_git_branch_list DEFINITION VALUE(rt_branches) TYPE zif_abapgit_definitions=>ty_git_branch_list_tt RAISING zcx_abapgit_exception . - METHODS get_tags_only " For potential future use + METHODS get_tags_only " For potential future use RETURNING VALUE(rt_tags) TYPE zif_abapgit_definitions=>ty_git_branch_list_tt RAISING - zcx_abapgit_exception. + zcx_abapgit_exception . CLASS-METHODS is_ignored IMPORTING !iv_branch_name TYPE clike @@ -45,11 +46,11 @@ CLASS zcl_abapgit_git_branch_list DEFINITION VALUE(rv_display_name) TYPE string . CLASS-METHODS get_type IMPORTING - !iv_branch_name TYPE clike - it_result TYPE stringtab OPTIONAL - iv_current_row_index TYPE sytabix OPTIONAL + !iv_branch_name TYPE clike + !it_result TYPE stringtab OPTIONAL + !iv_current_row_index TYPE sytabix OPTIONAL RETURNING - VALUE(rv_type) TYPE zif_abapgit_definitions=>ty_git_branch_type . + VALUE(rv_type) TYPE zif_abapgit_definitions=>ty_git_branch_type . CLASS-METHODS complete_heads_branch_name IMPORTING !iv_branch_name TYPE clike @@ -64,14 +65,19 @@ CLASS zcl_abapgit_git_branch_list DEFINITION DATA mt_branches TYPE zif_abapgit_definitions=>ty_git_branch_list_tt . DATA mv_head_symref TYPE string . + + CLASS-METHODS skip_first_pkt + IMPORTING + !iv_data TYPE string + RETURNING + VALUE(rv_data) TYPE string . METHODS find_tag_by_name IMPORTING - iv_branch_name TYPE string + !iv_branch_name TYPE string RETURNING VALUE(rs_branch) TYPE zif_abapgit_definitions=>ty_git_branch RAISING - zcx_abapgit_exception. - + zcx_abapgit_exception . CLASS-METHODS parse_branch_list IMPORTING !iv_data TYPE string @@ -112,7 +118,7 @@ CLASS ZCL_ABAPGIT_GIT_BRANCH_LIST IMPLEMENTATION. METHOD find_by_name. IF iv_branch_name IS INITIAL. - zcx_abapgit_exception=>raise( 'Branch name empty' ). + zcx_abapgit_exception=>raise( 'Branch name empty' ) ##NO_TEXT. ENDIF. IF iv_branch_name CP |refs/tags/*|. @@ -141,9 +147,9 @@ CLASS ZCL_ABAPGIT_GIT_BRANCH_LIST IMPLEMENTATION. IF sy-subrc <> 0. READ TABLE mt_branches INTO rs_branch - WITH KEY name = iv_branch_name. + WITH KEY name = iv_branch_name. IF sy-subrc <> 0. - zcx_abapgit_exception=>raise( 'Branch not found' ). + zcx_abapgit_exception=>raise( 'Branch not found' ) ##NO_TEXT. ENDIF. ENDIF. @@ -270,26 +276,24 @@ CLASS ZCL_ABAPGIT_GIT_BRANCH_LIST IMPLEMENTATION. CLEAR: et_list, ev_head_symref. - SPLIT iv_data AT zif_abapgit_definitions=>c_newline INTO TABLE lt_result. + lv_data = skip_first_pkt( iv_data ). + SPLIT lv_data AT zif_abapgit_definitions=>c_newline INTO TABLE lt_result. LOOP AT lt_result INTO lv_data. - lv_current_row_index = sy-tabix. - IF sy-tabix = 1. - CONTINUE. " current loop - ELSEIF sy-tabix = 2 AND strlen( lv_data ) > 49. + IF sy-tabix = 1 AND strlen( lv_data ) > 49. lv_hash = lv_data+8. lv_name = lv_data+49. lv_char = zcl_abapgit_git_utils=>get_null( ). SPLIT lv_name AT lv_char INTO lv_name lv_head_params. ev_head_symref = parse_head_params( lv_head_params ). - ELSEIF sy-tabix > 2 AND strlen( lv_data ) > 45. + ELSEIF sy-tabix > 1 AND strlen( lv_data ) > 45. lv_hash = lv_data+4. lv_name = lv_data+45. - ELSEIF sy-tabix = 2 AND strlen( lv_data ) = 8 AND lv_data(8) = '00000000'. - zcx_abapgit_exception=>raise( 'No branches, create branch manually by adding file' ). + ELSEIF sy-tabix = 1 AND strlen( lv_data ) = 8 AND lv_data(8) = '00000000'. + zcx_abapgit_exception=>raise( 'No branches, create branch manually by adding file' ) ##NO_TEXT. ELSE. CONTINUE. ENDIF. @@ -315,7 +319,7 @@ CLASS ZCL_ABAPGIT_GIT_BRANCH_LIST IMPLEMENTATION. METHOD parse_head_params. DATA: ls_match TYPE match_result, - ls_submatch TYPE submatch_result. + ls_submatch LIKE LINE OF ls_match-submatches. FIND FIRST OCCURRENCE OF REGEX '\ssymref=HEAD:([^\s]+)' IN iv_data RESULTS ls_match. READ TABLE ls_match-submatches INTO ls_submatch INDEX 1. @@ -324,4 +328,20 @@ CLASS ZCL_ABAPGIT_GIT_BRANCH_LIST IMPLEMENTATION. ENDIF. ENDMETHOD. + + + METHOD skip_first_pkt. + + DATA: lv_hex TYPE x LENGTH 1, + lv_length TYPE i. + +* channel + ASSERT iv_data(2) = '00'. + + lv_hex = to_upper( iv_data+2(2) ). + lv_length = lv_hex + 2. + + rv_data = iv_data+lv_length. + + ENDMETHOD. ENDCLASS. diff --git a/src/git/zcl_abapgit_git_branch_list.clas.testclasses.abap b/src/git/zcl_abapgit_git_branch_list.clas.testclasses.abap new file mode 100644 index 000000000..75c2a9ee2 --- /dev/null +++ b/src/git/zcl_abapgit_git_branch_list.clas.testclasses.abap @@ -0,0 +1,77 @@ +CLASS ltcl_parse DEFINITION DEFERRED. +CLASS zcl_abapgit_git_branch_list DEFINITION LOCAL FRIENDS ltcl_parse. + +CLASS ltcl_parse DEFINITION FOR TESTING + DURATION SHORT + RISK LEVEL HARMLESS FINAL. + + PRIVATE SECTION. + METHODS: + parse + RAISING + zcx_abapgit_exception. + + METHODS: + test01 FOR TESTING RAISING zcx_abapgit_exception, + test02 FOR TESTING RAISING zcx_abapgit_exception. + + DATA: mt_data TYPE STANDARD TABLE OF string WITH DEFAULT KEY. + +ENDCLASS. + + +CLASS ltcl_parse IMPLEMENTATION. + + METHOD parse. + + DATA: lv_data TYPE string, + lt_list TYPE zif_abapgit_definitions=>ty_git_branch_list_tt. + + + CONCATENATE LINES OF mt_data INTO lv_data SEPARATED BY zif_abapgit_definitions=>c_newline. + + zcl_abapgit_git_branch_list=>parse_branch_list( + EXPORTING + iv_data = lv_data + IMPORTING + et_list = lt_list ). + + cl_abap_unit_assert=>assert_not_initial( lt_list ). + + cl_abap_unit_assert=>assert_equals( + act = lines( lt_list ) + exp = 2 ). + + READ TABLE lt_list WITH KEY name = 'refs/heads/master' TRANSPORTING NO FIELDS. + cl_abap_unit_assert=>assert_subrc( ). + + ENDMETHOD. + + METHOD test01. + +* without linefeed after first pkt-line +* +* see https://github.com/git/git/blob/master/Documentation/technical/pack-protocol.txt +* +* "unless otherwise noted the usual pkt-line LF rules apply: the sender SHOULD include a +* LF, but the receiver MUST NOT complain if it is not present" + + APPEND '001d# service=git-upload-pack000000d2b5d5f1f84ebcaeb8a299edd14c959518e9d81bb5 HEAD#asdf' TO mt_data. + APPEND '003fb5d5f1f84ebcaeb8a299edd14c959518e9d81bb5 refs/heads/master' TO mt_data. + APPEND '0000' TO mt_data. + + parse( ). + + ENDMETHOD. + + METHOD test02. + + APPEND '001e# service=git-upload-pack' TO mt_data. + APPEND '000001080e6fe6b311f789ccbac6c5122702d4f48a4f6bda HEAD#asdf' TO mt_data. + APPEND '003f0e6fe6b311f789ccbac6c5122702d4f48a4f6bda refs/heads/master' TO mt_data. + + parse( ). + + ENDMETHOD. + +ENDCLASS. diff --git a/src/git/zcl_abapgit_git_branch_list.clas.xml b/src/git/zcl_abapgit_git_branch_list.clas.xml index f78528b35..c5f32b61e 100644 --- a/src/git/zcl_abapgit_git_branch_list.clas.xml +++ b/src/git/zcl_abapgit_git_branch_list.clas.xml @@ -12,6 +12,7 @@ X X X + X