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 <larshp@hotmail.com>
This commit is contained in:
Marc Bernard 2022-03-31 13:35:34 +02:00 committed by GitHub
parent 6e927e63c5
commit f712eb17a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 209 additions and 38 deletions

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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'