abapgit-agent 1.14.4 → 1.15.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/abap/CLAUDE.md +55 -8
- package/abap/guidelines/abapgit-fugr.md +159 -0
- package/abap/guidelines/abapgit-xml-only.md +397 -0
- package/abap/guidelines/abapgit.md +29 -154
- package/abap/guidelines/abaplint-local.md +1 -1
- package/abap/guidelines/abaplint.md +1 -1
- package/abap/guidelines/branch-workflow.md +1 -1
- package/abap/guidelines/cds-testing.md +1 -1
- package/abap/guidelines/common-errors.md +1 -1
- package/abap/guidelines/debug-dump.md +1 -1
- package/abap/guidelines/debug-session.md +77 -56
- package/abap/guidelines/object-creation.md +1 -1
- package/abap/guidelines/probe-poc.md +1 -1
- package/abap/guidelines/run-probe-classes.md +1 -1
- package/abap/guidelines/unit-testable-code.md +1 -43
- package/abap/guidelines/workflow-detailed.md +1 -1
- package/package.json +1 -1
- package/src/commands/debug.js +49 -7
- package/src/commands/view.js +115 -6
- package/src/utils/abap-reference.js +2 -0
|
@@ -6,9 +6,10 @@ parent: ABAP Coding Guidelines
|
|
|
6
6
|
grand_parent: ABAP Development
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
# abapGit
|
|
9
|
+
# abapGit XML Metadata — CLAS, INTF, PROG
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
This guide covers objects that have **both a source file and an XML metadata file**.
|
|
12
|
+
For objects with no source file (XML only), see `abapgit-agent ref --topic abapgit-xml-only`.
|
|
12
13
|
|
|
13
14
|
## QUICK REFERENCE
|
|
14
15
|
|
|
@@ -16,19 +17,16 @@ Each ABAP object requires an XML metadata file for abapGit to understand how to
|
|
|
16
17
|
File Type | ABAP File | XML File
|
|
17
18
|
-------------------|------------------------------|-------------------
|
|
18
19
|
Class | zcl_*.clas.abap | zcl_*.clas.xml
|
|
19
|
-
Test Class | zcl_*.clas.testclasses.abap
|
|
20
|
-
Interface | zif_*.intf.abap
|
|
21
|
-
Program | z*.prog.abap
|
|
22
|
-
CDS View (DDLS) | zc_*.ddls.asddls
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
Data Element (DTEL)| (no .abap file) | z*.dtel.xml
|
|
26
|
-
Table Type (TTYP) | (no .abap file) | z*.ttyp.xml
|
|
20
|
+
Test Class | zcl_*.clas.testclasses.abap | zcl_*.clas.xml
|
|
21
|
+
Interface | zif_*.intf.abap | zif_*.intf.xml
|
|
22
|
+
Program | z*.prog.abap | z*.prog.xml
|
|
23
|
+
CDS View (DDLS) | zc_*.ddls.asddls | zc_*.ddls.xml
|
|
24
|
+
CDS Access Control | zc_*.dcls.asdcls | zc_*.dcls.xml
|
|
25
|
+
Function Group | z*fugr*.abap (6 files) | z*.fugr.xml
|
|
27
26
|
```
|
|
28
27
|
|
|
29
|
-
> **XML-only objects (TABL, STRU, DTEL, TTYP)
|
|
30
|
-
>
|
|
31
|
-
> `abapgit-agent pull --files abap/zmy_table.tabl.xml --sync-xml`
|
|
28
|
+
> **XML-only objects** (TABL, STRU, DTEL, TTYP, DOMA, MSAG) have **no ABAP source file** and are not covered here.
|
|
29
|
+
> See `abapgit-agent ref --topic abapgit-xml-only`.
|
|
32
30
|
|
|
33
31
|
> **CRITICAL: Always write XML files with a UTF-8 BOM (`\ufeff`) as the very first character**, before `<?xml ...`.
|
|
34
32
|
> Without the BOM, abapGit shows the object as **"M" (modified)** after every pull because the
|
|
@@ -37,7 +35,7 @@ Table Type (TTYP) | (no .abap file) | z*.ttyp.xml
|
|
|
37
35
|
> **CRITICAL: Only include fields that abapGit's serializer actually writes. Never add fields with
|
|
38
36
|
> default values.** Extra fields cause a permanent "M" (modified) diff. Follow the exact templates below.
|
|
39
37
|
|
|
40
|
-
**Searchable keywords**: class xml, interface xml,
|
|
38
|
+
**Searchable keywords**: class xml, interface xml, program xml, cds view xml, ddls, dcls, access control xml, function group xml, fugr, test class, exposure, serializer, abapgit
|
|
41
39
|
|
|
42
40
|
## Why XML Metadata?
|
|
43
41
|
|
|
@@ -244,53 +242,9 @@ abapGit's serializer **omits fields that have their default value**. Writing ext
|
|
|
244
242
|
|
|
245
243
|
---
|
|
246
244
|
|
|
247
|
-
### Table (TABL)
|
|
248
|
-
|
|
249
|
-
**Filename**: `src/zmy_table.tabl.xml`
|
|
250
|
-
|
|
251
|
-
> **XML-only object** — no `.abap` source file. Pull with: `pull --files src/zmy_table.tabl.xml`
|
|
252
|
-
|
|
253
|
-
```xml
|
|
254
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
255
|
-
<abapGit version="v1.0.0" serializer="LCL_OBJECT_TABL" serializer_version="v1.0.0">
|
|
256
|
-
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
257
|
-
<asx:values>
|
|
258
|
-
<DD02V>
|
|
259
|
-
<TABNAME>ZMY_TABLE</TABNAME>
|
|
260
|
-
<DDLANGUAGE>E</DDLANGUAGE>
|
|
261
|
-
<TABCLASS>TRANSP</TABCLASS>
|
|
262
|
-
<DDTEXT>Description of the table</DDTEXT>
|
|
263
|
-
<CONTFLAG>A</CONTFLAG>
|
|
264
|
-
</DD02V>
|
|
265
|
-
</asx:values>
|
|
266
|
-
</asx:abap>
|
|
267
|
-
</abapGit>
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
**Key Fields**:
|
|
271
|
-
- `TABNAME`: Table name
|
|
272
|
-
- `DDTEXT`: Description (**not** `DESCRIPT`)
|
|
273
|
-
- `TABCLASS`: `TRANSP`=Transparent (most common), `POOL`, `CLUSTER`
|
|
274
|
-
- `CONTFLAG`: Delivery class — `A`=Application, `C`=Customizing, `S`=System, `G`=Customizing protected
|
|
275
|
-
|
|
276
|
-
**Note**: When abapGit serializes an existing table it also writes `<DD09L>` (technical settings) and `<DD03P_TABLE>` (field definitions). These sections are generated automatically from the ABAP Dictionary on pull — you only need the `<DD02V>` header when creating a new table. After the first pull the XML will be expanded with those sections.
|
|
277
|
-
|
|
278
|
-
**`DD03P` field-level rules** (apply when editing an existing table XML that includes `<DD03P_TABLE>`):
|
|
279
|
-
|
|
280
|
-
| Rule | Detail |
|
|
281
|
-
|---|---|
|
|
282
|
-
| `SHLPORIGIN` | Include `<SHLPORIGIN>D</SHLPORIGIN>` on fields where the Dictionary provides a value help (e.g. fields with a domain that has fixed values or a search help). Omit on fields with no value help. |
|
|
283
|
-
| Field order for raw-type fields | For fields with no `ROLLNAME` (raw type, e.g. `CHAR`, `NUMC`), the serializer writes `<MASK>` **before** `<DDTEXT>`. For fields with a `ROLLNAME`, only `ROLLNAME` appears (no `MASK` or `DDTEXT`). |
|
|
284
|
-
|
|
285
|
-
**Why this matters**: Missing `SHLPORIGIN` or wrong `MASK`/`DDTEXT` order causes a permanent diff between git and the system-serialized XML.
|
|
286
|
-
|
|
287
|
-
---
|
|
288
|
-
|
|
289
245
|
### CDS View / View Entity (DDLS)
|
|
290
246
|
|
|
291
|
-
**
|
|
292
|
-
|
|
293
|
-
The XML format is identical for both types — only `SOURCE_TYPE` differs:
|
|
247
|
+
**Files**: `src/zc_my_view.ddls.asddls` (source) + `src/zc_my_view.ddls.xml` (metadata)
|
|
294
248
|
|
|
295
249
|
```xml
|
|
296
250
|
<?xml version="1.0" encoding="utf-8"?>
|
|
@@ -308,121 +262,42 @@ The XML format is identical for both types — only `SOURCE_TYPE` differs:
|
|
|
308
262
|
</abapGit>
|
|
309
263
|
```
|
|
310
264
|
|
|
311
|
-
- `SOURCE_TYPE W` → View Entity (`define view entity`, modern
|
|
312
|
-
- `SOURCE_TYPE V` → View (`define view` + `@AbapCatalog.sqlViewName`, legacy
|
|
265
|
+
- `SOURCE_TYPE W` → View Entity (`define view entity`, modern — **use by default**)
|
|
266
|
+
- `SOURCE_TYPE V` → View (`define view` + `@AbapCatalog.sqlViewName`, legacy)
|
|
313
267
|
|
|
314
|
-
→ For DDL source syntax
|
|
268
|
+
→ For DDL source syntax: `abapgit-agent ref --topic cds-abapgit`
|
|
315
269
|
|
|
316
270
|
---
|
|
317
271
|
|
|
318
|
-
###
|
|
319
|
-
|
|
320
|
-
**Filename**: `src/zmy_dtel.dtel.xml`
|
|
272
|
+
### CDS Access Control (DCLS)
|
|
321
273
|
|
|
322
|
-
|
|
274
|
+
**Files**: `src/zc_my_view.dcls.asdcls` (source) + `src/zc_my_view.dcls.xml` (metadata)
|
|
323
275
|
|
|
324
276
|
```xml
|
|
325
277
|
<?xml version="1.0" encoding="utf-8"?>
|
|
326
|
-
<abapGit version="v1.0.0" serializer="
|
|
278
|
+
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DCLS" serializer_version="v1.0.0">
|
|
327
279
|
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
328
280
|
<asx:values>
|
|
329
|
-
<
|
|
330
|
-
<
|
|
331
|
-
<
|
|
332
|
-
<DDTEXT>
|
|
333
|
-
|
|
334
|
-
<SCRTEXT_S>Short text</SCRTEXT_S>
|
|
335
|
-
<SCRTEXT_M>Medium text</SCRTEXT_M>
|
|
336
|
-
<SCRTEXT_L>Long description text</SCRTEXT_L>
|
|
337
|
-
<DTELMASTER>E</DTELMASTER>
|
|
338
|
-
<DATATYPE>CHAR</DATATYPE>
|
|
339
|
-
<LENG>000010</LENG>
|
|
340
|
-
</DD04V>
|
|
281
|
+
<DCLS>
|
|
282
|
+
<DCLNAME>ZC_MY_VIEW</DCLNAME>
|
|
283
|
+
<DCLLANGUAGE>E</DCLLANGUAGE>
|
|
284
|
+
<DDTEXT>Access control for ZC_MY_VIEW</DDTEXT>
|
|
285
|
+
</DCLS>
|
|
341
286
|
</asx:values>
|
|
342
287
|
</asx:abap>
|
|
343
288
|
</abapGit>
|
|
344
289
|
```
|
|
345
290
|
|
|
346
|
-
|
|
347
|
-
-
|
|
348
|
-
- `DDTEXT`: Description (**not** `DESCRIPT`)
|
|
349
|
-
- `REPTEXT` / `SCRTEXT_S` / `SCRTEXT_M` / `SCRTEXT_L`: Field labels (report heading, short, medium, long)
|
|
350
|
-
- `DTELMASTER`: Language key for label master (`E` for English)
|
|
351
|
-
- `DATATYPE`: Data type (`CHAR`, `NUMC`, `DATS`, `TIMS`, `INT4`, etc.)
|
|
352
|
-
- `LENG`: Length padded to 6 digits (e.g. `000010` for 10 characters)
|
|
353
|
-
|
|
354
|
-
**Omit `<PARAMID>`** unless you specifically need a SET/GET parameter ID — the serializer omits it when empty, so including an empty tag causes a permanent diff.
|
|
291
|
+
- `DCLNAME` matches the CDS view name
|
|
292
|
+
- Source file contains the DCL (`@MappingRole ... define role ...`)
|
|
355
293
|
|
|
356
294
|
---
|
|
357
295
|
|
|
358
|
-
###
|
|
359
|
-
|
|
360
|
-
**Filename**: `src/zmy_struct.stru.xml`
|
|
296
|
+
### Function Group (FUGR)
|
|
361
297
|
|
|
362
|
-
|
|
363
|
-
> Pull with: `pull --files src/zmy_struct.stru.xml`
|
|
298
|
+
FUGR serializes as multiple files (main XML + TOP include + SAPL include + one source file per FM). The format is straightforward for screenless function groups — Claude can generate it from scratch.
|
|
364
299
|
|
|
365
|
-
|
|
366
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
367
|
-
<abapGit version="v1.0.0" serializer="LCL_OBJECT_TABL" serializer_version="v1.0.0">
|
|
368
|
-
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
369
|
-
<asx:values>
|
|
370
|
-
<DD02V>
|
|
371
|
-
<TABNAME>ZMY_STRUCT</TABNAME>
|
|
372
|
-
<DDLANGUAGE>E</DDLANGUAGE>
|
|
373
|
-
<TABCLASS>INTTAB</TABCLASS>
|
|
374
|
-
<DDTEXT>Description of the structure</DDTEXT>
|
|
375
|
-
<CONTFLAG>A</CONTFLAG>
|
|
376
|
-
</DD02V>
|
|
377
|
-
</asx:values>
|
|
378
|
-
</asx:abap>
|
|
379
|
-
</abapGit>
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
**Key difference from TABL**: `TABCLASS` is `INTTAB` (internal table / structure) instead of `TRANSP`.
|
|
383
|
-
|
|
384
|
-
**Note**: Like TABL, after the first pull abapGit expands the XML with `<DD03P_TABLE>` field definitions. When creating a new structure you only need the `<DD02V>` header.
|
|
385
|
-
|
|
386
|
-
---
|
|
387
|
-
|
|
388
|
-
### Table Type (TTYP)
|
|
389
|
-
|
|
390
|
-
**Filename**: `src/zmy_ttyp.ttyp.xml`
|
|
391
|
-
|
|
392
|
-
> **XML-only object** — no `.abap` source file.
|
|
393
|
-
> Pull with: `pull --files src/zmy_ttyp.ttyp.xml`
|
|
394
|
-
|
|
395
|
-
```xml
|
|
396
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
397
|
-
<abapGit version="v1.0.0" serializer="LCL_OBJECT_TTYP" serializer_version="v1.0.0">
|
|
398
|
-
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
399
|
-
<asx:values>
|
|
400
|
-
<DD40V>
|
|
401
|
-
<TYPENAME>ZMY_TTYP</TYPENAME>
|
|
402
|
-
<DDLANGUAGE>E</DDLANGUAGE>
|
|
403
|
-
<DDTEXT>Description of table type</DDTEXT>
|
|
404
|
-
<ROWTYPE>ZMY_STRUCT</ROWTYPE>
|
|
405
|
-
<ROWKIND>S</ROWKIND>
|
|
406
|
-
<DATATYPE>TABLE_T</DATATYPE>
|
|
407
|
-
<ACCESSMODE>T</ACCESSMODE>
|
|
408
|
-
<KEYDEF>D</KEYDEF>
|
|
409
|
-
<KEYKIND>N</KEYKIND>
|
|
410
|
-
</DD40V>
|
|
411
|
-
</asx:values>
|
|
412
|
-
</asx:abap>
|
|
413
|
-
</abapGit>
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
**Key Fields**:
|
|
417
|
-
- `TYPENAME`: Table type name
|
|
418
|
-
- `ROWTYPE`: Row type (a structure or data element name)
|
|
419
|
-
- `ROWKIND`: Row kind — `S`=Structure/Type, `D`=Data element, `R`=Reference
|
|
420
|
-
- `DATATYPE`: Always `TABLE_T` for table types
|
|
421
|
-
- `ACCESSMODE`: Table kind — `T`=Standard, `S`=Sorted, `H`=Hashed
|
|
422
|
-
- `KEYDEF`: Key definition — `D`=Default (standard key), `K`=User-defined
|
|
423
|
-
- `KEYKIND`: Key uniqueness — `N`=Non-unique, `U`=Unique
|
|
424
|
-
|
|
425
|
-
**Note**: After the first pull abapGit may expand the XML with `<DD42V>` (component definitions) if key fields are explicitly defined.
|
|
300
|
+
→ Full template and file-set rules: `abapgit-agent ref --topic abapgit-fugr`
|
|
426
301
|
|
|
427
302
|
---
|
|
428
303
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
layout: default
|
|
3
3
|
title: Debug Session Guide
|
|
4
|
-
nav_order:
|
|
4
|
+
nav_order: 15
|
|
5
5
|
parent: ABAP Coding Guidelines
|
|
6
6
|
grand_parent: ABAP Development
|
|
7
7
|
---
|
|
@@ -17,7 +17,7 @@ Use `debug` when:
|
|
|
17
17
|
|
|
18
18
|
**Step 1 — set a breakpoint** on the first executable statement you want to inspect:
|
|
19
19
|
|
|
20
|
-
Use `view --objects ZCL_MY_CLASS --full --lines` to see the full source with
|
|
20
|
+
Use `view --objects ZCL_MY_CLASS --full --lines` to see the full source with line numbers and ready-to-use `debug set` commands:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
23
|
abapgit-agent view --objects ZCL_MY_CLASS --full --lines
|
|
@@ -25,16 +25,11 @@ abapgit-agent view --objects ZCL_MY_CLASS --full --lines
|
|
|
25
25
|
|
|
26
26
|
> **Tip**: `view --full` (without `--lines`) shows the same full source as clean readable code without line numbers — useful for understanding logic. Add `--lines` when you need line numbers for breakpoints.
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
- **G** = assembled-source global line → use with `debug set --objects CLASS:G` or `debug set --files src/cls.clas.abap:G`
|
|
30
|
-
- **[N]** = include-relative (restarts at 1 per method) → for code navigation only, not for breakpoints
|
|
28
|
+
The output varies by section type:
|
|
31
29
|
|
|
32
|
-
|
|
30
|
+
**Regular methods (CM\* sections)** — dual line numbers `G [N]` per line, with a `debug set` hint at the method header:
|
|
33
31
|
|
|
34
32
|
```
|
|
35
|
-
1 CLASS zcl_my_class DEFINITION.
|
|
36
|
-
2 PUBLIC SECTION.
|
|
37
|
-
3 ENDCLASS.
|
|
38
33
|
* ---- Method: EXECUTE (CM002) — breakpoint: debug set --objects ZCL_MY_CLASS:9 ----
|
|
39
34
|
7 [ 1] METHOD execute.
|
|
40
35
|
8 [ 2] DATA lv_x TYPE i.
|
|
@@ -42,44 +37,91 @@ The method header shows the ready-to-use `debug set` command pointing to the fir
|
|
|
42
37
|
10 [ 4] ENDMETHOD.
|
|
43
38
|
```
|
|
44
39
|
|
|
45
|
-
**
|
|
40
|
+
- **G** = assembled-source global line → use with `debug set --objects CLASS:G` or `--files src/cls.clas.abap:G`
|
|
41
|
+
- **[N]** = include-relative (restarts at 1 per method) → for code navigation only, not for breakpoints
|
|
42
|
+
|
|
43
|
+
The hint already points to the first **executable** line, skipping `METHOD`, blank lines, comments, and all declaration forms (`DATA`, `DATA:`, `DATA(`).
|
|
44
|
+
|
|
45
|
+
**Two scenarios for CM* methods:**
|
|
46
46
|
|
|
47
47
|
| Scenario | Command |
|
|
48
48
|
|---|---|
|
|
49
49
|
| Source available locally (your own classes) | `debug set --files src/zcl_my_class.clas.abap:9` |
|
|
50
50
|
| No local source (abapGit library, SAP standard) | `debug set --objects ZCL_MY_CLASS:9` |
|
|
51
51
|
|
|
52
|
-
Both use the same assembled-source global line number **G** shown in the output. To set a breakpoint at `lv_x = 1.` (global line 9):
|
|
53
52
|
```bash
|
|
54
|
-
# With local file:
|
|
55
|
-
abapgit-agent debug set --files src/zcl_my_class.clas.abap:9
|
|
56
|
-
# Without local file:
|
|
57
53
|
abapgit-agent debug set --objects ZCL_MY_CLASS:9
|
|
58
54
|
abapgit-agent debug list # confirm it was registered
|
|
59
55
|
```
|
|
60
56
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
57
|
+
**Unit test methods (CCAU section)** and **local class methods (CCIMP section)** live in separate ADT includes — they cannot be addressed by the assembled-source global line. Their sections show section-local line numbers with a `--include` hint per method:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
* ---- Section: Unit Test (from .clas.testclasses.abap) ----
|
|
61
|
+
* ---- Method: SETUP — breakpoint: debug set --objects ZCL_MY_CLASS:12 --include testclasses ----
|
|
62
|
+
10 METHOD setup.
|
|
63
|
+
11 DATA lv_x TYPE i.
|
|
64
|
+
12 mo_cut = NEW #( ).
|
|
65
|
+
13 ENDMETHOD.
|
|
66
|
+
* ---- Method: TEST_PULL_SUCCESS — breakpoint: debug set --objects ZCL_MY_CLASS:18 --include testclasses ----
|
|
67
|
+
15 METHOD test_pull_success.
|
|
68
|
+
...
|
|
69
|
+
|
|
70
|
+
* ---- Section: Local Implementations (from .clas.locals_imp.abap) ----
|
|
71
|
+
* ---- Method: ZIF_FOO~DO_SOMETHING — breakpoint: debug set --objects ZCL_MY_CLASS:5 --include locals_imp ----
|
|
72
|
+
3 METHOD zif_foo~do_something.
|
|
73
|
+
4 DATA lv_x TYPE i.
|
|
74
|
+
5 lv_x = iv_input.
|
|
75
|
+
6 ENDMETHOD.
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The line numbers in these sections are **section-local** (same coordinate system as the `.clas.testclasses.abap` / `.clas.locals_imp.abap` file). Use the `--include` flag to target the correct ADT sub-include:
|
|
79
|
+
|
|
80
|
+
| Section | `--include` value |
|
|
81
|
+
|---|---|
|
|
82
|
+
| Unit Test (`.clas.testclasses.abap`) | `testclasses` |
|
|
83
|
+
| Local Implementations (`.clas.locals_imp.abap`) | `locals_imp` |
|
|
84
|
+
| Local Definitions (`.clas.locals_def.abap`) | `locals_def` |
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# Unit test method:
|
|
88
|
+
abapgit-agent debug set --objects ZCL_MY_CLASS:12 --include testclasses
|
|
89
|
+
# Local class method:
|
|
90
|
+
abapgit-agent debug set --objects ZCL_MY_CLASS:5 --include locals_imp
|
|
91
|
+
abapgit-agent debug list # confirm both were registered
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Function module (FUGR) methods** live in per-FM source includes (`L<GROUP>U<NN>`). Use `view` with `--full --fm <name> --lines` to see the source and breakpoint hint:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
abapgit-agent view --objects SUSR --type FUGR --full --fm AUTHORITY_CHECK --lines
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
* ---- FM: AUTHORITY_CHECK (LSUSRU04) — breakpoint: debug set --objects LSUSRU04:50 ----
|
|
102
|
+
1 function authority_check.
|
|
103
|
+
...
|
|
104
|
+
36 constants:
|
|
105
|
+
...
|
|
106
|
+
45 data:
|
|
107
|
+
...
|
|
108
|
+
50 ld_syuname = cl_abap_syst=>get_user_name( ).
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
abapgit-agent debug set --objects LSUSRU04:50
|
|
113
|
+
abapgit-agent debug list # confirm it was registered
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
> **Line number must point to an executable statement.** The hints already skip `METHOD`, blank lines, comments (`"`, `*`), and all declaration forms (`DATA`, `DATA:`, `DATA(`). One case still requires manual attention:
|
|
80
117
|
>
|
|
81
|
-
>
|
|
82
|
-
>
|
|
118
|
+
> **Multi-line inline `DATA(x) = call(`** — the ABAP debugger treats the whole expression as a declaration. Set the breakpoint on the **next standalone statement** after the closing `).`:
|
|
119
|
+
> ```
|
|
120
|
+
> 100 [ 1] DATA(ls_checks) = prepare_deserialize_checks( ← NOT valid (inline decl)
|
|
121
|
+
> 101 [ 2] it_files = it_files ← NOT valid (continuation)
|
|
122
|
+
> 104 [ 5] io_repo_desc = lo_repo_desc1 ). ← NOT valid (continuation)
|
|
123
|
+
> 106 [ 7] mo_repo->create_new_log( ). ← valid ✅ (use global 106)
|
|
124
|
+
> ```
|
|
83
125
|
|
|
84
126
|
**Step 2 — attach and trigger**
|
|
85
127
|
|
|
@@ -257,24 +299,3 @@ HTTP Request
|
|
|
257
299
|
> inside `find_remote_dot_abapgit()` via `COMMIT WORK AND WAIT` — i.e., the lock is released before
|
|
258
300
|
> BP2 fires. There is no active lock between BP1 and the end of CM00L.
|
|
259
301
|
|
|
260
|
-
### Known Limitations and Planned Improvements
|
|
261
|
-
|
|
262
|
-
The following issues were identified during a live debugging session (2026-03) and should be fixed to make future debugging easier:
|
|
263
|
-
|
|
264
|
-
#### ~~1. `view --full` global line numbers don't match ADT line numbers~~ ✅ Fixed
|
|
265
|
-
|
|
266
|
-
**Fixed**: `view --full --lines` now shows dual line numbers per line: `G [N] code` where G is the assembled-source global line (usable directly with `--objects CLASS:G` or `--files src/cls.clas.abap:G`) and `[N]` is the include-relative counter for navigation. Method headers show the ready-to-use `debug set --objects CLASS:G` command pointing to the first executable statement. `view --full` (without `--lines`) shows the same full source as clean readable code without line numbers.
|
|
267
|
-
|
|
268
|
-
Global line numbers are computed **client-side** in Node.js, not in ABAP:
|
|
269
|
-
- **Own classes** (local `.clas.abap` file exists): reads the local file — guaranteed exact match with ADT
|
|
270
|
-
- **Library classes** (no local file, e.g. abapGit): fetches assembled source from `/sap/bc/adt/oo/classes/<name>/source/main`
|
|
271
|
-
|
|
272
|
-
Both strategies scan for `METHOD <name>.` as the first token on the line to find `global_start`. The method header hint automatically points to the **first executable statement** (skipping the `METHOD` line, blank lines, and `DATA`/`FINAL`/`TYPES`/`CONSTANTS` declarations) so it can be used directly without adjustment.
|
|
273
|
-
|
|
274
|
-
#### ~~2. Include-relative breakpoint form (`=====CMxxx:N`) not implemented in the CLI~~ ✅ Superseded
|
|
275
|
-
|
|
276
|
-
**Superseded**: The `/programs/includes/` ADT endpoint was found to not accept breakpoints for OO class method includes — ADT only accepts the `/oo/classes/.../source/main` URI with assembled-source line numbers. The `=====CMxxx:N` approach was dropped. Instead, `view --full --lines` now provides the correct assembled-source global line number G directly, and both `--objects CLASS:G` and `--files src/cls.clas.abap:G` work reliably.
|
|
277
|
-
|
|
278
|
-
#### ~~3. `stepContinue` re-attach pattern missing from docs~~ ✅ Fixed
|
|
279
|
-
|
|
280
|
-
**Fixed**: Step 3 of the debug guide now documents the two possible return values of `step --type continue` and includes the re-attach pattern for when the program hits a second breakpoint instead of finishing.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
layout: default
|
|
3
3
|
title: Unit Testable Code
|
|
4
|
-
nav_order:
|
|
4
|
+
nav_order: 13
|
|
5
5
|
parent: ABAP Coding Guidelines
|
|
6
6
|
grand_parent: ABAP Development
|
|
7
7
|
---
|
|
@@ -557,45 +557,3 @@ DATA(lo_command) = NEW zcl_abgagt_command_pull(
|
|
|
557
557
|
io_agent = NEW zcl_abgagt_agent( ) ).
|
|
558
558
|
```
|
|
559
559
|
|
|
560
|
-
**Test usage:**
|
|
561
|
-
```abap
|
|
562
|
-
CLASS ltd_mock_agent DEFINITION FOR TESTING.
|
|
563
|
-
PUBLIC SECTION.
|
|
564
|
-
INTERFACES zif_abgagt_agent PARTIALLY IMPLEMENTED.
|
|
565
|
-
ENDCLASS.
|
|
566
|
-
|
|
567
|
-
CLASS ltd_mock_agent IMPLEMENTATION.
|
|
568
|
-
METHOD zif_abgagt_agent~pull.
|
|
569
|
-
rs_result-success = abap_true.
|
|
570
|
-
rs_result-message = 'Mocked success'.
|
|
571
|
-
ENDMETHOD.
|
|
572
|
-
ENDCLASS.
|
|
573
|
-
|
|
574
|
-
CLASS ltcl_test DEFINITION FOR TESTING.
|
|
575
|
-
METHOD test_pull_success.
|
|
576
|
-
DATA(lo_mock) = NEW ltd_mock_agent( ).
|
|
577
|
-
DATA(lo_cut) = NEW zcl_abgagt_command_pull( io_agent = lo_mock ).
|
|
578
|
-
|
|
579
|
-
DATA(lv_result) = lo_cut->execute( ... ).
|
|
580
|
-
|
|
581
|
-
" Assert mocked behavior
|
|
582
|
-
ENDMETHOD.
|
|
583
|
-
ENDCLASS.
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
---
|
|
587
|
-
|
|
588
|
-
## Key Takeaways
|
|
589
|
-
|
|
590
|
-
1. **Always use interfaces** for dependencies
|
|
591
|
-
2. **Use constructor injection** to pass dependencies
|
|
592
|
-
3. **Never hardcode `NEW` for dependencies** - pass them in
|
|
593
|
-
4. **Avoid static calls** - use instance methods with injected dependencies
|
|
594
|
-
5. **Keep constructors simple** - only assign dependencies
|
|
595
|
-
|
|
596
|
-
Following these guidelines ensures that:
|
|
597
|
-
- Unit tests can mock all dependencies
|
|
598
|
-
- Tests run fast without external systems
|
|
599
|
-
- Tests are reliable and repeatable
|
|
600
|
-
- Error conditions can be tested easily
|
|
601
|
-
- Code is modular and loosely coupled
|