diff --git a/src/zabapgit_git.prog.abap b/src/zabapgit_git.prog.abap index 1d7b3dc71..4f8b12003 100644 --- a/src/zabapgit_git.prog.abap +++ b/src/zabapgit_git.prog.abap @@ -269,6 +269,8 @@ CLASS lcl_git_transport IMPLEMENTATION. zcx_abapgit_exception=>raise( 'pre-receive hook declined' ). ELSEIF lv_string CP '*funny refname*'. zcx_abapgit_exception=>raise( 'funny refname' ). + ELSEIF lv_string CP '*failed to update ref*'. + zcx_abapgit_exception=>raise( 'failed to update ref' ). ENDIF. ENDMETHOD. "receive_pack @@ -1125,11 +1127,22 @@ CLASS lcl_git_porcelain DEFINITION FINAL FRIENDS ltcl_git_porcelain. iv_from TYPE zif_abapgit_definitions=>ty_sha1 RAISING zcx_abapgit_exception. + CLASS-METHODS create_tag + IMPORTING io_repo TYPE REF TO lcl_repo_online + iv_name TYPE string + iv_from TYPE zif_abapgit_definitions=>ty_sha1 + RAISING zcx_abapgit_exception. + CLASS-METHODS delete_branch IMPORTING io_repo TYPE REF TO lcl_repo_online is_branch TYPE lcl_git_branch_list=>ty_git_branch RAISING zcx_abapgit_exception. + CLASS-METHODS delete_tag + IMPORTING io_repo TYPE REF TO lcl_repo_online + is_tag TYPE lcl_git_branch_list=>ty_git_branch + RAISING zcx_abapgit_exception. + CLASS-METHODS full_tree IMPORTING it_objects TYPE zif_abapgit_definitions=>ty_objects_tt iv_branch TYPE zif_abapgit_definitions=>ty_sha1 @@ -1304,6 +1317,25 @@ CLASS lcl_git_porcelain IMPLEMENTATION. ENDMETHOD. + METHOD delete_tag. + + DATA: lt_objects TYPE zif_abapgit_definitions=>ty_objects_tt, + lv_pack TYPE xstring. + + +* "client MUST send an empty packfile" +* https://github.com/git/git/blob/master/Documentation/technical/pack-protocol.txt#L514 + lv_pack = lcl_git_pack=>encode( lt_objects ). + + lcl_git_transport=>receive_pack( + iv_url = io_repo->get_url( ) + iv_old = is_tag-sha1 + iv_new = c_zero + iv_branch_name = is_tag-name + iv_pack = lv_pack ). + + ENDMETHOD. + METHOD create_branch. DATA: lt_objects TYPE zif_abapgit_definitions=>ty_objects_tt, @@ -1313,6 +1345,28 @@ CLASS lcl_git_porcelain IMPLEMENTATION. zcx_abapgit_exception=>raise( 'Branch name cannot contain blank spaces' ). ENDIF. +* "client MUST send an empty packfile" +* https://github.com/git/git/blob/master/Documentation/technical/pack-protocol.txt#L514 + lv_pack = lcl_git_pack=>encode( lt_objects ). + + lcl_git_transport=>receive_pack( + iv_url = io_repo->get_url( ) + iv_old = c_zero + iv_new = iv_from + iv_branch_name = iv_name + iv_pack = lv_pack ). + + ENDMETHOD. + + METHOD create_tag. + + DATA: lt_objects TYPE zif_abapgit_definitions=>ty_objects_tt, + lv_pack TYPE xstring. + + IF iv_name CS ` `. + zcx_abapgit_exception=>raise( 'Tag name cannot contain blank spaces' ). + ENDIF. + * "client MUST send an empty packfile" * https://github.com/git/git/blob/master/Documentation/technical/pack-protocol.txt#L514 lv_pack = lcl_git_pack=>encode( lt_objects ). diff --git a/src/zabapgit_gui_router.prog.abap b/src/zabapgit_gui_router.prog.abap index 5e1f7cbc5..c53ce5c31 100644 --- a/src/zabapgit_gui_router.prog.abap +++ b/src/zabapgit_gui_router.prog.abap @@ -236,6 +236,17 @@ CLASS lcl_gui_router IMPLEMENTATION. WHEN zif_abapgit_definitions=>gc_action-git_branch_switch. " GIT Switch branch lcl_services_git=>switch_branch( lv_key ). ev_state = zif_abapgit_definitions=>gc_event_state-re_render. + WHEN zif_abapgit_definitions=>gc_action-go_tag_overview. " GIT Tag overview + lcl_services_git=>tag_overview( lv_key ). + ev_state = zif_abapgit_definitions=>gc_event_state-re_render. + WHEN zif_abapgit_definitions=>gc_action-git_tag_create. " GIT Tag create + lcl_services_git=>create_tag( lv_key ). + lcl_services_repo=>refresh( lv_key ). + ev_state = zif_abapgit_definitions=>gc_event_state-re_render. + WHEN zif_abapgit_definitions=>gc_action-git_tag_delete. " GIT Tag create + lcl_services_git=>delete_tag( lv_key ). + lcl_services_repo=>refresh( lv_key ). + ev_state = zif_abapgit_definitions=>gc_event_state-re_render. "Others WHEN OTHERS. diff --git a/src/zabapgit_page_main.prog.abap b/src/zabapgit_page_main.prog.abap index 15879eee1..5841010c7 100644 --- a/src/zabapgit_page_main.prog.abap +++ b/src/zabapgit_page_main.prog.abap @@ -174,7 +174,6 @@ CLASS lcl_gui_page_main IMPLEMENTATION. DATA: lo_advsub TYPE REF TO lcl_html_toolbar, lo_helpsub TYPE REF TO lcl_html_toolbar. - CREATE OBJECT ro_menu. CREATE OBJECT lo_advsub. CREATE OBJECT lo_helpsub. diff --git a/src/zabapgit_popups.prog.abap b/src/zabapgit_popups.prog.abap index bad7d6eff..87e56e771 100644 --- a/src/zabapgit_popups.prog.abap +++ b/src/zabapgit_popups.prog.abap @@ -27,6 +27,10 @@ CLASS lcl_popups DEFINITION FINAL. EXPORTING ev_name TYPE string ev_cancel TYPE abap_bool RAISING zcx_abapgit_exception, + create_tag_popup + EXPORTING ev_name TYPE string + ev_cancel TYPE abap_bool + RAISING zcx_abapgit_exception, run_page_class_popup EXPORTING ev_name TYPE string ev_cancel TYPE abap_bool @@ -40,6 +44,10 @@ CLASS lcl_popups DEFINITION FINAL. iv_show_new_option TYPE abap_bool OPTIONAL RETURNING VALUE(rs_branch) TYPE lcl_git_branch_list=>ty_git_branch RAISING zcx_abapgit_exception, + tag_list_popup + IMPORTING iv_url TYPE string + RETURNING VALUE(rs_tag) TYPE lcl_git_branch_list=>ty_git_branch + RAISING zcx_abapgit_exception, repo_popup IMPORTING iv_url TYPE string iv_package TYPE devclass OPTIONAL @@ -289,6 +297,44 @@ CLASS lcl_popups IMPLEMENTATION. ENDMETHOD. + METHOD create_tag_popup. + + DATA: lv_answer TYPE c LENGTH 1, + lt_fields TYPE TABLE OF sval. + + FIELD-SYMBOLS: LIKE LINE OF lt_fields. + + CLEAR: ev_name, ev_cancel. + + add_field( EXPORTING iv_tabname = 'TEXTL' + iv_fieldname = 'LINE' + iv_fieldtext = 'Name' + iv_value = 'new-tag-name' + CHANGING ct_fields = lt_fields ). + + CALL FUNCTION 'POPUP_GET_VALUES' + EXPORTING + popup_title = 'Create tag' + IMPORTING + returncode = lv_answer + TABLES + fields = lt_fields + EXCEPTIONS + error_in_fields = 1 + OTHERS = 2 ##NO_TEXT. + IF sy-subrc <> 0. + zcx_abapgit_exception=>raise( 'error from POPUP_GET_VALUES' ). + ENDIF. + + IF lv_answer = 'A'. + ev_cancel = abap_true. + ELSE. + READ TABLE lt_fields INDEX 1 ASSIGNING . + ASSERT sy-subrc = 0. + ev_name = to_lower( |refs/tags/{ -value }| ). + ENDIF. + ENDMETHOD. + METHOD run_page_class_popup. DATA: lv_answer TYPE c LENGTH 1, @@ -514,6 +560,59 @@ CLASS lcl_popups IMPLEMENTATION. ENDMETHOD. + METHOD tag_list_popup. + + DATA: lo_branches TYPE REF TO lcl_git_branch_list, + lt_tags TYPE lcl_git_branch_list=>ty_git_branch_list_tt, + lv_answer TYPE c LENGTH 1, + lt_selection TYPE TABLE OF spopli. + + FIELD-SYMBOLS: LIKE LINE OF lt_selection, + LIKE LINE OF lt_tags. + + lo_branches = lcl_git_transport=>branches( iv_url ). + lt_tags = lo_branches->get_tags_only( ). + + LOOP AT lt_tags ASSIGNING . + + INSERT INITIAL LINE INTO lt_selection INDEX 1 ASSIGNING . + -varoption = -name. + + ENDLOOP. + + CALL FUNCTION 'POPUP_TO_DECIDE_LIST' + EXPORTING + textline1 = 'Select tag' + titel = 'Select tag' + start_col = 30 + start_row = 5 + IMPORTING + answer = lv_answer + TABLES + t_spopli = lt_selection + EXCEPTIONS + not_enough_answers = 1 + too_much_answers = 2 + too_much_marks = 3 + OTHERS = 4. "#EC NOTEXT + IF sy-subrc <> 0. + zcx_abapgit_exception=>raise( 'Error from POPUP_TO_DECIDE_LIST' ). + ENDIF. + + IF lv_answer = 'A'. " cancel + RETURN. + ENDIF. + + READ TABLE lt_selection ASSIGNING WITH KEY selflag = abap_true. + ASSERT sy-subrc = 0. + + READ TABLE lt_tags ASSIGNING WITH KEY name = -varoption. + ASSERT sy-subrc = 0. + + rs_tag = . + + ENDMETHOD. + METHOD repo_popup. DATA: lv_returncode TYPE c, diff --git a/src/zabapgit_services_git.prog.abap b/src/zabapgit_services_git.prog.abap index ac1a6a3d7..b2d510580 100644 --- a/src/zabapgit_services_git.prog.abap +++ b/src/zabapgit_services_git.prog.abap @@ -35,6 +35,18 @@ CLASS lcl_services_git DEFINITION FINAL. IMPORTING iv_key TYPE lcl_persistence_repo=>ty_repo-key RAISING zcx_abapgit_exception zcx_abapgit_cancel. + CLASS-METHODS create_tag + IMPORTING iv_key TYPE lcl_persistence_repo=>ty_repo-key + RAISING zcx_abapgit_exception zcx_abapgit_cancel. + + CLASS-METHODS delete_tag + IMPORTING iv_key TYPE lcl_persistence_repo=>ty_repo-key + RAISING zcx_abapgit_exception zcx_abapgit_cancel. + + CLASS-METHODS tag_overview + IMPORTING iv_key TYPE lcl_persistence_repo=>ty_repo-key + RAISING zcx_abapgit_exception zcx_abapgit_cancel. + CLASS-METHODS commit IMPORTING io_repo TYPE REF TO lcl_repo_online is_commit TYPE ty_commit_fields @@ -205,6 +217,70 @@ CLASS lcl_services_git IMPLEMENTATION. ENDMETHOD. "delete_branch + METHOD create_tag. + + DATA: lv_name TYPE string, + lv_cancel TYPE abap_bool, + lo_repo TYPE REF TO lcl_repo_online, + lx_error TYPE REF TO zcx_abapgit_exception. + + lo_repo ?= lcl_app=>repo_srv( )->get( iv_key ). + + lcl_popups=>create_tag_popup( + IMPORTING + ev_name = lv_name + ev_cancel = lv_cancel ). + IF lv_cancel = abap_true. + RAISE EXCEPTION TYPE zcx_abapgit_cancel. + ENDIF. + + ASSERT lv_name CP 'refs/tags/+*'. + + TRY. + lcl_git_porcelain=>create_tag( io_repo = lo_repo + iv_name = lv_name + iv_from = lo_repo->get_sha1_local( ) ). + + CATCH zcx_abapgit_exception INTO lx_error. + zcx_abapgit_exception=>raise( |Cannot create tag { lv_name }. Error: '{ lx_error->text }'| ). + ENDTRY. + + MESSAGE |Tag { lv_name } created| TYPE 'S' ##NO_TEXT. + + ENDMETHOD. + + METHOD delete_tag. + + DATA: lo_repo TYPE REF TO lcl_repo_online, + ls_tag TYPE lcl_git_branch_list=>ty_git_branch. + + lo_repo ?= lcl_app=>repo_srv( )->get( iv_key ). + + ls_tag = lcl_popups=>tag_list_popup( lo_repo->get_url( ) ). + IF ls_tag IS INITIAL. + RAISE EXCEPTION TYPE zcx_abapgit_cancel. + ENDIF. + + lcl_git_porcelain=>delete_tag( + io_repo = lo_repo + is_tag = ls_tag ). + + MESSAGE |Tag { ls_tag-name } deleted| TYPE 'S'. + + ENDMETHOD. + + METHOD tag_overview. + + DATA: lo_repo TYPE REF TO lcl_repo_online. + + lo_repo ?= lcl_app=>repo_srv( )->get( iv_key ). + + DATA(lt_tag) = lo_repo->get_branches( )->get_tags_only( ). + + cl_demo_output=>display( lt_tag ). + + ENDMETHOD. + METHOD commit. DATA: ls_comment TYPE zif_abapgit_definitions=>ty_comment, diff --git a/src/zabapgit_view_repo.prog.abap b/src/zabapgit_view_repo.prog.abap index ef32cfa11..5e8be000a 100644 --- a/src/zabapgit_view_repo.prog.abap +++ b/src/zabapgit_view_repo.prog.abap @@ -264,6 +264,7 @@ CLASS lcl_gui_view_repo IMPLEMENTATION. DATA: lo_tb_advanced TYPE REF TO lcl_html_toolbar, lo_tb_branch TYPE REF TO lcl_html_toolbar, + lo_tb_tag TYPE REF TO lcl_html_toolbar, lv_key TYPE lcl_persistence_db=>ty_value, lv_wp_opt LIKE zif_abapgit_definitions=>gc_html_opt-crossout, lv_crossout LIKE zif_abapgit_definitions=>gc_html_opt-crossout, @@ -272,6 +273,7 @@ CLASS lcl_gui_view_repo IMPLEMENTATION. CREATE OBJECT ro_toolbar. CREATE OBJECT lo_tb_branch. CREATE OBJECT lo_tb_advanced. + CREATE OBJECT lo_tb_tag. lv_key = mo_repo->get_key( ). @@ -293,6 +295,14 @@ CLASS lcl_gui_view_repo IMPLEMENTATION. iv_act = |{ zif_abapgit_definitions=>gc_action-git_branch_create }?{ lv_key }| ). lo_tb_branch->add( iv_txt = 'Delete' iv_act = |{ zif_abapgit_definitions=>gc_action-git_branch_delete }?{ lv_key }| ). + + lo_tb_tag->add( iv_txt = 'Overview' + iv_act = |{ zif_abapgit_definitions=>gc_action-go_tag_overview }?{ lv_key }| ). + lo_tb_tag->add( iv_txt = 'Create' + iv_act = |{ zif_abapgit_definitions=>gc_action-git_tag_create }?{ lv_key }| ). + lo_tb_tag->add( iv_txt = 'Delete' + iv_act = |{ zif_abapgit_definitions=>gc_action-git_tag_delete }?{ lv_key }| ). + ENDIF. " Build advanced drop-down ======================== @@ -356,6 +366,11 @@ CLASS lcl_gui_view_repo IMPLEMENTATION. ENDTRY. ro_toolbar->add( iv_txt = 'Branch' io_sub = lo_tb_branch ) ##NO_TEXT. + + IF lcl_app=>settings( )->read( )->get_experimental_features( ) = abap_true. + ro_toolbar->add( iv_txt = 'Tag' + io_sub = lo_tb_tag ) ##NO_TEXT. + ENDIF. ELSE. ro_toolbar->add( iv_txt = 'Import ZIP' iv_act = |{ zif_abapgit_definitions=>gc_action-zip_import }?{ lv_key }| diff --git a/src/zif_abapgit_definitions.intf.abap b/src/zif_abapgit_definitions.intf.abap index 44c8409b4..b5f22ccfc 100644 --- a/src/zif_abapgit_definitions.intf.abap +++ b/src/zif_abapgit_definitions.intf.abap @@ -234,6 +234,8 @@ INTERFACE zif_abapgit_definitions git_branch_create TYPE string VALUE 'git_branch_create', git_branch_switch TYPE string VALUE 'git_branch_switch', git_branch_delete TYPE string VALUE 'git_branch_delete', + git_tag_create TYPE string VALUE 'git_tag_create', + git_tag_delete TYPE string VALUE 'git_tag_delete', git_commit TYPE string VALUE 'git_commit', db_delete TYPE string VALUE 'db_delete', @@ -251,6 +253,7 @@ INTERFACE zif_abapgit_definitions go_stage TYPE string VALUE 'go_stage', go_commit TYPE string VALUE 'go_commit', go_branch_overview TYPE string VALUE 'go_branch_overview', + go_tag_overview TYPE string VALUE 'go_tag_overview', go_playground TYPE string VALUE 'go_playground', go_debuginfo TYPE string VALUE 'go_debuginfo', go_settings TYPE string VALUE 'go_settings',