abapgit-agent 1.0.0 → 1.0.1
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/INSTALL.md +4 -4
- package/README.md +3 -1
- package/abap/zcl_abgagt_agent.clas.abap +0 -349
- package/abap/zcl_abgagt_cmd_factory.clas.abap +3 -1
- package/abap/zcl_abgagt_command_create.clas.abap +86 -0
- package/abap/zcl_abgagt_command_create.clas.xml +15 -0
- package/abap/zcl_abgagt_command_import.clas.abap +138 -0
- package/abap/zcl_abgagt_command_import.clas.xml +15 -0
- package/abap/zcl_abgagt_resource_create.clas.abap +70 -0
- package/abap/zcl_abgagt_resource_create.clas.xml +15 -0
- package/abap/zcl_abgagt_resource_import.clas.abap +66 -0
- package/abap/zcl_abgagt_resource_import.clas.xml +15 -0
- package/abap/zcl_abgagt_rest_handler.clas.abap +2 -0
- package/abap/zif_abgagt_agent.intf.abap +3 -84
- package/abap/zif_abgagt_command.intf.abap +3 -1
- package/bin/abapgit-agent +325 -16
- package/docs/commands.md +107 -0
- package/docs/create-command.md +211 -0
- package/docs/health-command.md +89 -0
- package/docs/import-command.md +196 -0
- package/docs/init-command.md +176 -0
- package/docs/inspect-command.md +158 -0
- package/docs/pull-command.md +188 -0
- package/docs/status-command.md +68 -0
- package/docs/unit-command.md +167 -0
- package/package.json +1 -1
- package/src/abap-client.js +60 -0
- package/src/agent.js +52 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# unit Command Requirements
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Run AUnit tests for ABAP test classes and display detailed results.
|
|
6
|
+
|
|
7
|
+
## Command
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# Single test class file
|
|
11
|
+
abapgit-agent unit --files zcl_my_test.clas.testclasses.abap
|
|
12
|
+
|
|
13
|
+
# Multiple test class files
|
|
14
|
+
abapgit-agent unit --files zcl_test1.clas.testclasses.abap,zcl_test2.clas.testclasses.abap
|
|
15
|
+
|
|
16
|
+
# With path
|
|
17
|
+
abapgit-agent unit --files abap/zcl_my_test.clas.testclasses.abap
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Prerequisite
|
|
21
|
+
|
|
22
|
+
- `.abapGitAgent` exists with valid credentials
|
|
23
|
+
- Files must be test class files (`.testclasses.abap`)
|
|
24
|
+
|
|
25
|
+
## Parameters
|
|
26
|
+
|
|
27
|
+
| Parameter | Required | Description |
|
|
28
|
+
|-----------|----------|-------------|
|
|
29
|
+
| `--files` | Yes | Comma-separated list of test class files |
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Tasks
|
|
34
|
+
|
|
35
|
+
### 1. Validate Parameters
|
|
36
|
+
|
|
37
|
+
- `--files` must be specified
|
|
38
|
+
- Files must be `.testclasses.abap` format
|
|
39
|
+
|
|
40
|
+
### 2. Load Configuration
|
|
41
|
+
|
|
42
|
+
Read `.abapGitAgent` for credentials
|
|
43
|
+
|
|
44
|
+
### 3. Fetch CSRF Token
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
GET /health (with X-CSRF-Token: fetch)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 4. Make Unit Request
|
|
51
|
+
|
|
52
|
+
**Endpoint:** `POST /unit`
|
|
53
|
+
|
|
54
|
+
**Request Body:**
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"files": ["ZCL_MY_TEST.CLASS.TESTCLASSES.ABAP"]
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 5. Display Results
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Output
|
|
66
|
+
|
|
67
|
+
### All Tests Passed
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
Running unit tests for 2 file(s)
|
|
71
|
+
|
|
72
|
+
✅ ZCL_MY_TEST - All tests passed
|
|
73
|
+
Tests: 10 | Passed: 10 | Failed: 0
|
|
74
|
+
|
|
75
|
+
✅ ZCL_OTHER_TEST - All tests passed
|
|
76
|
+
Tests: 5 | Passed: 5 | Failed: 0
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### With Failures
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
Running unit tests for 1 file(s)
|
|
83
|
+
|
|
84
|
+
❌ ZCL_MY_TEST - Tests failed
|
|
85
|
+
Tests: 10 | Passed: 8 | Failed: 2
|
|
86
|
+
✗ ZCL_MY_TEST=>TEST_METHOD_1: Error description
|
|
87
|
+
✗ ZCL_MY_TEST=>TEST_METHOD_2: Another error
|
|
88
|
+
|
|
89
|
+
Failed Tests:
|
|
90
|
+
────────────────────────────────────────────────────────────────────────────────
|
|
91
|
+
✗ ZCL_MY_TEST=>TEST_METHOD_1
|
|
92
|
+
Error: Expected X but got Y
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Response Structure
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"success": "X",
|
|
102
|
+
"message": "2 of 10 tests failed",
|
|
103
|
+
"test_count": 10,
|
|
104
|
+
"passed_count": 8,
|
|
105
|
+
"failed_count": 2,
|
|
106
|
+
"errors": [
|
|
107
|
+
{
|
|
108
|
+
"class_name": "ZCL_MY_TEST",
|
|
109
|
+
"method_name": "TEST_METHOD_1",
|
|
110
|
+
"error_kind": "ERROR",
|
|
111
|
+
"error_text": "Expected X but got Y"
|
|
112
|
+
}
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Error Handling
|
|
120
|
+
|
|
121
|
+
| Error | Message |
|
|
122
|
+
|-------|---------|
|
|
123
|
+
| File not found | `File not found: <path>` |
|
|
124
|
+
| Invalid format | `Invalid file format: <file>` |
|
|
125
|
+
| No --files specified | `Error: --files parameter required` |
|
|
126
|
+
| No tests found | `➖ <class> - No unit tests` |
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## File Format
|
|
131
|
+
|
|
132
|
+
Test class files must end with `.testclasses.abap`:
|
|
133
|
+
|
|
134
|
+
| File | Test Class |
|
|
135
|
+
|------|------------|
|
|
136
|
+
| `zcl_my_test.clas.testclasses.abap` | ZCL_MY_TEST |
|
|
137
|
+
| `src/tests/zcl_my_test.clas.testclasses.abap` | ZCL_MY_TEST |
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Error Details
|
|
142
|
+
|
|
143
|
+
When a test fails, output includes:
|
|
144
|
+
- **Class**: The test class name
|
|
145
|
+
- **Method**: Failed test method name (with `=>` notation)
|
|
146
|
+
- **Error Kind**: Type of error (ERROR, FAILURE, etc.)
|
|
147
|
+
- **Error Text**: Detailed error message from AUnit
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Example
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Run tests
|
|
155
|
+
abapgit-agent unit --files zcl_my_test.clas.testclasses.abap
|
|
156
|
+
|
|
157
|
+
# Multiple
|
|
158
|
+
abapgit-agent unit --files abap/zcl_test1.clas.testclasses.abap,abap/zcl_test2.clas.testclasses.abap
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Implementation
|
|
162
|
+
|
|
163
|
+
Uses `CL_SUT_AUNIT_RUNNER` to execute tests:
|
|
164
|
+
- `S_CREATE` - Create test runner
|
|
165
|
+
- `run()` - Execute tests
|
|
166
|
+
- `str_results` - Get test statistics
|
|
167
|
+
- `tab_objects` - Get detailed results
|
package/package.json
CHANGED
package/src/abap-client.js
CHANGED
|
@@ -296,6 +296,66 @@ class ABAPClient {
|
|
|
296
296
|
|
|
297
297
|
return await this.request('POST', '/unit', data, { csrfToken: this.csrfToken });
|
|
298
298
|
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Create a new online repository
|
|
302
|
+
* @param {string} repoUrl - Git repository URL
|
|
303
|
+
* @param {string} packageName - ABAP package name
|
|
304
|
+
* @param {string} branch - Branch name (default: 'main')
|
|
305
|
+
* @param {string} displayName - Display name for the repository (optional)
|
|
306
|
+
* @param {string} name - Repository name (optional)
|
|
307
|
+
* @param {string} folderLogic - Folder logic: 'PREFIX' or 'FULL' (default: 'PREFIX')
|
|
308
|
+
* @returns {object} Create result
|
|
309
|
+
*/
|
|
310
|
+
async create(repoUrl, packageName, branch = 'main', displayName = null, name = null, folderLogic = 'PREFIX') {
|
|
311
|
+
// Fetch CSRF token first
|
|
312
|
+
await this.fetchCsrfToken();
|
|
313
|
+
|
|
314
|
+
const data = {
|
|
315
|
+
url: repoUrl,
|
|
316
|
+
package: packageName,
|
|
317
|
+
branch: branch
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
if (displayName) {
|
|
321
|
+
data.display_name = displayName;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (name) {
|
|
325
|
+
data.name = name;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (folderLogic) {
|
|
329
|
+
data.folder_logic = folderLogic;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
logger.info('Creating repository', { repoUrl, packageName, branch, service: 'abapgit-agent' });
|
|
333
|
+
|
|
334
|
+
return await this.request('POST', '/create', data, { csrfToken: this.csrfToken });
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Import existing objects from package to git repository
|
|
339
|
+
* @param {string} repoUrl - Git repository URL
|
|
340
|
+
* @param {string} message - Commit message (optional)
|
|
341
|
+
* @returns {object} Import result with success, files_staged, commit_sha
|
|
342
|
+
*/
|
|
343
|
+
async import(repoUrl, message = null) {
|
|
344
|
+
// Fetch CSRF token first
|
|
345
|
+
await this.fetchCsrfToken();
|
|
346
|
+
|
|
347
|
+
const data = {
|
|
348
|
+
url: repoUrl
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
if (message) {
|
|
352
|
+
data.message = message;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
logger.info('Starting import operation', { repoUrl, message, service: 'abapgit-agent' });
|
|
356
|
+
|
|
357
|
+
return await this.request('POST', '/import', data, { csrfToken: this.csrfToken });
|
|
358
|
+
}
|
|
299
359
|
}
|
|
300
360
|
|
|
301
361
|
// Singleton instance
|
package/src/agent.js
CHANGED
|
@@ -112,6 +112,58 @@ class ABAPGitAgent {
|
|
|
112
112
|
throw new Error(`Unit tests failed: ${error.message}`);
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Create a new online repository
|
|
118
|
+
* @param {string} repoUrl - Git repository URL
|
|
119
|
+
* @param {string} packageName - ABAP package name
|
|
120
|
+
* @param {string} branch - Branch name (default: 'main')
|
|
121
|
+
* @param {string} displayName - Display name for the repository (optional)
|
|
122
|
+
* @param {string} name - Repository name (optional)
|
|
123
|
+
* @param {string} folderLogic - Folder logic: 'PREFIX' or 'FULL' (default: 'PREFIX')
|
|
124
|
+
* @returns {object} Create result with success, repo_key, repo_name, message
|
|
125
|
+
*/
|
|
126
|
+
async create(repoUrl, packageName, branch = 'main', displayName = null, name = null, folderLogic = 'PREFIX') {
|
|
127
|
+
logger.info('Creating repository', { repoUrl, packageName, branch });
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
const result = await this.abap.create(repoUrl, packageName, branch, displayName, name, folderLogic);
|
|
131
|
+
return {
|
|
132
|
+
success: result.SUCCESS === 'X' || result.success === 'X' || result.success === true,
|
|
133
|
+
repo_key: result.REPO_KEY || result.repo_key,
|
|
134
|
+
repo_name: result.REPO_NAME || result.repo_name,
|
|
135
|
+
message: result.MESSAGE || result.message || '',
|
|
136
|
+
error: result.ERROR || result.error || null
|
|
137
|
+
};
|
|
138
|
+
} catch (error) {
|
|
139
|
+
logger.error('Create failed', { error: error.message });
|
|
140
|
+
throw new Error(`Create failed: ${error.message}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Import existing objects from package to git repository
|
|
146
|
+
* @param {string} repoUrl - Git repository URL
|
|
147
|
+
* @param {string} message - Commit message (optional)
|
|
148
|
+
* @returns {object} Import result with success, files_staged, commit_sha
|
|
149
|
+
*/
|
|
150
|
+
async import(repoUrl, message = null) {
|
|
151
|
+
logger.info('Starting import operation', { repoUrl, message });
|
|
152
|
+
|
|
153
|
+
try {
|
|
154
|
+
const result = await this.abap.import(repoUrl, message);
|
|
155
|
+
return {
|
|
156
|
+
success: result.SUCCESS === 'X' || result.success === 'X' || result.success === true,
|
|
157
|
+
files_staged: result.FILES_STAGED || result.files_staged || 0,
|
|
158
|
+
commit_sha: result.COMMIT_SHA || result.commit_sha || '',
|
|
159
|
+
message: result.MESSAGE || result.message || '',
|
|
160
|
+
error: result.ERROR || result.error || null
|
|
161
|
+
};
|
|
162
|
+
} catch (error) {
|
|
163
|
+
logger.error('Import failed', { error: error.message });
|
|
164
|
+
throw new Error(`Import failed: ${error.message}`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
115
167
|
}
|
|
116
168
|
|
|
117
169
|
module.exports = {
|