fix: resolve SonarQube quality gate failures on PROG/FUGR PR#81
fix: resolve SonarQube quality gate failures on PROG/FUGR PR#81ThePlenkov merged 25 commits intomainfrom
Conversation
|
View your CI Pipeline Execution ↗ for commit 1f7a4e1
☁️ Nx Cloud last updated this comment at |
…upport Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
|
Important Review skippedBot user detected. To trigger a single review, invoke the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Comment |
XML serialization fixes (ts-xsd): - Add stripUnusedNamespaces() to remove xmlns declarations for prefixes not used by any element/attribute in the built XML tree - Remove hardcoded EXCLUDED_NAMESPACE_URIS blocklist (was SAP-specific, ts-xsd is a generic W3C XSD library) - Simplify collectAllNamespaces() to clean pass-through; unused xmlns cleanup is now handled generically by stripUnusedNamespaces() - Fix walker to return defining schema for elements (enables correct namespace prefix for inherited child elements like adtcore:packageRef) ADT contracts: - Change POST create Content-Type to application/* (matching reference implementation abap-adt-api) abapGit plugin: - Add SAP 1-char to ISO 639-1 language code mapping (lang.ts) - Update INTF and CLAS handlers to convert language codes - Pass through ABAP_LANGUAGE_VERSION from abapGit XML - Add FUGR and PROG abapGit XSD schemas and handlers ADT export CLI: - Add --abap-language-version option for BTP systems requiring S_ABPLNGVS authorization - Inject packageRef and abapLanguageVersion into object data during export Tested live on: - BHF (on-premise): 5/5 objects created (INTF, CLAS x2, FUGR, PROG) - TRL (BTP trial): 4/5 objects created (PROG blocked by BTP S_DEVELOP)
There was a problem hiding this comment.
Nx Cloud is proposing a fix for your failed CI:
We fix the adt-schemas:test regression by updating stripUnusedNamespaces to accept an optional preservePrefixes set, and passing the root schema's own namespace prefix (e.g. atc) at the call site in build.ts. This ensures schemas with elementFormDefault="unqualified" — where no element ever carries a namespace prefix in the serialized output — still emit the required xmlns:atc declaration on the root element rather than having it stripped.
Tip
✅ We verified this fix by re-running adt-schemas:test.
Suggested Fix changes
diff --git a/packages/ts-xsd/src/xml/build-utils.ts b/packages/ts-xsd/src/xml/build-utils.ts
index 0e4efc4..b574fd1 100644
--- a/packages/ts-xsd/src/xml/build-utils.ts
+++ b/packages/ts-xsd/src/xml/build-utils.ts
@@ -142,8 +142,15 @@ export function createRootElement(
* This prevents emitting unused namespace declarations (e.g. xmlns:abapsource,
* xmlns:abapoo) that come from the schema's $imports chain but aren't
* referenced by any element or attribute in the built XML.
+ *
+ * @param preservePrefixes - prefixes to keep even if not referenced by any
+ * element or attribute (e.g. the root schema's own target-namespace prefix,
+ * which must remain in schemas where elementFormDefault="unqualified")
*/
-export function stripUnusedNamespaces(root: XmlElement): void {
+export function stripUnusedNamespaces(
+ root: XmlElement,
+ preservePrefixes?: Set<string>,
+): void {
// Collect all prefixes actually used by elements and attributes in the tree
const usedPrefixes = new Set<string>();
@@ -192,7 +199,7 @@ export function stripUnusedNamespaces(root: XmlElement): void {
const attr = attrs[i];
if (attr.name.startsWith('xmlns:')) {
const pfx = attr.name.substring(6);
- if (!usedPrefixes.has(pfx)) {
+ if (!usedPrefixes.has(pfx) && !preservePrefixes?.has(pfx)) {
toRemove.push(attr.name);
}
}
diff --git a/packages/ts-xsd/src/xml/build.ts b/packages/ts-xsd/src/xml/build.ts
index 6644ef8..b2d01bc 100644
--- a/packages/ts-xsd/src/xml/build.ts
+++ b/packages/ts-xsd/src/xml/build.ts
@@ -168,8 +168,13 @@ export function build<T extends SchemaLike>(
buildElement(doc, root, elementData, rootType, rootSchema, schema, prefix);
- // Remove xmlns declarations for prefixes not actually used in the built XML
- stripUnusedNamespaces(root);
+ // Remove xmlns declarations for prefixes not actually used in the built XML.
+ // Always preserve the root schema's own namespace prefix: schemas with
+ // elementFormDefault="unqualified" never emit prefixed elements, so the
+ // prefix would otherwise be incorrectly stripped even though the declaration
+ // is semantically required (e.g. xmlns:atc on an atc:customizing document).
+ const preservedPrefixes = prefix ? new Set([prefix]) : undefined;
+ stripUnusedNamespaces(root, preservedPrefixes);
// Ensure root element is never self-closing (SAP ADT requires closing tags)
// If root has no child nodes, add an empty text node to force </element> instead of />
Or Apply changes locally with:
npx nx-cloud apply-locally Meq3-sP4F
Apply fix locally with your editor ↗ View interactive diff ↗
🎓 Learn more about Self-Healing CI on nx.dev
There was a problem hiding this comment.
Pull request overview
Extends the ADT/ADK toolchain to support ABAP Programs (PROG/P) and Function Groups (FUGR/F), including schemas/contracts/ADK objects and abapGit handlers, plus some cross-cutting improvements to XML namespace emission and CLI/auth/config behavior.
Changes:
- Add PROG/FUGR support across
adt-schemas,adt-contracts,adt-client,adk,adt-plugin-abapgit, andadt-fixtures. - Improve
ts-xsdXML building to resolve namespace prefixes across imported schemas and strip unusedxmlns:*declarations. - Enhance CLI/auth/config: service-key login redirect URI support, new destinations directory loading, and some dependency/lockfile updates.
Reviewed changes
Copilot reviewed 52 out of 70 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/ts-xsd/tests/unit/xml-build.test.ts | Updates XML build expectations to only emit used namespace declarations. |
| packages/ts-xsd/src/xml/build.ts | Adds inherited-schema prefix resolution and strips unused namespaces post-build. |
| packages/ts-xsd/src/xml/build-utils.ts | Collects namespaces via imports/includes and adds stripUnusedNamespaces(). |
| packages/ts-xsd/src/walker/index.ts | Carries defining schema through element walker for correct prefix resolution. |
| packages/adt-schemas/ts-xsd.config.ts | Adds schema targets for programs and function groups. |
| packages/adt-schemas/src/schemas/generated/types/sap/programs.types.ts | Adds generated TS types for programs schema. |
| packages/adt-schemas/src/schemas/generated/types/sap/groups.types.ts | Adds generated TS types for function groups schema. |
| packages/adt-schemas/src/schemas/generated/types/sap/abapProgram.types.ts | Adds generated TS types for abapProgram schema. |
| packages/adt-schemas/src/schemas/generated/types/sap/abapFunctionGroup.types.ts | Adds generated TS types for abapFunctionGroup schema. |
| packages/adt-schemas/src/schemas/generated/typed.ts | Wires new typed schema exports (programs, groups). |
| packages/adt-schemas/src/schemas/generated/schemas/sap/programs.ts | Adds generated programs schema definition. |
| packages/adt-schemas/src/schemas/generated/schemas/sap/groups.ts | Adds generated function groups schema definition. |
| packages/adt-schemas/src/schemas/generated/schemas/sap/index.ts | Re-exports new SAP schemas. |
| packages/adt-plugin-abapgit/xsd/types/progdir.xsd | Adds abapGit XSD types for program metadata/textpool. |
| packages/adt-plugin-abapgit/xsd/types/fugr.xsd | Adds abapGit XSD types for function group metadata. |
| packages/adt-plugin-abapgit/xsd/prog.xsd | Adds abapGit object schema for PROG. |
| packages/adt-plugin-abapgit/xsd/fugr.xsd | Adds abapGit object schema for FUGR. |
| packages/adt-plugin-abapgit/ts-xsd.config.ts | Adds prog and fugr to schema generation list. |
| packages/adt-plugin-abapgit/src/schemas/generated/types/prog.ts | Adds generated TS types for abapGit PROG schema. |
| packages/adt-plugin-abapgit/src/schemas/generated/types/fugr.ts | Adds generated TS types for abapGit FUGR schema. |
| packages/adt-plugin-abapgit/src/schemas/generated/types/index.ts | Re-exports new abapGit schema types. |
| packages/adt-plugin-abapgit/src/schemas/generated/schemas/prog.ts | Adds generated PROG schema literal. |
| packages/adt-plugin-abapgit/src/schemas/generated/schemas/fugr.ts | Adds generated FUGR schema literal. |
| packages/adt-plugin-abapgit/src/schemas/generated/schemas/index.ts | Re-exports new schema literals. |
| packages/adt-plugin-abapgit/src/schemas/generated/index.ts | Exposes new abapGit schema instances (prog, fugr). |
| packages/adt-plugin-abapgit/src/lib/handlers/objects/prog.ts | Adds abapGit handler for PROG. |
| packages/adt-plugin-abapgit/src/lib/handlers/objects/fugr.ts | Adds abapGit handler for FUGR. |
| packages/adt-plugin-abapgit/src/lib/handlers/objects/index.ts | Registers new handlers export surface. |
| packages/adt-plugin-abapgit/src/lib/handlers/objects/intf.ts | Adds SAP↔ISO language conversion for interface handler. |
| packages/adt-plugin-abapgit/src/lib/handlers/objects/clas.ts | Adds SAP↔ISO language conversion for class handler. |
| packages/adt-plugin-abapgit/src/lib/handlers/lang.ts | Adds language mapping utilities used by handlers. |
| packages/adt-plugin-abapgit/src/lib/handlers/adk.ts | Re-exports new ADK object classes. |
| packages/adt-fixtures/src/fixtures/registry.ts | Registers fixtures for programs and function groups. |
| packages/adt-fixtures/src/fixtures/programs/program.xml | Adds sample ADT fixture for a program. |
| packages/adt-fixtures/src/fixtures/functions/functionGroup.xml | Adds sample ADT fixture for a function group. |
| packages/adt-export/src/commands/export.ts | Adds --abap-language-version and mutates object data before deploy. |
| packages/adt-contracts/tests/contracts/oo.test.ts | Changes expected request Content-Type header behavior in tests. |
| packages/adt-contracts/src/helpers/crud.ts | Alters CRUD request headers (notably Content-Type). |
| packages/adt-contracts/src/generated/schemas.ts | Wires new typed schemas into contracts layer. |
| packages/adt-contracts/src/adt/programs/programs.ts | Adds Programs CRUD contract definition. |
| packages/adt-contracts/src/adt/programs/index.ts | Adds Programs module contract export surface. |
| packages/adt-contracts/src/adt/functions/groups.ts | Adds Function Groups CRUD contract definition. |
| packages/adt-contracts/src/adt/functions/index.ts | Adds Functions module contract export surface. |
| packages/adt-contracts/src/adt/index.ts | Adds programs and functions modules to the global ADT contract. |
| packages/adt-config/src/config-loader.ts | Adds .adt/destinations/*.json loading and local override merge logic. |
| packages/adt-codegen/package.json | Bumps fast-xml-parser dependency. |
| packages/adt-client/src/index.ts | Re-exports new response types for ADK consumption. |
| packages/adt-cli/src/lib/config.ts | Derives OAuth redirect URI from shared callback port constant. |
| packages/adt-cli/src/lib/commands/auth/login.ts | Adds service-key auth and redirect URI handling in login flow. |
| packages/adt-cli/src/lib/cli.ts | Refactors config path parsing and removes global service-key auto-auth. |
| packages/adt-auth/src/types/service-key.ts | Adds redirectUri option for service-key plugin. |
| packages/adt-auth/src/plugins/service-key.ts | Supports custom redirect URI and callback path matching in PKCE flow. |
| packages/adk/src/objects/repository/prog/prog.types.ts | Adds public types for Program objects. |
| packages/adk/src/objects/repository/prog/prog.model.ts | Adds AdkProgram implementation and self-registration. |
| packages/adk/src/objects/repository/prog/index.ts | Exposes Program object/types. |
| packages/adk/src/objects/repository/fugr/fugr.types.ts | Adds public types for Function Group objects. |
| packages/adk/src/objects/repository/fugr/fugr.model.ts | Adds AdkFunctionGroup implementation and self-registration. |
| packages/adk/src/objects/repository/fugr/index.ts | Exposes Function Group object/types. |
| packages/adk/src/index.ts | Re-exports new ADK objects and response types. |
| packages/adk/src/base/kinds.ts | Extends AdkObjectForKind mapping for Program/FunctionGroup. |
| packages/adk/src/base/adt.ts | Extends ADK contract proxy and exported response types. |
| package.json | Updates dependencies/devDeps and adds an override. |
| git_modules/abap-file-formats | Updates submodule commit. |
| bun.lock | Updates lockfile entries (deps and workspace versions). |
| adt.config.ts | Adds explicit AdtConfig typing and assertion. |
| .skills/skills | Adds skills subproject pointer. |
| .gitignore | Ignores .adt, package-lock.json, and .nx/polygraph. |
| .agents/skills/adt-reverse-engineering/SKILL.md | Adds new skill documentation file. |
| .agents/skills/add-object-type/SKILL.md | Documents chaining to reverse engineering skill. |
| .agents/skills/add-endpoint/SKILL.md | Documents chaining to reverse engineering skill. |
Comments suppressed due to low confidence (6)
packages/adt-contracts/src/helpers/crud.ts:1
- Setting request
Content-Typetoapplication/*is not a valid media type and may cause SAP ADT POST/PUT requests to be rejected (servers typically require an exact content type). Use thecontentTypepassed tocrud()forContent-Type, and if flexibility is needed, make it an explicit option per endpoint rather than forcing a wildcard.
packages/adt-fixtures/src/fixtures/programs/program.xml:1 - The fixture's namespace and
programTypevalue appear inconsistent with the generated schema/contract in this PR (schema targetNamespace useshttp://www.sap.com/adt/programs/programs, and the generated schema definesprogramTypeas anAbapProgramTypeenumeration). Align the fixture namespace URI with the schema used byprogramsContract, and ensureprog:programTypematches the schema's expected value format.
packages/adt-fixtures/src/fixtures/programs/program.xml:1 - The fixture's namespace and
programTypevalue appear inconsistent with the generated schema/contract in this PR (schema targetNamespace useshttp://www.sap.com/adt/programs/programs, and the generated schema definesprogramTypeas anAbapProgramTypeenumeration). Align the fixture namespace URI with the schema used byprogramsContract, and ensureprog:programTypematches the schema's expected value format.
packages/adt-fixtures/src/fixtures/functions/functionGroup.xml:1 - The fixture namespace URI (
http://www.sap.com/adt/functions) is inconsistent with the generated schema/contract added in this PR (http://www.sap.com/adt/functions/groups). Update the fixture so its namespace URI matches the schema used byfunctionGroupsContract.
packages/ts-xsd/src/xml/build.ts:1 collectAllXmlns()only traverses$imports, butcreateXmlDocument()collects namespaces from both$importsand$includes. This can causegetPrefixForSchema()to miss prefixes for schemas referenced via$includes, leading to incorrect prefix selection/fallbacks. ExtendcollectAllXmlns()to also traverse$includes(or refactor to reuse a single shared namespace-collection implementation) so prefix resolution matches document namespace collection.
packages/adt-export/src/commands/export.ts:1- This mutates an internal/private
_datafield viaany, which couples the CLI to ADK internals and can easily break with refactors. Prefer a public API on the object (or object set) to apply creation defaults (e.g.,setPackageRef(...),setAbapLanguageVersion(...), or an options object passed into create/save) so this logic remains stable and type-safe.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| if ( | ||
| typeof candidate.type === 'string' && | ||
| 'options' in candidate && | ||
| typeof candidate.options === 'object' |
| '--config <path>', | ||
| 'Path to config file (default: adt.config.ts, or .adt/config.ts if present)', |
…uard in config-loader - stripUnusedNamespaces() now accepts optional schema parameter and preserves the xmlns declaration for the schema's own targetNamespace prefix, even when elementFormDefault='unqualified' causes the root element to be emitted without a prefix (fixes atc.test.ts CI failure) - Add null guards to typeof === 'object' checks in config-loader.ts (typeof null === 'object' is true in JS)
- Extract nested ternary in prog.ts (S3358) - Convert for loops to for-of in build-utils.ts (S4138 x3) - Extract walk helper to reduce cognitive complexity in build-utils.ts (S3776 x2) - Consolidate fs imports to node:fs in cli.ts (S7772, S3863) - Replace findIndex with indexOf in cli.ts (S7753) - Remove useless empty objects in config-loader.ts (S7744 x2) - Extract helpers to reduce loadConfig cognitive complexity (S3776) Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
|
@copilot sonarqube failed again. How about removing generated types from git? And bringing schema generation to git? At least typescript ones? Alternatively we can exclude these types from sonarqube since they are generated ones |
…ality gate Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
Went with the exclusion approach (commit
The |
… packages - Add pre-lock source comparison in AdkClass to avoid locking when sources are identical to SAP - Introduce _unchanged flag on AdkObject to signal no-op saves - Add normalizeSource() to trim trailing whitespace for comparison - Implement checkPendingSourcesUnchanged() hook for pre-lock validation - Track unchanged count in BulkSaveResult (success/failed/unchanged) - Add AdkPackage.exists() and AdkPackage.create() static
… unchanged detection
- Implement savePendingSources() in AdkObject base class for single-source objects (GET/PUT to {objectUri}/source/main)
- Implement checkPendingSourcesUnchanged() in base class with normalizeSource() comparison
- Remove duplicate implementations from AdkInterface, AdkProgram, AdkFunctionGroup (now use base class)
- AdkClass keeps multi-include override for _pendingSources logic
- Update SKILL.md and AGENTS
- Add blank line after list items in SKILL.md and AGENTS.md for markdown consistency - Fix trailing newline in .claude/settings.json - Reformat multiline type annotations in export.ts for readability - Remove unnecessary line breaks in deserializer.ts and folder-logic.test.ts imports/calls
- Replace regex patterns flagged as ReDoS-vulnerable (S5852): - model.ts: /\s+$/gm → split+trimEnd per line - folder-logic.ts: /^\/+|\/+$/g → stripSlashes() loop - folder-logic.ts: XML tag regexes simplified (removed redundant \s*) - deserializer.ts: use shared stripSlashes() from folder-logic - Exclude AI agent docs (.agents/, .windsurf/, .claude/, .skills/) from SonarCloud analysis to fix duplication false positives
…and code quality Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
Co-authored-by: ThePlenkov <6381507+ThePlenkov@users.noreply.github.com>
|



SonarQube quality gate was failing with
new_duplicated_lines_density=25.7%(threshold 3%) andnew_security_hotspots_reviewed=68.8%(threshold 100%), plus 10 open code issues including two CRITICAL cognitive complexity violations.Exclusions
sonar.exclusionstosonar-project.propertiescovering all*/src/schemas/generated/**paths — removes generated schema files from analysis entirely (duplication + namespace-URI false-positive hotspots)ReDoS hotspots (S5852)
model.tsnormalizeSource:/\s+$/gm→split('\n').map(l => l.trimEnd()).join('\n')folder-logic.tsXML tag regexes: removed redundant\s*groups around[^<]+; switched to[^<]+(non-empty) with.trim()to fail fast on malformed tags/^\/+|\/+$/gwithstripSlashes()loop (exported for reuse in deserializer)Cognitive complexity (S3776 — CRITICAL)
Refactored
collectUsedPrefixes(16→≤15) andstripUnusedNamespaces(19→≤15) inbuild-utils.tsby extracting three focused helpers:addPrefixFromName— extracts prefix from a qualified namecollectPrefixesFromAttributes— scans a single element's non-xmlns attributesfindUnusedXmlnsAttrs— identifies removablexmlns:*attributes on the rootCode duplication
saveMainSourcewas copy-pasted verbatim acrossAdkInterface,AdkProgram, andAdkFunctionGroup. Moved toAdkMainObjectbase class usingthis.objectUri:Minor code quality
ExportOptionsimport inabapgit.tsString.match()→RegExp.exec()infolder-logic.ts!assertion already narrowed by preceding guardparts[parts.length - 1]→parts.at(-1)!Original prompt
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.