abapgit-agent 1.16.0 → 1.16.2
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 +24 -4
- package/package.json +1 -1
- package/src/commands/dump.js +30 -0
- package/src/commands/health.js +12 -0
- package/src/commands/help.js +32 -1
- package/src/commands/import.js +13 -1
- package/src/commands/inspect.js +23 -0
- package/src/commands/lint.js +26 -0
- package/src/commands/list.js +25 -0
- package/src/commands/preview.js +30 -0
- package/src/commands/pull.js +32 -0
- package/src/commands/run.js +21 -0
- package/src/commands/status.js +13 -0
- package/src/commands/syntax.js +159 -8
- package/src/commands/tree.js +22 -0
- package/src/commands/unit.js +23 -0
- package/src/commands/upgrade.js +28 -0
- package/src/commands/view.js +29 -0
- package/src/commands/where.js +24 -0
- package/src/config.js +2 -0
- package/src/utils/abap-reference.js +9 -10
package/abap/CLAUDE.md
CHANGED
|
@@ -494,7 +494,16 @@ Never assume — wait for the user's answer before proceeding.
|
|
|
494
494
|
|
|
495
495
|
**Critical rules for `debug` sessions:**
|
|
496
496
|
|
|
497
|
-
|
|
497
|
+
```
|
|
498
|
+
❌ WRONG: abapgit-agent debug attach
|
|
499
|
+
❌ WRONG: abapgit-agent debug vars
|
|
500
|
+
❌ WRONG: abapgit-agent debug step --type continue
|
|
501
|
+
✅ CORRECT: abapgit-agent debug attach --json > /tmp/a.json 2>&1 &
|
|
502
|
+
✅ CORRECT: abapgit-agent debug vars --json
|
|
503
|
+
✅ CORRECT: abapgit-agent debug step --type continue --json
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
1. **Always use `--json`** for ALL debug commands (`attach`, `vars`, `stack`, `step`) — human output is not machine-parseable. This is non-negotiable.
|
|
498
507
|
2. **Attach BEFORE trigger** — start `debug attach --json` in background first, wait for `"Listener active"`, THEN fire the trigger (`unit`/`pull`/`run`)
|
|
499
508
|
3. **Never pull to trigger** if a simpler trigger works — use `unit` when a test exists, `run` for a class runner; use `pull` only when the bug is specifically in the pull flow
|
|
500
509
|
4. **Never pass `--session`** to `step/vars/stack` — it bypasses the daemon and causes errors
|
|
@@ -502,7 +511,12 @@ Never assume — wait for the user's answer before proceeding.
|
|
|
502
511
|
|
|
503
512
|
**Finding the right line number for a breakpoint:**
|
|
504
513
|
|
|
505
|
-
|
|
514
|
+
```
|
|
515
|
+
❌ WRONG: abapgit-agent debug set --objects ZCL_FOO:42 ← never guess a line number
|
|
516
|
+
✅ CORRECT: abapgit-agent view --objects ZCL_FOO --full --lines ← get exact line from output
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
Always run `view --full --lines` first — it prints a ready-to-use `debug set` command for every method. Never guess or estimate line numbers.
|
|
506
520
|
|
|
507
521
|
```bash
|
|
508
522
|
abapgit-agent view --objects ZCL_FOO --full --lines
|
|
@@ -542,7 +556,8 @@ abapgit-agent debug set --objects LSUSRU04:50
|
|
|
542
556
|
|
|
543
557
|
Minimal correct sequence:
|
|
544
558
|
```bash
|
|
545
|
-
abapgit-agent
|
|
559
|
+
abapgit-agent view --objects ZCL_FOO --full --lines # 0. get exact line number from output hint
|
|
560
|
+
abapgit-agent debug set --objects ZCL_FOO:42 # 1. set breakpoint (use line from step 0)
|
|
546
561
|
abapgit-agent debug attach --json > /tmp/a.json 2>&1 & # 2. attach (background)
|
|
547
562
|
until grep -q "Listener active" /tmp/a.json 2>/dev/null; do sleep 0.3; done
|
|
548
563
|
abapgit-agent unit --files src/zcl_foo.clas.testclasses.abap > /tmp/t.json 2>&1 & # 3. trigger
|
|
@@ -555,7 +570,7 @@ abapgit-agent debug step --type continue --json # 4. release
|
|
|
555
570
|
|
|
556
571
|
---
|
|
557
572
|
|
|
558
|
-
###
|
|
573
|
+
### 13. abaplint — Static Analysis (Optional, Project-Controlled)
|
|
559
574
|
|
|
560
575
|
abaplint is **optional**. Only run it if `.abaplint.json` exists in the project root.
|
|
561
576
|
Each project defines its own rules — never assume which rules are active.
|
|
@@ -617,6 +632,7 @@ Checked into the repository — applies to all developers. **Read this file at t
|
|
|
617
632
|
|---------|--------|---------|--------|
|
|
618
633
|
| `safeguards.requireFilesForPull` | `true`/`false` | `false` | Requires `--files` on every pull |
|
|
619
634
|
| `safeguards.disablePull` | `true`/`false` | `false` | Disables pull entirely (CI/CD-only projects) |
|
|
635
|
+
| `safeguards.disableImport` | `true`/`false` | `false` | Disables import entirely (one-time or managed operation) |
|
|
620
636
|
| `conflictDetection.mode` | `"abort"`/`"ignore"` | `"abort"` | Whether to abort pull on conflict |
|
|
621
637
|
| `transports.hook.path` | string | `null` | Path to JS module that auto-selects a transport for pull |
|
|
622
638
|
| `transports.hook.description` | string | `null` | Optional label shown when the hook runs |
|
|
@@ -709,6 +725,10 @@ abapgit-agent pull --files src/<name>.clas.abap --sync-xml
|
|
|
709
725
|
1. ✗ Do not run `abapgit-agent run` at all
|
|
710
726
|
2. ✓ Inform the user that run is disabled for this project
|
|
711
727
|
|
|
728
|
+
**When `safeguards.disableImport = true`:**
|
|
729
|
+
1. ✗ Do not run `abapgit-agent import` at all
|
|
730
|
+
2. ✓ Inform the user that import is disabled for this project
|
|
731
|
+
|
|
712
732
|
**When `safeguards.disableProbeClasses = true`:**
|
|
713
733
|
1. ✗ Do not create probe classes in the current project
|
|
714
734
|
2. ✓ If `scratchWorkspace` is configured → create probe class there (see Rule 10)
|
package/package.json
CHANGED
package/src/commands/dump.js
CHANGED
|
@@ -196,6 +196,36 @@ module.exports = {
|
|
|
196
196
|
async execute(args, context) {
|
|
197
197
|
const { loadConfig, AbapHttp } = context;
|
|
198
198
|
|
|
199
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
200
|
+
console.log(`
|
|
201
|
+
Usage:
|
|
202
|
+
abapgit-agent dump [--user <user>] [--date <date>] [--time <HH:MM..HH:MM>]
|
|
203
|
+
[--program <prog>] [--error <error>] [--limit <n>] [--detail <n>] [--json]
|
|
204
|
+
|
|
205
|
+
Description:
|
|
206
|
+
Query short dumps (ST22) from the ABAP system.
|
|
207
|
+
|
|
208
|
+
Parameters:
|
|
209
|
+
--user <user> Filter by user name.
|
|
210
|
+
--date <date> Filter by date: TODAY, YESTERDAY, or YYYYMMDD or YYYYMMDD..YYYYMMDD.
|
|
211
|
+
--time <HH:MM..HH:MM> Filter by time range (e.g. 08:00..17:00).
|
|
212
|
+
--program <prog> Filter by program name.
|
|
213
|
+
--error <error> Filter by error type (e.g. RABAX_STATE).
|
|
214
|
+
--timezone <tz> Timezone for date/time filter (default: system timezone).
|
|
215
|
+
--limit <n> Maximum number of results (default: 10).
|
|
216
|
+
--detail <n> Show full detail of the Nth result (1-based).
|
|
217
|
+
--json Output as JSON.
|
|
218
|
+
|
|
219
|
+
Examples:
|
|
220
|
+
abapgit-agent dump
|
|
221
|
+
abapgit-agent dump --date TODAY
|
|
222
|
+
abapgit-agent dump --user DEVELOPER
|
|
223
|
+
abapgit-agent dump --date TODAY --limit 20
|
|
224
|
+
abapgit-agent dump --user DEVELOPER --detail 1
|
|
225
|
+
`);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
199
229
|
const idx = (flag) => args.indexOf(flag);
|
|
200
230
|
const val = (flag) => {
|
|
201
231
|
const i = idx(flag);
|
package/src/commands/health.js
CHANGED
|
@@ -11,6 +11,18 @@ module.exports = {
|
|
|
11
11
|
async execute(args, context) {
|
|
12
12
|
const { config, AbapHttp } = context;
|
|
13
13
|
|
|
14
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
15
|
+
console.log(`
|
|
16
|
+
Usage:
|
|
17
|
+
abapgit-agent health
|
|
18
|
+
|
|
19
|
+
Description:
|
|
20
|
+
Check if the ABAP REST API (z_abapgit_agent) is reachable and responding.
|
|
21
|
+
Useful for verifying connectivity and configuration.
|
|
22
|
+
`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
14
26
|
try {
|
|
15
27
|
const http = new AbapHttp(config);
|
|
16
28
|
const result = await http.get('/sap/bc/z_abapgit_agent/health');
|
package/src/commands/help.js
CHANGED
|
@@ -48,6 +48,24 @@ Commands:
|
|
|
48
48
|
unit --files <file1>,<file2>,...
|
|
49
49
|
Run AUnit tests for ABAP test class files (.testclasses.abap)
|
|
50
50
|
|
|
51
|
+
run --program <NAME> | --class <NAME>
|
|
52
|
+
Execute an ABAP program or class (IF_OO_ADT_CLASSRUN) and display its output.
|
|
53
|
+
|
|
54
|
+
drop --files <file> [--pull] [--transport <TRANSPORT>] [--conflict-mode <mode>]
|
|
55
|
+
Physically delete a single ABAP object from the ABAP system.
|
|
56
|
+
Use --pull to immediately re-activate from git after deletion.
|
|
57
|
+
|
|
58
|
+
lint [--files <file1,...>] [--base <branch>] [--config <file>]
|
|
59
|
+
Run abaplint static analysis on changed ABAP files. Requires .abaplint.json.
|
|
60
|
+
|
|
61
|
+
debug <subcommand> [options]
|
|
62
|
+
Manage ABAP debugger breakpoints and attach debug sessions.
|
|
63
|
+
Subcommands: set, list, delete, attach, step, vars, stack
|
|
64
|
+
|
|
65
|
+
transport <subcommand> [options]
|
|
66
|
+
List and manage SAP transport requests.
|
|
67
|
+
Subcommands: list, create, release
|
|
68
|
+
|
|
51
69
|
tree --package <package> [--depth <n>] [--include-types] [--json]
|
|
52
70
|
Display package hierarchy tree from ABAP system
|
|
53
71
|
|
|
@@ -57,6 +75,9 @@ Commands:
|
|
|
57
75
|
view --objects <obj1>,<obj2>,... [--type <type>] [--json]
|
|
58
76
|
View ABAP object definitions from the ABAP system
|
|
59
77
|
|
|
78
|
+
preview --objects <obj1>,... [--type <type>] [--limit <n>] [--where <cond>] [--json]
|
|
79
|
+
Preview data from ABAP tables or CDS views
|
|
80
|
+
|
|
60
81
|
where --objects <obj1>,<obj2>,... [--type <type>] [--limit <n>] [--json]
|
|
61
82
|
Find where-used list for ABAP objects (classes, interfaces, programs)
|
|
62
83
|
|
|
@@ -93,6 +114,9 @@ Commands:
|
|
|
93
114
|
- Use --dry-run to preview changes without applying them
|
|
94
115
|
- Use --yes to skip confirmation prompt
|
|
95
116
|
|
|
117
|
+
upgrade [--abap-only] [--cli-only] [--version <v>]
|
|
118
|
+
Upgrade CLI and/or ABAP backend to latest or specific version.
|
|
119
|
+
|
|
96
120
|
health
|
|
97
121
|
Check if ABAP REST API is healthy
|
|
98
122
|
|
|
@@ -114,9 +138,14 @@ Examples:
|
|
|
114
138
|
abapgit-agent syntax --files src/zcl_my_class.clas.abap # Check without pull
|
|
115
139
|
abapgit-agent syntax --files src/zmy_prog.prog.abap --cloud # ABAP Cloud check
|
|
116
140
|
abapgit-agent unit --files src/zcl_my_test.clas.testclasses.abap # Run unit tests
|
|
117
|
-
abapgit-agent
|
|
141
|
+
abapgit-agent run --program ZMY_REPORT # Execute report
|
|
142
|
+
abapgit-agent run --class ZCL_MY_RUNNER # Execute class
|
|
143
|
+
abapgit-agent drop --files src/zcl_foo.clas.abap --pull # Drop and re-activate
|
|
144
|
+
abapgit-agent lint # abaplint on changed files
|
|
145
|
+
abapgit-agent tree --package $MY_PACKAGE # Display package tree
|
|
118
146
|
abapgit-agent list --package $MY_PACKAGE --type CLAS,INTF # List classes & interfaces
|
|
119
147
|
abapgit-agent view --objects ZCL_MY_CLASS # View class definition
|
|
148
|
+
abapgit-agent preview --objects SFLIGHT # Preview table data
|
|
120
149
|
abapgit-agent where --objects ZCL_MY_CLASS # Find where class is used
|
|
121
150
|
abapgit-agent dump --date TODAY # Recent short dumps
|
|
122
151
|
abapgit-agent dump --user DEVELOPER --detail 1 # Full detail of first result
|
|
@@ -127,6 +156,8 @@ Examples:
|
|
|
127
156
|
abapgit-agent health # Health check
|
|
128
157
|
abapgit-agent status # Configuration status
|
|
129
158
|
|
|
159
|
+
Run "abapgit-agent <command> --help" for detailed usage of any command.
|
|
160
|
+
|
|
130
161
|
For more info: https://github.com/SylvosCai/abapgit-agent
|
|
131
162
|
`);
|
|
132
163
|
}
|
package/src/commands/import.js
CHANGED
|
@@ -18,7 +18,7 @@ module.exports = {
|
|
|
18
18
|
|
|
19
19
|
async execute(args, context) {
|
|
20
20
|
try {
|
|
21
|
-
const { loadConfig, gitUtils, AbapHttp } = context;
|
|
21
|
+
const { loadConfig, gitUtils, AbapHttp, getSafeguards } = context;
|
|
22
22
|
|
|
23
23
|
// Show help if requested
|
|
24
24
|
const helpIndex = args.findIndex(a => a === '--help' || a === '-h');
|
|
@@ -48,6 +48,18 @@ Examples:
|
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
// Get parameters from config
|
|
52
|
+
const safeguards = getSafeguards();
|
|
53
|
+
if (safeguards.disableImport) {
|
|
54
|
+
console.error('❌ Error: import command is disabled for this project\n');
|
|
55
|
+
if (safeguards.reason) {
|
|
56
|
+
console.error(`Reason: ${safeguards.reason}\n`);
|
|
57
|
+
}
|
|
58
|
+
console.error('The import command has been disabled in .abapgit-agent.json');
|
|
59
|
+
console.error('Please contact the project maintainer to enable it.');
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
51
63
|
// Get parameters from config
|
|
52
64
|
const config = loadConfig();
|
|
53
65
|
const repoUrl = gitUtils.getRemoteUrl();
|
package/src/commands/inspect.js
CHANGED
|
@@ -250,6 +250,29 @@ module.exports = {
|
|
|
250
250
|
async execute(args, context) {
|
|
251
251
|
const { loadConfig, AbapHttp } = context;
|
|
252
252
|
|
|
253
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
254
|
+
console.log(`
|
|
255
|
+
Usage:
|
|
256
|
+
abapgit-agent inspect --files <file1>,<file2>,... [--variant <check-variant>] [--junit-output <file>] [--json]
|
|
257
|
+
|
|
258
|
+
Description:
|
|
259
|
+
Run SAP Code Inspector checks on activated ABAP objects. Requires the objects
|
|
260
|
+
to be already active in the ABAP system (run pull first).
|
|
261
|
+
|
|
262
|
+
Parameters:
|
|
263
|
+
--files <file1,...> Comma-separated ABAP source files (required).
|
|
264
|
+
--variant <variant> Code Inspector variant (default: system default).
|
|
265
|
+
--junit-output <file> Write results as JUnit XML to this file.
|
|
266
|
+
--json Output as JSON.
|
|
267
|
+
|
|
268
|
+
Examples:
|
|
269
|
+
abapgit-agent inspect --files src/zcl_my_class.clas.abap
|
|
270
|
+
abapgit-agent inspect --files src/zcl_my_class.clas.abap --variant ALL_CHECKS
|
|
271
|
+
abapgit-agent inspect --files src/zcl_my_class.clas.abap --junit-output reports/inspect.xml
|
|
272
|
+
`);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
|
|
253
276
|
const jsonOutput = args.includes('--json');
|
|
254
277
|
const verbose = args.includes('--verbose');
|
|
255
278
|
const filesArgIndex = args.indexOf('--files');
|
package/src/commands/lint.js
CHANGED
|
@@ -24,6 +24,32 @@ module.exports = {
|
|
|
24
24
|
requiresAbapConfig: false,
|
|
25
25
|
|
|
26
26
|
execute(args) {
|
|
27
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
28
|
+
console.log(`
|
|
29
|
+
Usage:
|
|
30
|
+
abapgit-agent lint [--files <file1,...>] [--base <branch>] [--config <file>]
|
|
31
|
+
[--outformat <format>] [--outfile <file>]
|
|
32
|
+
|
|
33
|
+
Description:
|
|
34
|
+
Run abaplint static analysis on changed ABAP files. Requires .abaplint.json in repo root.
|
|
35
|
+
By default detects files changed vs HEAD~1 (or vs --base branch).
|
|
36
|
+
|
|
37
|
+
Parameters:
|
|
38
|
+
--files <file1,...> Check specific files instead of auto-detecting changed files.
|
|
39
|
+
--base <branch> Diff against this branch instead of HEAD~1 (e.g. main).
|
|
40
|
+
--config <file> abaplint config file (default: .abaplint.json).
|
|
41
|
+
--outformat <format> Output format: checkstyle (default: text).
|
|
42
|
+
--outfile <file> Write output to file instead of stdout.
|
|
43
|
+
|
|
44
|
+
Examples:
|
|
45
|
+
abapgit-agent lint
|
|
46
|
+
abapgit-agent lint --base main
|
|
47
|
+
abapgit-agent lint --files src/zcl_foo.clas.abap
|
|
48
|
+
abapgit-agent lint --outformat checkstyle --outfile reports/abaplint.xml
|
|
49
|
+
`);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
27
53
|
const configPath = argValue(args, '--config') || '.abaplint.json';
|
|
28
54
|
const baseBranch = argValue(args, '--base');
|
|
29
55
|
const filesArg = argValue(args, '--files');
|
package/src/commands/list.js
CHANGED
|
@@ -11,6 +11,31 @@ module.exports = {
|
|
|
11
11
|
async execute(args, context) {
|
|
12
12
|
const { loadConfig, AbapHttp } = context;
|
|
13
13
|
|
|
14
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
15
|
+
console.log(`
|
|
16
|
+
Usage:
|
|
17
|
+
abapgit-agent list --package <package> [--type <types>] [--name <pattern>] [--limit <n>] [--offset <n>] [--json]
|
|
18
|
+
|
|
19
|
+
Description:
|
|
20
|
+
List ABAP objects in a package with optional filtering and pagination.
|
|
21
|
+
|
|
22
|
+
Parameters:
|
|
23
|
+
--package <package> Package to list (required). Enclose $-packages in quotes.
|
|
24
|
+
--type <types> Comma-separated object types to filter (e.g. CLAS,INTF).
|
|
25
|
+
--name <pattern> Filter by object name pattern (e.g. ZCL_MY*).
|
|
26
|
+
--limit <n> Maximum number of results (default: 100).
|
|
27
|
+
--offset <n> Skip first N results (for pagination).
|
|
28
|
+
--json Output as JSON.
|
|
29
|
+
|
|
30
|
+
Examples:
|
|
31
|
+
abapgit-agent list --package ZMY_PACKAGE
|
|
32
|
+
abapgit-agent list --package ZMY_PACKAGE --type CLAS,INTF
|
|
33
|
+
abapgit-agent list --package ZMY_PACKAGE --name ZCL_MY*
|
|
34
|
+
abapgit-agent list --package ZMY_PACKAGE --limit 20 --offset 40
|
|
35
|
+
`);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
14
39
|
const packageArgIndex = args.indexOf('--package');
|
|
15
40
|
if (packageArgIndex === -1) {
|
|
16
41
|
console.error('Error: --package parameter required');
|
package/src/commands/preview.js
CHANGED
|
@@ -11,6 +11,36 @@ module.exports = {
|
|
|
11
11
|
async execute(args, context) {
|
|
12
12
|
const { loadConfig, AbapHttp, validators } = context;
|
|
13
13
|
|
|
14
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
15
|
+
console.log(`
|
|
16
|
+
Usage:
|
|
17
|
+
abapgit-agent preview --objects <obj1>,... [--type <type>] [--limit <n>] [--offset <n>]
|
|
18
|
+
[--where <condition>] [--columns <cols>] [--vertical] [--compact] [--json]
|
|
19
|
+
|
|
20
|
+
Description:
|
|
21
|
+
Preview data from ABAP tables or CDS views.
|
|
22
|
+
|
|
23
|
+
Parameters:
|
|
24
|
+
--objects <obj1,...> Comma-separated table/view names (required).
|
|
25
|
+
--type <type> Object type: TABL, DDLS (auto-detected if omitted).
|
|
26
|
+
--limit <n> Maximum number of rows (default: 20).
|
|
27
|
+
--offset <n> Skip first N rows (for pagination).
|
|
28
|
+
--where <condition> WHERE clause filter (e.g. "CARRID = 'AA'").
|
|
29
|
+
--columns <cols> Comma-separated column names to display.
|
|
30
|
+
--vertical Display each row vertically (field: value).
|
|
31
|
+
--compact Compact output (no borders).
|
|
32
|
+
--json Output as JSON.
|
|
33
|
+
|
|
34
|
+
Examples:
|
|
35
|
+
abapgit-agent preview --objects SFLIGHT
|
|
36
|
+
abapgit-agent preview --objects SFLIGHT --limit 5
|
|
37
|
+
abapgit-agent preview --objects SFLIGHT --where "CARRID = 'AA'"
|
|
38
|
+
abapgit-agent preview --objects ZC_MY_VIEW --type DDLS
|
|
39
|
+
abapgit-agent preview --objects SFLIGHT --offset 10 --limit 20
|
|
40
|
+
`);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
14
44
|
const objectsArgIndex = args.indexOf('--objects');
|
|
15
45
|
if (objectsArgIndex === -1 || objectsArgIndex + 1 >= args.length) {
|
|
16
46
|
console.error('Error: --objects parameter required');
|
package/src/commands/pull.js
CHANGED
|
@@ -42,6 +42,38 @@ module.exports = {
|
|
|
42
42
|
|
|
43
43
|
async execute(args, context) {
|
|
44
44
|
const { loadConfig, AbapHttp, gitUtils, getTransport, getSafeguards, getConflictSettings, getTransportSettings } = context;
|
|
45
|
+
|
|
46
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
47
|
+
console.log(`
|
|
48
|
+
Usage:
|
|
49
|
+
abapgit-agent pull [--url <git-url>] [--branch <branch>] [--files <file1,file2,...>]
|
|
50
|
+
[--transport <TRANSPORT>] [--conflict-mode <mode>] [--sync-xml]
|
|
51
|
+
|
|
52
|
+
Description:
|
|
53
|
+
Pull and activate ABAP objects from a git repository into the ABAP system.
|
|
54
|
+
Auto-detects git remote URL and branch from the current directory.
|
|
55
|
+
|
|
56
|
+
Parameters:
|
|
57
|
+
--url <git-url> Git repository URL. Auto-detected from git remote if omitted.
|
|
58
|
+
--branch <branch> Branch to pull from. Auto-detected from current branch if omitted.
|
|
59
|
+
--files <file1,...> Comma-separated list of files to pull (selective activation).
|
|
60
|
+
--transport <TRANSPORT> Transport request (e.g. DEVK900001).
|
|
61
|
+
--conflict-mode <mode> Conflict handling: abort (default) or ignore.
|
|
62
|
+
--sync-xml Rewrite XML metadata files to match ABAP serializer output.
|
|
63
|
+
--verbose Show detailed activation output.
|
|
64
|
+
|
|
65
|
+
Examples:
|
|
66
|
+
abapgit-agent pull
|
|
67
|
+
abapgit-agent pull --branch develop
|
|
68
|
+
abapgit-agent pull --files src/zcl_my_class.clas.abap
|
|
69
|
+
abapgit-agent pull --files src/zcl_foo.clas.abap,src/zif_foo.intf.abap
|
|
70
|
+
abapgit-agent pull --transport DEVK900001
|
|
71
|
+
abapgit-agent pull --conflict-mode ignore
|
|
72
|
+
abapgit-agent pull --files src/zcl_foo.clas.abap --sync-xml
|
|
73
|
+
`);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
45
77
|
const verbose = args.includes('--verbose');
|
|
46
78
|
const syncXml = args.includes('--sync-xml');
|
|
47
79
|
|
package/src/commands/run.js
CHANGED
|
@@ -33,6 +33,27 @@ module.exports = {
|
|
|
33
33
|
async execute(args, context) {
|
|
34
34
|
const { loadConfig, getSafeguards } = context;
|
|
35
35
|
|
|
36
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
37
|
+
console.log(`
|
|
38
|
+
Usage:
|
|
39
|
+
abapgit-agent run --program <NAME>
|
|
40
|
+
abapgit-agent run --class <NAME>
|
|
41
|
+
|
|
42
|
+
Description:
|
|
43
|
+
Execute an ABAP program or a class implementing IF_OO_ADT_CLASSRUN and display its output.
|
|
44
|
+
|
|
45
|
+
Parameters:
|
|
46
|
+
--program <NAME> Execute an ABAP report/program.
|
|
47
|
+
--class <NAME> Execute a class implementing IF_OO_ADT_CLASSRUN (run method).
|
|
48
|
+
--json Output as JSON.
|
|
49
|
+
|
|
50
|
+
Examples:
|
|
51
|
+
abapgit-agent run --program ZMY_REPORT
|
|
52
|
+
abapgit-agent run --class ZCL_MY_RUNNER
|
|
53
|
+
`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
36
57
|
// Check project-level safeguards
|
|
37
58
|
const safeguards = getSafeguards();
|
|
38
59
|
if (safeguards.disableRun) {
|
package/src/commands/status.js
CHANGED
|
@@ -13,6 +13,19 @@ module.exports = {
|
|
|
13
13
|
async execute(args, context) {
|
|
14
14
|
const { gitUtils, isAbapIntegrationEnabled, AbapHttp, loadConfig } = context;
|
|
15
15
|
|
|
16
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
17
|
+
console.log(`
|
|
18
|
+
Usage:
|
|
19
|
+
abapgit-agent status
|
|
20
|
+
|
|
21
|
+
Description:
|
|
22
|
+
Check whether ABAP integration is configured for the current repository.
|
|
23
|
+
Shows the config location, SAP host, and whether the abapGit online repository
|
|
24
|
+
is registered in the ABAP system.
|
|
25
|
+
`);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
16
29
|
if (isAbapIntegrationEnabled()) {
|
|
17
30
|
console.log('✅ ABAP Git Agent is ENABLED');
|
|
18
31
|
console.log(' Config location:', pathModule.join(process.cwd(), '.abapGitAgent'));
|
package/src/commands/syntax.js
CHANGED
|
@@ -14,6 +14,28 @@ module.exports = {
|
|
|
14
14
|
async execute(args, context) {
|
|
15
15
|
const { loadConfig, AbapHttp } = context;
|
|
16
16
|
|
|
17
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
18
|
+
console.log(`
|
|
19
|
+
Usage:
|
|
20
|
+
abapgit-agent syntax --files <file1>,<file2>,... [--cloud] [--json]
|
|
21
|
+
|
|
22
|
+
Description:
|
|
23
|
+
Check syntax of local ABAP source files WITHOUT pulling or activating them.
|
|
24
|
+
Reads source from local files and checks directly in the ABAP system.
|
|
25
|
+
|
|
26
|
+
Parameters:
|
|
27
|
+
--files <file1,...> Comma-separated ABAP source files (required). Accepts CLAS, INTF, PROG.
|
|
28
|
+
--cloud Use ABAP Cloud (BTP) stricter syntax check.
|
|
29
|
+
--json Output as JSON.
|
|
30
|
+
|
|
31
|
+
Examples:
|
|
32
|
+
abapgit-agent syntax --files src/zcl_my_class.clas.abap
|
|
33
|
+
abapgit-agent syntax --files src/zcl_foo.clas.abap,src/zif_foo.intf.abap
|
|
34
|
+
abapgit-agent syntax --files src/zmy_prog.prog.abap --cloud
|
|
35
|
+
`);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
|
|
17
39
|
const filesArgIndex = args.indexOf('--files');
|
|
18
40
|
if (filesArgIndex === -1 || filesArgIndex + 1 >= args.length) {
|
|
19
41
|
console.error('Error: --files parameter required');
|
|
@@ -49,6 +71,7 @@ module.exports = {
|
|
|
49
71
|
// Group class files together (main + locals)
|
|
50
72
|
const classFilesMap = new Map(); // className -> { main, locals_def, locals_imp }
|
|
51
73
|
const fugrGroupMap = new Map(); // groupName -> { dir, fmFiles: Map<fmName, source> }
|
|
74
|
+
const progIncludeMap = new Map(); // includeName -> { filePath, source }
|
|
52
75
|
const objects = [];
|
|
53
76
|
|
|
54
77
|
for (const file of syntaxFiles) {
|
|
@@ -143,7 +166,7 @@ module.exports = {
|
|
|
143
166
|
source: source
|
|
144
167
|
};
|
|
145
168
|
|
|
146
|
-
// Read FIXPT from XML metadata for INTF and PROG
|
|
169
|
+
// Read FIXPT and SUBC from XML metadata for INTF and PROG
|
|
147
170
|
if (objType === 'INTF' || objType === 'PROG') {
|
|
148
171
|
const dir = pathModule.dirname(filePath);
|
|
149
172
|
let xmlFile;
|
|
@@ -154,14 +177,22 @@ module.exports = {
|
|
|
154
177
|
}
|
|
155
178
|
if (xmlFile && fs.existsSync(xmlFile)) {
|
|
156
179
|
const xmlContent = fs.readFileSync(xmlFile, 'utf8');
|
|
157
|
-
// Simple regex to extract FIXPT value
|
|
158
180
|
const fixptMatch = xmlContent.match(/<FIXPT>([^<]+)<\/FIXPT>/);
|
|
159
181
|
if (fixptMatch && fixptMatch[1] === 'X') {
|
|
160
182
|
obj.fixpt = 'X';
|
|
161
183
|
} else {
|
|
162
|
-
// No FIXPT tag means FIXPT=false (blank)
|
|
163
184
|
obj.fixpt = '';
|
|
164
185
|
}
|
|
186
|
+
if (objType === 'PROG') {
|
|
187
|
+
const subcMatch = xmlContent.match(/<SUBC>([^<]+)<\/SUBC>/);
|
|
188
|
+
obj.subc = subcMatch ? subcMatch[1] : '';
|
|
189
|
+
|
|
190
|
+
// INCLUDE programs: stash for parent auto-detection instead of pushing directly
|
|
191
|
+
if (obj.subc === 'I') {
|
|
192
|
+
progIncludeMap.set(objName, { filePath, source });
|
|
193
|
+
continue; // skip objects.push — handled after auto-detection below
|
|
194
|
+
}
|
|
195
|
+
}
|
|
165
196
|
}
|
|
166
197
|
}
|
|
167
198
|
|
|
@@ -330,12 +361,102 @@ module.exports = {
|
|
|
330
361
|
}
|
|
331
362
|
}
|
|
332
363
|
|
|
364
|
+
// Helper: read SUBC from a .prog.xml file
|
|
365
|
+
function readProgSubc(xmlPath) {
|
|
366
|
+
if (!fs.existsSync(xmlPath)) return '';
|
|
367
|
+
const xml = fs.readFileSync(xmlPath, 'utf8');
|
|
368
|
+
const m = xml.match(/<SUBC>([^<]+)<\/SUBC>/);
|
|
369
|
+
return m ? m[1] : '';
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Helper: read FIXPT from a .prog.xml file
|
|
373
|
+
function readProgFixpt(xmlPath) {
|
|
374
|
+
if (!fs.existsSync(xmlPath)) return '';
|
|
375
|
+
const xml = fs.readFileSync(xmlPath, 'utf8');
|
|
376
|
+
const m = xml.match(/<FIXPT>([^<]+)<\/FIXPT>/);
|
|
377
|
+
return (m && m[1] === 'X') ? 'X' : '';
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Auto-detect parent program for INCLUDE files
|
|
381
|
+
// Scan the same directory for .prog.abap files that contain INCLUDE <name>.
|
|
382
|
+
// Assemble the parent source with the INCLUDE source substituted in-place.
|
|
383
|
+
for (const [includeName, includeData] of progIncludeMap) {
|
|
384
|
+
const includeDir = pathModule.dirname(includeData.filePath);
|
|
385
|
+
let parentFound = false;
|
|
386
|
+
|
|
387
|
+
let dirEntries;
|
|
388
|
+
try {
|
|
389
|
+
dirEntries = fs.readdirSync(includeDir);
|
|
390
|
+
} catch (e) {
|
|
391
|
+
dirEntries = [];
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
for (const entry of dirEntries) {
|
|
395
|
+
if (!entry.toLowerCase().endsWith('.prog.abap')) continue;
|
|
396
|
+
const candidatePath = pathModule.join(includeDir, entry);
|
|
397
|
+
if (candidatePath === includeData.filePath) continue; // skip itself
|
|
398
|
+
|
|
399
|
+
// Only consider executable/non-include programs as parents
|
|
400
|
+
const candidateName = entry.split('.')[0].toUpperCase();
|
|
401
|
+
const candidateXml = pathModule.join(includeDir, `${candidateName.toLowerCase()}.prog.xml`);
|
|
402
|
+
const candidateSubc = readProgSubc(candidateXml);
|
|
403
|
+
if (candidateSubc === 'I') continue; // another INCLUDE — skip
|
|
404
|
+
|
|
405
|
+
const parentSource = fs.readFileSync(candidatePath, 'utf8');
|
|
406
|
+
const parentLines = parentSource.split('\n');
|
|
407
|
+
|
|
408
|
+
// Find `INCLUDE <includeName>.` line (case-insensitive)
|
|
409
|
+
const includeRegex = new RegExp(`^\\s*INCLUDE\\s+${includeName}\\s*\\.`, 'i');
|
|
410
|
+
const includeLineIdx = parentLines.findIndex(l => includeRegex.test(l));
|
|
411
|
+
if (includeLineIdx === -1) continue;
|
|
412
|
+
|
|
413
|
+
// Found parent — assemble: replace INCLUDE statement with include's source lines
|
|
414
|
+
const includeLines = includeData.source.split('\n');
|
|
415
|
+
const assembled = [
|
|
416
|
+
...parentLines.slice(0, includeLineIdx),
|
|
417
|
+
...includeLines,
|
|
418
|
+
...parentLines.slice(includeLineIdx + 1)
|
|
419
|
+
];
|
|
420
|
+
const assembledSource = assembled.join('\n');
|
|
421
|
+
|
|
422
|
+
if (!jsonOutput) {
|
|
423
|
+
console.log(` Auto-detected parent: ${entry} (contains INCLUDE ${includeName}.)`);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
objects.push({
|
|
427
|
+
type: 'PROG',
|
|
428
|
+
name: candidateName,
|
|
429
|
+
source: assembledSource,
|
|
430
|
+
subc: candidateSubc || '1',
|
|
431
|
+
fixpt: readProgFixpt(candidateXml),
|
|
432
|
+
// offset into assembled source where include lines start (1-based)
|
|
433
|
+
include_offset: includeLineIdx + 1,
|
|
434
|
+
include_line_count: includeLines.length,
|
|
435
|
+
// carry include name for error line mapping
|
|
436
|
+
include_name: includeName
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
parentFound = true;
|
|
440
|
+
break; // use first matching parent
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (!parentFound) {
|
|
444
|
+
if (!jsonOutput) {
|
|
445
|
+
console.error(` Warning: No parent program found for INCLUDE ${includeName} — cannot syntax-check standalone`);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
333
450
|
if (objects.length === 0) {
|
|
334
451
|
console.error(' No valid files to check');
|
|
335
452
|
process.exit(1);
|
|
336
453
|
}
|
|
337
454
|
const data = {
|
|
338
|
-
objects: objects
|
|
455
|
+
objects: objects.map(o => {
|
|
456
|
+
// Strip client-side INCLUDE tracking fields before sending to ABAP
|
|
457
|
+
const { include_offset, include_line_count, include_name, ...abapObj } = o; // eslint-disable-line no-unused-vars
|
|
458
|
+
return abapObj;
|
|
459
|
+
}),
|
|
339
460
|
uccheck: cloudMode ? '5' : 'X'
|
|
340
461
|
};
|
|
341
462
|
|
|
@@ -365,26 +486,56 @@ module.exports = {
|
|
|
365
486
|
const fugrFmLabel = (objType === 'FUGR' && sentObj.fugr_include_name)
|
|
366
487
|
? ` (${sentObj.fugr_include_name})` : '';
|
|
367
488
|
|
|
489
|
+
// For INCLUDE-backed checks: determine display label and line remapping
|
|
490
|
+
const includeLabel = sentObj.include_name
|
|
491
|
+
? ` (checking via parent ${objName})` : '';
|
|
492
|
+
|
|
368
493
|
if (objSuccess) {
|
|
369
|
-
|
|
494
|
+
if (sentObj.include_name) {
|
|
495
|
+
console.log(`✅ PROG ${sentObj.include_name} - Syntax check passed${includeLabel}`);
|
|
496
|
+
} else {
|
|
497
|
+
console.log(`✅ ${objType} ${objName}${fugrFmLabel} - Syntax check passed`);
|
|
498
|
+
}
|
|
370
499
|
if (warnings.length > 0) {
|
|
371
500
|
console.log(` (${warnings.length} warning(s))`);
|
|
372
501
|
}
|
|
373
502
|
} else {
|
|
374
|
-
|
|
503
|
+
if (sentObj.include_name) {
|
|
504
|
+
console.log(`❌ PROG ${sentObj.include_name} - Syntax check failed (${errorCount} error(s))${includeLabel}`);
|
|
505
|
+
} else {
|
|
506
|
+
console.log(`❌ ${objType} ${objName}${fugrFmLabel} - Syntax check failed (${errorCount} error(s))`);
|
|
507
|
+
}
|
|
375
508
|
console.log('');
|
|
376
509
|
console.log('Errors:');
|
|
377
510
|
console.log('─'.repeat(60));
|
|
378
511
|
|
|
379
512
|
for (const err of errors) {
|
|
380
|
-
|
|
513
|
+
let line = err.LINE || err.line || '?';
|
|
381
514
|
const column = err.COLUMN || err.column || '';
|
|
382
515
|
const text = err.TEXT || err.text || 'Unknown error';
|
|
383
516
|
const methodName = err.METHOD_NAME || err.method_name || '';
|
|
384
517
|
const include = err.INCLUDE || err.include || '';
|
|
385
518
|
|
|
519
|
+
// Remap line numbers for INCLUDE-backed checks
|
|
520
|
+
let remappedFile = null;
|
|
521
|
+
if (sentObj.include_name && typeof line === 'number') {
|
|
522
|
+
const offset = sentObj.include_offset || 0;
|
|
523
|
+
const count = sentObj.include_line_count || 0;
|
|
524
|
+
if (line >= offset && line < offset + count) {
|
|
525
|
+
// Error is inside the INCLUDE — remap to include-relative line
|
|
526
|
+
line = line - offset + 1;
|
|
527
|
+
remappedFile = `${sentObj.include_name.toLowerCase()}.prog.abap`;
|
|
528
|
+
} else {
|
|
529
|
+
// Error is in the parent program context (e.g. header line)
|
|
530
|
+
remappedFile = `${objName.toLowerCase()}.prog.abap (parent)`;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
|
|
386
534
|
// Display which file/include the error is in
|
|
387
|
-
if (
|
|
535
|
+
if (remappedFile) {
|
|
536
|
+
// INCLUDE-backed check: show the actual source file the error maps to
|
|
537
|
+
console.log(` In: ${remappedFile}`);
|
|
538
|
+
} else if (include) {
|
|
388
539
|
// For FUGR: include = lowercase FM name → display as '<group>.fugr.<fm_name>.abap'
|
|
389
540
|
if (objType === 'FUGR') {
|
|
390
541
|
const fugrFile = `${objName.toLowerCase()}.fugr.${include}.abap`;
|
package/src/commands/tree.js
CHANGED
|
@@ -148,6 +148,28 @@ module.exports = {
|
|
|
148
148
|
async execute(args, context) {
|
|
149
149
|
const { loadConfig, AbapHttp } = context;
|
|
150
150
|
|
|
151
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
152
|
+
console.log(`
|
|
153
|
+
Usage:
|
|
154
|
+
abapgit-agent tree --package <package> [--depth <n>] [--include-types] [--json]
|
|
155
|
+
|
|
156
|
+
Description:
|
|
157
|
+
Display the package hierarchy tree from the ABAP system.
|
|
158
|
+
|
|
159
|
+
Parameters:
|
|
160
|
+
--package <package> Root package to display (required). Enclose $-packages in quotes.
|
|
161
|
+
--depth <n> Maximum depth to traverse (default: unlimited).
|
|
162
|
+
--include-types Show object type counts per package.
|
|
163
|
+
--json Output as JSON.
|
|
164
|
+
|
|
165
|
+
Examples:
|
|
166
|
+
abapgit-agent tree --package ZMY_PACKAGE
|
|
167
|
+
abapgit-agent tree --package '$MY_LOCAL_PKG'
|
|
168
|
+
abapgit-agent tree --package ZMY_PACKAGE --depth 2 --include-types
|
|
169
|
+
`);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
151
173
|
const packageArgIndex = args.indexOf('--package');
|
|
152
174
|
if (packageArgIndex === -1) {
|
|
153
175
|
console.error('Error: --package parameter required');
|
package/src/commands/unit.js
CHANGED
|
@@ -232,6 +232,29 @@ module.exports = {
|
|
|
232
232
|
async execute(args, context) {
|
|
233
233
|
const { loadConfig, AbapHttp } = context;
|
|
234
234
|
|
|
235
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
236
|
+
console.log(`
|
|
237
|
+
Usage:
|
|
238
|
+
abapgit-agent unit --files <file1>,<file2>,... [--coverage] [--junit-output <file>] [--json]
|
|
239
|
+
|
|
240
|
+
Description:
|
|
241
|
+
Run AUnit tests for ABAP test class files (.testclasses.abap).
|
|
242
|
+
Objects must be already active in the ABAP system (run pull first).
|
|
243
|
+
|
|
244
|
+
Parameters:
|
|
245
|
+
--files <file1,...> Comma-separated .testclasses.abap files (required).
|
|
246
|
+
--coverage Include code coverage data in output.
|
|
247
|
+
--junit-output <file> Write results as JUnit XML to this file.
|
|
248
|
+
--json Output as JSON.
|
|
249
|
+
|
|
250
|
+
Examples:
|
|
251
|
+
abapgit-agent unit --files src/zcl_my_test.clas.testclasses.abap
|
|
252
|
+
abapgit-agent unit --files src/zcl_my_test.clas.testclasses.abap --coverage
|
|
253
|
+
abapgit-agent unit --files src/zcl_my_test.clas.testclasses.abap --junit-output reports/unit.xml
|
|
254
|
+
`);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
235
258
|
const jsonOutput = args.includes('--json');
|
|
236
259
|
const verbose = args.includes('--verbose');
|
|
237
260
|
const filesArgIndex = args.indexOf('--files');
|
package/src/commands/upgrade.js
CHANGED
|
@@ -14,6 +14,34 @@ module.exports = {
|
|
|
14
14
|
async execute(args, context) {
|
|
15
15
|
const { versionCheck, loadConfig, isAbapIntegrationEnabled } = context;
|
|
16
16
|
|
|
17
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
18
|
+
console.log(`
|
|
19
|
+
Usage:
|
|
20
|
+
abapgit-agent upgrade [--abap-only] [--cli-only] [--version <v>] [--check] [--yes]
|
|
21
|
+
|
|
22
|
+
Description:
|
|
23
|
+
Upgrade the abapgit-agent CLI (npm package) and/or the ABAP backend to the latest
|
|
24
|
+
or a specific version.
|
|
25
|
+
|
|
26
|
+
Parameters:
|
|
27
|
+
--abap-only Upgrade only the ABAP backend (skip CLI npm upgrade).
|
|
28
|
+
--cli-only Upgrade only the CLI npm package (skip ABAP backend).
|
|
29
|
+
--version <v> Upgrade to a specific version (e.g. 1.15.0).
|
|
30
|
+
--check Check for available upgrades without installing.
|
|
31
|
+
--transport <T> Transport request for ABAP backend upgrade.
|
|
32
|
+
--yes, -y Skip confirmation prompt.
|
|
33
|
+
--dry-run Show what would be done without making changes.
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
abapgit-agent upgrade
|
|
37
|
+
abapgit-agent upgrade --check
|
|
38
|
+
abapgit-agent upgrade --cli-only
|
|
39
|
+
abapgit-agent upgrade --abap-only --transport DEVK900001
|
|
40
|
+
abapgit-agent upgrade --version 1.15.0
|
|
41
|
+
`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
17
45
|
// Parse flags
|
|
18
46
|
const flags = this.parseFlags(args);
|
|
19
47
|
|
package/src/commands/view.js
CHANGED
|
@@ -193,6 +193,35 @@ module.exports = {
|
|
|
193
193
|
async execute(args, context) {
|
|
194
194
|
const { loadConfig, AbapHttp } = context;
|
|
195
195
|
|
|
196
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
197
|
+
console.log(`
|
|
198
|
+
Usage:
|
|
199
|
+
abapgit-agent view --objects <obj1>,<obj2>,... [--type <type>] [--full] [--lines] [--json]
|
|
200
|
+
abapgit-agent view --objects <FUGR> --type FUGR [--full] [--fm <name>] [--lines]
|
|
201
|
+
|
|
202
|
+
Description:
|
|
203
|
+
View ABAP object definitions from the ABAP system.
|
|
204
|
+
|
|
205
|
+
Parameters:
|
|
206
|
+
--objects <obj1,...> Comma-separated object names (required).
|
|
207
|
+
--type <type> Object type: CLAS, INTF, PROG, TABL, STRU, DTEL, TTYP, DOMA,
|
|
208
|
+
DDLS, DCLS, MSAG, FUGR (auto-detected from TADIR if omitted).
|
|
209
|
+
--full Show full source including all method implementations.
|
|
210
|
+
--lines Show dual line numbers (G = global for debug set, [N] = include-local).
|
|
211
|
+
--fm <name> With --full: show only the specified function module (FUGR only).
|
|
212
|
+
--json Output as JSON.
|
|
213
|
+
|
|
214
|
+
Examples:
|
|
215
|
+
abapgit-agent view --objects ZCL_MY_CLASS
|
|
216
|
+
abapgit-agent view --objects ZCL_MY_CLASS --full
|
|
217
|
+
abapgit-agent view --objects ZCL_MY_CLASS --full --lines
|
|
218
|
+
abapgit-agent view --objects ZMY_TABLE --type TABL
|
|
219
|
+
abapgit-agent view --objects SUSR --type FUGR --full --fm AUTHORITY_CHECK --lines
|
|
220
|
+
abapgit-agent view --objects ZCL_FOO,ZIF_BAR
|
|
221
|
+
`);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
|
|
196
225
|
const objectsArgIndex = args.indexOf('--objects');
|
|
197
226
|
if (objectsArgIndex === -1 || objectsArgIndex + 1 >= args.length) {
|
|
198
227
|
console.error('Error: --objects parameter required');
|
package/src/commands/where.js
CHANGED
|
@@ -11,6 +11,30 @@ module.exports = {
|
|
|
11
11
|
async execute(args, context) {
|
|
12
12
|
const { loadConfig, AbapHttp } = context;
|
|
13
13
|
|
|
14
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
15
|
+
console.log(`
|
|
16
|
+
Usage:
|
|
17
|
+
abapgit-agent where --objects <obj1>,<obj2>,... [--type <type>] [--limit <n>] [--offset <n>] [--json]
|
|
18
|
+
|
|
19
|
+
Description:
|
|
20
|
+
Find where-used list for ABAP objects (classes, interfaces, programs, etc.).
|
|
21
|
+
|
|
22
|
+
Parameters:
|
|
23
|
+
--objects <obj1,...> Comma-separated object names (required).
|
|
24
|
+
--type <type> Object type (e.g. CLAS, INTF — auto-detected if omitted).
|
|
25
|
+
--limit <n> Maximum number of results (default: 50).
|
|
26
|
+
--offset <n> Skip first N results (for pagination).
|
|
27
|
+
--json Output as JSON.
|
|
28
|
+
|
|
29
|
+
Examples:
|
|
30
|
+
abapgit-agent where --objects ZCL_MY_CLASS
|
|
31
|
+
abapgit-agent where --objects ZIF_MY_INTERFACE
|
|
32
|
+
abapgit-agent where --objects ZCL_MY_CLASS --limit 20
|
|
33
|
+
abapgit-agent where --objects ZCL_MY_CLASS --offset 50 --limit 20
|
|
34
|
+
`);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
14
38
|
const objectsArgIndex = args.indexOf('--objects');
|
|
15
39
|
if (objectsArgIndex === -1 || objectsArgIndex + 1 >= args.length) {
|
|
16
40
|
console.error('Error: --objects parameter required');
|
package/src/config.js
CHANGED
|
@@ -123,6 +123,7 @@ function getSafeguards() {
|
|
|
123
123
|
requireFilesForPull: projectConfig.safeguards.requireFilesForPull === true,
|
|
124
124
|
disablePull: projectConfig.safeguards.disablePull === true,
|
|
125
125
|
disableRun: projectConfig.safeguards.disableRun === true,
|
|
126
|
+
disableImport: projectConfig.safeguards.disableImport === true,
|
|
126
127
|
disableProbeClasses: projectConfig.safeguards.disableProbeClasses === true,
|
|
127
128
|
reason: projectConfig.safeguards.reason || null
|
|
128
129
|
};
|
|
@@ -133,6 +134,7 @@ function getSafeguards() {
|
|
|
133
134
|
requireFilesForPull: false,
|
|
134
135
|
disablePull: false,
|
|
135
136
|
disableRun: false,
|
|
137
|
+
disableImport: false,
|
|
136
138
|
disableProbeClasses: false,
|
|
137
139
|
reason: null
|
|
138
140
|
};
|
|
@@ -531,8 +531,8 @@ async function getTopic(topic) {
|
|
|
531
531
|
return {
|
|
532
532
|
topic,
|
|
533
533
|
file: guidelineFile,
|
|
534
|
-
content: content.slice(0,
|
|
535
|
-
truncated: content.length >
|
|
534
|
+
content: content.slice(0, 20000),
|
|
535
|
+
truncated: content.length > 20000,
|
|
536
536
|
totalLength: content.length,
|
|
537
537
|
source: 'guidelines'
|
|
538
538
|
};
|
|
@@ -616,8 +616,8 @@ async function getTopic(topic) {
|
|
|
616
616
|
return {
|
|
617
617
|
topic,
|
|
618
618
|
file: exactMatch,
|
|
619
|
-
content: content.slice(0,
|
|
620
|
-
truncated: content.length >
|
|
619
|
+
content: content.slice(0, 20000),
|
|
620
|
+
truncated: content.length > 20000,
|
|
621
621
|
totalLength: content.length,
|
|
622
622
|
source: 'built-in guidelines'
|
|
623
623
|
};
|
|
@@ -630,8 +630,8 @@ async function getTopic(topic) {
|
|
|
630
630
|
return {
|
|
631
631
|
topic,
|
|
632
632
|
file: partialMatches[0],
|
|
633
|
-
content: content.slice(0,
|
|
634
|
-
truncated: content.length >
|
|
633
|
+
content: content.slice(0, 20000),
|
|
634
|
+
truncated: content.length > 20000,
|
|
635
635
|
totalLength: content.length,
|
|
636
636
|
source: 'built-in guidelines'
|
|
637
637
|
};
|
|
@@ -814,11 +814,10 @@ function displayTopic(result) {
|
|
|
814
814
|
console.log(' ' + '─'.repeat(60));
|
|
815
815
|
console.log('');
|
|
816
816
|
|
|
817
|
-
// Display
|
|
818
|
-
const lines = result.content.split('\n')
|
|
817
|
+
// Display full content (char limit already applied when reading)
|
|
818
|
+
const lines = result.content.split('\n');
|
|
819
819
|
lines.forEach(line => {
|
|
820
|
-
|
|
821
|
-
console.log(` ${trimmed}`);
|
|
820
|
+
console.log(` ${line}`);
|
|
822
821
|
});
|
|
823
822
|
|
|
824
823
|
if (result.truncated) {
|