abapgit-agent 1.14.0 → 1.14.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.
@@ -73,10 +73,47 @@ abapgit-agent pull --files src/zcl_auth_handler.clas.abap
73
73
  abapgit-agent unit --files src/zcl_auth_handler.clas.testclasses.abap
74
74
 
75
75
  # 3. Create PR (squash merge enabled on GitHub/GitLab)
76
- # Go to GitHub and create PR from feature/user-authentication to main
77
- # Select "Squash and merge" option to combine all commits into one
76
+ # See "Creating a PR" section below for transport handling
78
77
  ```
79
78
 
79
+ #### Creating a PR
80
+
81
+ When creating a PR with `gh pr create`:
82
+
83
+ **Check `.abapgit-agent.json` for `transports.hook`.**
84
+
85
+ ```
86
+ transports.hook present?
87
+ ├─ NO → create PR normally, no transport line needed. STOP here.
88
+ └─ YES → continue below
89
+ ```
90
+
91
+ **If hook is configured — resolve which transport to include:**
92
+
93
+ ```bash
94
+ abapgit-agent transport list --scope task --json
95
+ ```
96
+
97
+ - **One result** → use it directly, no need to ask the user
98
+ - **Multiple results** → show the list to the user and ask which one to use for this PR
99
+ - **No results** → ask the user to provide a transport number manually, or confirm to skip
100
+
101
+ **Append `transport: <number>` as the last line of the PR body:**
102
+
103
+ ```
104
+ ## Summary
105
+ - Implemented user authentication handler
106
+
107
+ ## Changed Objects
108
+ - ZCL_AUTH_HANDLER (CLAS)
109
+
110
+ transport: DEVK900001
111
+ ```
112
+
113
+ **Why:** The CI pipeline reads this line from the PR description and uses it for the
114
+ Activate stage, overriding the automatic hook selection. This lets the user control
115
+ which transport request receives the activated changes.
116
+
80
117
  #### Why Rebase Before Pull?
81
118
 
82
119
  ABAP is a **centralized system**. Multiple developers may modify the same files:
@@ -137,5 +174,6 @@ abapgit-agent pull --files src/zcl_auth_handler.clas.abap
137
174
  abapgit-agent unit --files src/zcl_auth_handler.clas.testclasses.abap
138
175
  git fetch origin main && git rebase origin/main
139
176
  git push origin feature/user-authentication --force-with-lease
140
- # Create PR on GitHub/GitLab (squash 3 commits into 1)
177
+ # Create PR: check transport hook, resolve transport, include in PR body
178
+ # abapgit-agent transport list --scope task --json → pick transport → append to PR body
141
179
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abapgit-agent",
3
- "version": "1.14.0",
3
+ "version": "1.14.1",
4
4
  "description": "ABAP Git Agent - Pull and activate ABAP code via abapGit from any git repository",
5
5
  "files": [
6
6
  "bin/",
@@ -57,7 +57,13 @@ module.exports = {
57
57
  }
58
58
 
59
59
  const cfg = JSON.parse(fs.readFileSync(configPath, 'utf8'));
60
- cfg.global.files = abapFiles.map(f => `/${f}`);
60
+
61
+ // Scope to changed files + their direct dependencies (interfaces, superclasses)
62
+ // so abaplint can resolve cross-references without including the whole repo.
63
+ const abapDir = cfg.global.files.replace(/\/\*\*.*$/, '').replace(/^\//, '') || 'abap';
64
+ const depFiles = resolveDependencies(abapFiles, abapDir);
65
+ const allFiles = [...new Set([...abapFiles, ...depFiles])];
66
+ cfg.global.files = allFiles.map(f => `/${f}`);
61
67
 
62
68
  const scopedConfig = '.abaplint-local.json';
63
69
  fs.writeFileSync(scopedConfig, JSON.stringify(cfg, null, 2));
@@ -117,6 +123,69 @@ function runGit(cmd) {
117
123
  }
118
124
  }
119
125
 
126
+ /**
127
+ * Resolve direct dependencies of the given ABAP files by scanning their source
128
+ * for interface/superclass/type references and mapping them to local files.
129
+ *
130
+ * Handles:
131
+ * INTERFACES <name>. → <name>.intf.abap + <name>.intf.xml
132
+ * INHERITING FROM <name> → <name>.clas.abap + <name>.clas.xml
133
+ * TYPE REF TO <name> → <name>.intf.abap or <name>.clas.abap (whichever exists)
134
+ *
135
+ * Only resolves one level deep — enough for abaplint to check the changed files.
136
+ * XML companion files are always included alongside their .abap counterpart
137
+ * so xml_consistency checks can run.
138
+ */
139
+ function resolveDependencies(abapFiles, abapDir) {
140
+ const deps = new Set();
141
+ const visited = new Set(abapFiles); // don't re-scan changed files as deps
142
+
143
+ // Patterns to extract referenced object names from ABAP source
144
+ const patterns = [
145
+ /^\s*INTERFACES\s+(\w+)\s*\./gim,
146
+ /INHERITING\s+FROM\s+(\w+)/gim,
147
+ /TYPE\s+REF\s+TO\s+(\w+)/gim,
148
+ ];
149
+
150
+ // BFS queue — seed with the changed files, then expand transitively
151
+ const queue = [...abapFiles];
152
+
153
+ while (queue.length > 0) {
154
+ const file = queue.shift();
155
+
156
+ let source;
157
+ try { source = fs.readFileSync(file, 'utf8'); } catch { continue; }
158
+
159
+ for (const pattern of patterns) {
160
+ pattern.lastIndex = 0;
161
+ let match;
162
+ while ((match = pattern.exec(source)) !== null) {
163
+ const name = match[1].toLowerCase();
164
+ for (const suffix of [`${name}.intf`, `${name}.clas`]) {
165
+ const abapFile = path.join(abapDir, `${suffix}.abap`);
166
+ const xmlFile = path.join(abapDir, `${suffix}.xml`);
167
+ if (fs.existsSync(abapFile)) {
168
+ deps.add(abapFile);
169
+ if (fs.existsSync(xmlFile)) deps.add(xmlFile);
170
+ // Recurse into this dep if not yet visited
171
+ if (!visited.has(abapFile)) {
172
+ visited.add(abapFile);
173
+ queue.push(abapFile);
174
+ }
175
+ break; // intf matched — don't also try clas
176
+ }
177
+ }
178
+ }
179
+ }
180
+
181
+ // Always include the XML companion of each scanned file
182
+ const xmlCompanion = file.replace(/\.abap$/, '.xml');
183
+ if (fs.existsSync(xmlCompanion)) deps.add(xmlCompanion);
184
+ }
185
+
186
+ return [...deps];
187
+ }
188
+
120
189
  /**
121
190
  * Keep only files that look like ABAP source files
122
191
  * (name.type.abap or name.type.subtype.abap).