new status implementation

This commit is contained in:
sbcgua 2016-11-07 13:47:26 +02:00
parent d36467dd93
commit 31727c352e
6 changed files with 311 additions and 47 deletions

View File

@ -14,12 +14,14 @@ TYPES: BEGIN OF ty_file_signature,
sha1 TYPE ty_sha1,
END OF ty_file_signature.
TYPES: ty_file_signatures_tt TYPE STANDARD TABLE OF ty_file_signature WITH DEFAULT KEY.
TYPES: ty_file_signatures_ts TYPE SORTED TABLE OF ty_file_signature WITH UNIQUE KEY path filename..
TYPES: BEGIN OF ty_file.
INCLUDE TYPE ty_file_signature.
TYPES: data TYPE xstring,
END OF ty_file.
TYPES: ty_files_tt TYPE STANDARD TABLE OF ty_file WITH DEFAULT KEY.
TYPES: ty_file_signatures_tt TYPE STANDARD TABLE OF ty_file_signature WITH DEFAULT KEY.
TYPES: ty_string_tt TYPE STANDARD TABLE OF string WITH DEFAULT KEY.
TYPES: tt_w3urls TYPE STANDARD TABLE OF w3url WITH DEFAULT KEY.
@ -34,7 +36,9 @@ TYPES: BEGIN OF ty_item,
obj_type TYPE tadir-object,
obj_name TYPE tadir-obj_name,
devclass TYPE devclass,
END OF ty_item.
END OF ty_item,
ty_items_tt TYPE STANDARD TABLE OF ty_item WITH DEFAULT KEY,
ty_items_ts TYPE SORTED TABLE OF ty_item WITH UNIQUE KEY obj_type obj_name.
TYPES: BEGIN OF ty_file_item,
file TYPE ty_file,
@ -102,8 +106,8 @@ TYPES: BEGIN OF ty_result,
filename TYPE string,
package TYPE devclass,
match TYPE sap_bool,
rstate TYPE char1,
lstate TYPE char1,
rstate TYPE char1,
END OF ty_result.
TYPES: ty_results_tt TYPE STANDARD TABLE OF ty_result WITH DEFAULT KEY.

View File

