Merge branch 'main' into APLO

This commit is contained in:
Marc Bernard 2024-10-30 21:39:36 -04:00 committed by GitHub
commit 6d0489628d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 400 additions and 109 deletions

View File

@ -23,7 +23,7 @@
]
},
"devDependencies": {
"@abaplint/cli": "^2.113.21",
"@abaplint/cli": "^2.113.31",
"@abaplint/database-sqlite": "^2.10.20",
"@abaplint/runtime": "^2.10.20",
"express": "^4.21.1",
@ -31,6 +31,6 @@
"globals": "^15.11.0",
"abapmerge": "^0.16.6",
"c8": "^10.1.2",
"eslint": "^9.12.0"
"eslint": "^9.13.0"
}
}

View File

@ -1,4 +1,3 @@
*"* use this source file for your ABAP unit test classes
CLASS ltcl_apack_manifest_reader DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
PRIVATE SECTION.
METHODS:

View File

@ -1,4 +1,3 @@
*"* use this source file for your ABAP unit test classes
CLASS ltcl_apack_manifest_writer DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
PRIVATE SECTION.
METHODS: the_serializator FOR TESTING RAISING cx_static_check.

View File

@ -26,11 +26,12 @@ CLASS zcl_abapgit_background DEFINITION
PROTECTED SECTION.
PRIVATE SECTION.
CONSTANTS c_enq_type TYPE c LENGTH 12 VALUE 'BACKGROUND'.
CONSTANTS c_interface TYPE seoclskey VALUE 'ZIF_ABAPGIT_BACKGROUND'.
ENDCLASS.
CLASS zcl_abapgit_background IMPLEMENTATION.
CLASS ZCL_ABAPGIT_BACKGROUND IMPLEMENTATION.
METHOD dequeue.
@ -59,36 +60,69 @@ CLASS zcl_abapgit_background IMPLEMENTATION.
METHOD list_methods.
DATA: ls_method LIKE LINE OF rt_methods,
ls_key TYPE seoclskey,
lt_implementing TYPE seor_implementing_keys,
ls_implementing LIKE LINE OF lt_implementing.
DATA: ls_method LIKE LINE OF rt_methods,
lt_implementing TYPE seor_implementing_keys,
ls_implementing LIKE LINE OF lt_implementing,
lt_interf TYPE abap_intfdescr_tab,
lt_local_classes TYPE STANDARD TABLE OF scompo,
lv_classname TYPE string,
lr_typedescr TYPE REF TO cl_abap_typedescr,
lr_typedescr_class TYPE REF TO cl_abap_classdescr.
FIELD-SYMBOLS: <ls_method> LIKE LINE OF rt_methods.
FIELD-SYMBOLS: <ls_local_class> LIKE LINE OF lt_local_classes,
<ls_method> LIKE LINE OF rt_methods.
IF zcl_abapgit_factory=>get_environment( )->is_merged( ) = abap_true.
" Assume the standalone version runs.
CALL FUNCTION 'WB_TREE_GET_OBJECTS'
EXPORTING
include = ' '
otype = 'L'
program = sy-repid
TABLES
olist = lt_local_classes.
* in order to handle local classes in the compiled report
ls_method-class = 'ZCL_ABAPGIT_BACKGROUND_PULL'.
INSERT ls_method INTO TABLE rt_methods.
ls_method-class = 'ZCL_ABAPGIT_BACKGROUND_PUSH_AU'.
INSERT ls_method INTO TABLE rt_methods.
ls_method-class = 'ZCL_ABAPGIT_BACKGROUND_PUSH_FI'.
INSERT ls_method INTO TABLE rt_methods.
LOOP AT lt_local_classes ASSIGNING <ls_local_class>.
lv_classname = |\\PROGRAM={ sy-repid }\\CLASS={ <ls_local_class>-name }|.
cl_abap_typedescr=>describe_by_name(
EXPORTING
p_name = lv_classname
RECEIVING
p_descr_ref = lr_typedescr
EXCEPTIONS
type_not_found = 1
OTHERS = 2 ).
ls_key-clsname = 'ZIF_ABAPGIT_BACKGROUND'.
IF sy-subrc = 0 AND lr_typedescr IS BOUND.
lr_typedescr_class ?= lr_typedescr.
IF lr_typedescr_class IS BOUND.
lt_interf = lr_typedescr_class->interfaces.
READ TABLE lt_interf WITH TABLE KEY name = c_interface TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
ls_method-class = <ls_local_class>-name.
INSERT ls_method INTO TABLE rt_methods.
ENDIF.
ENDIF.
ENDIF.
ENDLOOP.
CALL FUNCTION 'SEO_INTERFACE_IMPLEM_GET_ALL'
EXPORTING
intkey = ls_key
IMPORTING
impkeys = lt_implementing
EXCEPTIONS
not_existing = 1
OTHERS = 2 ##FM_SUBRC_OK.
LOOP AT lt_implementing INTO ls_implementing.
ls_method-class = ls_implementing-clsname.
INSERT ls_method INTO TABLE rt_methods.
ENDLOOP.
ELSE.
" Assume the developer version runs.
CALL FUNCTION 'SEO_INTERFACE_IMPLEM_GET_ALL'
EXPORTING
intkey = c_interface
IMPORTING
impkeys = lt_implementing
EXCEPTIONS
not_existing = 1
OTHERS = 2.
IF sy-subrc = 0.
LOOP AT lt_implementing INTO ls_implementing.
ls_method-class = ls_implementing-clsname.
INSERT ls_method INTO TABLE rt_methods.
ENDLOOP.
ENDIF.
ENDIF.
LOOP AT rt_methods ASSIGNING <ls_method>.
CALL METHOD (<ls_method>-class)=>zif_abapgit_background~get_description
@ -136,12 +170,17 @@ CLASS zcl_abapgit_background IMPLEMENTATION.
iv_username = <ls_list>-username
iv_password = <ls_list>-password ).
CREATE OBJECT li_background TYPE (<ls_list>-method).
TRY.
CREATE OBJECT li_background TYPE (<ls_list>-method).
li_background->run(
io_repo = lo_repo
ii_log = li_log
it_settings = <ls_list>-settings ).
li_background->run(
io_repo = lo_repo
ii_log = li_log
it_settings = <ls_list>-settings ).
CATCH cx_sy_create_object_error.
li_log->add_warning( |{ <ls_list>-method } could not be executed,|
& | as it is not accessible (local/global class).| ).
ENDTRY.
" Decrease memory usage for repository already processed (but keep log)
lo_repo->refresh(

View File

@ -209,7 +209,7 @@ CLASS zcl_abapgit_cts_api IMPLEMENTATION.
IMPORTING
pe_result = lv_type_check_result.
rv_transportable = boolc( lv_type_check_result CA 'RTL' ).
rv_transportable = boolc( lv_type_check_result CA 'RTL' OR iv_object_type = 'TABU' ).
ENDMETHOD.

View File

@ -1,5 +1,3 @@
*"* use this source file for your ABAP unit test classes
CLASS ltcl_test DEFINITION DEFERRED.
CLASS zcl_abapgit_exit DEFINITION LOCAL FRIENDS ltcl_test.

View File

@ -1,5 +1,3 @@
*"* use this source file for your ABAP unit test classes
CLASS ltcl_calculate_patch DEFINITION FINAL FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.

View File

@ -178,14 +178,18 @@ CLASS zcl_abapgit_git_pack IMPLEMENTATION.
lv_data = iv_data.
* header
IF NOT xstrlen( lv_data ) > 4 OR lv_data(4) <> c_pack_start.
zcx_abapgit_exception=>raise( |Unexpected pack header| ).
IF xstrlen( lv_data ) < 4.
zcx_abapgit_exception=>raise( |Unexpected pack header, short reply| ).
ENDIF.
IF lv_data(4) <> c_pack_start.
zcx_abapgit_exception=>raise( |Unexpected pack header, { lv_data(4) }| ).
ENDIF.
lv_data = lv_data+4.
* version
IF lv_data(4) <> c_version.
zcx_abapgit_exception=>raise( |Version not supported| ).
zcx_abapgit_exception=>raise( |Version not supported, { lv_data(4) }| ).
ENDIF.
lv_data = lv_data+4.

View File

@ -1,7 +1,3 @@
*"* use this source file for any type of declarations (class
*"* definitions, interfaces or type declarations) you need for
*"* components in the private section
CLASS lcl_stream DEFINITION FINAL.
PUBLIC SECTION.
TYPES: ty_hex TYPE x LENGTH 1.

View File

@ -1,7 +1,3 @@
*"* use this source file for the definition and implementation of
*"* local helper classes, interface definitions and type
*"* declarations
CLASS lcl_stream IMPLEMENTATION.
METHOD constructor.

View File

@ -50,7 +50,7 @@ CLASS zcl_abapgit_ajson DEFINITION
CLASS-METHODS parse
IMPORTING
!iv_json TYPE string
!iv_json TYPE any
!iv_freeze TYPE abap_bool DEFAULT abap_false
!ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL
!iv_keep_item_order TYPE abap_bool DEFAULT abap_false

View File

@ -20,27 +20,27 @@ INTERFACE lif_kind.
CONSTANTS:
BEGIN OF numeric,
int1 TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_int1,
int2 TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_int2,
int4 TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_int,
int8 TYPE ty_kind VALUE '8', " cl_abap_tabledescr=>typekind_int8 not in lower releases
float TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_float,
packed TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_packed,
decfloat16 TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_decfloat16,
decfloat34 TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_decfloat34,
int1 TYPE ty_kind VALUE cl_abap_typedescr=>typekind_int1,
int2 TYPE ty_kind VALUE cl_abap_typedescr=>typekind_int2,
int4 TYPE ty_kind VALUE cl_abap_typedescr=>typekind_int,
int8 TYPE ty_kind VALUE '8', " cl_abap_typedescr=>typekind_int8 not in lower releases
float TYPE ty_kind VALUE cl_abap_typedescr=>typekind_float,
packed TYPE ty_kind VALUE cl_abap_typedescr=>typekind_packed,
decfloat16 TYPE ty_kind VALUE cl_abap_typedescr=>typekind_decfloat16,
decfloat34 TYPE ty_kind VALUE cl_abap_typedescr=>typekind_decfloat34,
END OF numeric.
CONSTANTS:
BEGIN OF texts,
char TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_char,
numc TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_num,
string TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_string,
char TYPE ty_kind VALUE cl_abap_typedescr=>typekind_char,
numc TYPE ty_kind VALUE cl_abap_typedescr=>typekind_num,
string TYPE ty_kind VALUE cl_abap_typedescr=>typekind_string,
END OF texts.
CONSTANTS:
BEGIN OF binary,
hex TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_hex,
xstring TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_xstring,
hex TYPE ty_kind VALUE cl_abap_typedescr=>typekind_hex,
xstring TYPE ty_kind VALUE cl_abap_typedescr=>typekind_xstring,
END OF binary.
CONSTANTS:
@ -80,6 +80,25 @@ CLASS lcl_utils DEFINITION FINAL.
iv_str TYPE string
RETURNING
VALUE(rv_xstr) TYPE xstring.
CLASS-METHODS xstring_to_string_utf8
IMPORTING
iv_xstr TYPE xstring
RETURNING
VALUE(rv_str) TYPE string.
CLASS-METHODS any_to_xstring
IMPORTING
iv_data TYPE any
RETURNING
VALUE(rv_xstr) TYPE xstring
RAISING
zcx_abapgit_ajson_error.
CLASS-METHODS any_to_string
IMPORTING
iv_data TYPE any
RETURNING
VALUE(rv_str) TYPE string
RAISING
zcx_abapgit_ajson_error.
ENDCLASS.
@ -116,6 +135,37 @@ CLASS lcl_utils IMPLEMENTATION.
ENDMETHOD.
METHOD xstring_to_string_utf8.
DATA lo_conv TYPE REF TO object.
DATA lv_in_ce TYPE string.
lv_in_ce = 'CL_ABAP_CONV_IN_CE'.
TRY.
CALL METHOD ('CL_ABAP_CONV_CODEPAGE')=>create_in
RECEIVING
instance = lo_conv.
CALL METHOD lo_conv->('IF_ABAP_CONV_IN~CONVERT')
EXPORTING
source = iv_xstr
RECEIVING
result = rv_str.
CATCH cx_sy_dyn_call_illegal_class.
CALL METHOD (lv_in_ce)=>create
EXPORTING
encoding = 'UTF-8'
RECEIVING
conv = lo_conv.
CALL METHOD lo_conv->('CONVERT')
EXPORTING
data = iv_xstr
IMPORTING
buffer = rv_str.
ENDTRY.
ENDMETHOD.
METHOD validate_array_index.
IF NOT iv_index CO '0123456789'.
@ -176,6 +226,74 @@ CLASS lcl_utils IMPLEMENTATION.
ENDMETHOD.
METHOD any_to_xstring.
" supports xstring, char, string, or string_table as input
DATA lo_type TYPE REF TO cl_abap_typedescr.
DATA lo_table_type TYPE REF TO cl_abap_tabledescr.
DATA lv_str TYPE string.
FIELD-SYMBOLS: <data> TYPE STANDARD TABLE.
lo_type = cl_abap_typedescr=>describe_by_data( iv_data ).
CASE lo_type->type_kind.
WHEN lif_kind=>binary-xstring.
rv_xstr = iv_data.
WHEN lif_kind=>texts-string OR lif_kind=>texts-char.
rv_xstr = string_to_xstring_utf8( iv_data ).
WHEN lif_kind=>table.
lo_table_type ?= lo_type.
IF lo_table_type->table_kind <> cl_abap_tabledescr=>tablekind_std.
zcx_abapgit_ajson_error=>raise( 'Unsupported type of input table (must be standard table)' ).
ENDIF.
TRY.
ASSIGN iv_data TO <data>.
lv_str = concat_lines_of( table = <data>
sep = cl_abap_char_utilities=>newline ).
rv_xstr = string_to_xstring_utf8( lv_str ).
CATCH cx_root.
zcx_abapgit_ajson_error=>raise( 'Error converting input table (should be string_table)' ).
ENDTRY.
WHEN OTHERS.
zcx_abapgit_ajson_error=>raise( 'Unsupported type of input (must be char, string, string_table, or xstring)' ).
ENDCASE.
ENDMETHOD.
METHOD any_to_string.
" supports xstring, char, string, or string_table as input
DATA lo_type TYPE REF TO cl_abap_typedescr.
DATA lo_table_type TYPE REF TO cl_abap_tabledescr.
FIELD-SYMBOLS: <data> TYPE STANDARD TABLE.
lo_type = cl_abap_typedescr=>describe_by_data( iv_data ).
CASE lo_type->type_kind.
WHEN lif_kind=>binary-xstring.
rv_str = xstring_to_string_utf8( iv_data ).
WHEN lif_kind=>texts-string OR lif_kind=>texts-char.
rv_str = iv_data.
WHEN lif_kind=>table.
lo_table_type ?= lo_type.
IF lo_table_type->table_kind <> cl_abap_tabledescr=>tablekind_std.
zcx_abapgit_ajson_error=>raise( 'Unsupported type of input table (must be standard table)' ).
ENDIF.
TRY.
ASSIGN iv_data TO <data>.
rv_str = concat_lines_of( table = <data>
sep = cl_abap_char_utilities=>newline ).
CATCH cx_root.
zcx_abapgit_ajson_error=>raise( 'Error converting input table (should be string_table)' ).
ENDTRY.
WHEN OTHERS.
zcx_abapgit_ajson_error=>raise( 'Unsupported type of input (must be char, string, string_table, or xstring)' ).
ENDCASE.
ENDMETHOD.
ENDCLASS.
@ -188,7 +306,7 @@ CLASS lcl_json_parser DEFINITION FINAL.
METHODS parse
IMPORTING
iv_json TYPE string
iv_json TYPE any
iv_keep_item_order TYPE abap_bool DEFAULT abap_false
RETURNING
VALUE(rt_json_tree) TYPE zif_abapgit_ajson_types=>ty_nodes_tt
@ -212,7 +330,7 @@ CLASS lcl_json_parser DEFINITION FINAL.
METHODS _parse
IMPORTING
iv_json TYPE string
iv_json TYPE xstring
RETURNING
VALUE(rt_json_tree) TYPE zif_abapgit_ajson_types=>ty_nodes_tt
RAISING
@ -233,17 +351,20 @@ CLASS lcl_json_parser IMPLEMENTATION.
DATA lx_sxml_parse TYPE REF TO cx_sxml_parse_error.
DATA lx_sxml TYPE REF TO cx_dynamic_check.
DATA lv_location TYPE string.
DATA lv_json TYPE xstring.
mv_keep_item_order = iv_keep_item_order.
lv_json = lcl_utils=>any_to_xstring( iv_json ).
TRY.
" TODO sane JSON check:
" JSON can be true,false,null,(-)digits
" or start from " or from {
rt_json_tree = _parse( iv_json ).
rt_json_tree = _parse( lv_json ).
CATCH cx_sxml_parse_error INTO lx_sxml_parse.
lv_location = _get_location(
iv_json = iv_json
iv_json = lcl_utils=>any_to_string( iv_json )
iv_offset = lx_sxml_parse->xml_offset ).
zcx_abapgit_ajson_error=>raise(
iv_msg = |Json parsing error (SXML): { lx_sxml_parse->get_text( ) }|
@ -305,7 +426,7 @@ CLASS lcl_json_parser IMPLEMENTATION.
IF iv_json IS INITIAL.
RETURN.
ENDIF.
lo_reader = cl_sxml_string_reader=>create( lcl_utils=>string_to_xstring_utf8( iv_json ) ).
lo_reader = cl_sxml_string_reader=>create( iv_json ).
" TODO: self protection, check non-empty, check starting from object ...

View File

@ -85,6 +85,10 @@ CLASS ltcl_parser_test DEFINITION FINAL
METHODS parse_date FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS parse_bare_values FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS parse_error FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS parse_input_xstring FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS parse_input_string FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS parse_input_string_table FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS parse_input_error FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS duplicate_key FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS non_json FOR TESTING RAISING zcx_abapgit_ajson_error.
@ -248,6 +252,78 @@ CLASS ltcl_parser_test IMPLEMENTATION.
exp = mo_nodes->mt_nodes ).
ENDMETHOD.
METHOD parse_input_xstring.
mo_nodes->add( ' | |object | | |1' ).
mo_nodes->add( '/ |string |str |abc | |0' ).
DATA lt_act TYPE zif_abapgit_ajson_types=>ty_nodes_tt.
DATA lv_xstr TYPE xstring.
lv_xstr = '7B22737472696E67223A2022616263227D0A'.
lt_act = mo_cut->parse( lv_xstr ).
cl_abap_unit_assert=>assert_equals(
act = lt_act
exp = mo_nodes->mt_nodes ).
ENDMETHOD.
METHOD parse_input_string.
mo_nodes->add( ' | |object | | |1' ).
mo_nodes->add( '/ |string |str |abc | |0' ).
DATA lt_act TYPE zif_abapgit_ajson_types=>ty_nodes_tt.
DATA lv_str TYPE string.
lv_str = `{"string": "abc"}`.
lt_act = mo_cut->parse( lv_str ).
cl_abap_unit_assert=>assert_equals(
act = lt_act
exp = mo_nodes->mt_nodes ).
ENDMETHOD.
METHOD parse_input_string_table.
mo_nodes->add( ' | |object | | |2' ).
mo_nodes->add( '/ |string |str |abc | |0' ).
mo_nodes->add( '/ |number |num |123 | |0' ).
DATA lt_act TYPE zif_abapgit_ajson_types=>ty_nodes_tt.
DATA lt_json TYPE string_table.
INSERT `{` INTO TABLE lt_json.
INSERT `"string": "abc",` INTO TABLE lt_json.
INSERT `"number": 123` INTO TABLE lt_json.
INSERT `}` INTO TABLE lt_json.
lt_act = mo_cut->parse( lt_json ).
cl_abap_unit_assert=>assert_equals(
act = lt_act
exp = mo_nodes->mt_nodes ).
ENDMETHOD.
METHOD parse_input_error.
DATA lo_cut TYPE REF TO lcl_json_parser.
DATA lx TYPE REF TO zcx_abapgit_ajson_error.
DATA lv_numc TYPE n LENGTH 10.
DATA lt_hashed TYPE HASHED TABLE OF string WITH UNIQUE DEFAULT KEY.
CREATE OBJECT lo_cut.
TRY.
lo_cut->parse( lv_numc ).
cl_abap_unit_assert=>fail( ).
CATCH zcx_abapgit_ajson_error INTO lx.
cl_abap_unit_assert=>assert_not_initial( lx ).
ENDTRY.
TRY.
lo_cut->parse( lt_hashed ).
cl_abap_unit_assert=>fail( ).
CATCH zcx_abapgit_ajson_error INTO lx.
cl_abap_unit_assert=>assert_not_initial( lx ).
ENDTRY.
ENDMETHOD.
METHOD sample_json.
rv_json =
@ -2401,6 +2477,7 @@ CLASS ltcl_writer_test DEFINITION FINAL
METHODS set_bool_tab FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS set_str FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS set_int FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS set_number FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS set_date FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS set_timestamp FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS read_only FOR TESTING RAISING zcx_abapgit_ajson_error.
@ -3241,6 +3318,27 @@ CLASS ltcl_writer_test IMPLEMENTATION.
ENDMETHOD.
METHOD set_number.
DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper.
DATA li_json TYPE REF TO zif_abapgit_ajson.
DATA lv_p TYPE p LENGTH 5 DECIMALS 2 VALUE '123.45'.
li_json = zcl_abapgit_ajson=>create_empty( ).
CREATE OBJECT lo_nodes_exp.
lo_nodes_exp->add( ' | |object | ||1' ).
lo_nodes_exp->add( '/ |a |num |123.45 ||0' ).
li_json->set(
iv_path = '/a'
iv_val = lv_p ).
cl_abap_unit_assert=>assert_equals(
act = li_json->mt_json_tree
exp = lo_nodes_exp->sorted( ) ).
ENDMETHOD.
METHOD set_date.
DATA lo_cut TYPE REF TO zcl_abapgit_ajson.

View File

@ -1,5 +1,3 @@
*"* use this source file for your ABAP unit test classes
CLASS ltcl_adjust_filter DEFINITION FINAL FOR TESTING INHERITING FROM zcl_abapgit_object_filter_tran
DURATION SHORT
RISK LEVEL HARMLESS.

View File

@ -1,4 +1,3 @@
*"* use this source file for your ABAP unit test classes
CLASS ltcl_find_remote_dot_abapgit DEFINITION FINAL FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.

View File

@ -1,7 +1,3 @@
*"* use this source file for the definition and implementation of
*"* local helper classes, interface definitions and type
*"* declarations
CLASS lcl_sha1_stack DEFINITION.
PUBLIC SECTION.
METHODS clear

View File

@ -1,4 +1,3 @@
*"* use this source file for your ABAP unit test classes
CLASS ltcl_normalize_program_name DEFINITION FINAL FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.

View File

@ -66,7 +66,7 @@ ENDCLASS.
CLASS zcl_abapgit_gui_page_sett_bckg IMPLEMENTATION.
CLASS ZCL_ABAPGIT_GUI_PAGE_SETT_BCKG IMPLEMENTATION.
METHOD constructor.
@ -210,9 +210,13 @@ CLASS zcl_abapgit_gui_page_sett_bckg IMPLEMENTATION.
" skip invalid values, from old background logic
IF ls_per-method <> 'push' AND ls_per-method <> 'pull' AND ls_per-method <> 'nothing'.
CALL METHOD (ls_per-method)=>zif_abapgit_background~get_settings
CHANGING
ct_settings = lt_settings.
TRY.
CALL METHOD (ls_per-method)=>zif_abapgit_background~get_settings
CHANGING
ct_settings = lt_settings.
CATCH cx_sy_dyn_call_illegal_class.
CLEAR lt_settings.
ENDTRY.
ENDIF.
LOOP AT lt_settings INTO ls_settings.

View File

@ -1,5 +1,3 @@
*"* use this source file for your ABAP unit test classes
CLASS ltd_git_transport DEFINITION FINAL FOR TESTING.
PUBLIC SECTION.

View File

@ -1,5 +1,3 @@
*"* use this source file for your ABAP unit test classes
CLASS ltcl_get_patch_data DEFINITION FINAL FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.

View File

@ -75,7 +75,13 @@ CLASS zcl_abapgit_diff DEFINITION
METHODS create_regex_set
RETURNING
VALUE(rt_regex_set) TYPE ty_regexset_tt.
METHODS compute_and_render
METHODS compute_diff
IMPORTING
!it_new TYPE rswsourcet
!it_old TYPE rswsourcet
RETURNING
VALUE(rt_diff) TYPE zif_abapgit_definitions=>ty_diffs_tt.
METHODS compute_diff_extra
IMPORTING
!it_new TYPE rswsourcet
!it_old TYPE rswsourcet
@ -187,7 +193,7 @@ CLASS zcl_abapgit_diff IMPLEMENTATION.
ENDMETHOD.
METHOD compute_and_render.
METHOD compute_diff.
DATA:
lv_i TYPE i,
@ -195,8 +201,6 @@ CLASS zcl_abapgit_diff IMPLEMENTATION.
lt_delta TYPE STANDARD TABLE OF rsedcresul WITH DEFAULT KEY.
FIELD-SYMBOLS:
<ls_old> LIKE LINE OF it_old,
<ls_new> LIKE LINE OF it_new,
<ls_delta> LIKE LINE OF lt_delta.
" Note: Ignore case is for keywords, variables, types etc, but not for literals
@ -245,22 +249,9 @@ CLASS zcl_abapgit_diff IMPLEMENTATION.
APPEND ls_diff TO rt_diff.
ENDLOOP.
ELSEIF sy-subrc = 2.
" Copy input... but it might not be identical
LOOP AT it_old ASSIGNING <ls_old>.
CLEAR ls_diff.
ls_diff-old_num = sy-tabix.
ls_diff-old = <ls_old>.
READ TABLE it_new ASSIGNING <ls_new> INDEX sy-tabix.
ASSERT sy-subrc = 0.
ls_diff-new_num = sy-tabix.
ls_diff-new = <ls_new>.
" SAP function ignores lines that contain only whitespace so we compare directly
IF ( mv_compare_mode = 1 OR mv_compare_mode = 3 ) AND <ls_old> <> <ls_new> AND
( strlen( condense( <ls_old> ) ) = 0 OR strlen( condense( <ls_new> ) ) = 0 ).
ls_diff-result = zif_abapgit_definitions=>c_diff-update.
ENDIF.
APPEND ls_diff TO rt_diff.
ENDLOOP.
" The function doesn't find all diffs...
rt_diff = compute_diff_extra( it_new = it_new
it_old = it_old ).
ELSE.
ASSERT 0 = 1. " incorrect function call
ENDIF.
@ -268,6 +259,53 @@ CLASS zcl_abapgit_diff IMPLEMENTATION.
ENDMETHOD.
METHOD compute_diff_extra.
DATA:
lv_last_new TYPE c LENGTH 1,
lv_last_old TYPE c LENGTH 1,
ls_diff LIKE LINE OF rt_diff.
FIELD-SYMBOLS:
<ls_old> LIKE LINE OF it_old,
<ls_new> LIKE LINE OF it_new.
LOOP AT it_old ASSIGNING <ls_old>.
CLEAR ls_diff.
ls_diff-old_num = sy-tabix.
ls_diff-old = <ls_old>.
READ TABLE it_new ASSIGNING <ls_new> INDEX sy-tabix.
IF sy-subrc <> 0.
EXIT.
ENDIF.
ls_diff-new_num = sy-tabix.
ls_diff-new = <ls_new>.
" SAP function ignores lines that contain only whitespace so we compare directly
" Also check if one line has trailing space(s)
IF ( mv_compare_mode = 1 OR mv_compare_mode = 3 ) AND <ls_old> <> <ls_new>.
IF strlen( condense( <ls_old> ) ) = 0 OR strlen( condense( <ls_new> ) ) = 0.
ls_diff-result = zif_abapgit_definitions=>c_diff-update.
ELSEIF strlen( <ls_old> ) > 0 AND strlen( <ls_new> ) > 0.
lv_last_new = substring( val = <ls_new>
off = strlen( <ls_new> ) - 1 ).
lv_last_old = substring( val = <ls_old>
off = strlen( <ls_old> ) - 1 ).
IF lv_last_new = space OR lv_last_old = space.
ls_diff-result = zif_abapgit_definitions=>c_diff-update.
ENDIF.
ENDIF.
ENDIF.
APPEND ls_diff TO rt_diff.
ENDLOOP.
ENDMETHOD.
METHOD constructor.
DATA: lt_new TYPE rswsourcet,
@ -287,8 +325,8 @@ CLASS zcl_abapgit_diff IMPLEMENTATION.
IMPORTING et_new = lt_new
et_old = lt_old ).
mt_diff = compute_and_render( it_new = lt_new
it_old = lt_old ).
mt_diff = compute_diff( it_new = lt_new
it_old = lt_old ).
adjust_diff( ).

View File

@ -528,12 +528,14 @@ CLASS ltcl_diff IMPLEMENTATION.
add_new( ` ` ). " one space
add_new( ` ` ). " some spaces
add_new( 'E' ).
add_new( 'X' ). " no trailing space
add_old( 'A' ).
add_old( ` ` ). " some spaces
add_old( ` ` ). " two spaces
add_old( `` ). " empty line
add_old( 'E' ).
add_old( `X ` ). " some trailing space
add_expected( iv_new_num = ' 1'
iv_new = 'A'
@ -560,6 +562,11 @@ CLASS ltcl_diff IMPLEMENTATION.
iv_result = zif_abapgit_definitions=>c_diff-unchanged
iv_old_num = ' 5'
iv_old = 'E' ).
add_expected( iv_new_num = ' 6'
iv_new = 'X'
iv_result = zif_abapgit_definitions=>c_diff-update
iv_old_num = ' 6'
iv_old = `X ` ).
test( ).

View File

@ -44,6 +44,11 @@ INCLUDE zabapgit_authorizations_exit IF FOUND.
* place the object in a different package than ZABAPGIT
INCLUDE zabapgit_user_exit IF FOUND.
* place all implementations of ZIF_ABAPGIT_BACKGROUND in following include,
* if using the development version of abapGit create a global classes instead
* place the object in a different package than ZABAPGIT
INCLUDE zabapgit_background_user_exit IF FOUND.
INCLUDE zabapgit_gui_pages_userexit IF FOUND.
INCLUDE zabapgit_forms.

View File

@ -48,7 +48,8 @@ CLASS ltcl_test IMPLEMENTATION.
DATA lt_objects TYPE zif_abapgit_definitions=>ty_objects_tt.
DATA lt_sha1 TYPE zif_abapgit_git_definitions=>ty_sha1_tt.
INSERT '7bdd8f9f4c6bb0ece461b78c7b559957fad6c3ae' INTO TABLE lt_sha1.
* todo, given the sha1, this test might fail after a year?
INSERT 'e83a31ebafde4e8e7e80ca36662e42e8f20895c5' INTO TABLE lt_sha1.
lt_objects = zcl_abapgit_git_factory=>get_v2_porcelain( )->commits_last_year(
iv_url = 'https://github.com/abapGit/abapGit.git'