abapgit-agent 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +261 -0
- package/CLAUDE.md +152 -16
- package/RELEASE_NOTES.md +13 -0
- package/abap/CLAUDE.md +210 -0
- package/abap/copilot-instructions.md +28 -0
- package/abap/zcl_abgagt_agent.clas.abap +2 -2
- package/abap/zcl_abgagt_command_inspect.clas.abap +255 -36
- package/abap/zcl_abgagt_command_view.clas.abap +3 -1
- package/abap/zcl_abgagt_util.clas.abap +2 -2
- package/abap/zcl_abgagt_viewer_ddls.clas.abap +83 -0
- package/abap/zcl_abgagt_viewer_ddls.clas.xml +15 -0
- package/abap/zcl_abgagt_viewer_ttyp.clas.abap +93 -0
- package/abap/zcl_abgagt_viewer_ttyp.clas.xml +15 -0
- package/abap/zif_abgagt_viewer.intf.abap +2 -1
- package/bin/abapgit-agent +210 -40
- package/docs/view-command.md +94 -2
- package/package.json +1 -1
package/abap/CLAUDE.md
CHANGED
|
@@ -23,6 +23,58 @@ This is an ABAP project. **Do not attempt local syntax validation** - ABAP code
|
|
|
23
23
|
4. **"Error updating where-used list" = SYNTAX ERROR** - This is NOT a warning!
|
|
24
24
|
5. If Failed Objects > 0, there are syntax errors - fix them before proceeding
|
|
25
25
|
|
|
26
|
+
## Inspect Command (Syntax Check)
|
|
27
|
+
|
|
28
|
+
Use the `inspect` command to perform syntax validation on ABAP objects and CDS views.
|
|
29
|
+
|
|
30
|
+
### Usage
|
|
31
|
+
```bash
|
|
32
|
+
# Syntax check single file
|
|
33
|
+
abapgit-agent inspect --files abap/zcl_my_class.clas.abap
|
|
34
|
+
|
|
35
|
+
# Syntax check multiple files
|
|
36
|
+
abapgit-agent inspect --files abap/zcl_class1.clas.abap,abap/zcl_class2.clas.abap
|
|
37
|
+
|
|
38
|
+
# Syntax check CDS view
|
|
39
|
+
abapgit-agent inspect --files abap/zc_my_view.ddls.asddls
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Supported Object Types
|
|
43
|
+
|
|
44
|
+
| Type | Description | Validation Method |
|
|
45
|
+
|------|-------------|------------------|
|
|
46
|
+
| CLAS | Class | Code Inspector (SCI) |
|
|
47
|
+
| INTF | Interface | Code Inspector (SCI) |
|
|
48
|
+
| PROG | Program | Code Inspector (SCI) |
|
|
49
|
+
| DDLS | CDS View/Entity | DDL Handler |
|
|
50
|
+
|
|
51
|
+
### CDS Views (DDLS) Validation
|
|
52
|
+
|
|
53
|
+
For CDS views, the inspect command uses `CL_DD_DDL_HANDLER_FACTORY`:
|
|
54
|
+
- Checks **inactive version first** (`get_state = 'M'`)
|
|
55
|
+
- Falls back to active version if no inactive version exists
|
|
56
|
+
- Uses `get_errors()` and `get_warnings()` methods for detailed error information
|
|
57
|
+
|
|
58
|
+
### Examples
|
|
59
|
+
|
|
60
|
+
**Passed:**
|
|
61
|
+
```
|
|
62
|
+
✅ CLAS ZCL_MY_CLASS - Syntax check passed
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**With Warnings:**
|
|
66
|
+
```
|
|
67
|
+
⚠️ DDLS ZC_MY_VIEW - Syntax check passed with warnings (4):
|
|
68
|
+
Line 9 : ParentPackage
|
|
69
|
+
Line 11 : SoftwareComponent
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**Failed:**
|
|
73
|
+
```
|
|
74
|
+
❌ DDLS ZC_MY_VIEW - Syntax check failed (1 error(s)):
|
|
75
|
+
Line 21, Column 12: Error message text
|
|
76
|
+
```
|
|
77
|
+
|
|
26
78
|
## Fast Iteration Workflow
|
|
27
79
|
|
|
28
80
|
For quick ABAP code changes:
|
|
@@ -80,6 +132,12 @@ abapgit-agent view --objects ZMY_DTEL --type DTEL
|
|
|
80
132
|
# View a class definition
|
|
81
133
|
abapgit-agent view --objects ZCL_MY_CLASS
|
|
82
134
|
|
|
135
|
+
# View an interface definition
|
|
136
|
+
abapgit-agent view --objects ZIF_MY_INTERFACE
|
|
137
|
+
|
|
138
|
+
# View a table type definition
|
|
139
|
+
abapgit-agent view --objects ZMY_TTYP --type TTYP
|
|
140
|
+
|
|
83
141
|
# View multiple objects
|
|
84
142
|
abapgit-agent view --objects ZCL_CLASS1,ZCL_CLASS2,ZIF_INTERFACE1
|
|
85
143
|
|
|
@@ -87,6 +145,41 @@ abapgit-agent view --objects ZCL_CLASS1,ZCL_CLASS2,ZIF_INTERFACE1
|
|
|
87
145
|
abapgit-agent view --objects ZMY_TABLE --type TABL --json
|
|
88
146
|
```
|
|
89
147
|
|
|
148
|
+
### When to Use View Command
|
|
149
|
+
|
|
150
|
+
AI assistant SHOULD call `view` command when:
|
|
151
|
+
|
|
152
|
+
- User asks to "check", "look up", or "explore" an unfamiliar object
|
|
153
|
+
- Working with a table/structure and you don't know the field names/types
|
|
154
|
+
- Calling a class/interface method and you don't know the parameters
|
|
155
|
+
- User provides an object name that may not exist in the git repository
|
|
156
|
+
|
|
157
|
+
**Example workflow:**
|
|
158
|
+
```
|
|
159
|
+
User: "Check if SFLIGHT table has a PRICE field"
|
|
160
|
+
|
|
161
|
+
Assistant: <calls `abapgit-agent view --objects SFLIGHT --type TABL`>
|
|
162
|
+
→ Shows table structure with all fields including PRICE
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Explore Package Structure
|
|
166
|
+
|
|
167
|
+
Use the `tree` command to display package hierarchy from ABAP system:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Display package hierarchy
|
|
171
|
+
abapgit-agent tree --package $MY_PACKAGE
|
|
172
|
+
|
|
173
|
+
# With object counts
|
|
174
|
+
abapgit-agent tree --package $MY_PACKAGE --include-objects
|
|
175
|
+
|
|
176
|
+
# Limit depth
|
|
177
|
+
abapgit-agent tree --package $MY_PACKAGE --depth 2
|
|
178
|
+
|
|
179
|
+
# JSON output for scripting
|
|
180
|
+
abapgit-agent tree --package $MY_PACKAGE --json
|
|
181
|
+
```
|
|
182
|
+
|
|
90
183
|
**Table Output Example:**
|
|
91
184
|
```
|
|
92
185
|
TABLE ZCAIS_D1:
|
|
@@ -111,6 +204,16 @@ DATA ELEMENT ZMY_DTEL:
|
|
|
111
204
|
|----------------+----------------+----------+----------------+----------------------|
|
|
112
205
|
```
|
|
113
206
|
|
|
207
|
+
**Table Type Output Example:**
|
|
208
|
+
```
|
|
209
|
+
📖 ZMY_TTYP (Table Type)
|
|
210
|
+
Table Type ZMY_TTYP in $PACKAGE
|
|
211
|
+
|
|
212
|
+
Line Type: ZMY_STRUCTURE
|
|
213
|
+
Access Mode: STANDARD
|
|
214
|
+
Key Definition: WITH KEY
|
|
215
|
+
```
|
|
216
|
+
|
|
114
217
|
## JSON Handling - ALWAYS Use /ui2/cl_json
|
|
115
218
|
|
|
116
219
|
**CRITICAL**: Always use `/ui2/cl_json` for JSON serialization and deserialization.
|
|
@@ -369,6 +472,113 @@ Common object types in this project:
|
|
|
369
472
|
- `TABL` - Tables
|
|
370
473
|
- `DDLS` - Data Definitions
|
|
371
474
|
|
|
475
|
+
## Creating CDS Views (DDLS)
|
|
476
|
+
|
|
477
|
+
CDS views (Data Definition Language Source) require specific file naming and structure for abapGit.
|
|
478
|
+
|
|
479
|
+
### File Naming
|
|
480
|
+
|
|
481
|
+
CDS views require **two files**:
|
|
482
|
+
|
|
483
|
+
| File | Description |
|
|
484
|
+
|------|-------------|
|
|
485
|
+
| `zc_my_view.ddls.asddls` | DDL source code |
|
|
486
|
+
| `zc_my_view.ddls.xml` | XML metadata |
|
|
487
|
+
|
|
488
|
+
**Important:** Do NOT use `.ddls.abap` extension - use `.ddls.asddls` for the source.
|
|
489
|
+
|
|
490
|
+
### DDL Source File (`.ddls.asddls`)
|
|
491
|
+
|
|
492
|
+
```abap
|
|
493
|
+
@AbapCatalog.sqlViewName: 'ZCMYVIEW'
|
|
494
|
+
@AbapCatalog.compiler.compareFilter: true
|
|
495
|
+
@AccessControl.authorizationCheck: #NOT_REQUIRED
|
|
496
|
+
@EndUserText.label: 'My CDS View'
|
|
497
|
+
define view ZC_My_View as select from tdevc
|
|
498
|
+
{
|
|
499
|
+
key devclass as Devclass,
|
|
500
|
+
parentcl as ParentPackage,
|
|
501
|
+
ctext as Description
|
|
502
|
+
}
|
|
503
|
+
where devclass not like '$%'
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### XML Metadata File (`.ddls.xml`)
|
|
507
|
+
|
|
508
|
+
```xml
|
|
509
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
510
|
+
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DDLS" serializer_version="v1.0.0">
|
|
511
|
+
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
512
|
+
<asx:values>
|
|
513
|
+
<DDLS>
|
|
514
|
+
<DDLNAME>ZC_MY_VIEW</DDLNAME>
|
|
515
|
+
<DDLANGUAGE>E</DDLANGUAGE>
|
|
516
|
+
<DDTEXT>My CDS View</DDTEXT>
|
|
517
|
+
</DDLS>
|
|
518
|
+
</asx:values>
|
|
519
|
+
</asx:abap>
|
|
520
|
+
</abapGit>
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
### Key Points
|
|
524
|
+
|
|
525
|
+
1. **Avoid reserved words** - Field names like `PACKAGE`, `CLASS`, `INTERFACE` are reserved in CDS. Use alternatives like `PackageName`, `ClassName`.
|
|
526
|
+
|
|
527
|
+
2. **Pull all files to activate** - When activating CDS views, use `abapgit-agent pull` (not single file) to ensure proper activation:
|
|
528
|
+
```bash
|
|
529
|
+
abapgit-agent pull # Pull all files
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
3. **System support** - CDS views require SAP systems with CDS capability (S/4HANA, SAP BW/4HANA, or ABAP 7.51+). Older systems will show error: "Object type DDLS is not supported by this system"
|
|
533
|
+
|
|
534
|
+
### Debugging Activation Errors
|
|
535
|
+
|
|
536
|
+
When pull shows generic errors like "Activation cancelled. Check the inactive objects":
|
|
537
|
+
|
|
538
|
+
1. **Check in ADT/Eclipse** - Open the DDL source in ADT and run syntax check for detailed errors
|
|
539
|
+
2. **Pull all files** - Sometimes `abapgit-agent pull` (all files) works better than single file for CDS views
|
|
540
|
+
|
|
541
|
+
## Creating CDS View Entities
|
|
542
|
+
|
|
543
|
+
CDS View Entities (`define view entity`) are the modern replacement for CDS Views with additional features like **associations for OData navigation**.
|
|
544
|
+
|
|
545
|
+
### Differences from CDS Views
|
|
546
|
+
|
|
547
|
+
| Aspect | CDS View | View Entity |
|
|
548
|
+
|--------|----------|-------------|
|
|
549
|
+
| Syntax | `define view` | `define view entity` |
|
|
550
|
+
| Associations | No | Yes (exposed for navigation) |
|
|
551
|
+
| OData/Navigation | Requires separate service | Auto-exposes associations |
|
|
552
|
+
| ABAP Version | 7.40+ | 7.55+ / S/4HANA Cloud |
|
|
553
|
+
|
|
554
|
+
### DDL Source File with Association
|
|
555
|
+
|
|
556
|
+
```abap
|
|
557
|
+
@EndUserText.label: 'Package Hierarchy'
|
|
558
|
+
@AccessControl.authorizationCheck: #NOT_REQUIRED
|
|
559
|
+
define view entity ZC_Pkg_Hierarchy_VE
|
|
560
|
+
as select from tdevc
|
|
561
|
+
association [0..1] to tdevc as _Parent
|
|
562
|
+
on _Parent.devclass = $projection.ParentPackage
|
|
563
|
+
{
|
|
564
|
+
key devclass as PackageName,
|
|
565
|
+
parentcl as ParentPackage,
|
|
566
|
+
ctext as Description,
|
|
567
|
+
dlvunit as SoftwareComponent,
|
|
568
|
+
|
|
569
|
+
// Exposed associations
|
|
570
|
+
_Parent
|
|
571
|
+
}
|
|
572
|
+
where devclass not like '$%'
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### Key Points for View Entities
|
|
576
|
+
|
|
577
|
+
1. **Association syntax**: Use `$projection` to reference fields in the current entity
|
|
578
|
+
2. **Association cardinality**: `[0..1]`, `[1..1]`, `[0..n]`, `[1..n]`
|
|
579
|
+
3. **Expose associations**: Add the association name at the end of the SELECT to expose it for OData navigation
|
|
580
|
+
4. **Activation warnings**: Search help warnings are informational and don't block activation
|
|
581
|
+
|
|
372
582
|
## Naming Conventions
|
|
373
583
|
|
|
374
584
|
- Use `Z_` or `Y_` prefix for custom objects
|
|
@@ -10,6 +10,34 @@ You are working on an ABAP project using abapGit for version control.
|
|
|
10
10
|
| `abapgit-agent pull --files <file>` | Pull and activate specific file only |
|
|
11
11
|
| `abapgit-agent inspect --files <file>` | Syntax check ABAP source |
|
|
12
12
|
| `abapgit-agent unit --files <file>` | Run AUnit tests |
|
|
13
|
+
| `abapgit-agent tree --package <package>` | Display package hierarchy |
|
|
14
|
+
| `abapgit-agent view --objects <name>` | View object definitions |
|
|
15
|
+
|
|
16
|
+
## Explore Unknown Objects
|
|
17
|
+
|
|
18
|
+
**Before working with unfamiliar objects, use `view` command:**
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# Check table structure
|
|
22
|
+
abapgit-agent view --objects ZMY_TABLE --type TABL
|
|
23
|
+
|
|
24
|
+
# Check class definition
|
|
25
|
+
abapgit-agent view --objects ZCL_UNKNOWN_CLASS
|
|
26
|
+
|
|
27
|
+
# Check interface
|
|
28
|
+
abapgit-agent view --objects ZIF_UNKNOWN_INTERFACE
|
|
29
|
+
|
|
30
|
+
# Check data element
|
|
31
|
+
abapgit-agent view --objects ZMY_DTEL --type DTEL
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## When to Use View Command
|
|
35
|
+
|
|
36
|
+
AI assistant SHOULD call `view` command when:
|
|
37
|
+
- User asks to "check", "look up", or "explore" an unfamiliar object
|
|
38
|
+
- Working with a table/structure and you don't know the fields
|
|
39
|
+
- Calling a class/interface method and you don't know the parameters
|
|
40
|
+
- You need to verify an object exists before using it
|
|
13
41
|
|
|
14
42
|
## Key ABAP Rules
|
|
15
43
|
|
|
@@ -389,8 +389,8 @@ CLASS zcl_abgagt_agent IMPLEMENTATION.
|
|
|
389
389
|
ENDIF.
|
|
390
390
|
ENDIF.
|
|
391
391
|
|
|
392
|
-
" Error/Abort
|
|
393
|
-
IF ls_msg-type = 'E' OR ls_msg-type = 'A'
|
|
392
|
+
" Error/Abort messages - add to failed objects (warnings are not failures)
|
|
393
|
+
IF ls_msg-type = 'E' OR ls_msg-type = 'A'.
|
|
394
394
|
APPEND ls_object TO rs_result-failed_objects.
|
|
395
395
|
ENDIF.
|
|
396
396
|
ENDLOOP.
|
|
@@ -6,6 +6,7 @@ CLASS zcl_abgagt_command_inspect DEFINITION PUBLIC FINAL CREATE PUBLIC.
|
|
|
6
6
|
PUBLIC SECTION.
|
|
7
7
|
INTERFACES zif_abgagt_command.
|
|
8
8
|
|
|
9
|
+
" Error structure for syntax check results
|
|
9
10
|
TYPES: BEGIN OF ty_error,
|
|
10
11
|
line TYPE string,
|
|
11
12
|
column TYPE string,
|
|
@@ -15,21 +16,49 @@ CLASS zcl_abgagt_command_inspect DEFINITION PUBLIC FINAL CREATE PUBLIC.
|
|
|
15
16
|
|
|
16
17
|
TYPES ty_errors TYPE STANDARD TABLE OF ty_error WITH NON-UNIQUE DEFAULT KEY.
|
|
17
18
|
|
|
19
|
+
" Generic warning structure (for DDLS and other objects)
|
|
20
|
+
TYPES: BEGIN OF ty_warning,
|
|
21
|
+
type TYPE string,
|
|
22
|
+
line TYPE string,
|
|
23
|
+
column TYPE string,
|
|
24
|
+
severity TYPE string,
|
|
25
|
+
message TYPE string,
|
|
26
|
+
object_type TYPE string,
|
|
27
|
+
object_name TYPE string,
|
|
28
|
+
END OF ty_warning.
|
|
29
|
+
|
|
30
|
+
TYPES ty_warnings TYPE STANDARD TABLE OF ty_warning WITH NON-UNIQUE DEFAULT KEY.
|
|
31
|
+
|
|
32
|
+
" Result for each individual object
|
|
18
33
|
TYPES: BEGIN OF ty_inspect_result,
|
|
34
|
+
object_type TYPE string,
|
|
35
|
+
object_name TYPE string,
|
|
19
36
|
success TYPE abap_bool,
|
|
20
37
|
error_count TYPE i,
|
|
21
38
|
errors TYPE ty_errors,
|
|
39
|
+
warnings TYPE ty_warnings,
|
|
22
40
|
END OF ty_inspect_result.
|
|
23
41
|
|
|
42
|
+
" Table to hold results for multiple objects
|
|
43
|
+
TYPES ty_inspect_results TYPE STANDARD TABLE OF ty_inspect_result WITH NON-UNIQUE DEFAULT KEY.
|
|
44
|
+
|
|
24
45
|
TYPES: BEGIN OF ty_inspect_params,
|
|
25
46
|
files TYPE string_table,
|
|
26
47
|
END OF ty_inspect_params.
|
|
27
48
|
|
|
28
49
|
TYPES ty_object_keys TYPE TABLE OF scir_objs WITH NON-UNIQUE DEFAULT KEY.
|
|
29
50
|
|
|
51
|
+
" Type for DDLS object names
|
|
52
|
+
TYPES ty_ddls_names TYPE STANDARD TABLE OF tadir-obj_name WITH NON-UNIQUE DEFAULT KEY.
|
|
53
|
+
|
|
30
54
|
METHODS run_syntax_check
|
|
31
55
|
IMPORTING it_objects TYPE ty_object_keys
|
|
32
|
-
RETURNING VALUE(
|
|
56
|
+
RETURNING VALUE(rt_results) TYPE ty_inspect_results.
|
|
57
|
+
|
|
58
|
+
" Validate DDLS (CDS views)
|
|
59
|
+
METHODS validate_ddls
|
|
60
|
+
IMPORTING it_ddls_names TYPE ty_ddls_names
|
|
61
|
+
RETURNING VALUE(rt_results) TYPE ty_inspect_results.
|
|
33
62
|
|
|
34
63
|
ENDCLASS.
|
|
35
64
|
|
|
@@ -45,9 +74,11 @@ CLASS zcl_abgagt_command_inspect IMPLEMENTATION.
|
|
|
45
74
|
lv_obj_type TYPE string,
|
|
46
75
|
lv_obj_name TYPE string,
|
|
47
76
|
lo_util TYPE REF TO zcl_abgagt_util,
|
|
48
|
-
|
|
77
|
+
lt_results TYPE ty_inspect_results,
|
|
49
78
|
lt_objects TYPE ty_object_keys,
|
|
50
|
-
|
|
79
|
+
lt_ddls_names TYPE ty_ddls_names,
|
|
80
|
+
ls_obj TYPE scir_objs,
|
|
81
|
+
ls_result TYPE ty_inspect_result.
|
|
51
82
|
|
|
52
83
|
" Parse parameters from is_param
|
|
53
84
|
IF is_param IS SUPPLIED.
|
|
@@ -57,7 +88,10 @@ CLASS zcl_abgagt_command_inspect IMPLEMENTATION.
|
|
|
57
88
|
IF ls_params-files IS INITIAL.
|
|
58
89
|
ls_result-success = abap_false.
|
|
59
90
|
ls_result-error_count = 1.
|
|
60
|
-
|
|
91
|
+
ls_result-object_name = 'N/A'.
|
|
92
|
+
ls_result-object_type = 'N/A'.
|
|
93
|
+
APPEND ls_result TO lt_results.
|
|
94
|
+
rv_result = /ui2/cl_json=>serialize( data = lt_results ).
|
|
61
95
|
RETURN.
|
|
62
96
|
ENDIF.
|
|
63
97
|
|
|
@@ -72,24 +106,191 @@ CLASS zcl_abgagt_command_inspect IMPLEMENTATION.
|
|
|
72
106
|
ev_obj_name = lv_obj_name ).
|
|
73
107
|
|
|
74
108
|
IF lv_obj_type IS NOT INITIAL AND lv_obj_name IS NOT INITIAL.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
109
|
+
" Separate DDLS from other objects
|
|
110
|
+
IF lv_obj_type = 'DDLS'.
|
|
111
|
+
APPEND lv_obj_name TO lt_ddls_names.
|
|
112
|
+
ELSE.
|
|
113
|
+
CLEAR ls_obj.
|
|
114
|
+
ls_obj-objtype = lv_obj_type.
|
|
115
|
+
ls_obj-objname = lv_obj_name.
|
|
116
|
+
APPEND ls_obj TO lt_objects.
|
|
117
|
+
ENDIF.
|
|
79
118
|
ENDIF.
|
|
80
119
|
ENDLOOP.
|
|
81
120
|
|
|
82
|
-
|
|
121
|
+
" Run syntax check for non-DDLS objects
|
|
122
|
+
IF lt_objects IS NOT INITIAL.
|
|
123
|
+
DATA(lt_sci_results) = run_syntax_check( lt_objects ).
|
|
124
|
+
INSERT LINES OF lt_sci_results INTO TABLE lt_results.
|
|
125
|
+
ENDIF.
|
|
126
|
+
|
|
127
|
+
" Run DDLS validation
|
|
128
|
+
IF lt_ddls_names IS NOT INITIAL.
|
|
129
|
+
DATA(lt_ddls_results) = validate_ddls( lt_ddls_names ).
|
|
130
|
+
INSERT LINES OF lt_ddls_results INTO TABLE lt_results.
|
|
131
|
+
ENDIF.
|
|
132
|
+
|
|
133
|
+
" If no valid objects found
|
|
134
|
+
IF lt_objects IS INITIAL AND lt_ddls_names IS INITIAL.
|
|
83
135
|
ls_result-success = abap_false.
|
|
84
136
|
ls_result-error_count = 1.
|
|
85
|
-
|
|
86
|
-
|
|
137
|
+
ls_result-object_name = 'N/A'.
|
|
138
|
+
ls_result-object_type = 'N/A'.
|
|
139
|
+
APPEND ls_result TO lt_results.
|
|
87
140
|
ENDIF.
|
|
88
141
|
|
|
89
|
-
|
|
90
|
-
|
|
142
|
+
rv_result = /ui2/cl_json=>serialize( data = lt_results ).
|
|
143
|
+
ENDMETHOD.
|
|
91
144
|
|
|
92
|
-
|
|
145
|
+
METHOD validate_ddls.
|
|
146
|
+
" Validate DDLS (CDS views) using CL_DD_DDL_HANDLER_FACTORY
|
|
147
|
+
" First checks inactive version ('M'), falls back to active ('A')
|
|
148
|
+
DATA: lv_ddls_name TYPE ddlname,
|
|
149
|
+
lo_handler TYPE REF TO if_dd_ddl_handler,
|
|
150
|
+
ls_ddlsrcv TYPE ddddlsrcv,
|
|
151
|
+
ls_error TYPE ty_error,
|
|
152
|
+
ls_warning TYPE ty_warning,
|
|
153
|
+
lt_warnings TYPE ddl2ddicwarnings,
|
|
154
|
+
lx_error TYPE REF TO cx_dd_ddl_check,
|
|
155
|
+
lv_found TYPE abap_bool,
|
|
156
|
+
ls_result TYPE ty_inspect_result,
|
|
157
|
+
lv_err_msg TYPE string,
|
|
158
|
+
lv_warn_msg TYPE string.
|
|
159
|
+
|
|
160
|
+
rt_results = VALUE #( ).
|
|
161
|
+
|
|
162
|
+
" Create DDL handler
|
|
163
|
+
lo_handler = cl_dd_ddl_handler_factory=>create( ).
|
|
164
|
+
|
|
165
|
+
" Check each DDLS object
|
|
166
|
+
LOOP AT it_ddls_names INTO lv_ddls_name.
|
|
167
|
+
CLEAR: ls_ddlsrcv, lt_warnings, lv_found, ls_result.
|
|
168
|
+
|
|
169
|
+
ls_result-object_type = 'DDLS'.
|
|
170
|
+
ls_result-object_name = lv_ddls_name.
|
|
171
|
+
ls_result-success = abap_true.
|
|
172
|
+
|
|
173
|
+
" First try to read inactive version (get_state = 'M')
|
|
174
|
+
TRY.
|
|
175
|
+
lo_handler->read(
|
|
176
|
+
EXPORTING
|
|
177
|
+
name = lv_ddls_name
|
|
178
|
+
get_state = 'M'
|
|
179
|
+
IMPORTING
|
|
180
|
+
ddddlsrcv_wa = ls_ddlsrcv ).
|
|
181
|
+
|
|
182
|
+
IF ls_ddlsrcv-source IS NOT INITIAL.
|
|
183
|
+
lv_found = abap_true.
|
|
184
|
+
ENDIF.
|
|
185
|
+
|
|
186
|
+
CATCH cx_dd_ddl_check.
|
|
187
|
+
" Ignore - will try active version
|
|
188
|
+
ENDTRY.
|
|
189
|
+
|
|
190
|
+
" If no inactive version, try active version
|
|
191
|
+
IF lv_found = abap_false.
|
|
192
|
+
TRY.
|
|
193
|
+
lo_handler->read(
|
|
194
|
+
EXPORTING
|
|
195
|
+
name = lv_ddls_name
|
|
196
|
+
get_state = 'A'
|
|
197
|
+
IMPORTING
|
|
198
|
+
ddddlsrcv_wa = ls_ddlsrcv ).
|
|
199
|
+
|
|
200
|
+
IF ls_ddlsrcv-source IS NOT INITIAL.
|
|
201
|
+
lv_found = abap_true.
|
|
202
|
+
ENDIF.
|
|
203
|
+
CATCH cx_dd_ddl_check.
|
|
204
|
+
" Ignore
|
|
205
|
+
ENDTRY.
|
|
206
|
+
ENDIF.
|
|
207
|
+
|
|
208
|
+
" If still not found, report error
|
|
209
|
+
IF lv_found = abap_false.
|
|
210
|
+
ls_error-line = '1'.
|
|
211
|
+
ls_error-column = '1'.
|
|
212
|
+
ls_error-text = |DDLS { lv_ddls_name } not found in repository|.
|
|
213
|
+
APPEND ls_error TO ls_result-errors.
|
|
214
|
+
ls_result-success = abap_false.
|
|
215
|
+
ls_result-error_count = lines( ls_result-errors ).
|
|
216
|
+
APPEND ls_result TO rt_results.
|
|
217
|
+
CONTINUE.
|
|
218
|
+
ENDIF.
|
|
219
|
+
|
|
220
|
+
" Run validation check
|
|
221
|
+
TRY.
|
|
222
|
+
" Get warnings from check method
|
|
223
|
+
lo_handler->check(
|
|
224
|
+
EXPORTING
|
|
225
|
+
name = lv_ddls_name
|
|
226
|
+
IMPORTING
|
|
227
|
+
warnings = lt_warnings
|
|
228
|
+
CHANGING
|
|
229
|
+
ddlsrcv_wa = ls_ddlsrcv ).
|
|
230
|
+
|
|
231
|
+
" Parse warnings from check method
|
|
232
|
+
LOOP AT lt_warnings INTO DATA(ls_warn_from_check).
|
|
233
|
+
CLEAR ls_warning.
|
|
234
|
+
ls_warning-type = ls_warn_from_check-type.
|
|
235
|
+
ls_warning-line = ls_warn_from_check-line.
|
|
236
|
+
ls_warning-column = ls_warn_from_check-column.
|
|
237
|
+
ls_warning-severity = ls_warn_from_check-severity.
|
|
238
|
+
ls_warning-object_type = 'DDLS'.
|
|
239
|
+
ls_warning-object_name = lv_ddls_name.
|
|
240
|
+
" Use MESSAGE statement to get real warning message
|
|
241
|
+
MESSAGE ID ls_warn_from_check-arbgb TYPE 'E' NUMBER ls_warn_from_check-msgnr
|
|
242
|
+
WITH ls_warn_from_check-var1 ls_warn_from_check-var2 ls_warn_from_check-var3 ls_warn_from_check-var4
|
|
243
|
+
INTO lv_warn_msg.
|
|
244
|
+
ls_warning-message = lv_warn_msg.
|
|
245
|
+
APPEND ls_warning TO ls_result-warnings.
|
|
246
|
+
ENDLOOP.
|
|
247
|
+
|
|
248
|
+
" If no errors and no warnings, validation passed
|
|
249
|
+
IF ls_result-warnings IS INITIAL.
|
|
250
|
+
ls_result-success = abap_true.
|
|
251
|
+
ELSE.
|
|
252
|
+
ls_result-success = abap_false.
|
|
253
|
+
ENDIF.
|
|
254
|
+
|
|
255
|
+
CATCH cx_dd_ddl_check INTO lx_error.
|
|
256
|
+
" Validation failed - get error details using get_errors method
|
|
257
|
+
DATA(lt_errors) = lx_error->get_errors( ).
|
|
258
|
+
LOOP AT lt_errors INTO DATA(ls_err).
|
|
259
|
+
CLEAR ls_error.
|
|
260
|
+
ls_error-line = ls_err-line.
|
|
261
|
+
ls_error-column = ls_err-column.
|
|
262
|
+
" Use MESSAGE statement to get real error message
|
|
263
|
+
MESSAGE ID ls_err-arbgb TYPE 'E' NUMBER ls_err-msgnr
|
|
264
|
+
WITH ls_err-var1 ls_err-var2 ls_err-var3 ls_err-var4
|
|
265
|
+
INTO lv_err_msg.
|
|
266
|
+
ls_error-text = lv_err_msg.
|
|
267
|
+
APPEND ls_error TO ls_result-errors.
|
|
268
|
+
ENDLOOP.
|
|
269
|
+
|
|
270
|
+
" Also get warnings if any
|
|
271
|
+
DATA(lt_warn) = lx_error->get_warnings( ).
|
|
272
|
+
LOOP AT lt_warn INTO DATA(ls_warn2).
|
|
273
|
+
CLEAR ls_warning.
|
|
274
|
+
ls_warning-type = ls_warn2-type.
|
|
275
|
+
ls_warning-line = ls_warn2-line.
|
|
276
|
+
ls_warning-column = ls_warn2-column.
|
|
277
|
+
ls_warning-severity = ls_warn2-severity.
|
|
278
|
+
ls_warning-object_type = 'DDLS'.
|
|
279
|
+
ls_warning-object_name = lv_ddls_name.
|
|
280
|
+
" Use MESSAGE statement to get real warning message
|
|
281
|
+
MESSAGE ID ls_warn2-arbgb TYPE 'E' NUMBER ls_warn2-msgnr
|
|
282
|
+
WITH ls_warn2-var1 ls_warn2-var2 ls_warn2-var3 ls_warn2-var4
|
|
283
|
+
INTO lv_warn_msg.
|
|
284
|
+
ls_warning-message = lv_warn_msg.
|
|
285
|
+
APPEND ls_warning TO ls_result-warnings.
|
|
286
|
+
ENDLOOP.
|
|
287
|
+
|
|
288
|
+
ls_result-success = abap_false.
|
|
289
|
+
ENDTRY.
|
|
290
|
+
|
|
291
|
+
ls_result-error_count = lines( ls_result-errors ).
|
|
292
|
+
APPEND ls_result TO rt_results.
|
|
293
|
+
ENDLOOP.
|
|
93
294
|
ENDMETHOD.
|
|
94
295
|
|
|
95
296
|
METHOD run_syntax_check.
|
|
@@ -99,9 +300,11 @@ CLASS zcl_abgagt_command_inspect IMPLEMENTATION.
|
|
|
99
300
|
lo_inspection TYPE REF TO cl_ci_inspection,
|
|
100
301
|
lt_list TYPE scit_alvlist,
|
|
101
302
|
ls_error TYPE ty_error,
|
|
102
|
-
|
|
303
|
+
ls_list TYPE scir_alvlist,
|
|
304
|
+
lx_error TYPE REF TO cx_root,
|
|
305
|
+
ls_result TYPE ty_inspect_result.
|
|
103
306
|
|
|
104
|
-
|
|
307
|
+
rt_results = VALUE #( ).
|
|
105
308
|
|
|
106
309
|
TRY.
|
|
107
310
|
" Create unique name for inspection
|
|
@@ -145,14 +348,29 @@ CLASS zcl_abgagt_command_inspect IMPLEMENTATION.
|
|
|
145
348
|
" Get results
|
|
146
349
|
lo_inspection->plain_list( IMPORTING p_list = lt_list ).
|
|
147
350
|
|
|
148
|
-
"
|
|
149
|
-
LOOP AT
|
|
150
|
-
CLEAR
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
351
|
+
" Build result for each object
|
|
352
|
+
LOOP AT it_objects INTO DATA(ls_obj).
|
|
353
|
+
CLEAR ls_result.
|
|
354
|
+
ls_result-object_type = ls_obj-objtype.
|
|
355
|
+
ls_result-object_name = ls_obj-objname.
|
|
356
|
+
ls_result-success = abap_true.
|
|
357
|
+
|
|
358
|
+
" Get errors for this object
|
|
359
|
+
LOOP AT lt_list INTO ls_list WHERE objname = ls_obj-objname.
|
|
360
|
+
CLEAR ls_error.
|
|
361
|
+
ls_error-line = ls_list-line.
|
|
362
|
+
ls_error-column = ls_list-col.
|
|
363
|
+
ls_error-text = ls_list-text.
|
|
364
|
+
ls_error-word = ls_list-code.
|
|
365
|
+
APPEND ls_error TO ls_result-errors.
|
|
366
|
+
ENDLOOP.
|
|
367
|
+
|
|
368
|
+
ls_result-error_count = lines( ls_result-errors ).
|
|
369
|
+
IF ls_result-error_count > 0.
|
|
370
|
+
ls_result-success = abap_false.
|
|
371
|
+
ENDIF.
|
|
372
|
+
|
|
373
|
+
APPEND ls_result TO rt_results.
|
|
156
374
|
ENDLOOP.
|
|
157
375
|
|
|
158
376
|
" Cleanup
|
|
@@ -173,19 +391,20 @@ CLASS zcl_abgagt_command_inspect IMPLEMENTATION.
|
|
|
173
391
|
exists_in_objs = 5
|
|
174
392
|
OTHERS = 6 ).
|
|
175
393
|
|
|
176
|
-
rs_result-error_count = lines( rs_result-errors ).
|
|
177
|
-
IF rs_result-error_count > 0.
|
|
178
|
-
rs_result-success = abap_false.
|
|
179
|
-
ENDIF.
|
|
180
|
-
|
|
181
394
|
CATCH cx_root INTO lx_error.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
395
|
+
" Return error for all objects
|
|
396
|
+
LOOP AT it_objects INTO ls_obj.
|
|
397
|
+
CLEAR ls_result.
|
|
398
|
+
ls_result-object_type = ls_obj-objtype.
|
|
399
|
+
ls_result-object_name = ls_obj-objname.
|
|
400
|
+
ls_result-success = abap_false.
|
|
401
|
+
ls_error-line = '1'.
|
|
402
|
+
ls_error-column = '1'.
|
|
403
|
+
ls_error-text = lx_error->get_text( ).
|
|
404
|
+
APPEND ls_error TO ls_result-errors.
|
|
405
|
+
ls_result-error_count = 1.
|
|
406
|
+
APPEND ls_result TO rt_results.
|
|
407
|
+
ENDLOOP.
|
|
189
408
|
ENDTRY.
|
|
190
409
|
ENDMETHOD.
|
|
191
410
|
|
|
@@ -119,6 +119,8 @@ CLASS zcl_abgagt_command_view IMPLEMENTATION.
|
|
|
119
119
|
WHEN 'TABL'. ls_info-type_text = 'Table'.
|
|
120
120
|
WHEN 'STRU'. ls_info-type_text = 'Structure'.
|
|
121
121
|
WHEN 'DTEL'. ls_info-type_text = 'Data Element'.
|
|
122
|
+
WHEN 'TTYP'. ls_info-type_text = 'Table Type'.
|
|
123
|
+
WHEN 'DDLS'. ls_info-type_text = 'CDS View'.
|
|
122
124
|
WHEN OTHERS. ls_info-type_text = lv_type.
|
|
123
125
|
ENDCASE.
|
|
124
126
|
|
|
@@ -152,7 +154,7 @@ CLASS zcl_abgagt_command_view IMPLEMENTATION.
|
|
|
152
154
|
SELECT SINGLE object FROM tadir
|
|
153
155
|
INTO rv_type
|
|
154
156
|
WHERE obj_name = iv_name
|
|
155
|
-
AND object IN ('CLAS', 'INTF', 'TABL', 'DTEL', 'STRU').
|
|
157
|
+
AND object IN ('CLAS', 'INTF', 'TABL', 'DTEL', 'STRU', 'TTYP', 'DDLS').
|
|
156
158
|
ENDMETHOD.
|
|
157
159
|
|
|
158
160
|
METHOD get_object_info.
|
|
@@ -35,9 +35,9 @@ CLASS zcl_abgagt_util IMPLEMENTATION.
|
|
|
35
35
|
RETURN.
|
|
36
36
|
ENDIF.
|
|
37
37
|
|
|
38
|
-
" Last part should be 'ABAP' for verification
|
|
38
|
+
" Last part should be 'ABAP' or 'ASDDLS' for verification
|
|
39
39
|
READ TABLE lt_parts INDEX lv_part_count INTO DATA(lv_last).
|
|
40
|
-
IF lv_last <> 'ABAP'.
|
|
40
|
+
IF lv_last <> 'ABAP' AND lv_last <> 'ASDDLS'.
|
|
41
41
|
RETURN.
|
|
42
42
|
ENDIF.
|
|
43
43
|
|