@ -36,9 +36,27 @@ CLASS lcl_file_status DEFINITION FINAL
IMPORTING it_local TYPE ty_files_item_tt
it_remote TYPE ty_files_tt
it_cur_state TYPE ty_file_signatures_tt
iv_starting_folder TYPE string
RETURNING VALUE(rt_results) TYPE ty_results_tt.
CLASS-METHODS:
build_existing
IMPORTING is_local TYPE ty_file_item
is_remote TYPE ty_file
it_state TYPE ty_file_signatures_ts
RETURNING VALUE(rs_result) TYPE ty_result,
build_new_local
IMPORTING is_local TYPE ty_file_item
RETURNING VALUE(rs_result) TYPE ty_result,
build_new_remote
IMPORTING is_remote TYPE ty_file
it_items TYPE ty_items_ts
it_state TYPE ty_file_signatures_ts
RETURNING VALUE(rs_result) TYPE ty_result,
identify_object
IMPORTING iv_filename TYPE string
EXPORTING es_item TYPE ty_item
ev_is_xml TYPE abap_bool.
ENDCLASS. "lcl_file_status DEFINITION
*----------------------------------------------------------------------*
@ -60,32 +78,31 @@ CLASS lcl_file_status IMPLEMENTATION.
METHOD status.
DATA: lt_local TYPE ty_files_item_tt,
lt_remote TYPE ty_files_tt,
lt_tadir TYPE ty_tadir_tt,
lv_index LIKE sy-tabix,
DATA: lv_index LIKE sy-tabix,
lo_dot_abapgit TYPE REF TO lcl_dot_abapgit.
FIELD-SYMBOLS <ls_result> LIKE LINE OF rt_results.
lt_remote = io_repo->get_files_remote( ).
lt_local = io_repo->get_files_local( io_log ).
lo_dot_abapgit = io_repo->get_dot_abapgit( ).
lt_tadir = lcl_tadir=>read( io_repo->get_package( ) ).
rt_results = calculate_status_old(
it_local = lt_local
it_remote = lt_remote
it_tadir = lt_tadir
iv_starting_folder = lo_dot_abapgit->get_starting_folder( ) ).
* rt_results = calculate_status_old(
* it_local = io_repo->get_files_local( io_log )
* it_remote = io_repo->get_files_remote( )
* it_tadir = lcl_tadir=>read( io_repo->get_package( ) )
* iv_starting_folder = lo_dot_abapgit->get_starting_folder( ) ).
rt_results = calculate_status_new(
it_local = io_repo->get_files_local( io_log )
it_remote = io_repo->get_files_remote( )
it_cur_state = io_repo->get_local_checksums_per_file( ) ).
" Remove ignored files, fix .abapgit
LOOP AT rt_results ASSIGNING <ls_result>.
lv_index = sy-tabix.
" Crutch for .abapgit -> it is always match as generated dynamically
" However this is probably the place to compare it when local editing
" of it will be implemented
" However this is probably the place to compare it when .abapgit editing
" tool will be implemented
IF <ls_result>-path = gc_root_dir AND <ls_result>-filename = gc_dot_abapgit.
<ls_result>-match = abap_true.
CLEAR: <ls_result>-lstate, <ls_result>-rstate.
@ -108,8 +125,199 @@ CLASS lcl_file_status IMPLEMENTATION.
ENDMETHOD. "status
METHOD calculate_status_new.
DATA: lt_remote LIKE it_remote,
lt_items TYPE ty_items_tt,
ls_item LIKE LINE OF lt_items,
lv_is_xml TYPE abap_bool,
lt_items_idx TYPE ty_items_ts,
lt_state_idx TYPE ty_file_signatures_ts. " Sorted by path+filename
FIELD-SYMBOLS: <ls_remote> LIKE LINE OF it_remote,
<ls_result> LIKE LINE OF rt_results,
<ls_local> LIKE LINE OF it_local.
lt_state_idx = it_cur_state. " Force sort it
lt_remote = it_remote.
SORT lt_remote BY path filename.
" Process local files and new local files
LOOP AT it_local ASSIGNING <ls_local>.
APPEND INITIAL LINE TO rt_results ASSIGNING <ls_result>.
APPEND <ls_local>-item TO lt_items. " Collect for item index
READ TABLE lt_remote ASSIGNING <ls_remote>
WITH KEY path = <ls_local>-file-path filename = <ls_local>-file-filename
BINARY SEARCH.
IF sy-subrc = 0. " Exist L and R
<ls_result> = build_existing(
is_local = <ls_local>
is_remote = <ls_remote>
it_state = lt_state_idx ).
ASSERT <ls_remote>-sha1 IS NOT INITIAL.
CLEAR <ls_remote>-sha1. " Mark as processed
ELSE. " Only L exists
<ls_result> = build_new_local( is_local = <ls_local> ).
ENDIF.
ENDLOOP.
" Complete item index for unmarked remote files
LOOP AT lt_remote ASSIGNING <ls_remote> WHERE sha1 IS NOT INITIAL.
identify_object( EXPORTING iv_filename = <ls_remote>-filename
IMPORTING es_item = ls_item
ev_is_xml = lv_is_xml ).
CHECK lv_is_xml = abap_true. " Skip all but obj definitions
ls_item-devclass = lcl_tadir=>get_object_package(
iv_object = ls_item-obj_type
iv_obj_name = ls_item-obj_name ).
APPEND ls_item TO lt_items.
ENDLOOP.
SORT lt_items. " Default key - type, name, pkg
DELETE ADJACENT DUPLICATES FROM lt_items.
lt_items_idx = lt_items. " Self protection + UNIQUE records assertion
" Process new remote files (marked above with empty SHA1)
LOOP AT lt_remote ASSIGNING <ls_remote> WHERE sha1 IS NOT INITIAL.
APPEND INITIAL LINE TO rt_results ASSIGNING <ls_result>.
<ls_result> = build_new_remote( is_remote = <ls_remote>
it_items = lt_items_idx
it_state = lt_state_idx ).
ENDLOOP.
SORT rt_results BY
obj_type ASCENDING
obj_name ASCENDING
filename ASCENDING.
ENDMETHOD. "calculate_status_new.
METHOD identify_object.
DATA: lv_name TYPE tadir-obj_name,
lv_type TYPE string,
lv_ext TYPE string.
" Guess object type and name
SPLIT to_upper( iv_filename ) AT '.' INTO lv_name lv_type lv_ext.
" Handle namespaces
REPLACE ALL OCCURRENCES OF '#' IN lv_name WITH '/'.
CLEAR es_item.
es_item-obj_type = lv_type.
es_item-obj_name = lv_name.
ev_is_xml = boolc( lv_ext = 'XML' AND strlen( lv_type ) = 4 ).
ENDMETHOD. "identify_object.
METHOD build_existing.
DATA: ls_file_sig LIKE LINE OF it_state.
" Item
rs_result-obj_type = is_local-item-obj_type.
rs_result-obj_name = is_local-item-obj_name.
rs_result-package = is_local-item-devclass.
" File
rs_result-path = is_local-file-path.
rs_result-filename = is_local-file-filename.
" Match against current state
READ TABLE it_state INTO ls_file_sig
WITH KEY path = is_local-file-path filename = is_local-file-filename
BINARY SEARCH.
IF sy-subrc = 0.
IF ls_file_sig-sha1 <> is_local-file-sha1.
rs_result-lstate = gc_state-modified.
ENDIF.
IF ls_file_sig-sha1 <> is_remote-sha1.
rs_result-rstate = gc_state-modified.
ENDIF.
rs_result-match = boolc( rs_result-lstate IS INITIAL AND rs_result-rstate IS INITIAL ).
ELSE.
" This is a strange situation. As both local and remote exist
" the state should also be present. Maybe this is a first run of the code.
" In this case just compare hashes directly and mark both changed
" the user will presumably decide what to do after checking the actual diff
rs_result-match = boolc( is_local-file-sha1 = is_remote-sha1 ).
IF rs_result-match = abap_false.
rs_result-lstate = gc_state-modified.
rs_result-rstate = gc_state-modified.
ENDIF.
ENDIF.
ENDMETHOD. "build_existing
METHOD build_new_local.
" Item
rs_result-obj_type = is_local-item-obj_type.
rs_result-obj_name = is_local-item-obj_name.
rs_result-package = is_local-item-devclass.
" File
rs_result-path = is_local-file-path.
rs_result-filename = is_local-file-filename.
" Match
rs_result-match = abap_false.
rs_result-lstate = gc_state-added.
ENDMETHOD. "build_new_local
METHOD build_new_remote.
DATA: ls_item LIKE LINE OF it_items,
ls_file_sig LIKE LINE OF it_state.
" Common and default part
rs_result-path = is_remote-path.
rs_result-filename = is_remote-filename.
rs_result-match = abap_false.
rs_result-rstate = gc_state-added.
identify_object( EXPORTING iv_filename = is_remote-filename
IMPORTING es_item = ls_item ).
" Check if in item index + get package
READ TABLE it_items INTO ls_item
WITH KEY obj_type = ls_item-obj_type obj_name = ls_item-obj_name
BINARY SEARCH.
IF sy-subrc = 0.
" Completely new (xml, abap) and new file in an existing object
rs_result-obj_type = ls_item-obj_type.
rs_result-obj_name = ls_item-obj_name.
rs_result-package = ls_item-devclass.
READ TABLE it_state INTO ls_file_sig
WITH KEY path = is_remote-path filename = is_remote-filename
BINARY SEARCH.
" Existing file but from another package
" was not added during local file proc as was not in tadir for repo package
IF sy-subrc = 0.
IF ls_file_sig-sha1 = is_remote-sha1.
rs_result-match = abap_true.
CLEAR rs_result-rstate.
ELSE.
rs_result-rstate = gc_state-modified.
ENDIF.
ENDIF.
ELSE. " Completely unknown file, probably non-abapgit
" No action, just follow defaults
ASSERT 1 = 1.
ENDIF.
ENDMETHOD. "build_new_remote
METHOD calculate_status_old.
DATA: lv_pre TYPE tadir-obj_name,

