From f712eb17a5d0bb2e32b6e21230e3b5c194e890e6 Mon Sep 17 00:00:00 2001 From: Marc Bernard <59966492+mbtools@users.noreply.github.com> Date: Thu, 31 Mar 2022 13:35:34 +0200 Subject: [PATCH] Folder logic "mixed" (#5413) * Folder logic "mixed" Introduces a new folder logic named `mixed` which combines `prefix` and `full`. The root package name will be used as prefix for all sub-packages but the package names are *not* concatenated recursively. This will allow for using significantly logic package names. Also includes several new unit tests especially for nested packages which had not been tested before. Closes #5410 Todo: Update docs * Add constant * Add options to UI Co-authored-by: Lars Hvam --- .../core/zcl_abapgit_folder_logic.clas.abap | 20 ++- ...abapgit_folder_logic.clas.testclasses.abap | 155 +++++++++++++++++- src/repo/zif_abapgit_dot_abapgit.intf.abap | 1 + .../zcl_abapgit_gui_page_addofflin.clas.abap | 10 +- .../zcl_abapgit_gui_page_addonline.clas.abap | 10 +- .../zcl_abapgit_gui_page_ex_pckage.clas.abap | 48 +++--- .../zcl_abapgit_gui_page_sett_repo.clas.abap | 3 + 7 files changed, 209 insertions(+), 38 deletions(-) diff --git a/src/objects/core/zcl_abapgit_folder_logic.clas.abap b/src/objects/core/zcl_abapgit_folder_logic.clas.abap index 8b4f3010f..184f3f442 100644 --- a/src/objects/core/zcl_abapgit_folder_logic.clas.abap +++ b/src/objects/core/zcl_abapgit_folder_logic.clas.abap @@ -106,7 +106,15 @@ CLASS zcl_abapgit_folder_logic IMPLEMENTATION. * ZZZ_something. This will define the folder name in the zip file to be "something", * similarily with online projects. Alternatively change to FULL folder logic lv_message = 'PREFIX: Unexpected package naming (' && iv_package && ')' - && 'you might switch to FULL folder logic'. + && 'you might switch the folder logic'. + zcx_abapgit_exception=>raise( lv_message ). + ENDIF. + WHEN zif_abapgit_dot_abapgit=>c_folder_logic-mixed. + lv_len = strlen( iv_top ). + + IF iv_package(lv_len) <> iv_top. + lv_message = 'MIXED: Unexpected package naming (' && iv_package && ')' + && 'you might switch the folder logic'. zcx_abapgit_exception=>raise( lv_message ). ENDIF. WHEN OTHERS. @@ -150,6 +158,7 @@ CLASS zcl_abapgit_folder_logic IMPLEMENTATION. lv_new TYPE string, lv_path TYPE string, lv_absolute_name TYPE string, + lv_folder_logic TYPE string, lt_unique_package_names TYPE HASHED TABLE OF devclass WITH UNIQUE KEY table_line. lv_length = strlen( io_dot->get_starting_folder( ) ). @@ -179,7 +188,8 @@ CLASS zcl_abapgit_folder_logic IMPLEMENTATION. WHILE lv_path CA '/'. SPLIT lv_path AT '/' INTO lv_new lv_path. - CASE io_dot->get_folder_logic( ). + lv_folder_logic = io_dot->get_folder_logic( ). + CASE lv_folder_logic. WHEN zif_abapgit_dot_abapgit=>c_folder_logic-full. lv_absolute_name = lv_new. TRANSLATE lv_absolute_name USING '#/'. @@ -188,14 +198,16 @@ CLASS zcl_abapgit_folder_logic IMPLEMENTATION. ENDIF. WHEN zif_abapgit_dot_abapgit=>c_folder_logic-prefix. CONCATENATE rv_package '_' lv_new INTO lv_absolute_name. + WHEN zif_abapgit_dot_abapgit=>c_folder_logic-mixed. + CONCATENATE iv_top '_' lv_new INTO lv_absolute_name. WHEN OTHERS. - ASSERT 0 = 1. + zcx_abapgit_exception=>raise( |Invalid folder logic: { lv_folder_logic }| ). ENDCASE. TRANSLATE lv_absolute_name TO UPPER CASE. IF strlen( lv_absolute_name ) > 30. - zcx_abapgit_exception=>raise( |Package { lv_absolute_name } exceeds ABAP 30-characters-name limit| ). + zcx_abapgit_exception=>raise( |Package { lv_absolute_name } exceeds ABAP 30-characters name limit| ). ENDIF. rv_package = lv_absolute_name. diff --git a/src/objects/core/zcl_abapgit_folder_logic.clas.testclasses.abap b/src/objects/core/zcl_abapgit_folder_logic.clas.testclasses.abap index 63206c903..51739d77d 100644 --- a/src/objects/core/zcl_abapgit_folder_logic.clas.testclasses.abap +++ b/src/objects/core/zcl_abapgit_folder_logic.clas.testclasses.abap @@ -47,6 +47,57 @@ CLASS ltcl_folder_logic_helper IMPLEMENTATION. ENDCLASS. +CLASS ltcl_folder_logic_package DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL. + + PUBLIC SECTION. + INTERFACES: zif_abapgit_sap_package. + +ENDCLASS. + +CLASS ltcl_folder_logic_package IMPLEMENTATION. + + METHOD zif_abapgit_sap_package~list_subpackages. + RETURN. + ENDMETHOD. + + METHOD zif_abapgit_sap_package~list_superpackages. + RETURN. + ENDMETHOD. + + METHOD zif_abapgit_sap_package~read_parent. + rv_parentcl = '$TOP_FOO'. + ENDMETHOD. + + METHOD zif_abapgit_sap_package~create_child. + RETURN. + ENDMETHOD. + + METHOD zif_abapgit_sap_package~exists. + rv_bool = abap_true. + ENDMETHOD. + + METHOD zif_abapgit_sap_package~are_changes_recorded_in_tr_req. + RETURN. + ENDMETHOD. + + METHOD zif_abapgit_sap_package~get_transport_type. + RETURN. + ENDMETHOD. + + METHOD zif_abapgit_sap_package~get_transport_layer. + RETURN. + ENDMETHOD. + + METHOD zif_abapgit_sap_package~create. + RETURN. + ENDMETHOD. + + METHOD zif_abapgit_sap_package~create_local. + RETURN. + ENDMETHOD. + +ENDCLASS. + CLASS ltcl_folder_logic DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL. PUBLIC SECTION. @@ -60,9 +111,15 @@ CLASS ltcl_folder_logic DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHOR setup, prefix1 FOR TESTING RAISING zcx_abapgit_exception, prefix2 FOR TESTING RAISING zcx_abapgit_exception, + prefix3 FOR TESTING RAISING zcx_abapgit_exception, prefix_error1 FOR TESTING RAISING zcx_abapgit_exception, + mixed1 FOR TESTING RAISING zcx_abapgit_exception, + mixed2 FOR TESTING RAISING zcx_abapgit_exception, + mixed3 FOR TESTING RAISING zcx_abapgit_exception, + mixed_error1 FOR TESTING RAISING zcx_abapgit_exception, full1 FOR TESTING RAISING zcx_abapgit_exception, - full2 FOR TESTING RAISING zcx_abapgit_exception. + full2 FOR TESTING RAISING zcx_abapgit_exception, + full3 FOR TESTING RAISING zcx_abapgit_exception. ENDCLASS. @@ -77,7 +134,7 @@ CLASS ltcl_folder_logic IMPLEMENTATION. ENDMETHOD. METHOD zif_abapgit_sap_package~read_parent. - rv_parentcl = '$TOP'. + rv_parentcl = c_top. ENDMETHOD. METHOD zif_abapgit_sap_package~create_child. @@ -110,7 +167,11 @@ CLASS ltcl_folder_logic IMPLEMENTATION. METHOD setup. - zcl_abapgit_injector=>set_sap_package( iv_package = '$TOP' + DATA lo_top_foo TYPE REF TO ltcl_folder_logic_package. + + CREATE OBJECT lo_top_foo. + + zcl_abapgit_injector=>set_sap_package( iv_package = c_top ii_sap_package = me ). zcl_abapgit_injector=>set_sap_package( iv_package = '$TOP_FOO' @@ -119,6 +180,13 @@ CLASS ltcl_folder_logic IMPLEMENTATION. zcl_abapgit_injector=>set_sap_package( iv_package = '$FOOBAR' ii_sap_package = me ). + " Add sub-packages of $TOP_FOO + zcl_abapgit_injector=>set_sap_package( iv_package = '$TOP_BAR' + ii_sap_package = lo_top_foo ). + + zcl_abapgit_injector=>set_sap_package( iv_package = '$TOP_FOO_BAR' + ii_sap_package = lo_top_foo ). + ENDMETHOD. METHOD prefix1. @@ -139,6 +207,15 @@ CLASS ltcl_folder_logic IMPLEMENTATION. iv_path = '/src/foo/' ). ENDMETHOD. + METHOD prefix3. + ltcl_folder_logic_helper=>test( + iv_starting = c_src + iv_top = c_top + iv_logic = zif_abapgit_dot_abapgit=>c_folder_logic-prefix + iv_package = '$TOP_FOO_BAR' + iv_path = '/src/foo/bar/' ). + ENDMETHOD. + METHOD prefix_error1. * PREFIX mode, top package is $TOP, so all subpackages should be named $TOP_something TRY. @@ -153,6 +230,47 @@ CLASS ltcl_folder_logic IMPLEMENTATION. ENDTRY. ENDMETHOD. + METHOD mixed1. + ltcl_folder_logic_helper=>test( + iv_starting = c_src + iv_top = c_top + iv_logic = zif_abapgit_dot_abapgit=>c_folder_logic-mixed + iv_package = c_top + iv_path = c_src ). + ENDMETHOD. + + METHOD mixed2. + ltcl_folder_logic_helper=>test( + iv_starting = c_src + iv_top = c_top + iv_logic = zif_abapgit_dot_abapgit=>c_folder_logic-mixed + iv_package = '$TOP_FOO' + iv_path = '/src/foo/' ). + ENDMETHOD. + + METHOD mixed3. + ltcl_folder_logic_helper=>test( + iv_starting = c_src + iv_top = c_top + iv_logic = zif_abapgit_dot_abapgit=>c_folder_logic-mixed + iv_package = '$TOP_BAR' + iv_path = '/src/foo/bar/' ). + ENDMETHOD. + + METHOD mixed_error1. +* MIXED mode, top package is $TOP, so all subpackages should be named $TOP_something + TRY. + ltcl_folder_logic_helper=>test( + iv_starting = c_src + iv_top = c_top + iv_logic = zif_abapgit_dot_abapgit=>c_folder_logic-mixed + iv_package = '$FOOBAR' + iv_path = '/src/' ). + cl_abap_unit_assert=>fail( 'Error expected' ). + CATCH zcx_abapgit_exception ##NO_HANDLER. + ENDTRY. + ENDMETHOD. + METHOD full1. ltcl_folder_logic_helper=>test( iv_starting = c_src @@ -171,6 +289,15 @@ CLASS ltcl_folder_logic IMPLEMENTATION. iv_path = '/src/top_foo/' ). ENDMETHOD. + METHOD full3. + ltcl_folder_logic_helper=>test( + iv_starting = c_src + iv_top = c_top + iv_logic = zif_abapgit_dot_abapgit=>c_folder_logic-full + iv_package = '$TOP_BAR' + iv_path = '/src/top_foo/top_bar/' ). + ENDMETHOD. + ENDCLASS. CLASS ltcl_folder_logic_namespaces DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL. @@ -186,6 +313,8 @@ CLASS ltcl_folder_logic_namespaces DEFINITION FOR TESTING RISK LEVEL HARMLESS DU setup, prefix1 FOR TESTING RAISING zcx_abapgit_exception, prefix2 FOR TESTING RAISING zcx_abapgit_exception, + mixed1 FOR TESTING RAISING zcx_abapgit_exception, + mixed2 FOR TESTING RAISING zcx_abapgit_exception, full1 FOR TESTING RAISING zcx_abapgit_exception, full2 FOR TESTING RAISING zcx_abapgit_exception. @@ -235,7 +364,7 @@ CLASS ltcl_folder_logic_namespaces IMPLEMENTATION. METHOD setup. - zcl_abapgit_injector=>set_sap_package( iv_package = '/TEST/TOOLS' + zcl_abapgit_injector=>set_sap_package( iv_package = c_top ii_sap_package = me ). zcl_abapgit_injector=>set_sap_package( iv_package = '/TEST/T1' @@ -266,6 +395,24 @@ CLASS ltcl_folder_logic_namespaces IMPLEMENTATION. iv_path = '/src/t1/' ). ENDMETHOD. + METHOD mixed1. + ltcl_folder_logic_helper=>test( + iv_starting = c_src + iv_top = c_top + iv_logic = zif_abapgit_dot_abapgit=>c_folder_logic-mixed + iv_package = c_top + iv_path = c_src ). + ENDMETHOD. + + METHOD mixed2. + ltcl_folder_logic_helper=>test( + iv_starting = c_src + iv_top = c_top + iv_logic = zif_abapgit_dot_abapgit=>c_folder_logic-mixed + iv_package = '/TEST/TOOLS_T1' + iv_path = '/src/t1/' ). + ENDMETHOD. + METHOD full1. ltcl_folder_logic_helper=>test( iv_starting = c_src diff --git a/src/repo/zif_abapgit_dot_abapgit.intf.abap b/src/repo/zif_abapgit_dot_abapgit.intf.abap index 0822769d8..055af54dd 100644 --- a/src/repo/zif_abapgit_dot_abapgit.intf.abap +++ b/src/repo/zif_abapgit_dot_abapgit.intf.abap @@ -23,6 +23,7 @@ INTERFACE zif_abapgit_dot_abapgit PUBLIC. BEGIN OF c_folder_logic, prefix TYPE string VALUE 'PREFIX', full TYPE string VALUE 'FULL', + mixed TYPE string VALUE 'MIXED', END OF c_folder_logic . ENDINTERFACE. diff --git a/src/ui/zcl_abapgit_gui_page_addofflin.clas.abap b/src/ui/zcl_abapgit_gui_page_addofflin.clas.abap index c5ebb3049..800727773 100644 --- a/src/ui/zcl_abapgit_gui_page_addofflin.clas.abap +++ b/src/ui/zcl_abapgit_gui_page_addofflin.clas.abap @@ -113,6 +113,9 @@ CLASS zcl_abapgit_gui_page_addofflin IMPLEMENTATION. )->option( iv_label = 'Full' iv_value = zif_abapgit_dot_abapgit=>c_folder_logic-full + )->option( + iv_label = 'Mixed' + iv_value = zif_abapgit_dot_abapgit=>c_folder_logic-mixed )->checkbox( iv_name = c_id-main_lang_only iv_label = 'Serialize Main Language Only' @@ -148,12 +151,11 @@ CLASS zcl_abapgit_gui_page_addofflin IMPLEMENTATION. ENDIF. IF io_form_data->get( c_id-folder_logic ) <> zif_abapgit_dot_abapgit=>c_folder_logic-prefix - AND io_form_data->get( c_id-folder_logic ) <> zif_abapgit_dot_abapgit=>c_folder_logic-full. + AND io_form_data->get( c_id-folder_logic ) <> zif_abapgit_dot_abapgit=>c_folder_logic-full + AND io_form_data->get( c_id-folder_logic ) <> zif_abapgit_dot_abapgit=>c_folder_logic-mixed. ro_validation_log->set( iv_key = c_id-folder_logic - iv_val = |Invalid folder logic { io_form_data->get( c_id-folder_logic ) - }. Must be { zif_abapgit_dot_abapgit=>c_folder_logic-prefix - } or { zif_abapgit_dot_abapgit=>c_folder_logic-full } | ). + iv_val = |Invalid folder logic { io_form_data->get( c_id-folder_logic ) }| ). ENDIF. ENDMETHOD. diff --git a/src/ui/zcl_abapgit_gui_page_addonline.clas.abap b/src/ui/zcl_abapgit_gui_page_addonline.clas.abap index e77a021c5..083001503 100644 --- a/src/ui/zcl_abapgit_gui_page_addonline.clas.abap +++ b/src/ui/zcl_abapgit_gui_page_addonline.clas.abap @@ -125,6 +125,9 @@ CLASS zcl_abapgit_gui_page_addonline IMPLEMENTATION. )->option( iv_label = 'Full' iv_value = zif_abapgit_dot_abapgit=>c_folder_logic-full + )->option( + iv_label = 'Mixed' + iv_value = zif_abapgit_dot_abapgit=>c_folder_logic-mixed )->text( iv_name = c_id-display_name iv_label = 'Display Name' @@ -180,12 +183,11 @@ CLASS zcl_abapgit_gui_page_addonline IMPLEMENTATION. ENDIF. IF io_form_data->get( c_id-folder_logic ) <> zif_abapgit_dot_abapgit=>c_folder_logic-prefix - AND io_form_data->get( c_id-folder_logic ) <> zif_abapgit_dot_abapgit=>c_folder_logic-full. + AND io_form_data->get( c_id-folder_logic ) <> zif_abapgit_dot_abapgit=>c_folder_logic-full + AND io_form_data->get( c_id-folder_logic ) <> zif_abapgit_dot_abapgit=>c_folder_logic-mixed. ro_validation_log->set( iv_key = c_id-folder_logic - iv_val = |Invalid folder logic { io_form_data->get( c_id-folder_logic ) - }. Must be { zif_abapgit_dot_abapgit=>c_folder_logic-prefix - } or { zif_abapgit_dot_abapgit=>c_folder_logic-full } | ). + iv_val = |Invalid folder logic { io_form_data->get( c_id-folder_logic ) }| ). ENDIF. ENDMETHOD. diff --git a/src/ui/zcl_abapgit_gui_page_ex_pckage.clas.abap b/src/ui/zcl_abapgit_gui_page_ex_pckage.clas.abap index 1cce39499..f0bf83d13 100644 --- a/src/ui/zcl_abapgit_gui_page_ex_pckage.clas.abap +++ b/src/ui/zcl_abapgit_gui_page_ex_pckage.clas.abap @@ -49,6 +49,7 @@ CLASS zcl_abapgit_gui_page_ex_pckage DEFINITION ENDCLASS. + CLASS zcl_abapgit_gui_page_ex_pckage IMPLEMENTATION. @@ -71,6 +72,22 @@ CLASS zcl_abapgit_gui_page_ex_pckage IMPLEMENTATION. ENDMETHOD. + METHOD export_package. + DATA lv_package TYPE devclass. + DATA lv_folder_logic TYPE string. + DATA lv_main_lang_only TYPE abap_bool. + + lv_package = mo_form_data->get( c_id-package ). + lv_folder_logic = mo_form_data->get( c_id-folder_logic ). + lv_main_lang_only = mo_form_data->get( c_id-main_lang_only ). + + zcl_abapgit_zip=>export_package( + iv_package = lv_package + iv_folder_logic = lv_folder_logic + iv_main_lang_only = lv_main_lang_only ). + ENDMETHOD. + + METHOD get_form_schema. ro_form = zcl_abapgit_html_form=>create( iv_form_id = 'export-package-to-files' ). @@ -91,6 +108,9 @@ CLASS zcl_abapgit_gui_page_ex_pckage IMPLEMENTATION. )->option( iv_label = 'Full' iv_value = zif_abapgit_dot_abapgit=>c_folder_logic-full + )->option( + iv_label = 'Mixed' + iv_value = zif_abapgit_dot_abapgit=>c_folder_logic-mixed )->checkbox( iv_name = c_id-main_lang_only iv_label = 'Serialize Main Language Only' @@ -105,17 +125,6 @@ CLASS zcl_abapgit_gui_page_ex_pckage IMPLEMENTATION. ENDMETHOD. - METHOD zif_abapgit_gui_renderable~render. - gui_services( )->register_event_handler( me ). - - CREATE OBJECT ri_html TYPE zcl_abapgit_html. - - ri_html->add( mo_form->render( - io_values = mo_form_data - io_validation_log = mo_validation_log ) ). - ENDMETHOD. - - METHOD zif_abapgit_gui_event_handler~on_event. mo_form_data = mo_form_util->normalize( ii_event->form_data( ) ). @@ -150,18 +159,13 @@ CLASS zcl_abapgit_gui_page_ex_pckage IMPLEMENTATION. ENDMETHOD. - METHOD export_package. - DATA lv_package TYPE devclass. - DATA lv_folder_logic TYPE string. - DATA lv_main_lang_only TYPE abap_bool. + METHOD zif_abapgit_gui_renderable~render. + gui_services( )->register_event_handler( me ). - lv_package = mo_form_data->get( c_id-package ). - lv_folder_logic = mo_form_data->get( c_id-folder_logic ). - lv_main_lang_only = mo_form_data->get( c_id-main_lang_only ). + CREATE OBJECT ri_html TYPE zcl_abapgit_html. - zcl_abapgit_zip=>export_package( - iv_package = lv_package - iv_folder_logic = lv_folder_logic - iv_main_lang_only = lv_main_lang_only ). + ri_html->add( mo_form->render( + io_values = mo_form_data + io_validation_log = mo_validation_log ) ). ENDMETHOD. ENDCLASS. diff --git a/src/ui/zcl_abapgit_gui_page_sett_repo.clas.abap b/src/ui/zcl_abapgit_gui_page_sett_repo.clas.abap index ffd3eb704..220fb554d 100644 --- a/src/ui/zcl_abapgit_gui_page_sett_repo.clas.abap +++ b/src/ui/zcl_abapgit_gui_page_sett_repo.clas.abap @@ -136,6 +136,9 @@ CLASS zcl_abapgit_gui_page_sett_repo IMPLEMENTATION. )->option( iv_label = 'Full' iv_value = zif_abapgit_dot_abapgit=>c_folder_logic-full + )->option( + iv_label = 'Mixed' + iv_value = zif_abapgit_dot_abapgit=>c_folder_logic-mixed )->text( iv_name = c_id-starting_folder iv_label = 'Starting Folder'