abapgit-agent 1.4.0 → 1.5.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/.github/workflows/release.yml +4 -1
- package/CLAUDE.md +27 -0
- package/README.md +1 -0
- package/abap/CLAUDE.md +112 -0
- package/abap/zcl_abgagt_command_inspect.clas.abap +57 -12
- package/abap/zcl_abgagt_resource_health.clas.abap +1 -1
- package/abap/zcl_abgagt_resource_inspect.clas.abap +1 -0
- package/bin/abapgit-agent +133 -17
- package/docs/inspect-command.md +12 -1
- package/docs/list-command.md +289 -0
- package/docs/pull-command.md +15 -1
- package/package.json +4 -2
- package/scripts/release.js +298 -0
- package/scripts/unrelease.js +277 -0
- package/src/agent.js +1 -1
- package/src/config.js +9 -2
|
@@ -14,6 +14,8 @@ jobs:
|
|
|
14
14
|
steps:
|
|
15
15
|
- name: Checkout code
|
|
16
16
|
uses: actions/checkout@v4
|
|
17
|
+
with:
|
|
18
|
+
fetch-depth: 0
|
|
17
19
|
|
|
18
20
|
- name: Setup Node.js
|
|
19
21
|
uses: actions/setup-node@v4
|
|
@@ -39,6 +41,7 @@ jobs:
|
|
|
39
41
|
- name: Prepare release notes
|
|
40
42
|
id: release_notes
|
|
41
43
|
run: |
|
|
44
|
+
# Read release notes from file (generated by npm run release)
|
|
42
45
|
if [ -f "RELEASE_NOTES.md" ]; then
|
|
43
46
|
# Extract only the current release (first section until --- separator)
|
|
44
47
|
content=$(awk '/^---$/{exit}1' RELEASE_NOTES.md)
|
|
@@ -46,7 +49,7 @@ jobs:
|
|
|
46
49
|
echo "$content" >> $GITHUB_OUTPUT
|
|
47
50
|
echo "EOF" >> $GITHUB_OUTPUT
|
|
48
51
|
else
|
|
49
|
-
echo "CONTENT=
|
|
52
|
+
echo "CONTENT=Release ${{ steps.get_tag.outputs.VERSION }}" >> $GITHUB_OUTPUT
|
|
50
53
|
fi
|
|
51
54
|
|
|
52
55
|
- name: Create GitHub Release
|
package/CLAUDE.md
CHANGED
|
@@ -127,6 +127,7 @@ abapgit-agent health
|
|
|
127
127
|
# Check configuration
|
|
128
128
|
abapgit-agent status
|
|
129
129
|
```
|
|
130
|
+
Note: All ABAP commands automatically check CLI/ABAP API version compatibility.
|
|
130
131
|
|
|
131
132
|
## Pull Command
|
|
132
133
|
|
|
@@ -237,8 +238,21 @@ abapgit-agent inspect --files abap/zc_my_view.ddls.asddls
|
|
|
237
238
|
|
|
238
239
|
# Inspect mixed file types (DDLS + CLAS)
|
|
239
240
|
abapgit-agent inspect --files abap/zc_my_view.ddls.asddls,abap/zcl_my_class.clas.abap
|
|
241
|
+
|
|
242
|
+
# Inspect with specific Code Inspector variant
|
|
243
|
+
abapgit-agent inspect --files abap/zcl_my_class.clas.abap --variant ALL_CHECKS
|
|
244
|
+
|
|
245
|
+
# Inspect with no variant (uses default SAP standard checks)
|
|
246
|
+
abapgit-agent inspect --files abap/zcl_my_class.clas.abap --variant EMPTY
|
|
240
247
|
```
|
|
241
248
|
|
|
249
|
+
### Parameters
|
|
250
|
+
|
|
251
|
+
| Parameter | Required | Description |
|
|
252
|
+
|-----------|----------|-------------|
|
|
253
|
+
| `--files` | Yes | Comma-separated list of ABAP files to inspect |
|
|
254
|
+
| `--variant` | No | Code Inspector variant name (e.g., `ALL_CHECKS`, `EMPTY`) |
|
|
255
|
+
|
|
242
256
|
### Supported Object Types
|
|
243
257
|
|
|
244
258
|
| Type | Description | Validation Method |
|
|
@@ -809,6 +823,7 @@ Create `.abapGitAgent` in repository root:
|
|
|
809
823
|
| `language` | SAP language | EN |
|
|
810
824
|
| `gitUsername` | Git username/token | Optional |
|
|
811
825
|
| `gitPassword` | Git password/token | Optional |
|
|
826
|
+
| `transport` | Default transport request for pull | Optional |
|
|
812
827
|
|
|
813
828
|
### Environment Variables
|
|
814
829
|
```bash
|
|
@@ -820,8 +835,20 @@ export ABAP_PASSWORD="your-password"
|
|
|
820
835
|
export ABAP_LANGUAGE="EN"
|
|
821
836
|
export GIT_USERNAME="git-username"
|
|
822
837
|
export GIT_PASSWORD="git-token"
|
|
838
|
+
export ABAP_TRANSPORT="DEVK900001"
|
|
823
839
|
```
|
|
824
840
|
|
|
841
|
+
### Transport Request Precedence
|
|
842
|
+
|
|
843
|
+
When running `pull` command, the transport request is determined in this order:
|
|
844
|
+
|
|
845
|
+
| Priority | Source | Example |
|
|
846
|
+
|----------|--------|---------|
|
|
847
|
+
| 1 | CLI `--transport` argument | `--transport DEVK900001` |
|
|
848
|
+
| 2 | Config file `transport` | `"transport": "DEVK900001"` |
|
|
849
|
+
| 3 | Environment variable `ABAP_TRANSPORT` | `export ABAP_TRANSPORT="DEVK900001"` |
|
|
850
|
+
| 4 (default) | Not set | abapGit creates/uses default |
|
|
851
|
+
|
|
825
852
|
## Troubleshooting
|
|
826
853
|
|
|
827
854
|
**Pull fails with "Error updating where-used list":**
|
package/README.md
CHANGED
package/abap/CLAUDE.md
CHANGED
|
@@ -788,6 +788,118 @@ ENDCLASS.
|
|
|
788
788
|
- Syntax errors in one command don't affect others
|
|
789
789
|
- Add new commands by updating the mapping table
|
|
790
790
|
|
|
791
|
+
## Exception Handling in ABAP
|
|
792
|
+
|
|
793
|
+
ABAP has two different ways to handle exceptions. Understanding the difference is critical.
|
|
794
|
+
|
|
795
|
+
### Classical ABAP Exceptions (EXCEPTIONS)
|
|
796
|
+
|
|
797
|
+
Used in older function modules and some OO classes. Defined in method signature using `EXCEPTIONS` keyword.
|
|
798
|
+
|
|
799
|
+
**Method Definition:**
|
|
800
|
+
```abap
|
|
801
|
+
METHODS method_name
|
|
802
|
+
IMPORTING iv_param TYPE string
|
|
803
|
+
EXCEPTIONS
|
|
804
|
+
exc1 = 1
|
|
805
|
+
exc2 = 2
|
|
806
|
+
OTHERS = 3.
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
**Method Call:**
|
|
810
|
+
```abap
|
|
811
|
+
method_name(
|
|
812
|
+
EXPORTING iv_param = lv_value
|
|
813
|
+
EXCEPTIONS
|
|
814
|
+
exc1 = 1
|
|
815
|
+
exc2 = 2
|
|
816
|
+
OTHERS = 3 ).
|
|
817
|
+
|
|
818
|
+
IF sy-subrc <> 0.
|
|
819
|
+
" Handle error - check sy-subrc for exception number
|
|
820
|
+
ENDIF.
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
**Characteristics:**
|
|
824
|
+
- Return code in `sy-subrc`
|
|
825
|
+
- No exception objects
|
|
826
|
+
- Legacy approach
|
|
827
|
+
|
|
828
|
+
### Modern ABAP Exceptions (TRY-CATCH)
|
|
829
|
+
|
|
830
|
+
Used in modern OO ABAP (7.40+). Uses exception classes and RAISING clause.
|
|
831
|
+
|
|
832
|
+
**Exception Class:**
|
|
833
|
+
```abap
|
|
834
|
+
CLASS cx_my_exception DEFINITION INHERITING FROM cx_dynamic_check.
|
|
835
|
+
PUBLIC SECTION.
|
|
836
|
+
METHODS constructor IMPORTING textid LIKE textid OPTIONAL.
|
|
837
|
+
ENDCLASS.
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
**Method Definition:**
|
|
841
|
+
```abap
|
|
842
|
+
METHODS method_name
|
|
843
|
+
IMPORTING iv_param TYPE string
|
|
844
|
+
RAISING cx_my_exception.
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
**Method Call:**
|
|
848
|
+
```abap
|
|
849
|
+
TRY.
|
|
850
|
+
method_name( iv_param = lv_value ).
|
|
851
|
+
CATCH cx_my_exception INTO lx_error.
|
|
852
|
+
lv_message = lx_error->get_text( ).
|
|
853
|
+
ENDTRY.
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
### How to Identify Which to Use
|
|
857
|
+
|
|
858
|
+
Look at the method signature:
|
|
859
|
+
|
|
860
|
+
| Syntax | Type |
|
|
861
|
+
|--------|------|
|
|
862
|
+
| `EXCEPTIONS exc1 = 1` | Classical |
|
|
863
|
+
| `RAISING cx_exception` | Modern (TRY-CATCH) |
|
|
864
|
+
|
|
865
|
+
### Real Example: cl_ci_checkvariant=>get_ref
|
|
866
|
+
|
|
867
|
+
This method uses **classical exceptions**:
|
|
868
|
+
|
|
869
|
+
```abap
|
|
870
|
+
" WRONG - using TRY-CATCH
|
|
871
|
+
TRY.
|
|
872
|
+
lo_variant = cl_ci_checkvariant=>get_ref(
|
|
873
|
+
p_user = ''
|
|
874
|
+
p_name = lv_variant ).
|
|
875
|
+
CATCH cx_root.
|
|
876
|
+
" This won't work!
|
|
877
|
+
ENDTRY.
|
|
878
|
+
|
|
879
|
+
" CORRECT - using EXCEPTIONS with EXPORTING and RECEIVING
|
|
880
|
+
cl_ci_checkvariant=>get_ref(
|
|
881
|
+
EXPORTING
|
|
882
|
+
p_user = ''
|
|
883
|
+
p_name = lv_variant
|
|
884
|
+
RECEIVING
|
|
885
|
+
p_ref = lo_variant
|
|
886
|
+
EXCEPTIONS
|
|
887
|
+
chkv_not_exists = 1
|
|
888
|
+
missing_parameter = 2
|
|
889
|
+
broken_variant = 3
|
|
890
|
+
OTHERS = 4 ).
|
|
891
|
+
|
|
892
|
+
IF sy-subrc <> 0.
|
|
893
|
+
" Handle error
|
|
894
|
+
ENDIF.
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
**Key Points:**
|
|
898
|
+
1. Use `EXPORTING` before importing parameters when using `EXCEPTIONS`
|
|
899
|
+
2. Use `RECEIVING` for RETURNING parameters (not direct assignment)
|
|
900
|
+
3. Check `sy-subrc` for exception codes
|
|
901
|
+
4. Not all OO methods use TRY-CATCH - some still use classical exceptions
|
|
902
|
+
|
|
791
903
|
## Best Practices
|
|
792
904
|
|
|
793
905
|
### Always Return Interface Types, Not Class Types
|
|
@@ -44,6 +44,7 @@ CLASS zcl_abgagt_command_inspect DEFINITION PUBLIC FINAL CREATE PUBLIC.
|
|
|
44
44
|
|
|
45
45
|
TYPES: BEGIN OF ty_inspect_params,
|
|
46
46
|
files TYPE string_table,
|
|
47
|
+
variant TYPE string,
|
|
47
48
|
END OF ty_inspect_params.
|
|
48
49
|
|
|
49
50
|
TYPES ty_object_keys TYPE TABLE OF scir_objs WITH NON-UNIQUE DEFAULT KEY.
|
|
@@ -53,6 +54,7 @@ CLASS zcl_abgagt_command_inspect DEFINITION PUBLIC FINAL CREATE PUBLIC.
|
|
|
53
54
|
|
|
54
55
|
METHODS run_syntax_check
|
|
55
56
|
IMPORTING it_objects TYPE ty_object_keys
|
|
57
|
+
iv_variant TYPE string DEFAULT 'SYNTAX_CHECK'
|
|
56
58
|
RETURNING VALUE(rt_results) TYPE ty_inspect_results.
|
|
57
59
|
|
|
58
60
|
" Validate DDLS (CDS views)
|
|
@@ -120,7 +122,9 @@ CLASS zcl_abgagt_command_inspect IMPLEMENTATION.
|
|
|
120
122
|
|
|
121
123
|
" Run syntax check for non-DDLS objects
|
|
122
124
|
IF lt_objects IS NOT INITIAL.
|
|
123
|
-
DATA(lt_sci_results) = run_syntax_check(
|
|
125
|
+
DATA(lt_sci_results) = run_syntax_check(
|
|
126
|
+
it_objects = lt_objects
|
|
127
|
+
iv_variant = ls_params-variant ).
|
|
124
128
|
INSERT LINES OF lt_sci_results INTO TABLE lt_results.
|
|
125
129
|
ENDIF.
|
|
126
130
|
|
|
@@ -300,6 +304,7 @@ CLASS zcl_abgagt_command_inspect IMPLEMENTATION.
|
|
|
300
304
|
lo_inspection TYPE REF TO cl_ci_inspection,
|
|
301
305
|
lt_list TYPE scit_alvlist,
|
|
302
306
|
ls_error TYPE ty_error,
|
|
307
|
+
ls_warning TYPE ty_warning,
|
|
303
308
|
ls_list TYPE scir_alvlist,
|
|
304
309
|
lx_error TYPE REF TO cx_root,
|
|
305
310
|
ls_result TYPE ty_inspect_result.
|
|
@@ -315,10 +320,36 @@ CLASS zcl_abgagt_command_inspect IMPLEMENTATION.
|
|
|
315
320
|
p_name = lv_name
|
|
316
321
|
p_objects = it_objects ).
|
|
317
322
|
|
|
318
|
-
" Get check variant
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
323
|
+
" Get check variant (default: SYNTAX_CHECK)
|
|
324
|
+
DATA lv_variant TYPE sci_chkv.
|
|
325
|
+
lv_variant = iv_variant.
|
|
326
|
+
IF lv_variant IS INITIAL.
|
|
327
|
+
lv_variant = 'SYNTAX_CHECK'.
|
|
328
|
+
ENDIF.
|
|
329
|
+
|
|
330
|
+
" Try to get the variant using EXCEPTIONS
|
|
331
|
+
cl_ci_checkvariant=>get_ref(
|
|
332
|
+
EXPORTING
|
|
333
|
+
p_user = ''
|
|
334
|
+
p_name = lv_variant
|
|
335
|
+
RECEIVING
|
|
336
|
+
p_ref = lo_variant
|
|
337
|
+
EXCEPTIONS
|
|
338
|
+
chkv_not_exists = 1
|
|
339
|
+
missing_parameter = 2
|
|
340
|
+
broken_variant = 3
|
|
341
|
+
OTHERS = 4 ).
|
|
342
|
+
|
|
343
|
+
IF sy-subrc <> 0.
|
|
344
|
+
" Variant not found, return error
|
|
345
|
+
ls_result-object_type = 'VARIANT'.
|
|
346
|
+
ls_result-object_name = lv_variant.
|
|
347
|
+
ls_result-success = abap_false.
|
|
348
|
+
ls_result-error_count = 1.
|
|
349
|
+
APPEND VALUE #( line = '0' column = '0' text = |Check variant "{ lv_variant }" not found (rc={ sy-subrc })| word = '' ) TO ls_result-errors.
|
|
350
|
+
APPEND ls_result TO rt_results.
|
|
351
|
+
RETURN.
|
|
352
|
+
ENDIF.
|
|
322
353
|
|
|
323
354
|
" Create inspection
|
|
324
355
|
cl_ci_inspection=>create(
|
|
@@ -355,14 +386,28 @@ CLASS zcl_abgagt_command_inspect IMPLEMENTATION.
|
|
|
355
386
|
ls_result-object_name = ls_obj-objname.
|
|
356
387
|
ls_result-success = abap_true.
|
|
357
388
|
|
|
358
|
-
" Get errors for this object
|
|
389
|
+
" Get errors and warnings for this object
|
|
359
390
|
LOOP AT lt_list INTO ls_list WHERE objname = ls_obj-objname.
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
391
|
+
" Check severity - 'E' = Error, 'W' = Warning, 'I' = Info
|
|
392
|
+
IF ls_list-kind = 'E'.
|
|
393
|
+
" Error
|
|
394
|
+
CLEAR ls_error.
|
|
395
|
+
ls_error-line = ls_list-line.
|
|
396
|
+
ls_error-column = ls_list-col.
|
|
397
|
+
ls_error-text = ls_list-text.
|
|
398
|
+
ls_error-word = ls_list-code.
|
|
399
|
+
APPEND ls_error TO ls_result-errors.
|
|
400
|
+
ELSEIF ls_list-kind = 'W' OR ls_list-kind = 'I'.
|
|
401
|
+
" Warning or Info
|
|
402
|
+
CLEAR ls_warning.
|
|
403
|
+
ls_warning-line = ls_list-line.
|
|
404
|
+
ls_warning-column = ls_list-col.
|
|
405
|
+
ls_warning-severity = ls_list-kind.
|
|
406
|
+
ls_warning-message = ls_list-text.
|
|
407
|
+
ls_warning-object_type = ls_obj-objtype.
|
|
408
|
+
ls_warning-object_name = ls_obj-objname.
|
|
409
|
+
APPEND ls_warning TO ls_result-warnings.
|
|
410
|
+
ENDIF.
|
|
366
411
|
ENDLOOP.
|
|
367
412
|
|
|
368
413
|
ls_result-error_count = lines( ls_result-errors ).
|
|
@@ -14,7 +14,7 @@ CLASS zcl_abgagt_resource_health IMPLEMENTATION.
|
|
|
14
14
|
|
|
15
15
|
METHOD if_rest_resource~get.
|
|
16
16
|
DATA lv_json TYPE string.
|
|
17
|
-
lv_json = '{"status":"OK","version":"1.
|
|
17
|
+
lv_json = '{"status":"OK","version":"1.4.0"}'.
|
|
18
18
|
|
|
19
19
|
DATA(lo_entity) = mo_response->create_entity( ).
|
|
20
20
|
lo_entity->set_content_type( iv_media_type = if_rest_media_type=>gc_appl_json ).
|
package/bin/abapgit-agent
CHANGED
|
@@ -23,6 +23,74 @@ const TERM_WIDTH = getTermWidth();
|
|
|
23
23
|
|
|
24
24
|
const COOKIE_FILE = '.abapgit_agent_cookies.txt';
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Get CLI version from package.json
|
|
28
|
+
*/
|
|
29
|
+
function getCliVersion() {
|
|
30
|
+
const packageJsonPath = pathModule.join(__dirname, '..', 'package.json');
|
|
31
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
32
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
33
|
+
return pkg.version || '1.0.0';
|
|
34
|
+
}
|
|
35
|
+
return '1.0.0';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Check version compatibility between CLI and ABAP API
|
|
40
|
+
*/
|
|
41
|
+
async function checkVersionCompatibility() {
|
|
42
|
+
const cliVersion = getCliVersion();
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
const config = loadConfig();
|
|
46
|
+
const https = require('https');
|
|
47
|
+
const url = new URL(`/sap/bc/z_abapgit_agent/health`, `https://${config.host}:${config.sapport}`);
|
|
48
|
+
|
|
49
|
+
return new Promise((resolve) => {
|
|
50
|
+
const options = {
|
|
51
|
+
hostname: url.hostname,
|
|
52
|
+
port: url.port,
|
|
53
|
+
path: url.pathname,
|
|
54
|
+
method: 'GET',
|
|
55
|
+
headers: {
|
|
56
|
+
'Authorization': `Basic ${Buffer.from(`${config.user}:${config.password}`).toString('base64')}`,
|
|
57
|
+
'sap-client': config.client,
|
|
58
|
+
'sap-language': config.language || 'EN',
|
|
59
|
+
'Content-Type': 'application/json'
|
|
60
|
+
},
|
|
61
|
+
agent: new https.Agent({ rejectUnauthorized: false })
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const req = https.request(options, (res) => {
|
|
65
|
+
let body = '';
|
|
66
|
+
res.on('data', chunk => body += chunk);
|
|
67
|
+
res.on('end', () => {
|
|
68
|
+
try {
|
|
69
|
+
const result = JSON.parse(body);
|
|
70
|
+
const apiVersion = result.version || '1.0.0';
|
|
71
|
+
|
|
72
|
+
if (cliVersion !== apiVersion) {
|
|
73
|
+
console.log(`\n⚠️ Version mismatch: CLI ${cliVersion}, ABAP API ${apiVersion}`);
|
|
74
|
+
console.log(' Some commands may not work correctly.');
|
|
75
|
+
console.log(' Update ABAP code: abapgit-agent pull\n');
|
|
76
|
+
}
|
|
77
|
+
resolve({ cliVersion, apiVersion, compatible: cliVersion === apiVersion });
|
|
78
|
+
} catch (e) {
|
|
79
|
+
resolve({ cliVersion, apiVersion: null, compatible: false, error: e.message });
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
req.on('error', (e) => {
|
|
85
|
+
resolve({ cliVersion, apiVersion: null, compatible: false, error: e.message });
|
|
86
|
+
});
|
|
87
|
+
req.end();
|
|
88
|
+
});
|
|
89
|
+
} catch (error) {
|
|
90
|
+
return { cliVersion, apiVersion: null, compatible: false, error: error.message };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
26
94
|
/**
|
|
27
95
|
* Load configuration from .abapGitAgent in current working directory
|
|
28
96
|
*/
|
|
@@ -42,10 +110,19 @@ function loadConfig() {
|
|
|
42
110
|
password: process.env.ABAP_PASSWORD,
|
|
43
111
|
language: process.env.ABAP_LANGUAGE || 'EN',
|
|
44
112
|
gitUsername: process.env.GIT_USERNAME,
|
|
45
|
-
gitPassword: process.env.GIT_PASSWORD
|
|
113
|
+
gitPassword: process.env.GIT_PASSWORD,
|
|
114
|
+
transport: process.env.ABAP_TRANSPORT
|
|
46
115
|
};
|
|
47
116
|
}
|
|
48
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Get transport request from config or environment
|
|
120
|
+
*/
|
|
121
|
+
function getTransport() {
|
|
122
|
+
const config = loadConfig();
|
|
123
|
+
return config.transport;
|
|
124
|
+
}
|
|
125
|
+
|
|
49
126
|
/**
|
|
50
127
|
* Check if ABAP integration is configured for this repo
|
|
51
128
|
*/
|
|
@@ -385,7 +462,7 @@ async function syntaxCheckSource(sourceFile, csrfToken, config) {
|
|
|
385
462
|
/**
|
|
386
463
|
* Inspect all files in one request
|
|
387
464
|
*/
|
|
388
|
-
async function inspectAllFiles(files, csrfToken, config) {
|
|
465
|
+
async function inspectAllFiles(files, csrfToken, config, variant = null) {
|
|
389
466
|
// Convert files to uppercase names (same as syntaxCheckSource does)
|
|
390
467
|
const fileNames = files.map(f => {
|
|
391
468
|
const baseName = pathModule.basename(f).toUpperCase();
|
|
@@ -398,6 +475,11 @@ async function inspectAllFiles(files, csrfToken, config) {
|
|
|
398
475
|
files: fileNames
|
|
399
476
|
};
|
|
400
477
|
|
|
478
|
+
// Add variant if specified
|
|
479
|
+
if (variant) {
|
|
480
|
+
data.variant = variant;
|
|
481
|
+
}
|
|
482
|
+
|
|
401
483
|
const result = await request('POST', '/sap/bc/z_abapgit_agent/inspect', data, { csrfToken: csrfToken });
|
|
402
484
|
|
|
403
485
|
// Handle both table result and old single result
|
|
@@ -1195,6 +1277,12 @@ To enable integration:
|
|
|
1195
1277
|
}
|
|
1196
1278
|
}
|
|
1197
1279
|
|
|
1280
|
+
// Version compatibility check for commands that interact with ABAP
|
|
1281
|
+
const abapCommands = ['create', 'import', 'pull', 'inspect', 'unit', 'tree', 'view', 'preview'];
|
|
1282
|
+
if (command && abapCommands.includes(command)) {
|
|
1283
|
+
await checkVersionCompatibility();
|
|
1284
|
+
}
|
|
1285
|
+
|
|
1198
1286
|
try {
|
|
1199
1287
|
switch (command) {
|
|
1200
1288
|
case 'init':
|
|
@@ -1390,16 +1478,21 @@ Examples:
|
|
|
1390
1478
|
let gitUrl = urlArgIndex !== -1 ? args[urlArgIndex + 1] : null;
|
|
1391
1479
|
let branch = branchArgIndex !== -1 ? args[branchArgIndex + 1] : getGitBranch();
|
|
1392
1480
|
let files = null;
|
|
1481
|
+
|
|
1482
|
+
// Transport: CLI arg takes priority, then config/environment, then null
|
|
1393
1483
|
let transportRequest = null;
|
|
1484
|
+
if (transportArgIndex !== -1 && transportArgIndex + 1 < args.length) {
|
|
1485
|
+
// Explicit --transport argument
|
|
1486
|
+
transportRequest = args[transportArgIndex + 1];
|
|
1487
|
+
} else {
|
|
1488
|
+
// Fall back to config or environment variable
|
|
1489
|
+
transportRequest = getTransport();
|
|
1490
|
+
}
|
|
1394
1491
|
|
|
1395
1492
|
if (filesArgIndex !== -1 && filesArgIndex + 1 < args.length) {
|
|
1396
1493
|
files = args[filesArgIndex + 1].split(',').map(f => f.trim());
|
|
1397
1494
|
}
|
|
1398
1495
|
|
|
1399
|
-
if (transportArgIndex !== -1 && transportArgIndex + 1 < args.length) {
|
|
1400
|
-
transportRequest = args[transportArgIndex + 1];
|
|
1401
|
-
}
|
|
1402
|
-
|
|
1403
1496
|
if (!gitUrl) {
|
|
1404
1497
|
gitUrl = getGitRemoteUrl();
|
|
1405
1498
|
if (!gitUrl) {
|
|
@@ -1427,31 +1520,32 @@ Examples:
|
|
|
1427
1520
|
break;
|
|
1428
1521
|
|
|
1429
1522
|
case 'inspect': {
|
|
1430
|
-
// TODO: Implement full inspect feature with:
|
|
1431
|
-
// - Syntax check (currently implemented via /inspect)
|
|
1432
|
-
// - Code Inspector checks (SE51, SCI)
|
|
1433
|
-
// - ATC checks (SATC)
|
|
1434
|
-
// - Custom rule checks
|
|
1435
|
-
// Add --check-type parameter to specify which check to run
|
|
1436
|
-
|
|
1437
1523
|
const filesArgIndex = args.indexOf('--files');
|
|
1438
1524
|
if (filesArgIndex === -1 || filesArgIndex + 1 >= args.length) {
|
|
1439
1525
|
console.error('Error: --files parameter required');
|
|
1440
|
-
console.error('Usage: abapgit-agent inspect --files <file1>,<file2>,...');
|
|
1526
|
+
console.error('Usage: abapgit-agent inspect --files <file1>,<file2>,... [--variant <check-variant>]');
|
|
1441
1527
|
console.error('Example: abapgit-agent inspect --files zcl_my_class.clas.abap');
|
|
1528
|
+
console.error('Example: abapgit-agent inspect --files zcl_my_class.clas.abap --variant ALL_CHECKS');
|
|
1442
1529
|
process.exit(1);
|
|
1443
1530
|
}
|
|
1444
1531
|
|
|
1445
1532
|
const filesSyntaxCheck = args[filesArgIndex + 1].split(',').map(f => f.trim());
|
|
1446
1533
|
|
|
1534
|
+
// Parse optional --variant parameter
|
|
1535
|
+
const variantArgIndex = args.indexOf('--variant');
|
|
1536
|
+
const variant = variantArgIndex !== -1 ? args[variantArgIndex + 1] : null;
|
|
1537
|
+
|
|
1447
1538
|
console.log(`\n Inspect for ${filesSyntaxCheck.length} file(s)`);
|
|
1539
|
+
if (variant) {
|
|
1540
|
+
console.log(` Using variant: ${variant}`);
|
|
1541
|
+
}
|
|
1448
1542
|
console.log('');
|
|
1449
1543
|
|
|
1450
1544
|
const config = loadConfig();
|
|
1451
1545
|
const csrfToken = await fetchCsrfToken(config);
|
|
1452
1546
|
|
|
1453
1547
|
// Send all files in one request
|
|
1454
|
-
const results = await inspectAllFiles(filesSyntaxCheck, csrfToken, config);
|
|
1548
|
+
const results = await inspectAllFiles(filesSyntaxCheck, csrfToken, config, variant);
|
|
1455
1549
|
|
|
1456
1550
|
// Process results
|
|
1457
1551
|
for (const result of results) {
|
|
@@ -1485,15 +1579,37 @@ Examples:
|
|
|
1485
1579
|
|
|
1486
1580
|
case 'tree': {
|
|
1487
1581
|
const packageArgIndex = args.indexOf('--package');
|
|
1488
|
-
if (packageArgIndex === -1
|
|
1582
|
+
if (packageArgIndex === -1) {
|
|
1489
1583
|
console.error('Error: --package parameter required');
|
|
1490
1584
|
console.error('Usage: abapgit-agent tree --package <package> [--depth <n>] [--include-objects] [--json]');
|
|
1491
|
-
console.error('Example: abapgit-agent tree --package
|
|
1585
|
+
console.error('Example: abapgit-agent tree --package ZMY_PACKAGE');
|
|
1586
|
+
process.exit(1);
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1589
|
+
// Check if package value is missing (happens when shell variable expands to empty)
|
|
1590
|
+
if (packageArgIndex + 1 >= args.length) {
|
|
1591
|
+
console.error('Error: --package parameter value is missing');
|
|
1592
|
+
console.error('');
|
|
1593
|
+
console.error('Tip: If you are using a shell variable, make sure to quote it:');
|
|
1594
|
+
console.error(' abapgit-agent tree --package "$ZMY_PACKAGE"');
|
|
1595
|
+
console.error(' or escape the $ character:');
|
|
1596
|
+
console.error(' abapgit-agent tree --package \\$ZMY_PACKAGE');
|
|
1597
|
+
console.error('');
|
|
1598
|
+
console.error('Usage: abapgit-agent tree --package <package> [--depth <n>] [--include-objects] [--json]');
|
|
1599
|
+
console.error('Example: abapgit-agent tree --package ZMY_PACKAGE');
|
|
1492
1600
|
process.exit(1);
|
|
1493
1601
|
}
|
|
1494
1602
|
|
|
1495
1603
|
const packageName = args[packageArgIndex + 1];
|
|
1496
1604
|
|
|
1605
|
+
// Check for empty/whitespace-only package name
|
|
1606
|
+
if (!packageName || packageName.trim() === '') {
|
|
1607
|
+
console.error('Error: --package parameter cannot be empty');
|
|
1608
|
+
console.error('Usage: abapgit-agent tree --package <package> [--depth <n>] [--include-objects] [--json]');
|
|
1609
|
+
console.error('Example: abapgit-agent tree --package ZMY_PACKAGE');
|
|
1610
|
+
process.exit(1);
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1497
1613
|
// Optional depth parameter
|
|
1498
1614
|
const depthArgIndex = args.indexOf('--depth');
|
|
1499
1615
|
let depth = 3;
|
package/docs/inspect-command.md
CHANGED
|
@@ -15,6 +15,12 @@ abapgit-agent inspect --files zcl_my_class.clas.abap,zcl_other.clas.abap
|
|
|
15
15
|
|
|
16
16
|
# With path
|
|
17
17
|
abapgit-agent inspect --files abap/zcl_my_class.clas.abap
|
|
18
|
+
|
|
19
|
+
# With Code Inspector variant
|
|
20
|
+
abapgit-agent inspect --files abap/zcl_my_class.clas.abap --variant ALL_CHECKS
|
|
21
|
+
|
|
22
|
+
# With no variant (uses default SAP standard checks)
|
|
23
|
+
abapgit-agent inspect --files abap/zcl_my_class.clas.abap --variant EMPTY
|
|
18
24
|
```
|
|
19
25
|
|
|
20
26
|
## Prerequisite
|
|
@@ -27,6 +33,7 @@ abapgit-agent inspect --files abap/zcl_my_class.clas.abap
|
|
|
27
33
|
| Parameter | Required | Description |
|
|
28
34
|
|-----------|----------|-------------|
|
|
29
35
|
| `--files` | Yes | Comma-separated list of files to inspect |
|
|
36
|
+
| `--variant` | No | Code Inspector variant name (e.g., `ALL_CHECKS`, `EMPTY`) |
|
|
30
37
|
|
|
31
38
|
---
|
|
32
39
|
|
|
@@ -54,7 +61,8 @@ GET /health (with X-CSRF-Token: fetch)
|
|
|
54
61
|
**Request Body:**
|
|
55
62
|
```json
|
|
56
63
|
{
|
|
57
|
-
"files": ["ZCL_MY_CLASS.CLASS.ABAP"]
|
|
64
|
+
"files": ["ZCL_MY_CLASS.CLASS.ABAP"],
|
|
65
|
+
"variant": "ALL_CHECKS"
|
|
58
66
|
}
|
|
59
67
|
```
|
|
60
68
|
|
|
@@ -140,6 +148,9 @@ abapgit-agent inspect --files zcl_my_class.clas.abap
|
|
|
140
148
|
|
|
141
149
|
# Multiple files
|
|
142
150
|
abapgit-agent inspect --files abap/zcl_my_class.clas.abap,abap/zcl_other.clas.abap
|
|
151
|
+
|
|
152
|
+
# With Code Inspector variant
|
|
153
|
+
abapgit-agent inspect --files abap/zcl_my_class.clas.abap --variant ALL_CHECKS
|
|
143
154
|
```
|
|
144
155
|
|
|
145
156
|
## Use Case
|