View File

@ -22,6 +22,8 @@ CLASS lcl_repo DEFINITION ABSTRACT FRIENDS lcl_repo_srv.
RAISING lcx_exception,
get_local_checksums
RETURNING VALUE(rt_checksums) TYPE lcl_persistence_repo=>ty_local_checksum_tt,
get_local_checksums_per_file
RETURNING VALUE(rt_checksums) TYPE ty_file_signatures_tt,
get_files_remote
RETURNING VALUE(rt_files) TYPE ty_files_tt
RAISING lcx_exception,

View File

@ -389,6 +389,16 @@ CLASS lcl_repo IMPLEMENTATION.
rt_checksums = ms_data-local_checksums.
ENDMETHOD.
METHOD get_local_checksums_per_file.
FIELD-SYMBOLS <object> LIKE LINE OF ms_data-local_checksums.
LOOP AT ms_data-local_checksums ASSIGNING <object>.
APPEND LINES OF <object>-files TO rt_checksums.
ENDLOOP.
ENDMETHOD.
METHOD get_files_local.
DATA: lt_tadir TYPE ty_tadir_tt,

View File

@ -19,7 +19,12 @@ CLASS lcl_tadir DEFINITION FINAL.
IMPORTING iv_pgmid TYPE tadir-pgmid DEFAULT 'R3TR'
iv_object TYPE tadir-object
iv_obj_name TYPE tadir-obj_name
RETURNING VALUE(rs_tadir) TYPE tadir.
RETURNING VALUE(rs_tadir) TYPE tadir,
get_object_package
IMPORTING iv_pgmid TYPE tadir-pgmid DEFAULT 'R3TR'
iv_object TYPE tadir-object
iv_obj_name TYPE tadir-obj_name
RETURNING VALUE(rv_devclass) TYPE tadir-devclass.
PRIVATE SECTION.
CLASS-METHODS:
@ -60,6 +65,14 @@ CLASS lcl_tadir IMPLEMENTATION.
ENDMETHOD. "read_single
METHOD get_object_package.
rv_devclass = read_single( iv_pgmid = iv_pgmid
iv_object = iv_object
iv_obj_name = iv_obj_name )-devclass.
ENDMETHOD. "get_object_package.
METHOD check_exists.
DATA: lv_exists TYPE abap_bool,

