abapgit-agent 1.15.2 → 1.16.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/.github/copilot-instructions.slim.md +35 -4
- package/abap/CLAUDE.md +62 -10
- package/abap/guidelines/abapgit-fugr.md +19 -3
- package/abap/guidelines/abapgit-xml-only.md +68 -12
- package/abap/guidelines/abapgit.md +2 -1
- package/abap/guidelines/abaplint.md +35 -0
- package/abap/guidelines/common-errors.md +78 -1
- package/abap/guidelines/index.md +1 -0
- package/abap/guidelines/naming-limits.md +160 -0
- package/abap/guidelines/object-creation.md +1 -1
- package/abap/guidelines/objects.md +5 -2
- package/abap/guidelines/string-template.md +84 -0
- package/package.json +2 -1
- package/src/commands/drop.js +171 -0
- package/src/commands/index.js +2 -1
- package/src/commands/syntax.js +121 -17
- package/abap/.github/copilot-instructions.md +0 -264
|
@@ -36,8 +36,14 @@ The folder is configured in `.abapGitAgent` (property: `folder`):
|
|
|
36
36
|
|
|
37
37
|
Each ABAP object needs an XML metadata file. Local helper/test-double classes use separate `.locals_def.abap` / `.locals_imp.abap` files.
|
|
38
38
|
|
|
39
|
+
**Name length limits** (verify before naming anything):
|
|
40
|
+
- CLAS, INTF: name **30 chars** | method names: **30 chars**
|
|
41
|
+
- TABL, STRU: name **30 chars** | **field names: 16 chars** ← most common mistake
|
|
42
|
+
- DDLS (CDS view entity): **40 chars** | field alias: 30 | FUGR: 26 | MSAG: 20 | PROG/DTEL/DOMA/TTYP: 30
|
|
43
|
+
|
|
39
44
|
```bash
|
|
40
|
-
abapgit-agent ref --topic
|
|
45
|
+
abapgit-agent ref --topic naming-limits # full length reference
|
|
46
|
+
abapgit-agent ref --topic object-creation # XML templates and local class setup
|
|
41
47
|
```
|
|
42
48
|
|
|
43
49
|
### 4. Use Syntax Command Before Commit (for CLAS, INTF, PROG, DDLS)
|
|
@@ -65,6 +71,24 @@ abapgit-agent ref --topic debug-session # full debug guide
|
|
|
65
71
|
abapgit-agent ref --topic debug-dump # dump analysis guide
|
|
66
72
|
```
|
|
67
73
|
|
|
74
|
+
### 7. Never Run `run` Command Proactively
|
|
75
|
+
|
|
76
|
+
Never call `abapgit-agent run` unless the user explicitly asks — it can modify data or trigger RFCs.
|
|
77
|
+
|
|
78
|
+
### 8. Probe and PoC Objects — Always Z/Y, Never in SAP Packages
|
|
79
|
+
|
|
80
|
+
When `objects.local.md` shows SAP namespace (`CL_*`, `IF_*`, `/NAMESPACE/*`) and the user asks to create a new object, always ask first: *"Is this a production object, a PoC, or a probe?"*
|
|
81
|
+
|
|
82
|
+
→ `abapgit-agent ref --topic probe-poc`
|
|
83
|
+
|
|
84
|
+
### 9. abaplint — Optional, Project-Controlled
|
|
85
|
+
|
|
86
|
+
Only run if `.abaplint.json` exists. Run after `syntax`, before commit. Always check `ref --topic abaplint` before applying any quickfix.
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
ls .abaplint.json 2>/dev/null && abapgit-agent lint
|
|
90
|
+
```
|
|
91
|
+
|
|
68
92
|
---
|
|
69
93
|
|
|
70
94
|
## Development Workflow
|
|
@@ -77,6 +101,8 @@ Checked into the repository — applies to all developers. **Read this file at t
|
|
|
77
101
|
|---------|--------|
|
|
78
102
|
| `safeguards.requireFilesForPull: true` | Always include `--files` in every `pull` |
|
|
79
103
|
| `safeguards.disablePull: true` | Do not run `abapgit-agent pull` at all |
|
|
104
|
+
| `safeguards.disableRun: true` | Do not run `abapgit-agent run` at all |
|
|
105
|
+
| `safeguards.disableProbeClasses: true` | Use `scratchWorkspace` for probe classes instead |
|
|
80
106
|
| `conflictDetection.mode: "abort"` | Abort pull on conflict — inform user |
|
|
81
107
|
| `transports.allowCreate/allowRelease: false` | Blocked — inform user |
|
|
82
108
|
|
|
@@ -97,10 +123,15 @@ abapgit-agent ref --topic branch-workflow
|
|
|
97
123
|
```
|
|
98
124
|
Modified ABAP files?
|
|
99
125
|
├─ CLAS/INTF/PROG/DDLS files?
|
|
100
|
-
│ ├─ Independent files? → syntax → commit → push → pull
|
|
101
|
-
│ └─ Dependent files? → skip syntax → commit → push → pull
|
|
126
|
+
│ ├─ Independent files? → syntax → [abaplint] → commit → push → pull --sync-xml
|
|
127
|
+
│ └─ Dependent files? → skip syntax → [abaplint] → commit → push → pull --sync-xml
|
|
102
128
|
└─ Other types (FUGR, TABL, etc.)?
|
|
103
|
-
|
|
129
|
+
├─ XML-only (TABL, STRU, DTEL, TTYP, DOMA, MSAG)?
|
|
130
|
+
│ → skip syntax → [abaplint] → commit → push → pull --files <name>.tabl.xml --sync-xml
|
|
131
|
+
└─ FUGR and others?
|
|
132
|
+
→ skip syntax → [abaplint] → commit → push → pull --sync-xml → (if errors: inspect)
|
|
133
|
+
|
|
134
|
+
[abaplint] = run lint only if .abaplint.json exists; ref --topic abaplint before any quickfix
|
|
104
135
|
```
|
|
105
136
|
|
|
106
137
|
```bash
|
package/abap/CLAUDE.md
CHANGED
|
@@ -99,6 +99,20 @@ Never assume Z/Y prefix without checking.
|
|
|
99
99
|
XML-only objects (TABL, STRU, DTEL, TTYP, DOMA, MSAG) need ONLY the XML file
|
|
100
100
|
```
|
|
101
101
|
|
|
102
|
+
**Before choosing a name, verify the length limit for the object type:**
|
|
103
|
+
|
|
104
|
+
| Object type | Name limit | Field/sub-element limit |
|
|
105
|
+
|---|---|---|
|
|
106
|
+
| CLAS, INTF | **30 chars** | method names: **30 chars** |
|
|
107
|
+
| TABL, STRU | **30 chars** | **field names: 16 chars** |
|
|
108
|
+
| DDLS (CDS view entity) | **40 chars** | field alias: **30 chars** |
|
|
109
|
+
| DCLS (CDS access control) | **40 chars** | — (name must match its DDLS view) |
|
|
110
|
+
| FUGR (function group) | **26 chars** | function module name: **30 chars** |
|
|
111
|
+
| MSAG (message class) | **20 chars** | — |
|
|
112
|
+
| PROG, DTEL, DOMA, TTYP | **30 chars** | — |
|
|
113
|
+
|
|
114
|
+
→ Full length reference: `abapgit-agent ref --topic naming-limits`
|
|
115
|
+
|
|
102
116
|
Use the object name from `objects.local.md` (or `objects.md` as fallback) in place of `<name>`:
|
|
103
117
|
|
|
104
118
|
| Object Type | Source File | XML File |
|
|
@@ -110,7 +124,7 @@ Use the object name from `objects.local.md` (or `objects.md` as fallback) in pla
|
|
|
110
124
|
| CDS Access Control (DCLS) | `<name>.dcls.asdcls` | `<name>.dcls.xml` |
|
|
111
125
|
| Function Group (FUGR) | `<name>.fugr.abap` + includes | `<name>.fugr.xml` |
|
|
112
126
|
| Table (TABL) | *(none)* | `<name>.tabl.xml` |
|
|
113
|
-
| Structure (STRU) | *(none)* | `<name>.stru.xml` |
|
|
127
|
+
| Structure (STRU) | *(none)* | `<name>.tabl.xml` ⚠️ NOT `.stru.xml` |
|
|
114
128
|
| Data Element (DTEL) | *(none)* | `<name>.dtel.xml` |
|
|
115
129
|
| Table Type (TTYP) | *(none)* | `<name>.ttyp.xml` |
|
|
116
130
|
| Domain (DOMA) | *(none)* | `<name>.doma.xml` |
|
|
@@ -143,7 +157,7 @@ Anything else (SAP namespace object, or SAP-delivered package)?
|
|
|
143
157
|
|
|
144
158
|
Object: <NAME> (<Type>)
|
|
145
159
|
Package: <PACKAGE>
|
|
146
|
-
Files: <folder>/<name>.<ext>.abap
|
|
160
|
+
Files: <folder>/<name>.<ext>.abap ← omit this line for XML-only types (TABL/STRU/DTEL/TTYP/DOMA/MSAG)
|
|
147
161
|
<folder>/<name>.<ext>.xml
|
|
148
162
|
|
|
149
163
|
Shall I proceed?"
|
|
@@ -165,26 +179,27 @@ Anything else (SAP namespace object, or SAP-delivered package)?
|
|
|
165
179
|
|
|
166
180
|
---
|
|
167
181
|
|
|
168
|
-
### 4. Use Syntax Command Before Commit (for CLAS, INTF, PROG, DDLS)
|
|
182
|
+
### 4. Use Syntax Command Before Commit (for CLAS, INTF, PROG, DDLS, FUGR)
|
|
169
183
|
|
|
170
184
|
```
|
|
171
185
|
❌ WRONG: Make changes → Commit → Push → Pull → Find errors → Fix → Repeat
|
|
172
186
|
✅ CORRECT: Make changes → Run syntax → Fix locally → Commit → Push → Pull → Done
|
|
173
187
|
```
|
|
174
188
|
|
|
175
|
-
**For CLAS, INTF, PROG, DDLS files**: Run `syntax` command BEFORE commit to catch errors early.
|
|
189
|
+
**For CLAS, INTF, PROG, DDLS, FUGR files**: Run `syntax` command BEFORE commit to catch errors early.
|
|
176
190
|
|
|
177
191
|
```bash
|
|
178
192
|
# Check syntax of local code (no commit/push needed)
|
|
179
193
|
# Use the actual filename from your project (name comes from objects.local.md)
|
|
180
194
|
abapgit-agent syntax --files src/<name>.clas.abap
|
|
181
195
|
abapgit-agent syntax --files src/<name>.ddls.asddls
|
|
196
|
+
abapgit-agent syntax --files src/<name>.fugr.<fm_name>.abap
|
|
182
197
|
|
|
183
198
|
# Check multiple INDEPENDENT files
|
|
184
199
|
abapgit-agent syntax --files src/<name1>.clas.abap,src/<name2>.clas.abap
|
|
185
200
|
```
|
|
186
201
|
|
|
187
|
-
**For other types (
|
|
202
|
+
**For other types (TABL, STRU, DCLS, etc.)**: Skip syntax, proceed to commit/push/pull.
|
|
188
203
|
|
|
189
204
|
**Why use syntax command?**
|
|
190
205
|
- Catches syntax errors BEFORE polluting git history with fix commits
|
|
@@ -410,7 +425,39 @@ After activating a class, stop and tell the user: `"Class is activated. Run with
|
|
|
410
425
|
|
|
411
426
|
---
|
|
412
427
|
|
|
413
|
-
### 10.
|
|
428
|
+
### 10. Never Run `drop` Command Without Explicit Permission
|
|
429
|
+
|
|
430
|
+
**Never call `abapgit-agent drop` unless the user explicitly confirms.** Dropping an object physically deletes it from the ABAP system — this is irreversible without a subsequent pull.
|
|
431
|
+
|
|
432
|
+
**When to SUGGEST `drop --pull`:**
|
|
433
|
+
|
|
434
|
+
When an object is in a broken or inconsistent state that cannot be resolved by re-pulling:
|
|
435
|
+
- `inspect` reports **"INCLUDE report ... not found"** (stale include in ABAP not present in git)
|
|
436
|
+
- Pull repeatedly fails with **"Activation cancelled"** and re-pulling doesn't fix it
|
|
437
|
+
- Object has a corrupt inactive version that permanently blocks activation
|
|
438
|
+
|
|
439
|
+
In these cases, suggest the fix and wait for confirmation:
|
|
440
|
+
|
|
441
|
+
```
|
|
442
|
+
"The object ZCL_FOO has an inconsistent state (stale include in ABAP).
|
|
443
|
+
This can be fixed by dropping and re-pulling it:
|
|
444
|
+
|
|
445
|
+
abapgit-agent drop --files abap/zcl_foo.clas.abap --pull
|
|
446
|
+
|
|
447
|
+
This will delete ZCL_FOO from ABAP and immediately re-activate it from git.
|
|
448
|
+
Confirm when ready."
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
**What `drop --pull` does:**
|
|
452
|
+
1. Physically deletes the object from the ABAP system
|
|
453
|
+
2. Immediately re-pulls and re-activates it from git (clean state)
|
|
454
|
+
3. Does NOT touch the git repository file
|
|
455
|
+
|
|
456
|
+
**Constraint:** Only CLAS, INTF, PROG, TABL, TTYP are supported. DTEL (data elements) are rejected — edit the XML and use `pull` instead.
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
### 11. Probe and PoC Objects — Always Z/Y, Never in SAP Packages
|
|
414
461
|
|
|
415
462
|
```
|
|
416
463
|
❌ WRONG: Create a probe/PoC object with the project's SAP namespace prefix
|
|
@@ -436,7 +483,7 @@ Never assume — wait for the user's answer before proceeding.
|
|
|
436
483
|
|
|
437
484
|
---
|
|
438
485
|
|
|
439
|
-
###
|
|
486
|
+
### 12. Troubleshooting ABAP Issues
|
|
440
487
|
|
|
441
488
|
| Symptom | Tool | When |
|
|
442
489
|
|---|---|---|
|
|
@@ -708,15 +755,18 @@ abapgit-agent pull --files src/<name>.clas.abap --sync-xml
|
|
|
708
755
|
|
|
709
756
|
```
|
|
710
757
|
Modified ABAP files?
|
|
711
|
-
├─ CLAS/INTF/PROG/DDLS files?
|
|
758
|
+
├─ CLAS/INTF/PROG/DDLS/FUGR files?
|
|
712
759
|
│ ├─ Independent files (no cross-dependencies)?
|
|
713
760
|
│ │ └─ ✅ Use: syntax → [abaplint] → commit → push → pull --sync-xml
|
|
714
761
|
│ └─ Dependent files (interface + class, class uses class)?
|
|
715
762
|
│ └─ ✅ Use: skip syntax → [abaplint] → commit → push → pull --sync-xml
|
|
716
|
-
└─ Other types (
|
|
763
|
+
└─ Other types (TABL, STRU, DTEL, TTYP, etc.)?
|
|
717
764
|
├─ XML-only objects (TABL, STRU, DTEL, TTYP, DOMA, MSAG)?
|
|
718
765
|
│ └─ ✅ Use: skip syntax → [abaplint] → commit → push → pull --files abap/ztable.tabl.xml --sync-xml
|
|
719
|
-
|
|
766
|
+
├─ DCLS (CDS access control)?
|
|
767
|
+
│ └─ ✅ Use: skip syntax → [abaplint] → commit → push → pull --files abap/zc_view.dcls.xml --sync-xml
|
|
768
|
+
│ ⚠️ Pass the .xml file — pull --files does NOT accept .asdcls extensions
|
|
769
|
+
└─ Other complex objects?
|
|
720
770
|
└─ ✅ Use: skip syntax → [abaplint] → commit → push → pull --sync-xml → (if errors: inspect)
|
|
721
771
|
|
|
722
772
|
[abaplint] = run abapgit-agent lint only if .abaplint.json exists in repo root
|
|
@@ -736,6 +786,7 @@ Modified ABAP files?
|
|
|
736
786
|
| `ref --topic exceptions` | Exception Handling |
|
|
737
787
|
| `ref --topic classes` | ABAP Classes and Objects |
|
|
738
788
|
| `ref --topic objects` | Object Naming Conventions (defaults) |
|
|
789
|
+
| `ref --topic naming-limits` | Naming Length Limits — 30/16/40 char rules per type (CRITICAL before naming anything) |
|
|
739
790
|
| `ref --topic comments` | Documentation Comments (ABAP DOC, shorttext, @parameter, CDS `//`, program `*&---`) |
|
|
740
791
|
| `ref --topic testing` | Unit Testing |
|
|
741
792
|
| `ref --topic unit-testable-code` | Unit Testable Code (Dependency Injection) |
|
|
@@ -743,6 +794,7 @@ Modified ABAP files?
|
|
|
743
794
|
| `ref --topic cds-testing` | CDS Testing (Test Double Framework) |
|
|
744
795
|
| `ref --topic json` | JSON Handling |
|
|
745
796
|
| `ref --topic common-errors` | Common ABAP Errors - Quick Fixes |
|
|
797
|
+
| `ref --topic string-template` | String Templates — syntax, escaping `\{` `\}`, JSON payloads |
|
|
746
798
|
| `ref --topic abapgit` | abapGit XML Metadata — **use for CDS/DDLS XML**, also CLAS, INTF, PROG, DCLS, FUGR |
|
|
747
799
|
| `ref --topic abapgit-xml-only` | abapGit XML Metadata — XML-only objects (TABL, STRU, DTEL, TTYP, DOMA, MSAG) |
|
|
748
800
|
| `ref --topic abapgit-fugr` | abapGit XML Metadata — Function Group (FUGR) details |
|
|
@@ -22,10 +22,13 @@ A FUGR with group name `ZMY_FUGR` and one FM `ZMY_MY_FUNCTION` requires these fi
|
|
|
22
22
|
| `zmy_fugr.fugr.xml` | Main XML: group description, includes list, FM interfaces |
|
|
23
23
|
| `zmy_fugr.fugr.lzmy_fugrtop.abap` | TOP include source |
|
|
24
24
|
| `zmy_fugr.fugr.lzmy_fugrtop.xml` | TOP include metadata (`SUBC=I`) |
|
|
25
|
-
| `zmy_fugr.fugr.saplzmy_fugr.abap` | Main include source |
|
|
25
|
+
| `zmy_fugr.fugr.saplzmy_fugr.abap` | Main include source (lists all U-includes) |
|
|
26
26
|
| `zmy_fugr.fugr.saplzmy_fugr.xml` | Main include metadata (`SUBC=F`) |
|
|
27
|
+
| `zmy_fugr.fugr.lzmy_fugru01.abap` | FM implementation include (one per FM: U01, U02, …) |
|
|
27
28
|
| `zmy_fugr.fugr.zmy_my_function.abap` | FM source (one file per FM, named after FM in lowercase) |
|
|
28
29
|
|
|
30
|
+
> **7 files total for one FM** (6 without the U01 include causes a pull error — the SAPL source references `LZMY_FUGRU01` which abapGit can't find). For a second FM, add `lzmy_fugru02.abap` and `zmy_second_function.abap`.
|
|
31
|
+
|
|
29
32
|
---
|
|
30
33
|
|
|
31
34
|
### `zmy_fugr.fugr.xml`
|
|
@@ -145,15 +148,28 @@ FUNCTION zmy_my_function.
|
|
|
145
148
|
ENDFUNCTION.
|
|
146
149
|
```
|
|
147
150
|
|
|
151
|
+
### `zmy_fugr.fugr.lzmy_fugru01.abap`
|
|
152
|
+
|
|
153
|
+
The FM implementation include — **always required**. The SAPL source references `INCLUDE LZMY_FUGRU01.` so this file must exist or the pull fails.
|
|
154
|
+
|
|
155
|
+
```abap
|
|
156
|
+
*----------------------------------------------------------------------*
|
|
157
|
+
***INCLUDE LZMY_FUGRU01.
|
|
158
|
+
*----------------------------------------------------------------------*
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
For a second FM, create `zmy_fugr.fugr.lzmy_fugru02.abap` with the same pattern (replacing `U01` with `U02`).
|
|
162
|
+
|
|
148
163
|
---
|
|
149
164
|
|
|
150
165
|
## Key Rules
|
|
151
166
|
|
|
152
|
-
- **Include naming**: TOP = `L<GROUP>TOP`, main = `SAPL<GROUP
|
|
167
|
+
- **Include naming**: TOP = `L<GROUP>TOP`, main = `SAPL<GROUP>`, FM implementation = `L<GROUP>U01` (U02, U03, …) — uppercase in XML and filenames
|
|
153
168
|
- **FM source file**: named after the FM in **lowercase** (`zmy_my_function.abap`, not `ZMY_MY_FUNCTION.abap`)
|
|
169
|
+
- **U-include file required**: `lzmy_fugru01.abap` must exist — the SAPL source references it; missing it causes a pull error
|
|
154
170
|
- **`INCLUDES` list** in the main XML: only lists TOP and SAPL includes — FM source includes are implicit
|
|
155
171
|
- **`REMOTE_CALL>R`**: add only for RFC-enabled FMs; omit for local FMs
|
|
156
172
|
- **Optional parameters**: include both `<OPTIONAL>X</OPTIONAL>` and `<DEFAULT>...</DEFAULT>`
|
|
157
|
-
- **`DOCUMENTATION` section**:
|
|
173
|
+
- **`DOCUMENTATION` section**: the serializer always writes `<DOCUMENTATION>` with one `<RSFDO>` entry per parameter (containing only `<PARAMETER>` and `<KIND>P</KIND>`, no `<STEXT>`). Always include it — omitting it causes a permanent "M" diff
|
|
158
174
|
- **Screens/CUA**: omit `DYNPROS`/`CUA` sections for screenless function groups
|
|
159
175
|
- **Multiple FMs**: add one `<item>` per FM in `FUNCTIONS`; add one `INCLUDE` line per FM in the SAPL source
|
|
@@ -170,6 +170,12 @@ A **text table** stores translatable texts for another table (the "main table").
|
|
|
170
170
|
|
|
171
171
|
> Pull with: `pull --files src/zmy_dtel.dtel.xml`
|
|
172
172
|
|
|
173
|
+
**Two variants — choose based on whether the DTEL defines its own type or references a domain:**
|
|
174
|
+
|
|
175
|
+
#### Variant 1: Built-in type (no domain)
|
|
176
|
+
|
|
177
|
+
Use when the data element directly defines `DATATYPE` and `LENG` without referencing a domain.
|
|
178
|
+
|
|
173
179
|
```xml
|
|
174
180
|
<?xml version="1.0" encoding="utf-8"?>
|
|
175
181
|
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DTEL" serializer_version="v1.0.0">
|
|
@@ -192,13 +198,38 @@ A **text table** stores translatable texts for another table (the "main table").
|
|
|
192
198
|
</abapGit>
|
|
193
199
|
```
|
|
194
200
|
|
|
201
|
+
#### Variant 2: Domain reference
|
|
202
|
+
|
|
203
|
+
Use when the data element's type and length come from an existing domain (`DOMNAME`). Do **not** include `DATATYPE` or `LENG` — the domain owns those.
|
|
204
|
+
|
|
205
|
+
```xml
|
|
206
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
207
|
+
<abapGit version="v1.0.0" serializer="LCL_OBJECT_DTEL" serializer_version="v1.0.0">
|
|
208
|
+
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
|
209
|
+
<asx:values>
|
|
210
|
+
<DD04V>
|
|
211
|
+
<ROLLNAME>ZMY_DTEL</ROLLNAME>
|
|
212
|
+
<DDLANGUAGE>E</DDLANGUAGE>
|
|
213
|
+
<DDTEXT>Description of data element</DDTEXT>
|
|
214
|
+
<REPTEXT>Description</REPTEXT>
|
|
215
|
+
<SCRTEXT_S>Short text</SCRTEXT_S>
|
|
216
|
+
<SCRTEXT_M>Medium text</SCRTEXT_M>
|
|
217
|
+
<SCRTEXT_L>Long description text</SCRTEXT_L>
|
|
218
|
+
<DTELMASTER>E</DTELMASTER>
|
|
219
|
+
<DOMNAME>ZMY_DOMAIN</DOMNAME>
|
|
220
|
+
</DD04V>
|
|
221
|
+
</asx:values>
|
|
222
|
+
</asx:abap>
|
|
223
|
+
</abapGit>
|
|
224
|
+
```
|
|
225
|
+
|
|
195
226
|
**Key Fields**:
|
|
196
227
|
- `ROLLNAME`: Data element name
|
|
197
228
|
- `DDTEXT`: Description (**not** `DESCRIPT`)
|
|
198
229
|
- `REPTEXT` / `SCRTEXT_S` / `SCRTEXT_M` / `SCRTEXT_L`: Field labels (report heading, short, medium, long)
|
|
199
230
|
- `DTELMASTER`: Language key for label master (`E` for English)
|
|
200
|
-
- `DATATYPE`:
|
|
201
|
-
- `
|
|
231
|
+
- `DATATYPE` + `LENG`: Use for built-in type variant only (e.g. `CHAR` + `000010`)
|
|
232
|
+
- `DOMNAME`: Use for domain-reference variant only — omit `DATATYPE` and `LENG` entirely
|
|
202
233
|
|
|
203
234
|
**Omit `<PARAMID>`** unless you specifically need a SET/GET parameter ID — the serializer omits it when empty.
|
|
204
235
|
|
|
@@ -206,10 +237,14 @@ A **text table** stores translatable texts for another table (the "main table").
|
|
|
206
237
|
|
|
207
238
|
### Structure (STRU)
|
|
208
239
|
|
|
209
|
-
**Filename**: `src/zmy_struct.
|
|
240
|
+
**Filename**: `src/zmy_struct.tabl.xml`
|
|
210
241
|
|
|
211
|
-
>
|
|
212
|
-
>
|
|
242
|
+
> ⚠️ **Use `.tabl.xml` extension, NOT `.stru.xml`** — abapGit serializes structures with the TABL
|
|
243
|
+
> serializer and registers them as object type `TABL`. A `.stru.xml` filename causes
|
|
244
|
+
> "Step DDIC is only for DDIC objects" because abapGit treats it as object type `STRU`,
|
|
245
|
+
> which is not in its DDIC activation list.
|
|
246
|
+
>
|
|
247
|
+
> Pull with: `pull --files src/zmy_struct.tabl.xml`
|
|
213
248
|
|
|
214
249
|
```xml
|
|
215
250
|
<?xml version="1.0" encoding="utf-8"?>
|
|
@@ -221,16 +256,37 @@ A **text table** stores translatable texts for another table (the "main table").
|
|
|
221
256
|
<DDLANGUAGE>E</DDLANGUAGE>
|
|
222
257
|
<TABCLASS>INTTAB</TABCLASS>
|
|
223
258
|
<DDTEXT>Description of the structure</DDTEXT>
|
|
224
|
-
<
|
|
259
|
+
<EXCLASS>1</EXCLASS>
|
|
225
260
|
</DD02V>
|
|
261
|
+
<DD03P_TABLE>
|
|
262
|
+
<DD03P>
|
|
263
|
+
<FIELDNAME>FIELD1</FIELDNAME>
|
|
264
|
+
<ROLLNAME>S_CARR_ID</ROLLNAME>
|
|
265
|
+
<ADMINFIELD>0</ADMINFIELD>
|
|
266
|
+
<SHLPORIGIN>D</SHLPORIGIN>
|
|
267
|
+
<COMPTYPE>E</COMPTYPE>
|
|
268
|
+
</DD03P>
|
|
269
|
+
<DD03P>
|
|
270
|
+
<FIELDNAME>FIELD2</FIELDNAME>
|
|
271
|
+
<ROLLNAME>S_CARRNAME</ROLLNAME>
|
|
272
|
+
<ADMINFIELD>0</ADMINFIELD>
|
|
273
|
+
<COMPTYPE>E</COMPTYPE>
|
|
274
|
+
</DD03P>
|
|
275
|
+
</DD03P_TABLE>
|
|
226
276
|
</asx:values>
|
|
227
277
|
</asx:abap>
|
|
228
278
|
</abapGit>
|
|
229
279
|
```
|
|
230
280
|
|
|
231
|
-
**Key
|
|
281
|
+
**Key differences from TABL**:
|
|
282
|
+
- `TABCLASS` is `INTTAB` instead of `TRANSP`
|
|
283
|
+
- No `<CONTFLAG>` — omit it (not written by serializer for structures)
|
|
284
|
+
- `<EXCLASS>1</EXCLASS>` — include it
|
|
285
|
+
- Include `<DD03P_TABLE>` with field definitions from the start (unlike TABL where it is optional on creation)
|
|
232
286
|
|
|
233
|
-
|
|
287
|
+
**`DD03P` field rules** (same as TABL):
|
|
288
|
+
- Fields with `ROLLNAME` (data element): include `ROLLNAME`, `ADMINFIELD>0`, `SHLPORIGIN` (when domain provides value help — `D` for domain fixed values), `COMPTYPE>E`
|
|
289
|
+
- Fields with raw type (no data element): include `ADMINFIELD>0`, `INTTYPE`, `INTLEN`, `DATATYPE`, `MASK` (before any text fields)
|
|
234
290
|
|
|
235
291
|
---
|
|
236
292
|
|
|
@@ -248,13 +304,13 @@ A **text table** stores translatable texts for another table (the "main table").
|
|
|
248
304
|
<DD40V>
|
|
249
305
|
<TYPENAME>ZMY_TTYP</TYPENAME>
|
|
250
306
|
<DDLANGUAGE>E</DDLANGUAGE>
|
|
251
|
-
<DDTEXT>Description of table type</DDTEXT>
|
|
252
307
|
<ROWTYPE>ZMY_STRUCT</ROWTYPE>
|
|
253
308
|
<ROWKIND>S</ROWKIND>
|
|
254
|
-
<DATATYPE>
|
|
309
|
+
<DATATYPE>STRU</DATATYPE>
|
|
255
310
|
<ACCESSMODE>T</ACCESSMODE>
|
|
256
311
|
<KEYDEF>D</KEYDEF>
|
|
257
312
|
<KEYKIND>N</KEYKIND>
|
|
313
|
+
<DDTEXT>Description of table type</DDTEXT>
|
|
258
314
|
</DD40V>
|
|
259
315
|
</asx:values>
|
|
260
316
|
</asx:abap>
|
|
@@ -265,7 +321,7 @@ A **text table** stores translatable texts for another table (the "main table").
|
|
|
265
321
|
- `TYPENAME`: Table type name
|
|
266
322
|
- `ROWTYPE`: Row type (a structure or data element name)
|
|
267
323
|
- `ROWKIND`: Row kind — `S`=Structure/Type, `D`=Data element, `R`=Reference
|
|
268
|
-
- `DATATYPE`:
|
|
324
|
+
- `DATATYPE`: `STRU` when row type is a structure (`ROWKIND=S`); `TABLE_T` only for elementary-type row types
|
|
269
325
|
- `ACCESSMODE`: Table kind — `T`=Standard, `S`=Sorted, `H`=Hashed
|
|
270
326
|
- `KEYDEF`: Key definition — `D`=Default (standard key), `K`=User-defined
|
|
271
327
|
- `KEYKIND`: Key uniqueness — `N`=Non-unique, `U`=Unique
|
|
@@ -372,7 +428,7 @@ abapGit uses the view `DD01V` as the root element (not `DD01L`). The serializer
|
|
|
372
428
|
<SPRSL>E</SPRSL>
|
|
373
429
|
<ARBGB>ZMY_MSGS</ARBGB>
|
|
374
430
|
<MSGNR>000</MSGNR>
|
|
375
|
-
<TEXT>Object &1 not found</TEXT>
|
|
431
|
+
<TEXT>Object &1 not found</TEXT>
|
|
376
432
|
</T100>
|
|
377
433
|
<T100>
|
|
378
434
|
<SPRSL>E</SPRSL>
|
|
@@ -265,7 +265,7 @@ abapGit's serializer **omits fields that have their default value**. Writing ext
|
|
|
265
265
|
- `SOURCE_TYPE W` → View Entity (`define view entity`, modern — **use by default**)
|
|
266
266
|
- `SOURCE_TYPE V` → View (`define view` + `@AbapCatalog.sqlViewName`, legacy)
|
|
267
267
|
|
|
268
|
-
→ For DDL source syntax: `abapgit-agent ref --topic cds
|
|
268
|
+
→ For DDL source syntax: `abapgit-agent ref --topic cds`
|
|
269
269
|
|
|
270
270
|
---
|
|
271
271
|
|
|
@@ -290,6 +290,7 @@ abapGit's serializer **omits fields that have their default value**. Writing ext
|
|
|
290
290
|
|
|
291
291
|
- `DCLNAME` matches the CDS view name
|
|
292
292
|
- Source file contains the DCL (`@MappingRole ... define role ...`)
|
|
293
|
+
- **Pull with the `.xml` file, not `.asdcls`**: `pull --files src/zc_my_view.dcls.xml` — the `pull --files` filter does not accept `.asdcls` extensions
|
|
293
294
|
|
|
294
295
|
---
|
|
295
296
|
|
|
@@ -80,6 +80,41 @@ lv_response = lv_response && '"key":"val"}'.
|
|
|
80
80
|
| `DATA(lv) = 'literal'.` followed by `&&` | ❌ | Infers `C LENGTH N`, truncates |
|
|
81
81
|
| `DATA(lv) = 'literal'.` used only in `\|{ lv }\|` | ⚠️ | Technically works but misleading — prefer explicit type |
|
|
82
82
|
| `DATA(lv) = 'X'.` used as abap_bool flag | ✅ | `C LENGTH 1` is correct for flags |
|
|
83
|
+
| `DATA(lv) = COND string( WHEN ... THEN str+off ELSE str ).` | ❌ | Offset notation on `string` inside COND raises `CX_SY_RANGE_OUT_OF_BOUNDS` at runtime |
|
|
84
|
+
|
|
85
|
+
### The offset-notation-in-COND trap
|
|
86
|
+
|
|
87
|
+
Offset/length notation (`str+off` or `str(len)`) on a `string`-typed variable **cannot appear
|
|
88
|
+
as a result expression inside `COND`** — even when the `COND` is explicitly typed as `string`.
|
|
89
|
+
ABAP evaluates both branch types at generation time and the offset expression on a dynamic
|
|
90
|
+
string is invalid, causing a `CX_SY_RANGE_OUT_OF_BOUNDS` crash at runtime.
|
|
91
|
+
|
|
92
|
+
```abap
|
|
93
|
+
DATA lv_file TYPE string VALUE 'src/foo.clas.abap'.
|
|
94
|
+
DATA(lv_pos) = find( val = lv_file sub = '/' occ = -1 ).
|
|
95
|
+
|
|
96
|
+
* WRONG — CX_SY_RANGE_OUT_OF_BOUNDS at runtime
|
|
97
|
+
DATA(lv_path) = COND string(
|
|
98
|
+
WHEN lv_pos > 0 THEN '/' && lv_file(lv_pos + 1) " ← offset on string = crash
|
|
99
|
+
ELSE '/' ).
|
|
100
|
+
|
|
101
|
+
* CORRECT — use substring() which returns string and is safe in COND
|
|
102
|
+
DATA(lv_path) = COND string(
|
|
103
|
+
WHEN lv_pos > 0 THEN '/' && substring( val = lv_file len = lv_pos + 1 )
|
|
104
|
+
ELSE '/' ).
|
|
105
|
+
|
|
106
|
+
* ALSO CORRECT — keep IF/ELSE with DATA x TYPE string
|
|
107
|
+
DATA lv_path TYPE string.
|
|
108
|
+
IF lv_pos > 0.
|
|
109
|
+
DATA(lv_len) = lv_pos + 1.
|
|
110
|
+
lv_path = '/' && lv_file(lv_len).
|
|
111
|
+
ELSE.
|
|
112
|
+
lv_path = '/'.
|
|
113
|
+
ENDIF.
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Rule**: whenever the prefer_inline quickfix would produce `COND ... THEN str+off` or
|
|
117
|
+
`COND ... THEN str(len)`, use `substring()` instead, or keep the `IF/ELSE` form.
|
|
83
118
|
|
|
84
119
|
### Rule of thumb
|
|
85
120
|
|
|
@@ -8,7 +8,7 @@ grand_parent: ABAP Development
|
|
|
8
8
|
|
|
9
9
|
# Common ABAP Errors - Quick Fixes
|
|
10
10
|
|
|
11
|
-
**Searchable keywords**: error, syntax error, field mismatch, fixed point, comma, host variable, @ prefix, type incompatible
|
|
11
|
+
**Searchable keywords**: error, syntax error, field mismatch, fixed point, comma, host variable, @ prefix, type incompatible, string template, expression limiter, literal brace, http 500, xml metadata mismatch, interface description, descript, recompilation, offset notation, cond trap, cx_sy_range_out_of_bounds
|
|
12
12
|
|
|
13
13
|
## Fixed Point Arithmetic Error
|
|
14
14
|
|
|
@@ -119,6 +119,83 @@ or declare the variable explicitly with `TYPE string`.
|
|
|
119
119
|
|
|
120
120
|
---
|
|
121
121
|
|
|
122
|
+
## Offset Notation on String in COND — CX_SY_RANGE_OUT_OF_BOUNDS
|
|
123
|
+
|
|
124
|
+
**Symptom**: Pull succeeds but ABAP crashes at runtime with `CX_SY_RANGE_OUT_OF_BOUNDS`
|
|
125
|
+
inside a method using `COND`.
|
|
126
|
+
|
|
127
|
+
**Root cause**: Offset/length notation on a `string` variable (`str+off`, `str(len)`)
|
|
128
|
+
**cannot be used as a result expression inside `COND`** — even with an explicit `COND string(...)` type.
|
|
129
|
+
The abaplint `prefer_inline` quickfix can introduce this automatically when converting
|
|
130
|
+
an `IF/ELSE` block that assigns from a string-variable offset.
|
|
131
|
+
|
|
132
|
+
```abap
|
|
133
|
+
* WRONG — crashes at runtime with CX_SY_RANGE_OUT_OF_BOUNDS
|
|
134
|
+
DATA(lv_path) = COND string(
|
|
135
|
+
WHEN lv_pos > 0 THEN '/' && lv_file(lv_pos + 1) " ← string offset in COND
|
|
136
|
+
ELSE '/' ).
|
|
137
|
+
|
|
138
|
+
* CORRECT — use substring() instead
|
|
139
|
+
DATA(lv_path) = COND string(
|
|
140
|
+
WHEN lv_pos > 0 THEN '/' && substring( val = lv_file len = lv_pos + 1 )
|
|
141
|
+
ELSE '/' ).
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Fix**: Replace `str+off` / `str(len)` inside `COND` results with `substring( val = str off = off )` or
|
|
145
|
+
`substring( val = str len = len )`, or revert to the `IF/ELSE` form with `DATA x TYPE string`.
|
|
146
|
+
|
|
147
|
+
→ See `abaplint.md` for the full safe/unsafe table for `prefer_inline`.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## XML Metadata Mismatch — HTTP 500 on Pull
|
|
152
|
+
|
|
153
|
+
**Symptom**: `pull` returns HTTP 500 with no short dump (ST22) for the request user.
|
|
154
|
+
Other objects pull fine; only a specific interface or class fails.
|
|
155
|
+
|
|
156
|
+
**Root cause**: The `.intf.xml` or `.clas.xml` file in git has a metadata field (e.g. `DESCRIPT`,
|
|
157
|
+
`UNICODE`, `STATE`) that differs from the active ABAP system value. abapGit writes the git
|
|
158
|
+
value back to VSEOINTERF/VSEOCLASS, which forces the SAP class framework to recompile all
|
|
159
|
+
implementing/inheriting objects. If any implementing class has a syntax or generation
|
|
160
|
+
issue with the current active source, the recompilation crashes outside the normal exception
|
|
161
|
+
handler — producing HTTP 500 with no dump.
|
|
162
|
+
|
|
163
|
+
**Diagnosis**:
|
|
164
|
+
1. No dump in ST22 for your user → not a user-code crash
|
|
165
|
+
2. Only one specific INTF/CLAS fails → metadata delta in its XML triggers recompilation
|
|
166
|
+
3. Check what differs: `abapgit-agent view --objects ZIF_MY_INTF --type INTF` and compare
|
|
167
|
+
`DESCRIPT` / other fields with the XML file in git
|
|
168
|
+
|
|
169
|
+
**Fix**: Sync the XML to match the ABAP system value. The easiest way:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
# Pull without --sync-xml first to let abapGit rewrite the XML from the system
|
|
173
|
+
abapgit-agent pull --files abap/zif_my_intf.intf.abap --sync-xml
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Or manually correct the field in the XML file to match the system value, then push and pull.
|
|
177
|
+
|
|
178
|
+
**Prevention**: Always use `--sync-xml` after pulling new objects so the XML stays in sync
|
|
179
|
+
with what the ABAP serializer produces.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
**Error**: `Expression limiter '{' in string template not followed by space`
|
|
184
|
+
|
|
185
|
+
Literal `{` and `}` (e.g. in JSON payloads) must be escaped as `\{` and `\}` inside `|...|`.
|
|
186
|
+
|
|
187
|
+
```abap
|
|
188
|
+
" WRONG — unescaped { in JSON triggers parse error
|
|
189
|
+
rv_result = |{"success":"X","name":"{ lv_name }"}|.
|
|
190
|
+
|
|
191
|
+
" CORRECT
|
|
192
|
+
rv_result = |\{"success":"X","name":"{ lv_name }"\}|.
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
→ Full escaping rules and examples: `abapgit-agent ref --topic string-template`
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
122
199
|
## See Also
|
|
123
200
|
- **ABAP SQL** (sql.md) - for SQL syntax rules
|
|
124
201
|
- **CDS Views** (cds.md) - for CDS selection patterns
|
package/abap/guidelines/index.md
CHANGED
|
@@ -20,6 +20,7 @@ This folder contains detailed ABAP coding guidelines that can be searched using
|
|
|
20
20
|
| `cds.md` | CDS Views |
|
|
21
21
|
| `classes.md` | ABAP Classes and Objects |
|
|
22
22
|
| `objects.md` | Object Naming Conventions |
|
|
23
|
+
| `naming-limits.md` | Naming Length Limits (30/16/40 char rules per type) |
|
|
23
24
|
| `json.md` | JSON Handling |
|
|
24
25
|
| `abapgit.md` | abapGit XML Metadata Templates |
|
|
25
26
|
| `unit-testable-code.md` | Unit Testable Code Guidelines (Dependency Injection) |
|