From 98cf60c2a800b6fb9b4b8b543e2181aad1debd39 Mon Sep 17 00:00:00 2001 From: Christian Tapia Sabogal Date: Thu, 19 Jan 2017 17:07:59 -0500 Subject: [PATCH 01/13] Transport to zip improvement: #553 Don't serialize objects that are not in the transport request. --- src/zabapgit_zip.prog.abap | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/zabapgit_zip.prog.abap b/src/zabapgit_zip.prog.abap index 497f0b474..528c3a3f8 100644 --- a/src/zabapgit_zip.prog.abap +++ b/src/zabapgit_zip.prog.abap @@ -404,24 +404,25 @@ CLASS lcl_zip IMPLEMENTATION. CREATE OBJECT lo_log. - lt_zip = io_repo->get_files_local( lo_log ). + lt_zip = io_repo->get_files_local( io_log = lo_log + it_filter = it_filter ). IF lo_log->count( ) > 0. lo_log->show( ). ENDIF. - IF lines( it_filter ) > 0. - LOOP AT lt_zip ASSIGNING . - lv_index = sy-tabix. - READ TABLE it_filter WITH KEY - object = -item-obj_type - obj_name = -item-obj_name - TRANSPORTING NO FIELDS. - IF sy-subrc <> 0. - DELETE lt_zip INDEX lv_index. - ENDIF. - ENDLOOP. - ENDIF. +* IF lines( it_filter ) > 0. +* LOOP AT lt_zip ASSIGNING . +* lv_index = sy-tabix. +* READ TABLE it_filter WITH KEY +* object = -item-obj_type +* obj_name = -item-obj_name +* TRANSPORTING NO FIELDS. +* IF sy-subrc <> 0. +* DELETE lt_zip INDEX lv_index. +* ENDIF. +* ENDLOOP. +* ENDIF. file_download( iv_package = io_repo->get_package( ) iv_xstr = encode_files( lt_zip ) ). @@ -551,4 +552,4 @@ CLASS lcl_zip IMPLEMENTATION. ENDMETHOD. "export_package -ENDCLASS. "lcl_zip IMPLEMENTATION \ No newline at end of file +ENDCLASS. "lcl_zip IMPLEMENTATION From f47e4c236321d8c88e7e5704e5c0c9f24ab5d85b Mon Sep 17 00:00:00 2001 From: Christian Tapia Sabogal Date: Thu, 19 Jan 2017 17:11:40 -0500 Subject: [PATCH 02/13] Update zabapgit_repo_impl.prog.abap --- src/zabapgit_repo_impl.prog.abap | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/zabapgit_repo_impl.prog.abap b/src/zabapgit_repo_impl.prog.abap index 364f8a55b..16c4e8a35 100644 --- a/src/zabapgit_repo_impl.prog.abap +++ b/src/zabapgit_repo_impl.prog.abap @@ -500,19 +500,21 @@ CLASS lcl_repo IMPLEMENTATION. ENDMETHOD. - METHOD get_files_local. + METHOD get_files_local. DATA: lt_tadir TYPE ty_tadir_tt, ls_item TYPE ty_item, lt_files TYPE ty_files_tt. DATA: lt_cache TYPE SORTED TABLE OF ty_file_item - WITH NON-UNIQUE KEY item. + WITH NON-UNIQUE KEY item, + lt_tadir_aux LIKE lt_tadir. FIELD-SYMBOLS: LIKE LINE OF lt_files, LIKE LINE OF rt_files, LIKE LINE OF lt_cache, - LIKE LINE OF lt_tadir. + LIKE LINE OF lt_tadir, + LIKE LINE OF it_filter. " Serialization happened before and no refresh request @@ -533,7 +535,16 @@ CLASS lcl_repo IMPLEMENTATION. lt_cache = mt_local. lt_tadir = lcl_tadir=>read( get_package( ) ). - LOOP AT lt_tadir ASSIGNING . + + LOOP AT it_filter ASSIGNING . + READ TABLE lt_tadir ASSIGNING WITH KEY object = -object + obj_name = -obj_name. + IF sy-subrc = 0. + APPEND TO lt_tadir_aux. + ENDIF. + ENDLOOP. + + LOOP AT lt_tadir_aux ASSIGNING . lcl_progress=>show( iv_key = 'Serialize' iv_current = sy-tabix @@ -923,4 +934,4 @@ CLASS lcl_repo_srv IMPLEMENTATION. ENDMETHOD. "switch_repo_type -ENDCLASS. "lcl_repo_srv IMPLEMENTATION \ No newline at end of file +ENDCLASS. "lcl_repo_srv IMPLEMENTATION From 14b91e5b887447ae754f38d08d82df68e0c073c6 Mon Sep 17 00:00:00 2001 From: Christian Tapia Sabogal Date: Thu, 19 Jan 2017 17:13:10 -0500 Subject: [PATCH 03/13] Update zabapgit_repo.prog.abap --- src/zabapgit_repo.prog.abap | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/zabapgit_repo.prog.abap b/src/zabapgit_repo.prog.abap index 6d6eb40b5..8353d11d9 100644 --- a/src/zabapgit_repo.prog.abap +++ b/src/zabapgit_repo.prog.abap @@ -18,6 +18,7 @@ CLASS lcl_repo DEFINITION ABSTRACT FRIENDS lcl_repo_srv. RAISING lcx_exception, get_files_local IMPORTING io_log TYPE REF TO lcl_log OPTIONAL + it_filter TYPE scts_tadir OPTIONAL RETURNING VALUE(rt_files) TYPE ty_files_item_tt RAISING lcx_exception, get_local_checksums @@ -223,4 +224,4 @@ CLASS lcl_repo_srv DEFINITION FINAL CREATE PRIVATE FRIENDS lcl_app. IMPORTING iv_package TYPE devclass RAISING lcx_exception. -ENDCLASS. "lcl_repo_srv DEFINITION \ No newline at end of file +ENDCLASS. "lcl_repo_srv DEFINITION From dfa7c4bce3f7b9c449dadd7c866f1faafb0e971e Mon Sep 17 00:00:00 2001 From: Christian Tapia Sabogal Date: Thu, 19 Jan 2017 17:13:49 -0500 Subject: [PATCH 04/13] Update zabapgit_file_status.prog.abap --- src/zabapgit_file_status.prog.abap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zabapgit_file_status.prog.abap b/src/zabapgit_file_status.prog.abap index d30919b97..87854b255 100644 --- a/src/zabapgit_file_status.prog.abap +++ b/src/zabapgit_file_status.prog.abap @@ -61,7 +61,7 @@ CLASS lcl_file_status IMPLEMENTATION. rt_results = calculate_status( - it_local = io_repo->get_files_local( io_log ) + it_local = io_repo->get_files_local( io_log = io_log ) it_remote = io_repo->get_files_remote( ) it_cur_state = io_repo->get_local_checksums_per_file( ) ). @@ -290,4 +290,4 @@ CLASS lcl_file_status IMPLEMENTATION. ENDMETHOD. "build_new_remote -ENDCLASS. "lcl_file_status IMPLEMENTATION \ No newline at end of file +ENDCLASS. "lcl_file_status IMPLEMENTATION From 2a9084783711021b0163842ac249a8ecc827d5da Mon Sep 17 00:00:00 2001 From: Christian Tapia Sabogal Date: Fri, 20 Jan 2017 11:57:34 -0500 Subject: [PATCH 05/13] Update zabapgit_repo_impl.prog.abap --- src/zabapgit_repo_impl.prog.abap | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/zabapgit_repo_impl.prog.abap b/src/zabapgit_repo_impl.prog.abap index 16c4e8a35..9369eab7e 100644 --- a/src/zabapgit_repo_impl.prog.abap +++ b/src/zabapgit_repo_impl.prog.abap @@ -500,7 +500,7 @@ CLASS lcl_repo IMPLEMENTATION. ENDMETHOD. - METHOD get_files_local. + METHOD get_files_local. DATA: lt_tadir TYPE ty_tadir_tt, ls_item TYPE ty_item, @@ -535,15 +535,19 @@ CLASS lcl_repo IMPLEMENTATION. lt_cache = mt_local. lt_tadir = lcl_tadir=>read( get_package( ) ). - - LOOP AT it_filter ASSIGNING . - READ TABLE lt_tadir ASSIGNING WITH KEY object = -object - obj_name = -obj_name. - IF sy-subrc = 0. - APPEND TO lt_tadir_aux. - ENDIF. - ENDLOOP. - + + IF it_filter[] IS INITIAL. + lt_tadir_aux[] = lt_tadir[]. + ELSE. + LOOP AT it_filter ASSIGNING . + READ TABLE lt_tadir ASSIGNING WITH KEY object = -object + obj_name = -obj_name. + IF sy-subrc = 0. + APPEND TO lt_tadir_aux. + ENDIF. + ENDLOOP. + ENDIF. + LOOP AT lt_tadir_aux ASSIGNING . lcl_progress=>show( iv_key = 'Serialize' From de05a94c7495e9493b3d0ad2a1ad51bfdad663b6 Mon Sep 17 00:00:00 2001 From: Christian Tapia Sabogal Date: Fri, 20 Jan 2017 11:58:12 -0500 Subject: [PATCH 06/13] Update zabapgit_zip.prog.abap --- src/zabapgit_zip.prog.abap | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/zabapgit_zip.prog.abap b/src/zabapgit_zip.prog.abap index 528c3a3f8..76927dc15 100644 --- a/src/zabapgit_zip.prog.abap +++ b/src/zabapgit_zip.prog.abap @@ -411,19 +411,6 @@ CLASS lcl_zip IMPLEMENTATION. lo_log->show( ). ENDIF. -* IF lines( it_filter ) > 0. -* LOOP AT lt_zip ASSIGNING . -* lv_index = sy-tabix. -* READ TABLE it_filter WITH KEY -* object = -item-obj_type -* obj_name = -item-obj_name -* TRANSPORTING NO FIELDS. -* IF sy-subrc <> 0. -* DELETE lt_zip INDEX lv_index. -* ENDIF. -* ENDLOOP. -* ENDIF. - file_download( iv_package = io_repo->get_package( ) iv_xstr = encode_files( lt_zip ) ). From 772355fcdb030142d0997dd0a1ee190c2f03c8f2 Mon Sep 17 00:00:00 2001 From: Christian Tapia Sabogal Date: Fri, 20 Jan 2017 12:18:42 -0500 Subject: [PATCH 07/13] Update zabapgit_repo_impl.prog.abap --- src/zabapgit_repo_impl.prog.abap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zabapgit_repo_impl.prog.abap b/src/zabapgit_repo_impl.prog.abap index 9369eab7e..8c20cf998 100644 --- a/src/zabapgit_repo_impl.prog.abap +++ b/src/zabapgit_repo_impl.prog.abap @@ -535,7 +535,7 @@ CLASS lcl_repo IMPLEMENTATION. lt_cache = mt_local. lt_tadir = lcl_tadir=>read( get_package( ) ). - + IF it_filter[] IS INITIAL. lt_tadir_aux[] = lt_tadir[]. ELSE. @@ -547,7 +547,7 @@ CLASS lcl_repo IMPLEMENTATION. ENDIF. ENDLOOP. ENDIF. - + LOOP AT lt_tadir_aux ASSIGNING . lcl_progress=>show( iv_key = 'Serialize' From a917d8946161b182232037dd76f7d2ed3d34889d Mon Sep 17 00:00:00 2001 From: Christian Tapia Sabogal Date: Fri, 20 Jan 2017 15:56:23 -0500 Subject: [PATCH 08/13] Update zabapgit_zip.prog.abap --- src/zabapgit_zip.prog.abap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/zabapgit_zip.prog.abap b/src/zabapgit_zip.prog.abap index 76927dc15..b27607ed9 100644 --- a/src/zabapgit_zip.prog.abap +++ b/src/zabapgit_zip.prog.abap @@ -404,7 +404,7 @@ CLASS lcl_zip IMPLEMENTATION. CREATE OBJECT lo_log. - lt_zip = io_repo->get_files_local( io_log = lo_log + lt_zip = io_repo->get_files_local( io_log = lo_log it_filter = it_filter ). IF lo_log->count( ) > 0. From 0479eb36b2f03053ce835ca69e699ca5061fefc4 Mon Sep 17 00:00:00 2001 From: Christian Tapia Sabogal Date: Fri, 20 Jan 2017 18:20:26 -0500 Subject: [PATCH 09/13] Filter logic improvement when serializing --- src/zabapgit_app_impl.prog.abap | 989 ++++++++++++++++++++++++++++++-- 1 file changed, 930 insertions(+), 59 deletions(-) diff --git a/src/zabapgit_app_impl.prog.abap b/src/zabapgit_app_impl.prog.abap index 9af5079b0..36b8f7cce 100644 --- a/src/zabapgit_app_impl.prog.abap +++ b/src/zabapgit_app_impl.prog.abap @@ -1,70 +1,941 @@ *&---------------------------------------------------------------------* -*& Include ZABAPGIT_APP_IMPL +*& Include ZABAPGIT_REPO_IMPL *&---------------------------------------------------------------------* *----------------------------------------------------------------------* -* CLASS lcl_app IMPLEMENTATION +* CLASS lcl_repo_offline IMPLEMENTATION *----------------------------------------------------------------------* -CLASS lcl_app IMPLEMENTATION. +CLASS lcl_repo_offline IMPLEMENTATION. - METHOD run. + METHOD set_files_remote. - IF sy-batch = abap_true. - lcl_background=>run( ). - ELSE. - gui( )->go_home( ). - CALL SELECTION-SCREEN 1001. " trigger screen - ENDIF. + mt_remote = it_files. - ENDMETHOD. "run + find_dot_abapgit( ). - METHOD gui. - - IF go_gui IS NOT BOUND. - CREATE OBJECT go_gui. - ENDIF. - ro_gui = go_gui. - - ENDMETHOD. "gui - - METHOD user. - - IF iv_user = sy-uname ##USER_OK. - IF go_current_user IS NOT BOUND. - CREATE OBJECT go_current_user. - ENDIF. - ro_user = go_current_user. - ELSE. - CREATE OBJECT ro_user - EXPORTING - iv_user = iv_user. - ENDIF. - - ENDMETHOD. "user - - METHOD repo_srv. - - IF go_repo_srv IS NOT BOUND. - CREATE OBJECT go_repo_srv. - ENDIF. - ro_repo_srv = go_repo_srv. - - ENDMETHOD. "repo_srv - - METHOD db. - - IF go_db IS NOT BOUND. - CREATE OBJECT go_db. - ENDIF. - ro_db = go_db. - - ENDMETHOD. "repo_srv - - METHOD settings. - IF go_settings IS NOT BOUND. - CREATE OBJECT go_settings. - ENDIF. - ro_settings = go_settings. ENDMETHOD. -ENDCLASS. "lcl_app \ No newline at end of file +ENDCLASS. "lcl_repo_offline IMPLEMENTATION + +*----------------------------------------------------------------------* +* CLASS lcl_repo_online IMPLEMENTATION +*----------------------------------------------------------------------* +* +*----------------------------------------------------------------------* +CLASS lcl_repo_online IMPLEMENTATION. + + METHOD constructor. + + super->constructor( is_data ). + + mv_initialized = abap_false. + + ENDMETHOD. "constructor + + METHOD initialize. + IF mv_initialized = abap_false. + refresh( ). + ENDIF. + ENDMETHOD. + + METHOD status. + + initialize( ). + + IF lines( mt_status ) = 0. + mt_status = lcl_file_status=>status( io_repo = me + io_log = io_log ). + ENDIF. + rt_results = mt_status. + + ENDMETHOD. "status + + METHOD deserialize. + + IF ms_data-write_protect = abap_true. + lcx_exception=>raise( 'Cannot deserialize. Local code is write-protected by repo config' ). + ENDIF. + + initialize( ). + + super->deserialize( ). + + set( iv_sha1 = mv_branch ). + + reset_status( ). + + COMMIT WORK AND WAIT. + + ENDMETHOD. "deserialize + + METHOD reset_status. + CLEAR mt_status. + ENDMETHOD. " reset_status. + + METHOD refresh. + + super->refresh( iv_drop_cache ). + reset_status( ). + + lcl_progress=>show( iv_key = 'Fetch' + iv_current = 1 + iv_total = 1 + iv_text = 'Remote files' ) ##NO_TEXT. + + lcl_git_porcelain=>pull( EXPORTING io_repo = me + IMPORTING et_files = mt_remote + et_objects = mt_objects + ev_branch = mv_branch ). + + mo_branches = lcl_git_transport=>branches( get_url( ) ). + actualize_head_branch( ). + + find_dot_abapgit( ). + + mv_initialized = abap_true. + + ENDMETHOD. "refresh + + METHOD actualize_head_branch. + DATA lv_branch_name TYPE string. + lv_branch_name = mo_branches->get_head( )-name. + + IF lv_branch_name <> ms_data-head_branch. + set( iv_head_branch = lv_branch_name ). + ENDIF. + + ENDMETHOD. "actualize_head_branch + + METHOD get_sha1_remote. + initialize( ). + + rv_sha1 = mv_branch. + ENDMETHOD. "get_sha1_remote + + METHOD get_files_remote. + initialize( ). + + rt_files = mt_remote. + ENDMETHOD. "get_files + + METHOD get_objects. + initialize( ). + + rt_objects = mt_objects. + ENDMETHOD. "get_objects + + METHOD get_url. + rv_url = ms_data-url. + ENDMETHOD. "get_url + + METHOD get_branch_name. + rv_name = ms_data-branch_name. + ENDMETHOD. "get_branch_name + + METHOD get_head_branch_name. + rv_name = ms_data-head_branch. + ENDMETHOD. "get_head_branch_name + + METHOD get_branches. + IF mo_branches IS NOT BOUND. + mo_branches = lcl_git_transport=>branches( get_url( ) ). + ENDIF. + ro_branches = mo_branches. + ENDMETHOD. "get_branches + + METHOD set_url. + + IF ms_data-write_protect = abap_true. + lcx_exception=>raise( 'Cannot change URL. Local code is write-protected by repo config' ). + ENDIF. + + mv_initialized = abap_false. + set( iv_url = iv_url ). + + ENDMETHOD. + + METHOD set_branch_name. + + IF ms_data-write_protect = abap_true. + lcx_exception=>raise( 'Cannot switch branch. Local code is write-protected by repo config' ). + ENDIF. + + mv_initialized = abap_false. + set( iv_branch_name = iv_branch_name ). + + ENDMETHOD. + + METHOD set_new_remote. + + IF ms_data-write_protect = abap_true. + lcx_exception=>raise( 'Cannot change remote. Local code is write-protected by repo config' ). + ENDIF. + + mv_initialized = abap_false. + set( iv_url = iv_url + iv_branch_name = iv_branch_name + iv_head_branch = '' + iv_sha1 = '' ). + + ENDMETHOD. "set_new_remote + + METHOD get_sha1_local. + rv_sha1 = ms_data-sha1. + ENDMETHOD. "get_sha1_local + + METHOD push. + + DATA: lv_branch TYPE ty_sha1, + lt_updated_files TYPE ty_file_signatures_tt. + + + handle_stage_ignore( io_stage ). + + lcl_git_porcelain=>push( EXPORTING is_comment = is_comment + io_repo = me + io_stage = io_stage + IMPORTING ev_branch = lv_branch + et_updated_files = lt_updated_files ). + + IF io_stage->get_branch_sha1( ) = get_sha1_local( ). +* pushing to the branch currently represented by this repository object + set( iv_sha1 = lv_branch ). + ENDIF. + + refresh( ). + update_local_checksums( lt_updated_files ). + + IF lcl_stage_logic=>count( me ) = 0. + set( iv_sha1 = lv_branch ). + ENDIF. + + ENDMETHOD. "push + + METHOD handle_stage_ignore. + + DATA: lv_add TYPE abap_bool, + lt_stage TYPE lcl_stage=>ty_stage_tt. + + FIELD-SYMBOLS: LIKE LINE OF lt_stage. + + + lt_stage = io_stage->get_all( ). + LOOP AT lt_stage ASSIGNING WHERE method = lcl_stage=>c_method-ignore. + + mo_dot_abapgit->add_ignore( + iv_path = -file-path + iv_filename = -file-filename ). + + " remove it from the staging object, as the action is handled here + io_stage->reset( iv_path = -file-path + iv_filename = -file-filename ). + + lv_add = abap_true. + + ENDLOOP. + + IF lv_add = abap_true. + io_stage->add( + iv_path = gc_root_dir + iv_filename = gc_dot_abapgit + iv_data = mo_dot_abapgit->serialize( ) ). + ENDIF. + + ENDMETHOD. + + METHOD rebuild_local_checksums. "REMOTE + + DATA: lt_remote TYPE ty_files_tt, + lt_local TYPE ty_files_item_tt, + ls_last_item TYPE ty_item, + lv_branch_equal TYPE abap_bool, + lt_checksums TYPE lcl_persistence_repo=>ty_local_checksum_tt. + + FIELD-SYMBOLS: LIKE LINE OF lt_checksums, + LIKE LINE OF -files, + LIKE LINE OF lt_remote, + LIKE LINE OF lt_local. + + lt_remote = get_files_remote( ). + lt_local = get_files_local( ). + lv_branch_equal = boolc( get_sha1_remote( ) = get_sha1_local( ) ). + + DELETE lt_local " Remove non-code related files except .abapgit + WHERE item IS INITIAL + AND NOT ( file-path = gc_root_dir AND file-filename = gc_dot_abapgit ). + + SORT lt_local BY item. + SORT lt_remote BY path filename. + + LOOP AT lt_local ASSIGNING . + IF ls_last_item <> -item OR sy-tabix = 1. " First or New item reached ? + APPEND INITIAL LINE TO lt_checksums ASSIGNING . + -item = -item. + ls_last_item = -item. + ENDIF. + + READ TABLE lt_remote ASSIGNING + WITH KEY path = -file-path filename = -file-filename + BINARY SEARCH. + CHECK sy-subrc = 0. " Ignore new ones + + APPEND INITIAL LINE TO -files ASSIGNING . + MOVE-CORRESPONDING -file TO . + + " If hashes are equal -> local sha1 is OK + " Else if R-branch is ahead -> assume changes were remote, state - local sha1 + " Else (branches equal) -> assume changes were local, state - remote sha1 + IF -file-sha1 <> -sha1 AND lv_branch_equal = abap_true. + -sha1 = -sha1. + ENDIF. + ENDLOOP. + + set( it_checksums = lt_checksums ). + reset_status( ). + + ENDMETHOD. " rebuild_local_checksums. + +ENDCLASS. "lcl_repo_online IMPLEMENTATION + +*----------------------------------------------------------------------* +* CLASS lcl_repo IMPLEMENTATION +*----------------------------------------------------------------------* +* +*----------------------------------------------------------------------* +CLASS lcl_repo IMPLEMENTATION. + + METHOD constructor. + + ASSERT NOT is_data-key IS INITIAL. + + ms_data = is_data. + + ENDMETHOD. "constructor + + METHOD find_dot_abapgit. + + FIELD-SYMBOLS: LIKE LINE OF mt_remote. + + + READ TABLE mt_remote ASSIGNING + WITH KEY path = gc_root_dir + filename = gc_dot_abapgit. + IF sy-subrc = 0. + mo_dot_abapgit = lcl_dot_abapgit=>deserialize( -data ). + ENDIF. + + ENDMETHOD. + + METHOD get_files_remote. + rt_files = mt_remote. + ENDMETHOD. + + METHOD set. + + DATA: lo_persistence TYPE REF TO lcl_persistence_repo. + + + ASSERT iv_sha1 IS SUPPLIED + OR it_checksums IS SUPPLIED + OR iv_url IS SUPPLIED + OR iv_branch_name IS SUPPLIED + OR iv_head_branch IS SUPPLIED + OR iv_offline IS SUPPLIED. + + CREATE OBJECT lo_persistence. + + IF iv_sha1 IS SUPPLIED. + lo_persistence->update_sha1( + iv_key = ms_data-key + iv_branch_sha1 = iv_sha1 ). + ms_data-sha1 = iv_sha1. + ENDIF. + + IF it_checksums IS SUPPLIED. + lo_persistence->update_local_checksums( + iv_key = ms_data-key + it_checksums = it_checksums ). + ms_data-local_checksums = it_checksums. + ENDIF. + + IF iv_url IS SUPPLIED. + lo_persistence->update_url( + iv_key = ms_data-key + iv_url = iv_url ). + ms_data-url = iv_url. + ENDIF. + + IF iv_branch_name IS SUPPLIED. + lo_persistence->update_branch_name( + iv_key = ms_data-key + iv_branch_name = iv_branch_name ). + ms_data-branch_name = iv_branch_name. + ENDIF. + + IF iv_head_branch IS SUPPLIED. + lo_persistence->update_head_branch( + iv_key = ms_data-key + iv_head_branch = iv_head_branch ). + ms_data-head_branch = iv_head_branch. + ENDIF. + + IF iv_offline IS SUPPLIED. + lo_persistence->update_offline( + iv_key = ms_data-key + iv_offline = iv_offline ). + ms_data-offline = iv_offline. + ENDIF. + + ENDMETHOD. "set_sha1 + + METHOD update_local_checksums. + + " ASSUMTION: SHA1 in param is actual and correct. + " Push fills it from local files before pushing, deserialize from remote + " If this is not true that there is an error somewhere but not here + + DATA: lt_checksums TYPE lcl_persistence_repo=>ty_local_checksum_tt, + lt_files_idx TYPE ty_file_signatures_tt, + lt_local TYPE ty_files_item_tt, + lv_chks_row TYPE i, + lv_file_row TYPE i. + + FIELD-SYMBOLS: LIKE LINE OF lt_checksums, + LIKE LINE OF -files, + LIKE LINE OF lt_local, + LIKE LINE OF it_files. + + lt_checksums = get_local_checksums( ). + lt_files_idx = it_files. + SORT lt_files_idx BY path filename. " Sort for binary search + + " Loop through current chacksum state, update sha1 for common files + LOOP AT lt_checksums ASSIGNING . + lv_chks_row = sy-tabix. + + LOOP AT -files ASSIGNING . + lv_file_row = sy-tabix. + + READ TABLE lt_files_idx ASSIGNING + WITH KEY path = -path filename = -filename + BINARY SEARCH. + CHECK sy-subrc = 0. " Missing in param table, skip + + IF -sha1 IS INITIAL. " Empty input sha1 is a deletion marker + DELETE -files INDEX lv_file_row. + ELSE. + -sha1 = -sha1. " Update sha1 + CLEAR -sha1. " Mark as processed + ENDIF. + ENDLOOP. + + IF lines( -files ) = 0. " Remove empty objects + DELETE lt_checksums INDEX lv_chks_row. + ENDIF. + ENDLOOP. + + DELETE lt_files_idx WHERE sha1 IS INITIAL. " Remove processed + IF lines( lt_files_idx ) > 0. + lt_local = get_files_local( ). + SORT lt_local BY file-path file-filename. " Sort for binary search + ENDIF. + + " Add new files - not deleted and not marked as processed above + LOOP AT lt_files_idx ASSIGNING . + + READ TABLE lt_local ASSIGNING + WITH KEY file-path = -path file-filename = -filename + BINARY SEARCH. + IF sy-subrc <> 0. +* if the deserialization fails, the local file might not be there + CONTINUE. + ENDIF. + + READ TABLE lt_checksums ASSIGNING " TODO Optimize + WITH KEY item = -item. + IF sy-subrc > 0. + APPEND INITIAL LINE TO lt_checksums ASSIGNING . + -item = -item. + ENDIF. + + APPEND TO -files. + ENDLOOP. + + SORT lt_checksums BY item. + set( it_checksums = lt_checksums ). + + ENDMETHOD. " update_local_checksums + + METHOD deserialize. + + DATA: lt_updated_files TYPE ty_file_signatures_tt. + + IF mo_dot_abapgit IS INITIAL. + mo_dot_abapgit = lcl_dot_abapgit=>build_default( ms_data-master_language ). + ENDIF. + IF mo_dot_abapgit->get_master_language( ) <> sy-langu. + lcx_exception=>raise( 'Current login language does not match master language' ). + ENDIF. + + lt_updated_files = lcl_objects=>deserialize( me ). + APPEND mo_dot_abapgit->get_signature( ) TO lt_updated_files. + + CLEAR: mt_local, mv_last_serialization. + + update_local_checksums( lt_updated_files ). + + ENDMETHOD. + + METHOD get_local_checksums. + rt_checksums = ms_data-local_checksums. + ENDMETHOD. + + METHOD get_local_checksums_per_file. + + FIELD-SYMBOLS LIKE LINE OF ms_data-local_checksums. + + LOOP AT ms_data-local_checksums ASSIGNING . + APPEND LINES OF -files TO rt_checksums. + ENDLOOP. + + ENDMETHOD. + + METHOD get_files_local. + + DATA: lt_tadir TYPE ty_tadir_tt, + ls_item TYPE ty_item, + lt_files TYPE ty_files_tt, + lt_cache TYPE SORTED TABLE OF ty_file_item + WITH NON-UNIQUE KEY item. + + DATA: lt_filter TYPE SORTED TABLE OF tadir + WITH NON-UNIQUE KEY object obj_name, + lv_filter_exist TYPE abap_bool. + + FIELD-SYMBOLS: LIKE LINE OF lt_files, + LIKE LINE OF rt_files, + LIKE LINE OF lt_cache, + LIKE LINE OF lt_tadir. + + + " Serialization happened before and no refresh request + IF mv_last_serialization IS NOT INITIAL AND mv_do_local_refresh = abap_false. + rt_files = mt_local. + RETURN. + ENDIF. + + IF mo_dot_abapgit IS INITIAL. + mo_dot_abapgit = lcl_dot_abapgit=>build_default( ms_data-master_language ). + ENDIF. + APPEND INITIAL LINE TO rt_files ASSIGNING . + -file-path = gc_root_dir. + -file-filename = gc_dot_abapgit. + -file-data = mo_dot_abapgit->serialize( ). + -file-sha1 = lcl_hash=>sha1( iv_type = gc_type-blob + iv_data = -file-data ). + + lt_cache = mt_local. + lt_tadir = lcl_tadir=>read( get_package( ) ). + + lt_filter = it_filter. + lv_filter_exist = boolc( lines( lt_filter ) > 0 ) . + + LOOP AT lt_tadir ASSIGNING . + IF lv_filter_exist = abap_true. + READ TABLE lt_filter TRANSPORTING NO FIELDS WITH KEY object = -object + obj_name = -obj_name + BINARY SEARCH. + IF sy-subrc <> 0. + CONTINUE. + ENDIF. + ENDIF. + + lcl_progress=>show( iv_key = 'Serialize' + iv_current = sy-tabix + iv_total = lines( lt_tadir ) + iv_text = -obj_name ) ##NO_TEXT. + + ls_item-obj_type = -object. + ls_item-obj_name = -obj_name. + ls_item-devclass = -devclass. + + IF mv_last_serialization IS NOT INITIAL. " Try to fetch from cache + READ TABLE lt_cache TRANSPORTING NO FIELDS + WITH KEY item = ls_item. " type+name+package key + " There is something in cache and the object is unchanged + IF sy-subrc = 0 + AND abap_false = lcl_objects=>has_changed_since( + is_item = ls_item + iv_timestamp = mv_last_serialization ). + LOOP AT lt_cache ASSIGNING WHERE item = ls_item. + APPEND TO rt_files. + ENDLOOP. + + CONTINUE. + ENDIF. + ENDIF. + + lt_files = lcl_objects=>serialize( + is_item = ls_item + iv_language = get_master_language( ) + io_log = io_log ). + LOOP AT lt_files ASSIGNING . + -path = mo_dot_abapgit->get_starting_folder( ) && -path. + -sha1 = lcl_hash=>sha1( iv_type = gc_type-blob iv_data = -data ). + + APPEND INITIAL LINE TO rt_files ASSIGNING . + -file = . + -item = ls_item. + ENDLOOP. + ENDLOOP. + + GET TIME STAMP FIELD mv_last_serialization. + mt_local = rt_files. + mv_do_local_refresh = abap_false. " Fulfill refresh + + ENDMETHOD. + + METHOD get_dot_abapgit. + ro_dot_abapgit = mo_dot_abapgit. + ENDMETHOD. + + METHOD delete. + + DATA: lo_persistence TYPE REF TO lcl_persistence_repo. + + + CREATE OBJECT lo_persistence. + + lo_persistence->delete( ms_data-key ). + + ENDMETHOD. "delete + + METHOD is_offline. + rv_offline = ms_data-offline. + ENDMETHOD. + + METHOD refresh. + + mv_do_local_refresh = abap_true. + + IF iv_drop_cache = abap_true. + CLEAR: mv_last_serialization, mt_local. + ENDIF. + + ENDMETHOD. "refresh + + METHOD refresh_local. " For testing purposes, maybe removed later + mv_do_local_refresh = abap_true. + ENDMETHOD. "refresh_local + + METHOD get_package. + rv_package = ms_data-package. + ENDMETHOD. "get_package + + METHOD get_master_language. + rv_language = ms_data-master_language. + ENDMETHOD. + + METHOD get_key. + rv_key = ms_data-key. + ENDMETHOD. "get_key + + METHOD get_name. + + IF ms_data-offline = abap_true. + rv_name = ms_data-url. + ELSE. + rv_name = lcl_url=>name( ms_data-url ). + rv_name = cl_http_utility=>if_http_utility~unescape_url( rv_name ). + ENDIF. + + ENDMETHOD. "get_name + + METHOD is_write_protected. + rv_yes = ms_data-write_protect. + ENDMETHOD. "is_write_protected + + METHOD rebuild_local_checksums. "LOCAL (BASE) + + DATA: lt_local TYPE ty_files_item_tt, + ls_last_item TYPE ty_item, + lt_checksums TYPE lcl_persistence_repo=>ty_local_checksum_tt. + + FIELD-SYMBOLS: LIKE LINE OF lt_checksums, + LIKE LINE OF -files, + LIKE LINE OF lt_local. + + lt_local = get_files_local( ). + + DELETE lt_local " Remove non-code related files except .abapgit + WHERE item IS INITIAL + AND NOT ( file-path = gc_root_dir AND file-filename = gc_dot_abapgit ). + + SORT lt_local BY item. + + LOOP AT lt_local ASSIGNING . + IF ls_last_item <> -item OR sy-tabix = 1. " First or New item reached ? + APPEND INITIAL LINE TO lt_checksums ASSIGNING . + -item = -item. + ls_last_item = -item. + ENDIF. + + APPEND INITIAL LINE TO -files ASSIGNING . + MOVE-CORRESPONDING -file TO . + + ENDLOOP. + + set( it_checksums = lt_checksums ). + + ENDMETHOD. " rebuild_local_checksums. + +ENDCLASS. "lcl_repo IMPLEMENTATION + +*----------------------------------------------------------------------* +* CLASS lcl_repo_srv IMPLEMENTATION +*----------------------------------------------------------------------* +* +*----------------------------------------------------------------------* +CLASS lcl_repo_srv IMPLEMENTATION. + + METHOD constructor. + CREATE OBJECT mo_persistence. + ENDMETHOD. "class_constructor + + METHOD list. + + IF mv_init = abap_false. + refresh( ). + ENDIF. + + rt_list = mt_list. + + ENDMETHOD. "list + + METHOD get. + + FIELD-SYMBOLS: LIKE LINE OF mt_list. + + + IF mv_init = abap_false. + refresh( ). + ENDIF. + + LOOP AT mt_list ASSIGNING . + IF ->get_key( ) = iv_key. + ro_repo = . + RETURN. + ENDIF. + ENDLOOP. + + lcx_exception=>raise( 'repo not found, get' ). + + ENDMETHOD. "get + + METHOD refresh. + + DATA: lt_list TYPE lcl_persistence_repo=>tt_repo, + lo_online TYPE REF TO lcl_repo_online, + lo_offline TYPE REF TO lcl_repo_offline. + + FIELD-SYMBOLS: LIKE LINE OF lt_list. + + + CLEAR mt_list. + + lt_list = mo_persistence->list( ). + LOOP AT lt_list ASSIGNING . + IF -offline = abap_false. + CREATE OBJECT lo_online + EXPORTING + is_data = . + APPEND lo_online TO mt_list. + ELSE. + CREATE OBJECT lo_offline + EXPORTING + is_data = . + APPEND lo_offline TO mt_list. + ENDIF. + ENDLOOP. + + mv_init = abap_true. + + ENDMETHOD. "refresh + + METHOD new_online. + + DATA: ls_repo TYPE lcl_persistence_repo=>ty_repo, + lv_key TYPE lcl_persistence_repo=>ty_repo-key. + + + validate_package( iv_package ). + + lv_key = mo_persistence->add( + iv_url = iv_url + iv_branch_name = iv_branch_name + iv_package = iv_package + iv_offline = abap_false ). + + TRY. + ls_repo = mo_persistence->read( lv_key ). + CATCH lcx_not_found. + lcx_exception=>raise( 'new_online not found' ). + ENDTRY. + + CREATE OBJECT ro_repo + EXPORTING + is_data = ls_repo. + + add( ro_repo ). + + ENDMETHOD. "new_online + + METHOD new_offline. + + DATA: ls_repo TYPE lcl_persistence_repo=>ty_repo, + lv_key TYPE lcl_persistence_repo=>ty_repo-key. + + + validate_package( iv_package ). + + lv_key = mo_persistence->add( + iv_url = iv_url + iv_branch_name = '' + iv_package = iv_package + iv_offline = abap_true ). + + TRY. + ls_repo = mo_persistence->read( lv_key ). + CATCH lcx_not_found. + lcx_exception=>raise( 'new_offline not found' ). + ENDTRY. + + CREATE OBJECT ro_repo + EXPORTING + is_data = ls_repo. + + add( ro_repo ). + + ENDMETHOD. "new_offline + + METHOD add. + + DATA: lo_repo LIKE LINE OF mt_list. + + + LOOP AT mt_list INTO lo_repo. + IF lo_repo->get_key( ) = io_repo->get_key( ). + IF lo_repo = io_repo. + RETURN. + ENDIF. + lcx_exception=>raise( 'identical keys' ). + ENDIF. + ENDLOOP. + + APPEND io_repo TO mt_list. + + ENDMETHOD. "add + + METHOD validate_package. + + DATA: lv_devclass TYPE tdevc-devclass, + lt_repos TYPE lcl_persistence_repo=>tt_repo. + + + IF iv_package IS INITIAL. + lcx_exception=>raise( 'add, package empty' ). + ENDIF. + + IF iv_package = '$TMP'. + lcx_exception=>raise( 'not possible to use $TMP, create new (local) package' ). + ENDIF. + + SELECT SINGLE devclass FROM tdevc INTO lv_devclass + WHERE devclass = iv_package + AND as4user <> 'SAP'. "#EC CI_GENBUFF + IF sy-subrc <> 0. + lcx_exception=>raise( 'package not found or not allowed' ). + ENDIF. + + " make sure its not already in use for a different repository + lt_repos = mo_persistence->list( ). + READ TABLE lt_repos WITH KEY package = iv_package TRANSPORTING NO FIELDS. + IF sy-subrc = 0. + lcx_exception=>raise( 'Package already in use' ). + ENDIF. + + ENDMETHOD. "validate_package + + METHOD delete. + + io_repo->delete( ). + + DELETE TABLE mt_list FROM io_repo. + ASSERT sy-subrc = 0. + + ENDMETHOD. "delete + + METHOD is_repo_installed. + + DATA: lt_repo TYPE lcl_repo_srv=>ty_repo_tt, + lo_repo TYPE REF TO lcl_repo, + lv_url TYPE string, + lv_package TYPE devclass, + lo_repo_online TYPE REF TO lcl_repo_online, + lv_err TYPE string. + + lt_repo = list( ). + + LOOP AT lt_repo INTO lo_repo. + CHECK lo_repo->is_offline( ) = abap_false. + lo_repo_online ?= lo_repo. + + lv_url = lo_repo_online->get_url( ). + lv_package = lo_repo_online->get_package( ). + CHECK to_upper( lv_url ) = to_upper( iv_url ). + + " Validate bindings + "TODO refactor: move this message out of this method + IF iv_target_package IS NOT INITIAL AND iv_target_package <> lv_package. + lv_err = |Installation to package { lv_package } detected. | + && |Cancelling installation|. + lcx_exception=>raise( lv_err ). + ENDIF. + + rv_installed = abap_true. + EXIT. + ENDLOOP. + + ENDMETHOD. "is_repo_installed + + METHOD switch_repo_type. + + DATA lo_repo TYPE REF TO lcl_repo. + + FIELD-SYMBOLS LIKE LINE OF mt_list. + + lo_repo = get( iv_key ). + READ TABLE mt_list ASSIGNING FROM lo_repo. + ASSERT sy-subrc IS INITIAL. + ASSERT iv_offline <> lo_repo->ms_data-offline. + + IF iv_offline = abap_true. " On-line -> OFFline + lo_repo->set( + iv_url = lcl_url=>name( lo_repo->ms_data-url ) + iv_branch_name = '' + iv_sha1 = '' + iv_head_branch = '' + iv_offline = abap_true ). + CREATE OBJECT TYPE lcl_repo_offline + EXPORTING + is_data = lo_repo->ms_data. + ELSE. " OFFline -> On-line + lo_repo->set( iv_offline = abap_false ). + CREATE OBJECT TYPE lcl_repo_online + EXPORTING + is_data = lo_repo->ms_data. + ENDIF. + + ENDMETHOD. "switch_repo_type + +ENDCLASS. "lcl_repo_srv IMPLEMENTATION From cb021acb566cadc38566729ebca9fbd6d7d7f9ee Mon Sep 17 00:00:00 2001 From: Christian Tapia Sabogal Date: Fri, 20 Jan 2017 18:25:14 -0500 Subject: [PATCH 10/13] Filter logic improvement when serializing --- src/zabapgit_repo_impl.prog.abap | 36 ++++++++++++++++---------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/zabapgit_repo_impl.prog.abap b/src/zabapgit_repo_impl.prog.abap index 8c20cf998..36b8f7cce 100644 --- a/src/zabapgit_repo_impl.prog.abap +++ b/src/zabapgit_repo_impl.prog.abap @@ -504,17 +504,18 @@ CLASS lcl_repo IMPLEMENTATION. DATA: lt_tadir TYPE ty_tadir_tt, ls_item TYPE ty_item, - lt_files TYPE ty_files_tt. + lt_files TYPE ty_files_tt, + lt_cache TYPE SORTED TABLE OF ty_file_item + WITH NON-UNIQUE KEY item. - DATA: lt_cache TYPE SORTED TABLE OF ty_file_item - WITH NON-UNIQUE KEY item, - lt_tadir_aux LIKE lt_tadir. + DATA: lt_filter TYPE SORTED TABLE OF tadir + WITH NON-UNIQUE KEY object obj_name, + lv_filter_exist TYPE abap_bool. FIELD-SYMBOLS: LIKE LINE OF lt_files, LIKE LINE OF rt_files, LIKE LINE OF lt_cache, - LIKE LINE OF lt_tadir, - LIKE LINE OF it_filter. + LIKE LINE OF lt_tadir. " Serialization happened before and no refresh request @@ -536,19 +537,18 @@ CLASS lcl_repo IMPLEMENTATION. lt_cache = mt_local. lt_tadir = lcl_tadir=>read( get_package( ) ). - IF it_filter[] IS INITIAL. - lt_tadir_aux[] = lt_tadir[]. - ELSE. - LOOP AT it_filter ASSIGNING . - READ TABLE lt_tadir ASSIGNING WITH KEY object = -object - obj_name = -obj_name. - IF sy-subrc = 0. - APPEND TO lt_tadir_aux. - ENDIF. - ENDLOOP. - ENDIF. + lt_filter = it_filter. + lv_filter_exist = boolc( lines( lt_filter ) > 0 ) . - LOOP AT lt_tadir_aux ASSIGNING . + LOOP AT lt_tadir ASSIGNING . + IF lv_filter_exist = abap_true. + READ TABLE lt_filter TRANSPORTING NO FIELDS WITH KEY object = -object + obj_name = -obj_name + BINARY SEARCH. + IF sy-subrc <> 0. + CONTINUE. + ENDIF. + ENDIF. lcl_progress=>show( iv_key = 'Serialize' iv_current = sy-tabix From 3adc8ca9fd163901c443419595278f856d1b784a Mon Sep 17 00:00:00 2001 From: Christian Tapia Sabogal Date: Fri, 20 Jan 2017 18:34:21 -0500 Subject: [PATCH 11/13] Update zabapgit_app_impl.prog.abap --- src/zabapgit_app_impl.prog.abap | 971 ++------------------------------ 1 file changed, 50 insertions(+), 921 deletions(-) diff --git a/src/zabapgit_app_impl.prog.abap b/src/zabapgit_app_impl.prog.abap index 36b8f7cce..f41691290 100644 --- a/src/zabapgit_app_impl.prog.abap +++ b/src/zabapgit_app_impl.prog.abap @@ -1,941 +1,70 @@ *&---------------------------------------------------------------------* -*& Include ZABAPGIT_REPO_IMPL +*& Include ZABAPGIT_APP_IMPL *&---------------------------------------------------------------------* *----------------------------------------------------------------------* -* CLASS lcl_repo_offline IMPLEMENTATION +* CLASS lcl_app IMPLEMENTATION *----------------------------------------------------------------------* -CLASS lcl_repo_offline IMPLEMENTATION. +CLASS lcl_app IMPLEMENTATION. - METHOD set_files_remote. + METHOD run. - mt_remote = it_files. - - find_dot_abapgit( ). - - ENDMETHOD. - -ENDCLASS. "lcl_repo_offline IMPLEMENTATION - -*----------------------------------------------------------------------* -* CLASS lcl_repo_online IMPLEMENTATION -*----------------------------------------------------------------------* -* -*----------------------------------------------------------------------* -CLASS lcl_repo_online IMPLEMENTATION. - - METHOD constructor. - - super->constructor( is_data ). - - mv_initialized = abap_false. - - ENDMETHOD. "constructor - - METHOD initialize. - IF mv_initialized = abap_false. - refresh( ). - ENDIF. - ENDMETHOD. - - METHOD status. - - initialize( ). - - IF lines( mt_status ) = 0. - mt_status = lcl_file_status=>status( io_repo = me - io_log = io_log ). - ENDIF. - rt_results = mt_status. - - ENDMETHOD. "status - - METHOD deserialize. - - IF ms_data-write_protect = abap_true. - lcx_exception=>raise( 'Cannot deserialize. Local code is write-protected by repo config' ). - ENDIF. - - initialize( ). - - super->deserialize( ). - - set( iv_sha1 = mv_branch ). - - reset_status( ). - - COMMIT WORK AND WAIT. - - ENDMETHOD. "deserialize - - METHOD reset_status. - CLEAR mt_status. - ENDMETHOD. " reset_status. - - METHOD refresh. - - super->refresh( iv_drop_cache ). - reset_status( ). - - lcl_progress=>show( iv_key = 'Fetch' - iv_current = 1 - iv_total = 1 - iv_text = 'Remote files' ) ##NO_TEXT. - - lcl_git_porcelain=>pull( EXPORTING io_repo = me - IMPORTING et_files = mt_remote - et_objects = mt_objects - ev_branch = mv_branch ). - - mo_branches = lcl_git_transport=>branches( get_url( ) ). - actualize_head_branch( ). - - find_dot_abapgit( ). - - mv_initialized = abap_true. - - ENDMETHOD. "refresh - - METHOD actualize_head_branch. - DATA lv_branch_name TYPE string. - lv_branch_name = mo_branches->get_head( )-name. - - IF lv_branch_name <> ms_data-head_branch. - set( iv_head_branch = lv_branch_name ). - ENDIF. - - ENDMETHOD. "actualize_head_branch - - METHOD get_sha1_remote. - initialize( ). - - rv_sha1 = mv_branch. - ENDMETHOD. "get_sha1_remote - - METHOD get_files_remote. - initialize( ). - - rt_files = mt_remote. - ENDMETHOD. "get_files - - METHOD get_objects. - initialize( ). - - rt_objects = mt_objects. - ENDMETHOD. "get_objects - - METHOD get_url. - rv_url = ms_data-url. - ENDMETHOD. "get_url - - METHOD get_branch_name. - rv_name = ms_data-branch_name. - ENDMETHOD. "get_branch_name - - METHOD get_head_branch_name. - rv_name = ms_data-head_branch. - ENDMETHOD. "get_head_branch_name - - METHOD get_branches. - IF mo_branches IS NOT BOUND. - mo_branches = lcl_git_transport=>branches( get_url( ) ). - ENDIF. - ro_branches = mo_branches. - ENDMETHOD. "get_branches - - METHOD set_url. - - IF ms_data-write_protect = abap_true. - lcx_exception=>raise( 'Cannot change URL. Local code is write-protected by repo config' ). - ENDIF. - - mv_initialized = abap_false. - set( iv_url = iv_url ). - - ENDMETHOD. - - METHOD set_branch_name. - - IF ms_data-write_protect = abap_true. - lcx_exception=>raise( 'Cannot switch branch. Local code is write-protected by repo config' ). - ENDIF. - - mv_initialized = abap_false. - set( iv_branch_name = iv_branch_name ). - - ENDMETHOD. - - METHOD set_new_remote. - - IF ms_data-write_protect = abap_true. - lcx_exception=>raise( 'Cannot change remote. Local code is write-protected by repo config' ). - ENDIF. - - mv_initialized = abap_false. - set( iv_url = iv_url - iv_branch_name = iv_branch_name - iv_head_branch = '' - iv_sha1 = '' ). - - ENDMETHOD. "set_new_remote - - METHOD get_sha1_local. - rv_sha1 = ms_data-sha1. - ENDMETHOD. "get_sha1_local - - METHOD push. - - DATA: lv_branch TYPE ty_sha1, - lt_updated_files TYPE ty_file_signatures_tt. - - - handle_stage_ignore( io_stage ). - - lcl_git_porcelain=>push( EXPORTING is_comment = is_comment - io_repo = me - io_stage = io_stage - IMPORTING ev_branch = lv_branch - et_updated_files = lt_updated_files ). - - IF io_stage->get_branch_sha1( ) = get_sha1_local( ). -* pushing to the branch currently represented by this repository object - set( iv_sha1 = lv_branch ). - ENDIF. - - refresh( ). - update_local_checksums( lt_updated_files ). - - IF lcl_stage_logic=>count( me ) = 0. - set( iv_sha1 = lv_branch ). - ENDIF. - - ENDMETHOD. "push - - METHOD handle_stage_ignore. - - DATA: lv_add TYPE abap_bool, - lt_stage TYPE lcl_stage=>ty_stage_tt. - - FIELD-SYMBOLS: LIKE LINE OF lt_stage. - - - lt_stage = io_stage->get_all( ). - LOOP AT lt_stage ASSIGNING WHERE method = lcl_stage=>c_method-ignore. - - mo_dot_abapgit->add_ignore( - iv_path = -file-path - iv_filename = -file-filename ). - - " remove it from the staging object, as the action is handled here - io_stage->reset( iv_path = -file-path - iv_filename = -file-filename ). - - lv_add = abap_true. - - ENDLOOP. - - IF lv_add = abap_true. - io_stage->add( - iv_path = gc_root_dir - iv_filename = gc_dot_abapgit - iv_data = mo_dot_abapgit->serialize( ) ). - ENDIF. - - ENDMETHOD. - - METHOD rebuild_local_checksums. "REMOTE - - DATA: lt_remote TYPE ty_files_tt, - lt_local TYPE ty_files_item_tt, - ls_last_item TYPE ty_item, - lv_branch_equal TYPE abap_bool, - lt_checksums TYPE lcl_persistence_repo=>ty_local_checksum_tt. - - FIELD-SYMBOLS: LIKE LINE OF lt_checksums, - LIKE LINE OF -files, - LIKE LINE OF lt_remote, - LIKE LINE OF lt_local. - - lt_remote = get_files_remote( ). - lt_local = get_files_local( ). - lv_branch_equal = boolc( get_sha1_remote( ) = get_sha1_local( ) ). - - DELETE lt_local " Remove non-code related files except .abapgit - WHERE item IS INITIAL - AND NOT ( file-path = gc_root_dir AND file-filename = gc_dot_abapgit ). - - SORT lt_local BY item. - SORT lt_remote BY path filename. - - LOOP AT lt_local ASSIGNING . - IF ls_last_item <> -item OR sy-tabix = 1. " First or New item reached ? - APPEND INITIAL LINE TO lt_checksums ASSIGNING . - -item = -item. - ls_last_item = -item. - ENDIF. - - READ TABLE lt_remote ASSIGNING - WITH KEY path = -file-path filename = -file-filename - BINARY SEARCH. - CHECK sy-subrc = 0. " Ignore new ones - - APPEND INITIAL LINE TO -files ASSIGNING . - MOVE-CORRESPONDING -file TO . - - " If hashes are equal -> local sha1 is OK - " Else if R-branch is ahead -> assume changes were remote, state - local sha1 - " Else (branches equal) -> assume changes were local, state - remote sha1 - IF -file-sha1 <> -sha1 AND lv_branch_equal = abap_true. - -sha1 = -sha1. - ENDIF. - ENDLOOP. - - set( it_checksums = lt_checksums ). - reset_status( ). - - ENDMETHOD. " rebuild_local_checksums. - -ENDCLASS. "lcl_repo_online IMPLEMENTATION - -*----------------------------------------------------------------------* -* CLASS lcl_repo IMPLEMENTATION -*----------------------------------------------------------------------* -* -*----------------------------------------------------------------------* -CLASS lcl_repo IMPLEMENTATION. - - METHOD constructor. - - ASSERT NOT is_data-key IS INITIAL. - - ms_data = is_data. - - ENDMETHOD. "constructor - - METHOD find_dot_abapgit. - - FIELD-SYMBOLS: LIKE LINE OF mt_remote. - - - READ TABLE mt_remote ASSIGNING - WITH KEY path = gc_root_dir - filename = gc_dot_abapgit. - IF sy-subrc = 0. - mo_dot_abapgit = lcl_dot_abapgit=>deserialize( -data ). - ENDIF. - - ENDMETHOD. - - METHOD get_files_remote. - rt_files = mt_remote. - ENDMETHOD. - - METHOD set. - - DATA: lo_persistence TYPE REF TO lcl_persistence_repo. - - - ASSERT iv_sha1 IS SUPPLIED - OR it_checksums IS SUPPLIED - OR iv_url IS SUPPLIED - OR iv_branch_name IS SUPPLIED - OR iv_head_branch IS SUPPLIED - OR iv_offline IS SUPPLIED. - - CREATE OBJECT lo_persistence. - - IF iv_sha1 IS SUPPLIED. - lo_persistence->update_sha1( - iv_key = ms_data-key - iv_branch_sha1 = iv_sha1 ). - ms_data-sha1 = iv_sha1. - ENDIF. - - IF it_checksums IS SUPPLIED. - lo_persistence->update_local_checksums( - iv_key = ms_data-key - it_checksums = it_checksums ). - ms_data-local_checksums = it_checksums. - ENDIF. - - IF iv_url IS SUPPLIED. - lo_persistence->update_url( - iv_key = ms_data-key - iv_url = iv_url ). - ms_data-url = iv_url. - ENDIF. - - IF iv_branch_name IS SUPPLIED. - lo_persistence->update_branch_name( - iv_key = ms_data-key - iv_branch_name = iv_branch_name ). - ms_data-branch_name = iv_branch_name. - ENDIF. - - IF iv_head_branch IS SUPPLIED. - lo_persistence->update_head_branch( - iv_key = ms_data-key - iv_head_branch = iv_head_branch ). - ms_data-head_branch = iv_head_branch. - ENDIF. - - IF iv_offline IS SUPPLIED. - lo_persistence->update_offline( - iv_key = ms_data-key - iv_offline = iv_offline ). - ms_data-offline = iv_offline. - ENDIF. - - ENDMETHOD. "set_sha1 - - METHOD update_local_checksums. - - " ASSUMTION: SHA1 in param is actual and correct. - " Push fills it from local files before pushing, deserialize from remote - " If this is not true that there is an error somewhere but not here - - DATA: lt_checksums TYPE lcl_persistence_repo=>ty_local_checksum_tt, - lt_files_idx TYPE ty_file_signatures_tt, - lt_local TYPE ty_files_item_tt, - lv_chks_row TYPE i, - lv_file_row TYPE i. - - FIELD-SYMBOLS: LIKE LINE OF lt_checksums, - LIKE LINE OF -files, - LIKE LINE OF lt_local, - LIKE LINE OF it_files. - - lt_checksums = get_local_checksums( ). - lt_files_idx = it_files. - SORT lt_files_idx BY path filename. " Sort for binary search - - " Loop through current chacksum state, update sha1 for common files - LOOP AT lt_checksums ASSIGNING . - lv_chks_row = sy-tabix. - - LOOP AT -files ASSIGNING . - lv_file_row = sy-tabix. - - READ TABLE lt_files_idx ASSIGNING - WITH KEY path = -path filename = -filename - BINARY SEARCH. - CHECK sy-subrc = 0. " Missing in param table, skip - - IF -sha1 IS INITIAL. " Empty input sha1 is a deletion marker - DELETE -files INDEX lv_file_row. - ELSE. - -sha1 = -sha1. " Update sha1 - CLEAR -sha1. " Mark as processed - ENDIF. - ENDLOOP. - - IF lines( -files ) = 0. " Remove empty objects - DELETE lt_checksums INDEX lv_chks_row. - ENDIF. - ENDLOOP. - - DELETE lt_files_idx WHERE sha1 IS INITIAL. " Remove processed - IF lines( lt_files_idx ) > 0. - lt_local = get_files_local( ). - SORT lt_local BY file-path file-filename. " Sort for binary search - ENDIF. - - " Add new files - not deleted and not marked as processed above - LOOP AT lt_files_idx ASSIGNING . - - READ TABLE lt_local ASSIGNING - WITH KEY file-path = -path file-filename = -filename - BINARY SEARCH. - IF sy-subrc <> 0. -* if the deserialization fails, the local file might not be there - CONTINUE. - ENDIF. - - READ TABLE lt_checksums ASSIGNING " TODO Optimize - WITH KEY item = -item. - IF sy-subrc > 0. - APPEND INITIAL LINE TO lt_checksums ASSIGNING . - -item = -item. - ENDIF. - - APPEND TO -files. - ENDLOOP. - - SORT lt_checksums BY item. - set( it_checksums = lt_checksums ). - - ENDMETHOD. " update_local_checksums - - METHOD deserialize. - - DATA: lt_updated_files TYPE ty_file_signatures_tt. - - IF mo_dot_abapgit IS INITIAL. - mo_dot_abapgit = lcl_dot_abapgit=>build_default( ms_data-master_language ). - ENDIF. - IF mo_dot_abapgit->get_master_language( ) <> sy-langu. - lcx_exception=>raise( 'Current login language does not match master language' ). - ENDIF. - - lt_updated_files = lcl_objects=>deserialize( me ). - APPEND mo_dot_abapgit->get_signature( ) TO lt_updated_files. - - CLEAR: mt_local, mv_last_serialization. - - update_local_checksums( lt_updated_files ). - - ENDMETHOD. - - METHOD get_local_checksums. - rt_checksums = ms_data-local_checksums. - ENDMETHOD. - - METHOD get_local_checksums_per_file. - - FIELD-SYMBOLS LIKE LINE OF ms_data-local_checksums. - - LOOP AT ms_data-local_checksums ASSIGNING . - APPEND LINES OF -files TO rt_checksums. - ENDLOOP. - - ENDMETHOD. - - METHOD get_files_local. - - DATA: lt_tadir TYPE ty_tadir_tt, - ls_item TYPE ty_item, - lt_files TYPE ty_files_tt, - lt_cache TYPE SORTED TABLE OF ty_file_item - WITH NON-UNIQUE KEY item. - - DATA: lt_filter TYPE SORTED TABLE OF tadir - WITH NON-UNIQUE KEY object obj_name, - lv_filter_exist TYPE abap_bool. - - FIELD-SYMBOLS: LIKE LINE OF lt_files, - LIKE LINE OF rt_files, - LIKE LINE OF lt_cache, - LIKE LINE OF lt_tadir. - - - " Serialization happened before and no refresh request - IF mv_last_serialization IS NOT INITIAL AND mv_do_local_refresh = abap_false. - rt_files = mt_local. - RETURN. - ENDIF. - - IF mo_dot_abapgit IS INITIAL. - mo_dot_abapgit = lcl_dot_abapgit=>build_default( ms_data-master_language ). - ENDIF. - APPEND INITIAL LINE TO rt_files ASSIGNING . - -file-path = gc_root_dir. - -file-filename = gc_dot_abapgit. - -file-data = mo_dot_abapgit->serialize( ). - -file-sha1 = lcl_hash=>sha1( iv_type = gc_type-blob - iv_data = -file-data ). - - lt_cache = mt_local. - lt_tadir = lcl_tadir=>read( get_package( ) ). - - lt_filter = it_filter. - lv_filter_exist = boolc( lines( lt_filter ) > 0 ) . - - LOOP AT lt_tadir ASSIGNING . - IF lv_filter_exist = abap_true. - READ TABLE lt_filter TRANSPORTING NO FIELDS WITH KEY object = -object - obj_name = -obj_name - BINARY SEARCH. - IF sy-subrc <> 0. - CONTINUE. - ENDIF. - ENDIF. - - lcl_progress=>show( iv_key = 'Serialize' - iv_current = sy-tabix - iv_total = lines( lt_tadir ) - iv_text = -obj_name ) ##NO_TEXT. - - ls_item-obj_type = -object. - ls_item-obj_name = -obj_name. - ls_item-devclass = -devclass. - - IF mv_last_serialization IS NOT INITIAL. " Try to fetch from cache - READ TABLE lt_cache TRANSPORTING NO FIELDS - WITH KEY item = ls_item. " type+name+package key - " There is something in cache and the object is unchanged - IF sy-subrc = 0 - AND abap_false = lcl_objects=>has_changed_since( - is_item = ls_item - iv_timestamp = mv_last_serialization ). - LOOP AT lt_cache ASSIGNING WHERE item = ls_item. - APPEND TO rt_files. - ENDLOOP. - - CONTINUE. - ENDIF. - ENDIF. - - lt_files = lcl_objects=>serialize( - is_item = ls_item - iv_language = get_master_language( ) - io_log = io_log ). - LOOP AT lt_files ASSIGNING . - -path = mo_dot_abapgit->get_starting_folder( ) && -path. - -sha1 = lcl_hash=>sha1( iv_type = gc_type-blob iv_data = -data ). - - APPEND INITIAL LINE TO rt_files ASSIGNING . - -file = . - -item = ls_item. - ENDLOOP. - ENDLOOP. - - GET TIME STAMP FIELD mv_last_serialization. - mt_local = rt_files. - mv_do_local_refresh = abap_false. " Fulfill refresh - - ENDMETHOD. - - METHOD get_dot_abapgit. - ro_dot_abapgit = mo_dot_abapgit. - ENDMETHOD. - - METHOD delete. - - DATA: lo_persistence TYPE REF TO lcl_persistence_repo. - - - CREATE OBJECT lo_persistence. - - lo_persistence->delete( ms_data-key ). - - ENDMETHOD. "delete - - METHOD is_offline. - rv_offline = ms_data-offline. - ENDMETHOD. - - METHOD refresh. - - mv_do_local_refresh = abap_true. - - IF iv_drop_cache = abap_true. - CLEAR: mv_last_serialization, mt_local. - ENDIF. - - ENDMETHOD. "refresh - - METHOD refresh_local. " For testing purposes, maybe removed later - mv_do_local_refresh = abap_true. - ENDMETHOD. "refresh_local - - METHOD get_package. - rv_package = ms_data-package. - ENDMETHOD. "get_package - - METHOD get_master_language. - rv_language = ms_data-master_language. - ENDMETHOD. - - METHOD get_key. - rv_key = ms_data-key. - ENDMETHOD. "get_key - - METHOD get_name. - - IF ms_data-offline = abap_true. - rv_name = ms_data-url. + IF sy-batch = abap_true. + lcl_background=>run( ). ELSE. - rv_name = lcl_url=>name( ms_data-url ). - rv_name = cl_http_utility=>if_http_utility~unescape_url( rv_name ). + gui( )->go_home( ). + CALL SELECTION-SCREEN 1001. " trigger screen ENDIF. - ENDMETHOD. "get_name + ENDMETHOD. "run - METHOD is_write_protected. - rv_yes = ms_data-write_protect. - ENDMETHOD. "is_write_protected + METHOD gui. - METHOD rebuild_local_checksums. "LOCAL (BASE) + IF go_gui IS NOT BOUND. + CREATE OBJECT go_gui. + ENDIF. + ro_gui = go_gui. - DATA: lt_local TYPE ty_files_item_tt, - ls_last_item TYPE ty_item, - lt_checksums TYPE lcl_persistence_repo=>ty_local_checksum_tt. + ENDMETHOD. "gui - FIELD-SYMBOLS: LIKE LINE OF lt_checksums, - LIKE LINE OF -files, - LIKE LINE OF lt_local. + METHOD user. - lt_local = get_files_local( ). - - DELETE lt_local " Remove non-code related files except .abapgit - WHERE item IS INITIAL - AND NOT ( file-path = gc_root_dir AND file-filename = gc_dot_abapgit ). - - SORT lt_local BY item. - - LOOP AT lt_local ASSIGNING . - IF ls_last_item <> -item OR sy-tabix = 1. " First or New item reached ? - APPEND INITIAL LINE TO lt_checksums ASSIGNING . - -item = -item. - ls_last_item = -item. + IF iv_user = sy-uname ##USER_OK. + IF go_current_user IS NOT BOUND. + CREATE OBJECT go_current_user. ENDIF. - - APPEND INITIAL LINE TO -files ASSIGNING . - MOVE-CORRESPONDING -file TO . - - ENDLOOP. - - set( it_checksums = lt_checksums ). - - ENDMETHOD. " rebuild_local_checksums. - -ENDCLASS. "lcl_repo IMPLEMENTATION - -*----------------------------------------------------------------------* -* CLASS lcl_repo_srv IMPLEMENTATION -*----------------------------------------------------------------------* -* -*----------------------------------------------------------------------* -CLASS lcl_repo_srv IMPLEMENTATION. - - METHOD constructor. - CREATE OBJECT mo_persistence. - ENDMETHOD. "class_constructor - - METHOD list. - - IF mv_init = abap_false. - refresh( ). - ENDIF. - - rt_list = mt_list. - - ENDMETHOD. "list - - METHOD get. - - FIELD-SYMBOLS: LIKE LINE OF mt_list. - - - IF mv_init = abap_false. - refresh( ). - ENDIF. - - LOOP AT mt_list ASSIGNING . - IF ->get_key( ) = iv_key. - ro_repo = . - RETURN. - ENDIF. - ENDLOOP. - - lcx_exception=>raise( 'repo not found, get' ). - - ENDMETHOD. "get - - METHOD refresh. - - DATA: lt_list TYPE lcl_persistence_repo=>tt_repo, - lo_online TYPE REF TO lcl_repo_online, - lo_offline TYPE REF TO lcl_repo_offline. - - FIELD-SYMBOLS: LIKE LINE OF lt_list. - - - CLEAR mt_list. - - lt_list = mo_persistence->list( ). - LOOP AT lt_list ASSIGNING . - IF -offline = abap_false. - CREATE OBJECT lo_online - EXPORTING - is_data = . - APPEND lo_online TO mt_list. - ELSE. - CREATE OBJECT lo_offline - EXPORTING - is_data = . - APPEND lo_offline TO mt_list. - ENDIF. - ENDLOOP. - - mv_init = abap_true. - - ENDMETHOD. "refresh - - METHOD new_online. - - DATA: ls_repo TYPE lcl_persistence_repo=>ty_repo, - lv_key TYPE lcl_persistence_repo=>ty_repo-key. - - - validate_package( iv_package ). - - lv_key = mo_persistence->add( - iv_url = iv_url - iv_branch_name = iv_branch_name - iv_package = iv_package - iv_offline = abap_false ). - - TRY. - ls_repo = mo_persistence->read( lv_key ). - CATCH lcx_not_found. - lcx_exception=>raise( 'new_online not found' ). - ENDTRY. - - CREATE OBJECT ro_repo - EXPORTING - is_data = ls_repo. - - add( ro_repo ). - - ENDMETHOD. "new_online - - METHOD new_offline. - - DATA: ls_repo TYPE lcl_persistence_repo=>ty_repo, - lv_key TYPE lcl_persistence_repo=>ty_repo-key. - - - validate_package( iv_package ). - - lv_key = mo_persistence->add( - iv_url = iv_url - iv_branch_name = '' - iv_package = iv_package - iv_offline = abap_true ). - - TRY. - ls_repo = mo_persistence->read( lv_key ). - CATCH lcx_not_found. - lcx_exception=>raise( 'new_offline not found' ). - ENDTRY. - - CREATE OBJECT ro_repo - EXPORTING - is_data = ls_repo. - - add( ro_repo ). - - ENDMETHOD. "new_offline - - METHOD add. - - DATA: lo_repo LIKE LINE OF mt_list. - - - LOOP AT mt_list INTO lo_repo. - IF lo_repo->get_key( ) = io_repo->get_key( ). - IF lo_repo = io_repo. - RETURN. - ENDIF. - lcx_exception=>raise( 'identical keys' ). - ENDIF. - ENDLOOP. - - APPEND io_repo TO mt_list. - - ENDMETHOD. "add - - METHOD validate_package. - - DATA: lv_devclass TYPE tdevc-devclass, - lt_repos TYPE lcl_persistence_repo=>tt_repo. - - - IF iv_package IS INITIAL. - lcx_exception=>raise( 'add, package empty' ). - ENDIF. - - IF iv_package = '$TMP'. - lcx_exception=>raise( 'not possible to use $TMP, create new (local) package' ). - ENDIF. - - SELECT SINGLE devclass FROM tdevc INTO lv_devclass - WHERE devclass = iv_package - AND as4user <> 'SAP'. "#EC CI_GENBUFF - IF sy-subrc <> 0. - lcx_exception=>raise( 'package not found or not allowed' ). - ENDIF. - - " make sure its not already in use for a different repository - lt_repos = mo_persistence->list( ). - READ TABLE lt_repos WITH KEY package = iv_package TRANSPORTING NO FIELDS. - IF sy-subrc = 0. - lcx_exception=>raise( 'Package already in use' ). - ENDIF. - - ENDMETHOD. "validate_package - - METHOD delete. - - io_repo->delete( ). - - DELETE TABLE mt_list FROM io_repo. - ASSERT sy-subrc = 0. - - ENDMETHOD. "delete - - METHOD is_repo_installed. - - DATA: lt_repo TYPE lcl_repo_srv=>ty_repo_tt, - lo_repo TYPE REF TO lcl_repo, - lv_url TYPE string, - lv_package TYPE devclass, - lo_repo_online TYPE REF TO lcl_repo_online, - lv_err TYPE string. - - lt_repo = list( ). - - LOOP AT lt_repo INTO lo_repo. - CHECK lo_repo->is_offline( ) = abap_false. - lo_repo_online ?= lo_repo. - - lv_url = lo_repo_online->get_url( ). - lv_package = lo_repo_online->get_package( ). - CHECK to_upper( lv_url ) = to_upper( iv_url ). - - " Validate bindings - "TODO refactor: move this message out of this method - IF iv_target_package IS NOT INITIAL AND iv_target_package <> lv_package. - lv_err = |Installation to package { lv_package } detected. | - && |Cancelling installation|. - lcx_exception=>raise( lv_err ). - ENDIF. - - rv_installed = abap_true. - EXIT. - ENDLOOP. - - ENDMETHOD. "is_repo_installed - - METHOD switch_repo_type. - - DATA lo_repo TYPE REF TO lcl_repo. - - FIELD-SYMBOLS LIKE LINE OF mt_list. - - lo_repo = get( iv_key ). - READ TABLE mt_list ASSIGNING FROM lo_repo. - ASSERT sy-subrc IS INITIAL. - ASSERT iv_offline <> lo_repo->ms_data-offline. - - IF iv_offline = abap_true. " On-line -> OFFline - lo_repo->set( - iv_url = lcl_url=>name( lo_repo->ms_data-url ) - iv_branch_name = '' - iv_sha1 = '' - iv_head_branch = '' - iv_offline = abap_true ). - CREATE OBJECT TYPE lcl_repo_offline + ro_user = go_current_user. + ELSE. + CREATE OBJECT ro_user EXPORTING - is_data = lo_repo->ms_data. - ELSE. " OFFline -> On-line - lo_repo->set( iv_offline = abap_false ). - CREATE OBJECT TYPE lcl_repo_online - EXPORTING - is_data = lo_repo->ms_data. + iv_user = iv_user. ENDIF. - ENDMETHOD. "switch_repo_type + ENDMETHOD. "user -ENDCLASS. "lcl_repo_srv IMPLEMENTATION + METHOD repo_srv. + + IF go_repo_srv IS NOT BOUND. + CREATE OBJECT go_repo_srv. + ENDIF. + ro_repo_srv = go_repo_srv. + + ENDMETHOD. "repo_srv + + METHOD db. + + IF go_db IS NOT BOUND. + CREATE OBJECT go_db. + ENDIF. + ro_db = go_db. + + ENDMETHOD. "repo_srv + + METHOD settings. + IF go_settings IS NOT BOUND. + CREATE OBJECT go_settings. + ENDIF. + ro_settings = go_settings. + ENDMETHOD. + +ENDCLASS. "lcl_app From 5596ab3175d8f01519d19811017dd64646d47442 Mon Sep 17 00:00:00 2001 From: Christian Tapia Sabogal Date: Fri, 20 Jan 2017 18:41:38 -0500 Subject: [PATCH 12/13] Update zabapgit_app_impl.prog.abap From c0ccfb73b5281b5d6fff4731b7584fb757522a33 Mon Sep 17 00:00:00 2001 From: Christian Tapia Sabogal Date: Fri, 20 Jan 2017 18:41:57 -0500 Subject: [PATCH 13/13] Update zabapgit_app_impl.prog.abap