2023 Nov 06 8:58 AM
Hello,
The Check Variant of ATC/Code Inspector can be displayed and maintained, but I'd like to print its details into a PDF file, with all the details (see screenshots below).
The question is not about printing the results of Code Inspector, but only about printing the details of the checks done.
Is it possible? Did someone create a program? A SAP GUI Scripting script to share maybe?
Thanks a lot.
Sandra
2023 Nov 06 9:41 AM
Each time I did it manually to fit the Development rules and the checks done on the system. If you find it ...
2023 Nov 06 12:43 PM
I'd love to have that option as well but when I did some digging during setting up our ATC-systems, I didn't find anything to get a listing. And seeing that package S_CODE_INSPECTOR contains - among others - Cluster table for Check Variant Parameters (SCICHKV_PA) doesn't make me too hopeful that something exists or could easily be created.
Getting curious, I quickly ran ATC via SAT to see where that cluster table gets accessed to add a breakpoint at the "import from database" statement. This is how the retrieved data looks internally:
So, the selected checks for the variant are legible but their respective details and attributes not so much.
Sorry to not have better news for you!
2023 Nov 06 4:44 PM
Thanks frdric.girod and 8b889d0e8e6f4ed39f6c58e35664518f for your feedback. Alas, the parameters of each CI Check are compressed and can only be decoded by their corresponding CI Check class. I'll wait for good answers or do same as Frederic suggested 😉
2023 Nov 06 5:07 PM
This code snippet is a starting point. Not a satisfactory answer though, because it doesn't output the checks without parameters and I had an exception which forced me to debug and skip the wrong case (a parameter being an internal table, in CL_CI_TEST_EMPTY_UNUSED_PROCS). Test in ABAP 7.56.
baerbelwinkler For information.
TRY.
cl_ci_checkvariant=>get_ref(
EXPORTING
p_user = space " space for global variant
p_name = 'Z_GLOBAL_VARIANT'
RECEIVING
p_ref = DATA(variant)
EXCEPTIONS
chkv_not_exists = 1
missing_parameter = 2
broken_variant = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
LEAVE PROGRAM.
ENDIF.
DATA(config) = NEW cl_ci_variant_configuration( ).
config->variant_to_xml(
EXPORTING
variant = variant
RECEIVING
xml = DATA(xml) ).
CATCH cx_root INTO DATA(error).
ASSERT 1 = 1. " debugger
ENDTRY.
The final XML:
2023 Nov 06 8:33 PM
After the XML code has been generated, I convert it into an ABAP internal table via a Simple Transformation Z_CI_XML_TO_ITAB:
TYPES:
BEGIN OF ty_parameter,
value TYPE string,
description TYPE string,
END OF ty_parameter.
TYPES ty_parameters TYPE STANDARD TABLE OF ty_parameter WITH EMPTY KEY.
TYPES:
BEGIN OF ty_group,
description TYPE string,
parameters TYPE ty_parameters,
END OF ty_group.
TYPES ty_groups TYPE STANDARD TABLE OF ty_group WITH EMPTY KEY.
TYPES:
BEGIN OF ty_check,
version TYPE string,
check_class_name TYPE seoclsname,
category_class_name TYPE seoclsname,
parameters TYPE ty_parameters,
groups TYPE ty_groups,
END OF ty_check.
TYPES ty_checks TYPE STANDARD TABLE OF ty_check WITH EMPTY KEY.
CALL TRANSFORMATION z_ci_xml_to_itab
SOURCE XML xml
RESULT checks = checks.
DATA(checks_2) = cl_ci_tests=>get_list( p_variant = variant->variant )->give_list( ).
LOOP AT checks_2 INTO DATA(check_2)
WHERE table_line->has_attributes = abap_false.
INSERT VALUE #( check_class_name = check_2->name
category_class_name = check_2->category )
INTO TABLE checks.
ENDLOOP.
LOOP AT checks REFERENCE INTO DATA(check)
GROUP BY ( category_class_name = check->category_class_name )
REFERENCE INTO DATA(category).
WRITE / category->category_class_name.
LOOP AT GROUP category REFERENCE INTO DATA(group_item).
check_2 = VALUE #( checks_2[ table_line->name = group_item->check_class_name ] OPTIONAL ).
WRITE : /5 group_item->check_class_name, COND #( WHEN check_2 IS BOUND THEN check_2->description ).
LOOP AT group_item->parameters REFERENCE INTO DATA(parameter).
WRITE : /10 COND #( WHEN parameter->description IS NOT INITIAL THEN parameter->description ELSE '(no parameter description)' ), ':',
COND #( WHEN parameter->value IS NOT INITIAL THEN parameter->value ELSE '(no value or false)' ).
ENDLOOP.
LOOP AT group_item->groups REFERENCE INTO DATA(group).
WRITE : /10 COND #( WHEN group->description IS NOT INITIAL THEN group->description ELSE '(no group description)' ).
LOOP AT group->parameters REFERENCE INTO parameter.
WRITE : /15 COND #( WHEN parameter->description IS NOT INITIAL THEN parameter->description ELSE '(no parameter description)' ), ':',
COND #( WHEN parameter->value IS NOT INITIAL THEN parameter->value ELSE '(no value or false)' ).
ENDLOOP.
ENDLOOP.
ENDLOOP.
ENDLOOP.
Simple Transformation Z_CI_XML_TO_ITAB:
<?sap.transform simple?>
<tt:transform
xmlns:tt="http://www.sap.com/transformation-templates"
xmlns:ci="https://www.sap.com/adt/codeinspector/checkvariant">
<tt:root name="CHECKS"/>
<tt:template>
<ci:variant tt:extensible="deep-dynamic">
<tt:loop ref="CHECKS">
<check>
<tt:attribute name="technicalName" value-ref="CHECK_CLASS_NAME"/>
<tt:attribute name="category" value-ref="CATEGORY_CLASS_NAME"/>
<tt:loop ref="PARAMETERS">
<parameter>
<tt:cond>
<tt:attribute name="value" value-ref="VALUE"/>
</tt:cond>
<tt:cond>
<tt:attribute name="description" value-ref="DESCRIPTION"/>
</tt:cond>
</parameter>
</tt:loop>
<tt:loop ref="GROUPS">
<group>
<tt:attribute name="description" value-ref="DESCRIPTION"/>
<tt:loop ref="PARAMETERS">
<parameter>
<tt:cond>
<tt:attribute name="value" value-ref="VALUE"/>
</tt:cond>
<tt:cond>
<tt:attribute name="description" value-ref="DESCRIPTION"/>
</tt:cond>
</parameter>
</tt:loop>
</group>
</tt:loop>
</check>
</tt:loop>
</ci:variant>
</tt:template>
</tt:transform>
Final result in an ABAP List (ABAP WRITE) / truncated to fit forum maximum:
CL_CI_CATEGORY_ABAP_COMPILER
CL_CI_TEST_ABAP_GENERATE Generate ABAP Programs
Generate only if necessary : false
CL_CI_TEST_EXPORT_COMP_PROCS_E Export of Program Information
Export Using RFC : false
RFC Destination : (no value or false)
With Call Level : 0
Force Generation : false
CL_CI_TEST_EXTENDED_CHECK Extended Program Check (SLIN)
(no parameter description) : 1
(no group description)
PERFORM/FORM Interfaces : true
CALL FUNCTION/METHOD Interfaces : true
CL_CI_TEST_SYNTAX_CHECK Syntax Check
More than one error : true
Warnings : true
Message Codes : (no value or false)
CL_CI_CATEGORY_SECURITY
CL_CI_TEST_CRITICAL_STATEMENTS Critical Statements
Calls
C-CALLs : true
SYSTEM-CALL : true
Database
ROLLBACK WORK : true
Dynamic Program Editing
GENERATE ... : true
READ REPORT : false
INSERT/DELETE REPORT : true
CL_CI_TEST_FIND_DYN_SQL Use of ADBC Interface
Find uses of ...
... ADBC classes : true
... other classes : (no value or false)
One message per ...
(no parameter description) : 1
CL_CI_TEST_SHO_CLIENT Client-Specific Shared Objects Methods
Attach Class Methods
ATTACH_FOR_READ : true
ATTACH_FOR_WRITE : true
ATTACH_FOR_UPDATE : true
Detach Class Methods
DETACH_AREA : true
DETACH_ALL_AREAS : true
CL_CI_CATEGORY_ROBUSTNESS
CL_CI_TEST_INT8 Test to check handling of type INT8
Analyze only local procedures : true
Non-local analysis depth : 1
(no group description)
Show detail information : false
Inverted check : false
2023 Nov 07 6:42 AM
Very good job Sandra !
if you are playing with ATC, I have created a specfic control to check object name (class, prog, ..)
2023 Nov 07 8:17 AM
frdric.girod Thanks. A standard check of program names already exists. Don't hesitate to share it with the community!
2023 Nov 07 9:45 AM
sandra.rossi these rules already exist ?
(I never been able to understand GitHub 😉 )
2023 Nov 07 9:37 AM
Why do you want to *print* a check variant? I feel there's another underlying problem here which should have a different solution.