abapgit-agent 1.14.5 → 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 +34 -4
- package/abap/guidelines/abapgit-fugr.md +159 -0
- package/abap/guidelines/abapgit-xml-only.md +397 -0
- package/abap/guidelines/abapgit.md +29 -304
- 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 +23 -24
- 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 +9 -0
- package/src/commands/view.js +63 -2
- 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,203 +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
|
-
#### Text Tables and Foreign Keys
|
|
288
|
-
|
|
289
|
-
A **text table** stores translatable texts for another table (the "main table"). It shares the same key fields as the main table plus a language field (`SPRAS` with data element `SPRAS`, or `LANGU` with data element `LANGU`).
|
|
290
|
-
|
|
291
|
-
**How to recognise a text table relationship in the XML:**
|
|
292
|
-
- `<DD09L>` has `<UEBERSETZ>X</UEBERSETZ>` — marks this table as a text table
|
|
293
|
-
- `<DD08V>` has `<FRKART>TEXT</FRKART>` — marks the foreign key as a text-table relationship (ordinary foreign keys omit this field)
|
|
294
|
-
|
|
295
|
-
**Three sections required in the text table XML:**
|
|
296
|
-
|
|
297
|
-
| Section | Purpose |
|
|
298
|
-
|---|---|
|
|
299
|
-
| `DD03P_TABLE` | Field definitions — same key fields as main table + language field + text fields |
|
|
300
|
-
| `DD05M_TABLE` | Foreign key field mappings — one entry per key field of the main table (excluding the language field) |
|
|
301
|
-
| `DD08V_TABLE` | Foreign key relationship — one entry with `FRKART>TEXT` |
|
|
302
|
-
|
|
303
|
-
**`DD03P` rules for the text table:**
|
|
304
|
-
- First key field (`MANDT`) must have `<CHECKTABLE>` pointing to the main table and `<SHLPORIGIN>P</SHLPORIGIN>`
|
|
305
|
-
- Language field (`SPRAS` or `LANGU`) gets `<SHLPORIGIN>D</SHLPORIGIN>` (added by serializer after activation — omit when writing manually)
|
|
306
|
-
|
|
307
|
-
**`DD05M` rules:**
|
|
308
|
-
- `FIELDNAME` = the anchor field in the text table (typically `MANDT` — the first key field)
|
|
309
|
-
- `FORTABLE` = text table name
|
|
310
|
-
- `FORKEY` = key field name in the main table
|
|
311
|
-
- `CHECKFIELD` = same as `FORKEY`
|
|
312
|
-
- `CHECKTABLE` = main table name
|
|
313
|
-
- `PRIMPOS` = position sequence (0001, 0002, …)
|
|
314
|
-
- `DOMNAME` / `DATATYPE` = domain and type of the check field (omit `DOMNAME` if unknown — serializer fills it in)
|
|
315
|
-
|
|
316
|
-
**`DD08V` rules:**
|
|
317
|
-
- `FIELDNAME` = same anchor field as used in `DD05M` (typically `MANDT`)
|
|
318
|
-
- `CHECKTABLE` = main table name
|
|
319
|
-
- `FRKART` = `TEXT` (text table) or omit (ordinary foreign key)
|
|
320
|
-
- `CARD` = `CN` (n:1 cardinality)
|
|
321
|
-
- `CARDLEFT` = `1`
|
|
322
|
-
|
|
323
|
-
**Example — text table `ZMY_TABLE_T` for main table `ZMY_TABLE` (keys: MANDT, ID1, ID2):**
|
|
324
|
-
|
|
325
|
-
```xml
|
|
326
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
327
|
-
<abapGit version="v1.0.0" serializer="LCL_OBJECT_TABL" serializer_version="v1.0.0">
|
|
328
|
-
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
329
|
-
<asx:values>
|
|
330
|
-
<DD02V>
|
|
331
|
-
<TABNAME>ZMY_TABLE_T</TABNAME>
|
|
332
|
-
<DDLANGUAGE>E</DDLANGUAGE>
|
|
333
|
-
<TABCLASS>TRANSP</TABCLASS>
|
|
334
|
-
<CLIDEP>X</CLIDEP>
|
|
335
|
-
<DDTEXT>My Table: Texts</DDTEXT>
|
|
336
|
-
<CONTFLAG>C</CONTFLAG>
|
|
337
|
-
</DD02V>
|
|
338
|
-
<DD09L>
|
|
339
|
-
<TABNAME>ZMY_TABLE_T</TABNAME>
|
|
340
|
-
<AS4LOCAL>A</AS4LOCAL>
|
|
341
|
-
<TABKAT>0</TABKAT>
|
|
342
|
-
<TABART>APPL0</TABART>
|
|
343
|
-
<UEBERSETZ>X</UEBERSETZ>
|
|
344
|
-
<BUFALLOW>N</BUFALLOW>
|
|
345
|
-
</DD09L>
|
|
346
|
-
<DD03P_TABLE>
|
|
347
|
-
<DD03P>
|
|
348
|
-
<FIELDNAME>MANDT</FIELDNAME>
|
|
349
|
-
<KEYFLAG>X</KEYFLAG>
|
|
350
|
-
<ROLLNAME>MANDT</ROLLNAME>
|
|
351
|
-
<CHECKTABLE>ZMY_TABLE</CHECKTABLE>
|
|
352
|
-
<ADMINFIELD>0</ADMINFIELD>
|
|
353
|
-
<NOTNULL>X</NOTNULL>
|
|
354
|
-
<SHLPORIGIN>P</SHLPORIGIN>
|
|
355
|
-
<COMPTYPE>E</COMPTYPE>
|
|
356
|
-
</DD03P>
|
|
357
|
-
<DD03P>
|
|
358
|
-
<FIELDNAME>ID1</FIELDNAME>
|
|
359
|
-
<KEYFLAG>X</KEYFLAG>
|
|
360
|
-
<ROLLNAME>ZMY_ID1</ROLLNAME>
|
|
361
|
-
<ADMINFIELD>0</ADMINFIELD>
|
|
362
|
-
<NOTNULL>X</NOTNULL>
|
|
363
|
-
<COMPTYPE>E</COMPTYPE>
|
|
364
|
-
</DD03P>
|
|
365
|
-
<DD03P>
|
|
366
|
-
<FIELDNAME>ID2</FIELDNAME>
|
|
367
|
-
<KEYFLAG>X</KEYFLAG>
|
|
368
|
-
<ROLLNAME>ZMY_ID2</ROLLNAME>
|
|
369
|
-
<ADMINFIELD>0</ADMINFIELD>
|
|
370
|
-
<NOTNULL>X</NOTNULL>
|
|
371
|
-
<COMPTYPE>E</COMPTYPE>
|
|
372
|
-
</DD03P>
|
|
373
|
-
<DD03P>
|
|
374
|
-
<FIELDNAME>SPRAS</FIELDNAME>
|
|
375
|
-
<KEYFLAG>X</KEYFLAG>
|
|
376
|
-
<ROLLNAME>SPRAS</ROLLNAME>
|
|
377
|
-
<ADMINFIELD>0</ADMINFIELD>
|
|
378
|
-
<NOTNULL>X</NOTNULL>
|
|
379
|
-
<COMPTYPE>E</COMPTYPE>
|
|
380
|
-
</DD03P>
|
|
381
|
-
<DD03P>
|
|
382
|
-
<FIELDNAME>DESCRIPTION</FIELDNAME>
|
|
383
|
-
<ROLLNAME>ZMY_DESCRIPTION</ROLLNAME>
|
|
384
|
-
<ADMINFIELD>0</ADMINFIELD>
|
|
385
|
-
<COMPTYPE>E</COMPTYPE>
|
|
386
|
-
</DD03P>
|
|
387
|
-
</DD03P_TABLE>
|
|
388
|
-
<DD05M_TABLE>
|
|
389
|
-
<DD05M>
|
|
390
|
-
<FIELDNAME>MANDT</FIELDNAME>
|
|
391
|
-
<FORTABLE>ZMY_TABLE_T</FORTABLE>
|
|
392
|
-
<FORKEY>MANDT</FORKEY>
|
|
393
|
-
<CHECKTABLE>ZMY_TABLE</CHECKTABLE>
|
|
394
|
-
<CHECKFIELD>MANDT</CHECKFIELD>
|
|
395
|
-
<PRIMPOS>0001</PRIMPOS>
|
|
396
|
-
<DOMNAME>MANDT</DOMNAME>
|
|
397
|
-
<DATATYPE>CLNT</DATATYPE>
|
|
398
|
-
</DD05M>
|
|
399
|
-
<DD05M>
|
|
400
|
-
<FIELDNAME>MANDT</FIELDNAME>
|
|
401
|
-
<FORTABLE>ZMY_TABLE_T</FORTABLE>
|
|
402
|
-
<FORKEY>ID1</FORKEY>
|
|
403
|
-
<CHECKTABLE>ZMY_TABLE</CHECKTABLE>
|
|
404
|
-
<CHECKFIELD>ID1</CHECKFIELD>
|
|
405
|
-
<PRIMPOS>0002</PRIMPOS>
|
|
406
|
-
<DATATYPE>CHAR</DATATYPE>
|
|
407
|
-
</DD05M>
|
|
408
|
-
<DD05M>
|
|
409
|
-
<FIELDNAME>MANDT</FIELDNAME>
|
|
410
|
-
<FORTABLE>ZMY_TABLE_T</FORTABLE>
|
|
411
|
-
<FORKEY>ID2</FORKEY>
|
|
412
|
-
<CHECKTABLE>ZMY_TABLE</CHECKTABLE>
|
|
413
|
-
<CHECKFIELD>ID2</CHECKFIELD>
|
|
414
|
-
<PRIMPOS>0003</PRIMPOS>
|
|
415
|
-
<DATATYPE>CHAR</DATATYPE>
|
|
416
|
-
</DD05M>
|
|
417
|
-
</DD05M_TABLE>
|
|
418
|
-
<DD08V_TABLE>
|
|
419
|
-
<DD08V>
|
|
420
|
-
<FIELDNAME>MANDT</FIELDNAME>
|
|
421
|
-
<CHECKTABLE>ZMY_TABLE</CHECKTABLE>
|
|
422
|
-
<FRKART>TEXT</FRKART>
|
|
423
|
-
<CARD>CN</CARD>
|
|
424
|
-
<CARDLEFT>1</CARDLEFT>
|
|
425
|
-
</DD08V>
|
|
426
|
-
</DD08V_TABLE>
|
|
427
|
-
</asx:values>
|
|
428
|
-
</asx:abap>
|
|
429
|
-
</abapGit>
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
**Key rules:**
|
|
433
|
-
- Always activate the main table **before** the text table — the foreign key check requires the main table to exist
|
|
434
|
-
- Language field can be `SPRAS` (data element `SPRAS`) or `LANGU` (data element `LANGU`) — both are recognised by the system
|
|
435
|
-
- For an **ordinary foreign key** (not a text table): same `DD05M`/`DD08V` structure, but omit `<FRKART>TEXT</FRKART>` from `DD08V`
|
|
436
|
-
|
|
437
|
-
---
|
|
438
|
-
|
|
439
245
|
### CDS View / View Entity (DDLS)
|
|
440
246
|
|
|
441
|
-
**
|
|
442
|
-
|
|
443
|
-
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)
|
|
444
248
|
|
|
445
249
|
```xml
|
|
446
250
|
<?xml version="1.0" encoding="utf-8"?>
|
|
@@ -458,121 +262,42 @@ The XML format is identical for both types — only `SOURCE_TYPE` differs:
|
|
|
458
262
|
</abapGit>
|
|
459
263
|
```
|
|
460
264
|
|
|
461
|
-
- `SOURCE_TYPE W` → View Entity (`define view entity`, modern
|
|
462
|
-
- `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)
|
|
463
267
|
|
|
464
|
-
→ For DDL source syntax
|
|
268
|
+
→ For DDL source syntax: `abapgit-agent ref --topic cds-abapgit`
|
|
465
269
|
|
|
466
270
|
---
|
|
467
271
|
|
|
468
|
-
###
|
|
469
|
-
|
|
470
|
-
**Filename**: `src/zmy_dtel.dtel.xml`
|
|
272
|
+
### CDS Access Control (DCLS)
|
|
471
273
|
|
|
472
|
-
|
|
274
|
+
**Files**: `src/zc_my_view.dcls.asdcls` (source) + `src/zc_my_view.dcls.xml` (metadata)
|
|
473
275
|
|
|
474
276
|
```xml
|
|
475
277
|
<?xml version="1.0" encoding="utf-8"?>
|
|
476
|
-
<abapGit version="v1.0.0" serializer="
|
|
278
|
+
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DCLS" serializer_version="v1.0.0">
|
|
477
279
|
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
478
280
|
<asx:values>
|
|
479
|
-
<
|
|
480
|
-
<
|
|
481
|
-
<
|
|
482
|
-
<DDTEXT>
|
|
483
|
-
|
|
484
|
-
<SCRTEXT_S>Short text</SCRTEXT_S>
|
|
485
|
-
<SCRTEXT_M>Medium text</SCRTEXT_M>
|
|
486
|
-
<SCRTEXT_L>Long description text</SCRTEXT_L>
|
|
487
|
-
<DTELMASTER>E</DTELMASTER>
|
|
488
|
-
<DATATYPE>CHAR</DATATYPE>
|
|
489
|
-
<LENG>000010</LENG>
|
|
490
|
-
</DD04V>
|
|
281
|
+
<DCLS>
|
|
282
|
+
<DCLNAME>ZC_MY_VIEW</DCLNAME>
|
|
283
|
+
<DCLLANGUAGE>E</DCLLANGUAGE>
|
|
284
|
+
<DDTEXT>Access control for ZC_MY_VIEW</DDTEXT>
|
|
285
|
+
</DCLS>
|
|
491
286
|
</asx:values>
|
|
492
287
|
</asx:abap>
|
|
493
288
|
</abapGit>
|
|
494
289
|
```
|
|
495
290
|
|
|
496
|
-
|
|
497
|
-
-
|
|
498
|
-
- `DDTEXT`: Description (**not** `DESCRIPT`)
|
|
499
|
-
- `REPTEXT` / `SCRTEXT_S` / `SCRTEXT_M` / `SCRTEXT_L`: Field labels (report heading, short, medium, long)
|
|
500
|
-
- `DTELMASTER`: Language key for label master (`E` for English)
|
|
501
|
-
- `DATATYPE`: Data type (`CHAR`, `NUMC`, `DATS`, `TIMS`, `INT4`, etc.)
|
|
502
|
-
- `LENG`: Length padded to 6 digits (e.g. `000010` for 10 characters)
|
|
503
|
-
|
|
504
|
-
**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 ...`)
|
|
505
293
|
|
|
506
294
|
---
|
|
507
295
|
|
|
508
|
-
###
|
|
509
|
-
|
|
510
|
-
**Filename**: `src/zmy_struct.stru.xml`
|
|
511
|
-
|
|
512
|
-
> **XML-only object** — no `.abap` source file. abapGit uses the same TABL serializer for STRU.
|
|
513
|
-
> Pull with: `pull --files src/zmy_struct.stru.xml`
|
|
296
|
+
### Function Group (FUGR)
|
|
514
297
|
|
|
515
|
-
|
|
516
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
517
|
-
<abapGit version="v1.0.0" serializer="LCL_OBJECT_TABL" serializer_version="v1.0.0">
|
|
518
|
-
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
519
|
-
<asx:values>
|
|
520
|
-
<DD02V>
|
|
521
|
-
<TABNAME>ZMY_STRUCT</TABNAME>
|
|
522
|
-
<DDLANGUAGE>E</DDLANGUAGE>
|
|
523
|
-
<TABCLASS>INTTAB</TABCLASS>
|
|
524
|
-
<DDTEXT>Description of the structure</DDTEXT>
|
|
525
|
-
<CONTFLAG>A</CONTFLAG>
|
|
526
|
-
</DD02V>
|
|
527
|
-
</asx:values>
|
|
528
|
-
</asx:abap>
|
|
529
|
-
</abapGit>
|
|
530
|
-
```
|
|
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.
|
|
531
299
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
**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.
|
|
535
|
-
|
|
536
|
-
---
|
|
537
|
-
|
|
538
|
-
### Table Type (TTYP)
|
|
539
|
-
|
|
540
|
-
**Filename**: `src/zmy_ttyp.ttyp.xml`
|
|
541
|
-
|
|
542
|
-
> **XML-only object** — no `.abap` source file.
|
|
543
|
-
> Pull with: `pull --files src/zmy_ttyp.ttyp.xml`
|
|
544
|
-
|
|
545
|
-
```xml
|
|
546
|
-
<?xml version="1.0" encoding="utf-8"?>
|
|
547
|
-
<abapGit version="v1.0.0" serializer="LCL_OBJECT_TTYP" serializer_version="v1.0.0">
|
|
548
|
-
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
549
|
-
<asx:values>
|
|
550
|
-
<DD40V>
|
|
551
|
-
<TYPENAME>ZMY_TTYP</TYPENAME>
|
|
552
|
-
<DDLANGUAGE>E</DDLANGUAGE>
|
|
553
|
-
<DDTEXT>Description of table type</DDTEXT>
|
|
554
|
-
<ROWTYPE>ZMY_STRUCT</ROWTYPE>
|
|
555
|
-
<ROWKIND>S</ROWKIND>
|
|
556
|
-
<DATATYPE>TABLE_T</DATATYPE>
|
|
557
|
-
<ACCESSMODE>T</ACCESSMODE>
|
|
558
|
-
<KEYDEF>D</KEYDEF>
|
|
559
|
-
<KEYKIND>N</KEYKIND>
|
|
560
|
-
</DD40V>
|
|
561
|
-
</asx:values>
|
|
562
|
-
</asx:abap>
|
|
563
|
-
</abapGit>
|
|
564
|
-
```
|
|
565
|
-
|
|
566
|
-
**Key Fields**:
|
|
567
|
-
- `TYPENAME`: Table type name
|
|
568
|
-
- `ROWTYPE`: Row type (a structure or data element name)
|
|
569
|
-
- `ROWKIND`: Row kind — `S`=Structure/Type, `D`=Data element, `R`=Reference
|
|
570
|
-
- `DATATYPE`: Always `TABLE_T` for table types
|
|
571
|
-
- `ACCESSMODE`: Table kind — `T`=Standard, `S`=Sorted, `H`=Hashed
|
|
572
|
-
- `KEYDEF`: Key definition — `D`=Default (standard key), `K`=User-defined
|
|
573
|
-
- `KEYKIND`: Key uniqueness — `N`=Non-unique, `U`=Unique
|
|
574
|
-
|
|
575
|
-
**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`
|
|
576
301
|
|
|
577
302
|
---
|
|
578
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
|
---
|
|
@@ -91,6 +91,28 @@ abapgit-agent debug set --objects ZCL_MY_CLASS:5 --include locals_imp
|
|
|
91
91
|
abapgit-agent debug list # confirm both were registered
|
|
92
92
|
```
|
|
93
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
|
+
|
|
94
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:
|
|
95
117
|
>
|
|
96
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 `).`:
|
|
@@ -277,26 +299,3 @@ HTTP Request
|
|
|
277
299
|
> inside `find_remote_dot_abapgit()` via `COMMIT WORK AND WAIT` — i.e., the lock is released before
|
|
278
300
|
> BP2 fires. There is no active lock between BP1 and the end of CM00L.
|
|
279
301
|
|
|
280
|
-
### Known Limitations and Planned Improvements
|
|
281
|
-
|
|
282
|
-
The following issues were identified during live debugging sessions and resolved:
|
|
283
|
-
|
|
284
|
-
#### ~~1. `view --full` global line numbers don't match ADT line numbers~~ ✅ Fixed
|
|
285
|
-
|
|
286
|
-
**Fixed**: `view --full --lines` now shows dual line numbers per line: `G [N] code` where G is the assembled-source global line and `[N]` is the include-relative counter. Method headers show the ready-to-use `debug set --objects CLASS:G` command pointing to the first executable statement (skipping `METHOD`, blank lines, comments, and all `DATA`/`DATA:`/`DATA(` declaration forms).
|
|
287
|
-
|
|
288
|
-
Global line numbers are computed **client-side** in Node.js, not in ABAP:
|
|
289
|
-
- **Own classes** (local `.clas.abap` file exists): reads the local file — guaranteed exact match with ADT
|
|
290
|
-
- **Library classes** (no local file, e.g. abapGit): fetches assembled source from `/sap/bc/adt/oo/classes/<name>/source/main`
|
|
291
|
-
|
|
292
|
-
#### ~~2. No breakpoint support for unit test and local class methods~~ ✅ Fixed
|
|
293
|
-
|
|
294
|
-
**Fixed**: CCAU (unit test) and CCIMP (local class implementation) sections in `view --full --lines` now show per-method `debug set --objects CLASS:N --include <type>` hints. These use the `/includes/<type>` ADT sub-include URI which ADT accepts for CCAU/CCIMP includes. See Step 1 above for details.
|
|
295
|
-
|
|
296
|
-
#### ~~3. Include-relative breakpoint form (`=====CMxxx:N`) not implemented in the CLI~~ ✅ Superseded
|
|
297
|
-
|
|
298
|
-
**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.
|
|
299
|
-
|
|
300
|
-
#### ~~4. `stepContinue` re-attach pattern missing from docs~~ ✅ Fixed
|
|
301
|
-
|
|
302
|
-
**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
|
package/package.json
CHANGED
package/src/commands/debug.js
CHANGED
|
@@ -89,6 +89,10 @@ const INCLUDE_TYPE_TO_ADT = {
|
|
|
89
89
|
* e.g. ZCL_ABGAGT_AGENT=============CM00D
|
|
90
90
|
* These must be routed to the programs/includes ADT endpoint.
|
|
91
91
|
*
|
|
92
|
+
* FUGR source includes follow L<group><suffix> naming (e.g. LSUSRU04, LSUSRTOP,
|
|
93
|
+
* LSUSRF10, L_ABAU01). They start with 'L' and are routed to programs/includes.
|
|
94
|
+
* Customer-namespace programs always start with Z/Y, so this branch is safe.
|
|
95
|
+
*
|
|
92
96
|
* When includeType is supplied (testclasses|locals_imp|locals_def),
|
|
93
97
|
* the URI targets the sub-include of the class instead of /source/main.
|
|
94
98
|
* Line numbers are then section-local (from the .clas.<file>.abap file).
|
|
@@ -103,6 +107,11 @@ function objectUri(name, includeType) {
|
|
|
103
107
|
}
|
|
104
108
|
return `/sap/bc/adt/oo/classes/${lower}/source/main`;
|
|
105
109
|
}
|
|
110
|
+
// FUGR source includes: L<group>U<NN>, L<group>TOP, L<group>F<NN>, etc.
|
|
111
|
+
// All start with 'L'. Customer Z/Y programs never start with 'L'.
|
|
112
|
+
if (/^L/.test(upper)) {
|
|
113
|
+
return `/sap/bc/adt/programs/includes/${lower}`;
|
|
114
|
+
}
|
|
106
115
|
return `/sap/bc/adt/programs/programs/${lower}`;
|
|
107
116
|
}
|
|
108
117
|
|