View File

@ -1778,9 +1778,9 @@ CLASS ltcl_file_status IMPLEMENTATION.
DEFINE _append_state.
APPEND INITIAL LINE TO lt_state ASSIGNING <state>.
<remote>-path = '/'.
<remote>-filename = &1.
<remote>-sha1 = &2.
<state>-path = '/'.
<state>-filename = &1.
<state>-sha1 = &2.
END-OF-DEFINITION.
DEFINE _append_tadir.
@ -1818,58 +1818,85 @@ CLASS ltcl_file_status IMPLEMENTATION.
<tadir> LIKE LINE OF lt_tadir.
"STATE FILE SHA1
_append_state 'zclass1.clas.xml' 'C1_F1'.
" class1 testclasses is new locally, abap is new remotely
" class2 is completely new remotely
_append_state 'zdoma1.doma.xml' 'D1'.
_append_state 'zdoma2.doma.xml' 'D2'.
_append_state 'zdoma3.doma.xml' 'D3'.
_append_state 'zclass1.clas.xml' 'C1_F1'.
_append_state 'zclass1.clas.testclasses.abap' 'C1_F3'.
_append_state 'zdoma5.doma.xml' 'D5'.
" doma4 is new locally
" doma5 is new remotely
_append_state 'zdoma6.doma.xml' 'D6'.
" doma7 is not in state - emulate brocken cache
" doma8 is not in state - emulate brocken cache
_append_state 'xfeld.doma.xml' 'XFELD'. " from different package
_append_state 'num01.doma.xml' 'NUM01'. " another from different package
"LOCAL TYPE NAME FILE SHA1
_append_local 'CLAS' 'ZCLASS1' 'zclass1.clas.testclasses.abap' 'C1_F3'.
_append_local 'CLAS' 'ZCLASS1' 'zclass1.clas.xml' 'C1_F1'.
_append_local 'DOMA' 'ZDOMA1' 'zdoma1.doma.xml' 'D1'.
_append_local 'DOMA' 'ZDOMA2' 'zdoma2.doma.xml' 'D2_CHANGED_L'.
_append_local 'DOMA' 'ZDOMA3' 'zdoma3.doma.xml' 'D3'.
_append_local 'CLAS' 'ZCLASS1' 'zclass1.clas.xml' 'C1_F1'.
_append_local 'CLAS' 'ZCLASS1' 'zclass1.clas.testclasses.abap' 'C1_F3'.
_append_local 'DOMA' 'ZDOMA5' 'zdoma5.doma.xml' 'D5'.
_append_local 'DOMA' 'ZDOMA4' 'zdoma4.doma.xml' 'D4'.
_append_local 'DOMA' 'ZDOMA6' 'zdoma6.doma.xml' 'D6_CHANGED_L'.
_append_local 'DOMA' 'ZDOMA7' 'zdoma7.doma.xml' 'D7'.
_append_local 'DOMA' 'ZDOMA8' 'zdoma8.doma.xml' 'D8'.
"REMOTE FILE SHA1
_append_remote 'textfile.txt' 'T1'.
_append_remote 'zclass1.clas.abap' 'C1_F2'. " Must be before xml for tougher test
_append_remote 'zclass1.clas.xml' 'C1_F1'.
_append_remote 'zclass2.clas.abap' 'C1_F2'. " Must be before xml for tougher test
_append_remote 'zclass2.clas.xml' 'C1_F1'.
_append_remote 'zdoma1.doma.xml' 'D1'.
_append_remote 'zdoma2.doma.xml' 'D2'.
_append_remote 'zdoma3.doma.xml' 'D3_CHANGED_R'.
_append_remote 'zclass1.clas.xml' 'C1_F1'.
_append_remote 'zclass1.clas.abap' 'C1_F2'.
_append_remote 'zdoma4.doma.xml' 'D4'.
_append_remote 'zdoma5.doma.xml' 'D5'.
_append_remote 'zdoma6.doma.xml' 'D6_CHANGED_R'.
_append_remote 'textfile.txt' 'T1'.
_append_remote 'zdoma7.doma.xml' 'D7'.
_append_remote 'zdoma8.doma.xml' 'D8_CHANGED_R'. " This one is changed
_append_remote 'xfeld.doma.xml' 'XFELD'. " Object from different package
_append_remote 'num01.doma.xml' 'NUM01_CHANGED'. " Changed object from different package
"TADIR TYPE NAME
_append_tadir 'DOMA' 'ZDOMA1'.
_append_tadir 'DOMA' 'ZDOMA2'.
_append_tadir 'DOMA' 'ZDOMA3'.
_append_tadir 'CLAS' 'ZCLASS1'.
_append_tadir 'DOMA' 'ZDOMA5'.
_append_tadir 'DOMA' 'ZDOMA4'.
_append_tadir 'DOMA' 'ZDOMA6'.
_append_tadir 'DOMA' 'ZDOMA7'.
_append_tadir 'DOMA' 'ZDOMA8'.
"EXP RESULT TYPE NAME MATCH LST RST PKG FILE
_append_result '' '' '' '' 'A' '' 'textfile.txt'.
_append_result 'CLAS' 'ZCLASS1' '' 'R' 'L' '$Z$' 'zclass1.clas.abap'.
_append_result 'CLAS' 'ZCLASS1' '' 'L' 'R' '$Z$' 'zclass1.clas.testclasses.abap'.
_append_result 'CLAS' 'ZCLASS1' 'X' '' '' '$Z$' 'zclass1.clas.xml'.
_append_result 'DOMA' 'ZDOMA1' 'X' '' '' '$Z$' 'zdoma1.doma.xml'.
_append_result 'DOMA' 'ZDOMA2' '' 'M' '' '$Z$' 'zdoma2.doma.xml'.
_append_result 'DOMA' 'ZDOMA3' '' '' 'M' '$Z$' 'zdoma3.doma.xml'.
_append_result 'DOMA' 'ZDOMA4' '' '' 'A' '$Z$' 'zdoma4.doma.xml'.
_append_result 'DOMA' 'ZDOMA5' '' 'A' '' '$Z$' 'zdoma5.doma.xml'.
_append_result 'DOMA' 'ZDOMA6' '' 'M' 'M' '$Z$' 'zdoma6.doma.xml'.
"EXP RESULT TYPE NAME MATCH LST RST PKG FILE
_append_result '' '' ' ' ' ' 'A' '' 'textfile.txt'.
_append_result 'CLAS' 'ZCLASS1' ' ' ' ' 'A' '$Z$' 'zclass1.clas.abap'.
_append_result 'CLAS' 'ZCLASS1' ' ' 'A' ' ' '$Z$' 'zclass1.clas.testclasses.abap'.
_append_result 'CLAS' 'ZCLASS1' 'X' ' ' ' ' '$Z$' 'zclass1.clas.xml'.
_append_result 'CLAS' 'ZCLASS2' ' ' ' ' 'A' '' 'zclass2.clas.abap'.
_append_result 'CLAS' 'ZCLASS2' ' ' ' ' 'A' '' 'zclass2.clas.xml'.
_append_result 'DOMA' 'NUM01' ' ' ' ' 'M' 'SUTI' 'num01.doma.xml'.
_append_result 'DOMA' 'XFELD' 'X' ' ' ' ' 'SUTI' 'xfeld.doma.xml'.
_append_result 'DOMA' 'ZDOMA1' 'X' ' ' ' ' '$Z$' 'zdoma1.doma.xml'.
_append_result 'DOMA' 'ZDOMA2' ' ' 'M' ' ' '$Z$' 'zdoma2.doma.xml'.
_append_result 'DOMA' 'ZDOMA3' ' ' ' ' 'M' '$Z$' 'zdoma3.doma.xml'.
_append_result 'DOMA' 'ZDOMA4' ' ' 'A' ' ' '$Z$' 'zdoma4.doma.xml'.
_append_result 'DOMA' 'ZDOMA5' ' ' ' ' 'A' '' 'zdoma5.doma.xml'.
_append_result 'DOMA' 'ZDOMA6' ' ' 'M' 'M' '$Z$' 'zdoma6.doma.xml'.
_append_result 'DOMA' 'ZDOMA7' 'X' ' ' ' ' '$Z$' 'zdoma7.doma.xml'.
_append_result 'DOMA' 'ZDOMA8' ' ' 'M' 'M' '$Z$' 'zdoma8.doma.xml'.
lt_results = lcl_file_status=>calculate_status_old(
* lt_results = lcl_file_status=>calculate_status_old(
* it_local = lt_local
* it_remote = lt_remote
* it_tadir = lt_tadir
* iv_starting_folder = '/' ).
lt_results = lcl_file_status=>calculate_status_new(
it_local = lt_local
it_remote = lt_remote
it_tadir = lt_tadir
iv_starting_folder = '/' ).
it_cur_state = lt_state ).
assert_equals( act = lt_results exp = lt_results_exp ).