Improve package / sub-package check (#5628)

If a sub-package is removed from the package hierarchy, instead of an exception, abapGit now shows a detailed warning message in the log.

This allows to remedy the situation either by adding the sub-package to the package hierarchy or by removing the sub-package from the repository (via push).
This commit is contained in:
Marc Bernard 2022-07-12 11:14:02 +02:00 committed by GitHub
parent b6de2d0dc8
commit bdfe982ee8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 243 additions and 24 deletions

View File

@ -110,6 +110,13 @@ CLASS zcl_abapgit_file_status DEFINITION
!it_results TYPE zif_abapgit_definitions=>ty_results_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS check_package_sub_package
IMPORTING
!ii_log TYPE REF TO zif_abapgit_log
!it_results TYPE zif_abapgit_definitions=>ty_results_tt
!iv_top TYPE devclass
RAISING
zcx_abapgit_exception .
CLASS-METHODS check_package_folder
IMPORTING
!ii_log TYPE REF TO zif_abapgit_log
@ -455,9 +462,11 @@ CLASS zcl_abapgit_file_status IMPLEMENTATION.
iv_package = <ls_result>-package ).
IF lv_path <> <ls_result>-path.
ii_log->add( iv_msg = |Package and path does not match for object, {
ii_log->add( iv_msg = |Package and path do not match for object {
<ls_result>-obj_type } { <ls_result>-obj_name }|
iv_type = 'W' ).
ELSEIF lv_path IS INITIAL.
zcx_abapgit_exception=>raise( |Error determining parent package of package { <ls_result>-package }| ).
ENDIF.
ENDLOOP.
@ -495,6 +504,34 @@ CLASS zcl_abapgit_file_status IMPLEMENTATION.
ENDMETHOD.
METHOD check_package_sub_package.
DATA lv_msg TYPE string.
FIELD-SYMBOLS <ls_result> LIKE LINE OF it_results.
LOOP AT it_results ASSIGNING <ls_result> WHERE package IS INITIAL AND obj_type = 'DEVC'.
IF zcl_abapgit_factory=>get_sap_package( |{ <ls_result>-obj_name }| )->exists( ) = abap_true.
" If package already exist but is not included in the package hierarchy of
" the package assigned to the repository, then a manual change of the package
" is required i.e. setting a parent package to the repo package (or one of its
" subpackages). We don't do this automatically since it's not clear where in the
" hierarchy the new package should be located or whether the sub package shall be
" removed from the repo.
lv_msg = |Package { <ls_result>-obj_name } already exists but is not a sub-package of { iv_top }. |
&& |Check your package and folder logic, and either assign { <ls_result>-obj_name } |
&& |to the package hierarchy of { iv_top } or remove package { <ls_result>-obj_name } |
&& |from the repository.|.
ii_log->add( iv_msg = lv_msg
iv_type = 'W' ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD get_object_package.
DATA: lv_name TYPE devclass,
li_package TYPE REF TO zif_abapgit_sap_package.
@ -520,8 +557,7 @@ CLASS zcl_abapgit_file_status IMPLEMENTATION.
lv_is_xml TYPE abap_bool,
lv_is_json TYPE abap_bool,
lv_sub_fetched TYPE abap_bool,
lt_sub_packages TYPE zif_abapgit_sap_package=>ty_devclass_tt,
lv_msg TYPE string.
lt_sub_packages TYPE zif_abapgit_sap_package=>ty_devclass_tt.
FIELD-SYMBOLS <ls_remote> LIKE LINE OF it_remote.
@ -555,22 +591,10 @@ CLASS zcl_abapgit_file_status IMPLEMENTATION.
READ TABLE lt_sub_packages TRANSPORTING NO FIELDS
WITH KEY table_line = ls_item-devclass
BINARY SEARCH.
IF sy-subrc <> 0.
IF ls_item-obj_type = 'DEVC'.
" If package already exist but is not included in the package hierarchy of
" the package assigned to the repository, then a manual change of the package
" is required i.e. setting a parent package to iv_devclass (or one of its
" subpackages). We don't this automatically since it's not clear where in the
" hierarchy the new package should be located. (#4108)
lv_msg = |Package { ls_item-devclass } already exists but is not a subpackage of { iv_devclass
}. Check your package and folder logic or assign { ls_item-devclass
} to package hierarchy of { iv_devclass } to match the repository.|.
zcx_abapgit_exception=>raise( lv_msg ).
ELSE.
IF sy-subrc <> 0 AND ls_item-obj_type = 'DEVC'.
CLEAR ls_item-devclass.
ENDIF.
ENDIF.
ENDIF.
APPEND ls_item TO ct_items.
ENDLOOP.
@ -710,6 +734,12 @@ CLASS zcl_abapgit_file_status IMPLEMENTATION.
ii_log = ii_log
it_results = it_results ).
" Check that sub packages are included in the package hierarchy
check_package_sub_package(
ii_log = ii_log
it_results = it_results
iv_top = iv_top ).
" Check that objects are created in package corresponding to folder
check_package_folder(
ii_log = ii_log

View File

@ -33,6 +33,9 @@ ENDCLASS.
CLASS ltcl_run_checks DEFINITION FOR TESTING RISK LEVEL HARMLESS
DURATION SHORT FINAL.
PUBLIC SECTION.
INTERFACES: zif_abapgit_sap_package.
PRIVATE SECTION.
DATA: mt_results TYPE zif_abapgit_definitions=>ty_results_tt,
mo_dot TYPE REF TO zcl_abapgit_dot_abapgit,
@ -55,12 +58,53 @@ CLASS ltcl_run_checks DEFINITION FOR TESTING RISK LEVEL HARMLESS
neg_similar_filenames FOR TESTING RAISING zcx_abapgit_exception,
neg_empty_filenames FOR TESTING RAISING zcx_abapgit_exception,
package_move FOR TESTING RAISING zcx_abapgit_exception,
check_namespace FOR TESTING RAISING zcx_abapgit_exception.
check_namespace FOR TESTING RAISING zcx_abapgit_exception,
check_sub_package FOR TESTING RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS ltcl_run_checks 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 = '$MAIN'.
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.
METHOD append_result.
DATA ls_result LIKE LINE OF mt_results.
@ -88,6 +132,12 @@ CLASS ltcl_run_checks IMPLEMENTATION.
mo_dot = zcl_abapgit_dot_abapgit=>build_default( ).
mo_dot->set_starting_folder( '/' ). " assumed by unit tests
zcl_abapgit_injector=>set_sap_package( iv_package = '$MAIN'
ii_sap_package = me ).
zcl_abapgit_injector=>set_sap_package( iv_package = '$MAIN_SUB'
ii_sap_package = me ).
ENDMETHOD.
METHOD positive.
@ -249,7 +299,7 @@ CLASS ltcl_run_checks IMPLEMENTATION.
ltcl_util=>check_contains(
ii_log = mi_log
iv_pattern = |Package and path does not match for object, *| ).
iv_pattern = |Package and path do not match for object*| ).
ENDMETHOD.
@ -462,6 +512,42 @@ CLASS ltcl_run_checks IMPLEMENTATION.
ENDMETHOD.
METHOD check_sub_package.
append_result( iv_obj_type = 'DEVC'
iv_obj_name = '$MAIN'
iv_match = 'X'
iv_lstate = ' '
iv_rstate = ' '
iv_package = '$MAIN'
iv_path = '/'
iv_filename = 'package.devc.xml' ).
append_result( iv_obj_type = 'DEVC'
iv_obj_name = '$MAIN_SUB'
iv_match = ' '
iv_lstate = ' '
iv_rstate = 'X'
iv_package = ''
iv_path = ''
iv_filename = 'package.devc.xml' ).
zcl_abapgit_file_status=>run_checks(
ii_log = mi_log
it_results = mt_results
io_dot = mo_dot
iv_top = '$MAIN' ).
cl_abap_unit_assert=>assert_equals(
act = mi_log->count( )
exp = 1 ).
ltcl_util=>check_contains(
ii_log = mi_log
iv_pattern = |Package $MAIN_SUB already exists but is not a sub-package of $MAIN*| ).
ENDMETHOD.
ENDCLASS.
CLASS lcl_status_result DEFINITION.

View File

@ -88,9 +88,9 @@ CLASS zcl_abapgit_folder_logic IMPLEMENTATION.
ELSE.
lv_parentcl = get_parent( iv_package ).
IF lv_parentcl IS INITIAL.
zcx_abapgit_exception=>raise( |error, expected parent package, { iv_package }| ).
ELSE.
" If the parent package can not be determined, we return an initial path and handle
" it outside of this class (in zcl_abapgit_file_status)
IF lv_parentcl IS NOT INITIAL.
lv_folder_logic = io_dot->get_folder_logic( ).
CASE lv_folder_logic.
WHEN zif_abapgit_dot_abapgit=>c_folder_logic-full.

View File

@ -375,8 +375,6 @@ CLASS ltcl_folder_logic_namespaces IMPLEMENTATION.
ENDMETHOD.
METHOD prefix1.
ltcl_folder_logic_helper=>test(
iv_starting = c_src
@ -432,3 +430,108 @@ CLASS ltcl_folder_logic_namespaces IMPLEMENTATION.
ENDMETHOD.
ENDCLASS.
CLASS ltcl_folder_logic_no_parent DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT FINAL.
PUBLIC SECTION.
INTERFACES: zif_abapgit_sap_package.
PRIVATE SECTION.
CONSTANTS: c_top TYPE devclass VALUE '$TOP',
c_src TYPE string VALUE '/src/'.
DATA mo_dot TYPE REF TO zcl_abapgit_dot_abapgit.
METHODS:
setup,
test IMPORTING iv_folder_logic TYPE string RAISING zcx_abapgit_exception,
prefix FOR TESTING RAISING zcx_abapgit_exception,
mixed FOR TESTING RAISING zcx_abapgit_exception,
full FOR TESTING RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS ltcl_folder_logic_no_parent 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 = ''.
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.
METHOD setup.
zcl_abapgit_injector=>set_sap_package( iv_package = c_top
ii_sap_package = me ).
zcl_abapgit_injector=>set_sap_package( iv_package = '$FOOBAR'
ii_sap_package = me ).
ENDMETHOD.
METHOD test.
DATA lv_path TYPE string.
mo_dot = zcl_abapgit_dot_abapgit=>build_default( ).
mo_dot->set_starting_folder( c_src ).
mo_dot->set_folder_logic( iv_folder_logic ).
lv_path = zcl_abapgit_folder_logic=>get_instance( )->package_to_path(
iv_top = c_top
io_dot = mo_dot
iv_package = '$FOOBAR' ).
" If package is not in the package hierarchy i.e. a sub-package of $TOP, then return no path
cl_abap_unit_assert=>assert_equals(
act = lv_path
exp = '' ).
ENDMETHOD.
METHOD prefix.
test( zif_abapgit_dot_abapgit=>c_folder_logic-prefix ).
ENDMETHOD.
METHOD mixed.
test( zif_abapgit_dot_abapgit=>c_folder_logic-mixed ).
ENDMETHOD.
METHOD full.
test( zif_abapgit_dot_abapgit=>c_folder_logic-full ).
ENDMETHOD.
ENDCLASS.