From ad5ae2a185420157304252b516ac5a9b5473819e Mon Sep 17 00:00:00 2001 From: Christian Guenter Date: Thu, 28 Jun 2018 10:23:45 +0000 Subject: [PATCH] delete empty packages --- src/objects/zcl_abapgit_object_devc.clas.abap | 152 +++++++++++++--- src/zcl_abapgit_dependencies.clas.abap | 47 ++++- ...abapgit_dependencies.clas.testclasses.abap | 168 ++++++++++++++++++ src/zcl_abapgit_dependencies.clas.xml | 1 + 4 files changed, 342 insertions(+), 26 deletions(-) create mode 100644 src/zcl_abapgit_dependencies.clas.testclasses.abap diff --git a/src/objects/zcl_abapgit_object_devc.clas.abap b/src/objects/zcl_abapgit_object_devc.clas.abap index cd5f50025..20a8d8996 100644 --- a/src/objects/zcl_abapgit_object_devc.clas.abap +++ b/src/objects/zcl_abapgit_object_devc.clas.abap @@ -20,7 +20,16 @@ CLASS zcl_abapgit_object_devc DEFINITION PUBLIC RAISING zcx_abapgit_exception, set_lock IMPORTING ii_package TYPE REF TO if_package iv_lock TYPE abap_bool - RAISING zcx_abapgit_exception. + RAISING zcx_abapgit_exception, + is_empty + IMPORTING iv_package_name TYPE devclass + RETURNING VALUE(rv_is_empty) TYPE abap_bool + RAISING zcx_abapgit_exception, + load_package + IMPORTING iv_package_name TYPE devclass + RETURNING VALUE(ri_package) TYPE REF TO if_package + RAISING zcx_abapgit_exception. + DATA: mv_local_devclass TYPE devclass. ENDCLASS. @@ -39,24 +48,7 @@ CLASS zcl_abapgit_object_devc IMPLEMENTATION. METHOD get_package. IF me->zif_abapgit_object~exists( ) = abap_true. - cl_package_factory=>load_package( - EXPORTING - i_package_name = mv_local_devclass - i_force_reload = abap_true - IMPORTING - e_package = ri_package - EXCEPTIONS - object_not_existing = 1 - unexpected_error = 2 - intern_err = 3 - no_access = 4 - object_locked_and_modified = 5 - OTHERS = 6 ). - IF sy-subrc = 1. - RETURN. - ELSEIF sy-subrc <> 0. - zcx_abapgit_exception=>raise_t100( ). - ENDIF. + ri_package = load_package( mv_local_devclass ). ENDIF. ENDMETHOD. @@ -209,12 +201,83 @@ CLASS zcl_abapgit_object_devc IMPLEMENTATION. METHOD zif_abapgit_object~delete. + + DATA: li_package TYPE REF TO if_package, + lv_package TYPE devclass. + " Package deletion is a bit tricky. A package can only be deleted if there are no objects " contained in it. This includes subpackages, so first the leaf packages need to be deleted. " Unfortunately deleted objects that are still contained in an unreleased transport request " also count towards the contained objects counter. - " -> Package deletion is currently not supported by abapGit - RETURN. + " -> Currently we delete only empty packages + " + " If objects are deleted, the TADIR entry is deleted when the transport request is released. + " So before we can delete the package, the transport which deletes the objects + " in the package has to be released. + + lv_package = ms_item-obj_name. + + IF is_empty( lv_package ) = abap_true. + + li_package = load_package( lv_package ). + + IF li_package IS NOT BOUND. + RETURN. + ENDIF. + + li_package->set_changeable( + EXPORTING + i_changeable = abap_true + i_suppress_dialog = abap_true + EXCEPTIONS + object_locked_by_other_user = 1 + permission_failure = 2 + object_already_changeable = 3 + object_already_unlocked = 4 + object_just_created = 5 + object_deleted = 6 + object_modified = 7 + object_not_existing = 8 + object_invalid = 9 + unexpected_error = 10 + OTHERS = 11 ). + + IF sy-subrc <> 0. + zcx_abapgit_exception=>raise_t100( ). + ENDIF. + + li_package->delete( + EXPORTING + i_suppress_dialog = abap_true + EXCEPTIONS + object_not_empty = 1 + object_not_changeable = 2 + object_invalid = 3 + intern_err = 4 + OTHERS = 5 ). + + IF sy-subrc <> 0. + zcx_abapgit_exception=>raise_t100( ). + ENDIF. + + li_package->save( + EXPORTING + i_suppress_dialog = abap_true + EXCEPTIONS + object_invalid = 1 + object_not_changeable = 2 + cancelled_in_corr = 3 + permission_failure = 4 + unexpected_error = 5 + intern_err = 6 + OTHERS = 7 ). + + IF sy-subrc <> 0. + zcx_abapgit_exception=>raise_t100( ). + ENDIF. + + ENDIF. + ENDMETHOD. @@ -558,4 +621,51 @@ CLASS zcl_abapgit_object_devc IMPLEMENTATION. ENDMETHOD. + + METHOD is_empty. + + DATA: lv_object_name TYPE tadir-obj_name, + lt_subpackages TYPE zif_abapgit_sap_package=>ty_devclass_tt. + + lt_subpackages = zcl_abapgit_factory=>get_sap_package( iv_package_name )->list_subpackages( ). + + IF lines( lt_subpackages ) > 0. + rv_is_empty = abap_false. + RETURN. + ENDIF. + + SELECT SINGLE obj_name + FROM tadir + INTO lv_object_name + WHERE pgmid = 'R3TR' + AND NOT ( object = 'DEVC' AND obj_name = iv_package_name ) + AND devclass = iv_package_name. + rv_is_empty = boolc( sy-subrc <> 0 ). + + ENDMETHOD. + + + METHOD load_package. + + cl_package_factory=>load_package( + EXPORTING + i_package_name = iv_package_name + i_force_reload = abap_true + IMPORTING + e_package = ri_package + EXCEPTIONS + object_not_existing = 1 + unexpected_error = 2 + intern_err = 3 + no_access = 4 + object_locked_and_modified = 5 + OTHERS = 6 ). + IF sy-subrc = 1. + RETURN. + ELSEIF sy-subrc <> 0. + zcx_abapgit_exception=>raise_t100( ). + ENDIF. + + ENDMETHOD. + ENDCLASS. diff --git a/src/zcl_abapgit_dependencies.clas.abap b/src/zcl_abapgit_dependencies.clas.abap index 3131f6d8e..54de4a95b 100644 --- a/src/zcl_abapgit_dependencies.clas.abap +++ b/src/zcl_abapgit_dependencies.clas.abap @@ -22,7 +22,6 @@ CLASS zcl_abapgit_dependencies DEFINITION !ct_tadir TYPE ty_tadir_tt RAISING zcx_abapgit_exception . - PRIVATE SECTION. TYPES: @@ -51,14 +50,17 @@ CLASS zcl_abapgit_dependencies DEFINITION zcx_abapgit_exception . CLASS-METHODS get_ddls_dependencies IMPORTING - !iv_ddls_name TYPE tadir-obj_name + iv_ddls_name TYPE tadir-obj_name RETURNING VALUE(rt_dependency) TYPE tty_dedenpency . + CLASS-METHODS resolve_packages + CHANGING + ct_tadir TYPE zcl_abapgit_dependencies=>ty_tadir_tt. ENDCLASS. -CLASS ZCL_ABAPGIT_DEPENDENCIES IMPLEMENTATION. +CLASS zcl_abapgit_dependencies IMPLEMENTATION. METHOD get_ddls_dependencies. @@ -84,14 +86,16 @@ CLASS ZCL_ABAPGIT_DEPENDENCIES IMPLEMENTATION. METHOD resolve. - DATA: lv_tabclass TYPE dd02l-tabclass. + DATA: lv_tabclass TYPE dd02l-tabclass. - FIELD-SYMBOLS: LIKE LINE OF ct_tadir. + FIELD-SYMBOLS: LIKE LINE OF ct_tadir. * misuse field KORRNUM to fix deletion sequence LOOP AT ct_tadir ASSIGNING . CASE -object. + WHEN 'DEVC'. + -korrnum = '9990'. WHEN 'IATU'. -korrnum = '5500'. WHEN 'IARP'. @@ -137,6 +141,7 @@ CLASS ZCL_ABAPGIT_DEPENDENCIES IMPLEMENTATION. ENDLOOP. resolve_ddic( CHANGING ct_tadir = ct_tadir ). + resolve_packages( CHANGING ct_tadir = ct_tadir ). SORT ct_tadir BY korrnum ASCENDING. @@ -292,4 +297,36 @@ CLASS ZCL_ABAPGIT_DEPENDENCIES IMPLEMENTATION. ENDDO. ENDMETHOD. "resolve_ddic + + + METHOD resolve_packages. + + DATA: lt_subpackages TYPE zif_abapgit_sap_package=>ty_devclass_tt. + + FIELD-SYMBOLS: LIKE LINE OF ct_tadir, + LIKE LINE OF lt_subpackages, + LIKE LINE OF ct_tadir. + + " List subpackage before corresponding superpackage + + LOOP AT ct_tadir ASSIGNING + WHERE object = 'DEVC'. + + lt_subpackages = zcl_abapgit_factory=>get_sap_package( |{ -obj_name }| )->list_subpackages( ). + + LOOP AT lt_subpackages ASSIGNING . + + READ TABLE ct_tadir ASSIGNING + WITH KEY object = 'DEVC' + obj_name = . + IF sy-subrc = 0. + -korrnum = condense( |{ -korrnum - 1 }| ). + ENDIF. + + ENDLOOP. + + ENDLOOP. + + ENDMETHOD. + ENDCLASS. diff --git a/src/zcl_abapgit_dependencies.clas.testclasses.abap b/src/zcl_abapgit_dependencies.clas.testclasses.abap new file mode 100644 index 000000000..aa039edc9 --- /dev/null +++ b/src/zcl_abapgit_dependencies.clas.testclasses.abap @@ -0,0 +1,168 @@ +*"* use this source file for your ABAP unit test classes +CLASS ltd_sap_package DEFINITION FOR TESTING. + + PUBLIC SECTION. + TYPES: + tty_package TYPE STANDARD TABLE OF devclass + WITH NON-UNIQUE DEFAULT KEY. + + METHODS: + constructor + IMPORTING + iv_package TYPE devclass, + + set_sub_packages + IMPORTING + it_sub_packages TYPE tty_package. + + INTERFACES: zif_abapgit_sap_package PARTIALLY IMPLEMENTED. + + PRIVATE SECTION. + DATA: mv_package TYPE devclass, + mt_sub_packages TYPE tty_package. + +ENDCLASS. + +CLASS ltd_sap_package IMPLEMENTATION. + + METHOD constructor. + + mv_package = iv_package. + + ENDMETHOD. + + METHOD zif_abapgit_sap_package~list_subpackages. + + DATA: ls_package LIKE LINE OF rt_list. + FIELD-SYMBOLS: TYPE devclass. + + IF mv_package = 'Z_MAIN'. + + rt_list = mt_sub_packages. + + ENDIF. + + ENDMETHOD. + + + METHOD set_sub_packages. + + mt_sub_packages = it_sub_packages. + + ENDMETHOD. + +ENDCLASS. + +CLASS ltcl_resolve_packages DEFINITION FOR TESTING + DURATION SHORT + RISK LEVEL HARMLESS. + + PRIVATE SECTION. + DATA: + mt_tadir TYPE zcl_abapgit_dependencies=>ty_tadir_tt, + mt_sub_packages TYPE ltd_sap_package=>tty_package. + + METHODS: + resolve_single FOR TESTING RAISING cx_static_check, + + given_tadir + IMPORTING + iv_object TYPE tadir-object + iv_obj_name TYPE tadir-obj_name + iv_korrnum TYPE tadir-korrnum + iv_super_package TYPE devclass, + + when_packages_are_resolved, + + then_korrnum_should_be + IMPORTING + iv_line TYPE i + iv_korrnum TYPE tadir-korrnum. + +ENDCLASS. + +CLASS zcl_abapgit_dependencies DEFINITION LOCAL FRIENDS ltcl_resolve_packages. + +CLASS ltcl_resolve_packages IMPLEMENTATION. + + METHOD resolve_single. + + + given_tadir( iv_object = 'DEVC' + iv_obj_name = 'Z_MAIN' + iv_korrnum = '9990' + iv_super_package = '' ). + + given_tadir( iv_object = 'DEVC' + iv_obj_name = 'Z_SUB1' + iv_korrnum = '9990' + iv_super_package = 'Z_MAIN' ). + + given_tadir( iv_object = 'DEVC' + iv_obj_name = 'Z_SUB2' + iv_korrnum = '9990' + iv_super_package = 'Z_MAIN' ). + + when_packages_are_resolved( ). + + then_korrnum_should_be( iv_line = 1 + iv_korrnum = '9990' ). + then_korrnum_should_be( iv_line = 2 + iv_korrnum = '9989' ). + then_korrnum_should_be( iv_line = 3 + iv_korrnum = '9989' ). + + ENDMETHOD. + + + METHOD given_tadir. + + DATA: ls_tadir LIKE LINE OF mt_tadir, + lv_package TYPE devclass. + + ls_tadir-object = iv_object. + ls_tadir-obj_name = iv_obj_name. + ls_tadir-korrnum = iv_korrnum. + INSERT ls_tadir INTO TABLE mt_tadir. + + IF iv_super_package IS NOT INITIAL. + lv_package = iv_obj_name. + INSERT lv_package INTO TABLE mt_sub_packages. + ENDIF. + + ENDMETHOD. + + + METHOD when_packages_are_resolved. + + DATA: lo_mock_sap_package TYPE REF TO ltd_sap_package. + + CREATE OBJECT lo_mock_sap_package + EXPORTING + iv_package = 'Z_MAIN'. + + lo_mock_sap_package->set_sub_packages( mt_sub_packages ). + + zcl_abapgit_injector=>set_sap_package( iv_package = 'Z_MAIN' + ii_sap_package = lo_mock_sap_package ). + + zcl_abapgit_dependencies=>resolve_packages( + CHANGING + ct_tadir = mt_tadir ). + + ENDMETHOD. + + + METHOD then_korrnum_should_be. + + FIELD-SYMBOLS: LIKE LINE OF mt_tadir. + + READ TABLE mt_tadir INDEX iv_line + ASSIGNING . + + cl_abap_unit_assert=>assert_equals( exp = iv_korrnum + act = -korrnum ). + + ENDMETHOD. + +ENDCLASS. diff --git a/src/zcl_abapgit_dependencies.clas.xml b/src/zcl_abapgit_dependencies.clas.xml index 2458887eb..58a4f2c7a 100644 --- a/src/zcl_abapgit_dependencies.clas.xml +++ b/src/zcl_abapgit_dependencies.clas.xml @@ -13,6 +13,7 @@ X X X + X