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.
@@ -6,9 +6,10 @@ parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
8
8
 
9
- # abapGit Object XML Metadata
9
+ # abapGit XML Metadata — CLAS, INTF, PROG
10
10
 
11
- Each ABAP object requires an XML metadata file for abapGit to understand how to serialize/deserialize it. This guide provides templates for common object types.
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 | zcl_*.clas.xml
20
- Interface | zif_*.intf.abap | zif_*.intf.xml
21
- Program | z*.prog.abap | z*.prog.xml
22
- CDS View (DDLS) | zc_*.ddls.asddls | zc_*.ddls.xml
23
- Table (TABL) | (no .abap file) | z*.tabl.xml
24
- Structure (STRU) | (no .abap file) | z*.stru.xml
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)** have **no ABAP source file**. abapGit serializes
30
- > them as XML metadata only. When using `--files`, pass the `.xml` file directly:
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, table xml, cds xml, test class, exposure, serializer, abapgit
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
- **Filename**: `src/zc_my_view.ddls.xml`
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, **use by default**)
462
- - `SOURCE_TYPE V` → View (`define view` + `@AbapCatalog.sqlViewName`, legacy — only if explicitly requested)
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 and full guidance: `abapgit-agent ref --topic cds-abapgit`
268
+ → For DDL source syntax: `abapgit-agent ref --topic cds-abapgit`
465
269
 
466
270
  ---
467
271
 
468
- ### Data Element (DTEL)
469
-
470
- **Filename**: `src/zmy_dtel.dtel.xml`
272
+ ### CDS Access Control (DCLS)
471
273
 
472
- > **XML-only object** — no `.abap` source file. Pull with: `pull --files src/zmy_dtel.dtel.xml`
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="LCL_OBJECT_DTEL" serializer_version="v1.0.0">
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
- <DD04V>
480
- <ROLLNAME>ZMY_DTEL</ROLLNAME>
481
- <DDLANGUAGE>E</DDLANGUAGE>
482
- <DDTEXT>Description of data element</DDTEXT>
483
- <REPTEXT>Description</REPTEXT>
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
- **Key Fields**:
497
- - `ROLLNAME`: Data element name
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
- ### Structure (STRU)
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
- ```xml
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
- **Key difference from TABL**: `TABCLASS` is `INTTAB` (internal table / structure) instead of `TRANSP`.
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: abaplint Local Rules
4
- nav_order: 18
4
+ nav_order: 21
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: abaplint Rule Guidelines
4
- nav_order: 17
4
+ nav_order: 20
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Branch Workflow
4
- nav_order: 14
4
+ nav_order: 17
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: CDS Testing
4
- nav_order: 19
4
+ nav_order: 22
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Common ABAP Errors
4
- nav_order: 11
4
+ nav_order: 14
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Dump Analysis Guide
4
- nav_order: 13
4
+ nav_order: 16
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Debug Session Guide
4
- nav_order: 12
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: Object Creation
4
- nav_order: 16
4
+ nav_order: 19
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Probe and PoC Guide
4
- nav_order: 21
4
+ nav_order: 24
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: run Command Guide
4
- nav_order: 20
4
+ nav_order: 23
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Unit Testable Code
4
- nav_order: 10
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
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  layout: default
3
3
  title: Development Workflow (Detailed)
4
- nav_order: 15
4
+ nav_order: 18
5
5
  parent: ABAP Coding Guidelines
6
6
  grand_parent: ABAP Development
7
7
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abapgit-agent",
3
- "version": "1.14.5",
3
+ "version": "1.15.0",
4
4
  "description": "ABAP Git Agent - Pull and activate ABAP code via abapGit from any git repository",
5
5
  "files": [
6
6
  "bin/",
@@ -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