From acd6d30800b20bf80fc064498948b736dbd99fa5 Mon Sep 17 00:00:00 2001 From: Jeppe Fredsgaard Blaabjerg Date: Tue, 12 May 2026 14:08:39 +0200 Subject: [PATCH 1/3] fix(manifest): copy sbt-generated poms out of `target/` (REA-437) `socket manifest scala` runs `sbt makePom`, which writes poms into each subproject's `target/scala-X.Y/` dir. That path is gitignored in standard SBT projects, so downstream SBOM/scan steps that respect `.gitignore` never see the generated manifests. After sbt finishes, walk up from each reported `Wrote .pom` to its `target/` ancestor and copy the pom to `/socket.pom.xml` (or ``). Single-pom case with an explicit path `--out` still honors the exact path; stdout mode unchanged. Mirrors what `init.gradle` already does on the gradle path, just from Node since sbt has no direct analogue of `gradle --init-script`. Also tightens the success output to one list of destinations to match the gradle command's verbosity. --- package.json | 2 +- .../manifest/convert_sbt_to_maven.mts | 72 +++++++++++++++---- 2 files changed, 61 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 601fc7464..1e78f22ea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "socket", - "version": "1.1.93", + "version": "1.1.94", "description": "CLI for Socket.dev", "homepage": "https://github.com/SocketDev/socket-cli", "license": "MIT AND OFL-1.1", diff --git a/src/commands/manifest/convert_sbt_to_maven.mts b/src/commands/manifest/convert_sbt_to_maven.mts index 4846117b5..926db79a9 100644 --- a/src/commands/manifest/convert_sbt_to_maven.mts +++ b/src/commands/manifest/convert_sbt_to_maven.mts @@ -1,9 +1,28 @@ +import { promises as fs } from 'node:fs' +import path from 'node:path' + import { safeReadFile } from '@socketsecurity/registry/lib/fs' import { logger } from '@socketsecurity/registry/lib/logger' import { spawn } from '@socketsecurity/registry/lib/spawn' import constants from '../../constants.mts' +// Walk up from a pom path to find a `target` directory ancestor and return +// its parent (the project root). Returns undefined if no `target` ancestor +// is found, which means we cannot safely lift the file out of the ignored +// build dir. +function findProjectRootAboveTarget(pomPath: string): string | undefined { + let dir = path.dirname(pomPath) + const { root } = path.parse(dir) + while (dir !== root) { + if (path.basename(dir) === 'target') { + return path.dirname(dir) + } + dir = path.dirname(dir) + } + return undefined +} + export async function convertSbtToMaven({ bin, cwd, @@ -92,18 +111,47 @@ export async function convertSbtToMaven({ logger.info('Exiting now...') return } else { - // if (verbose) { - // logger.log( - // `Moving manifest file from \`${loc.replace(/^\/home\/[^/]*?\//, '~/')}\` to \`${out}\`` - // ) - // } else { - // logger.log('Moving output pom file') - // } - // TODO: Do we prefer fs-extra? Renaming can be gnarly on windows and fs-extra's version is better. - // await renamep(loc, out) - logger.success(`Generated ${poms.length} pom files`) - poms.forEach(fn => logger.log('-', fn)) - logger.success(`OK`) + // sbt writes poms inside each project's `target/` directory, which is + // typically gitignored. Copy them out to a sibling of `target/` so + // downstream SBOM/scan steps see them. + const copied: string[] = [] + const outBasename = path.basename(out) || 'socket.pom.xml' + for (const pomPath of poms) { + let destPath: string + if (poms.length === 1 && out !== outBasename) { + // Honor the full `--out` path verbatim when exactly one pom was + // produced and the user (or default) supplied a path, not just a + // bare filename. + destPath = path.resolve(cwd, out) + } else { + const projectRoot = findProjectRootAboveTarget(pomPath) + if (!projectRoot) { + logger.warn( + `Could not locate \`target/\` ancestor for \`${pomPath}\`, leaving in place`, + ) + continue + } + destPath = path.join(projectRoot, outBasename) + } + try { + // eslint-disable-next-line no-await-in-loop + await fs.mkdir(path.dirname(destPath), { recursive: true }) + // eslint-disable-next-line no-await-in-loop + await fs.copyFile(pomPath, destPath) + copied.push(destPath) + } catch (e) { + logger.warn( + `Failed to copy \`${pomPath}\` to \`${destPath}\`: ${(e as Error).message}`, + ) + } + } + logger.success( + `Generated ${copied.length} pom file${copied.length === 1 ? '' : 's'}`, + ) + logger.log('Reported exports:') + for (const fn of copied) { + logger.log('-', fn) + } } } catch (e) { process.exitCode = 1 From a4e83465d7fb61a53cb1cf3eba9a69e1de883420 Mon Sep 17 00:00:00 2001 From: Jeppe Fredsgaard Blaabjerg Date: Tue, 12 May 2026 14:17:36 +0200 Subject: [PATCH 2/3] fix(manifest): use getErrorCause helper in sbt copy catch Replaces the ad-hoc `(e as Error).message` cast in the pom-copy catch block with `getErrorCause(e)` from `utils/errors.mts`, matching the project's existing convention. Addresses cursor bugbot review on #1311. --- src/commands/manifest/convert_sbt_to_maven.mts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/commands/manifest/convert_sbt_to_maven.mts b/src/commands/manifest/convert_sbt_to_maven.mts index 926db79a9..170d40499 100644 --- a/src/commands/manifest/convert_sbt_to_maven.mts +++ b/src/commands/manifest/convert_sbt_to_maven.mts @@ -6,6 +6,7 @@ import { logger } from '@socketsecurity/registry/lib/logger' import { spawn } from '@socketsecurity/registry/lib/spawn' import constants from '../../constants.mts' +import { getErrorCause } from '../../utils/errors.mts' // Walk up from a pom path to find a `target` directory ancestor and return // its parent (the project root). Returns undefined if no `target` ancestor @@ -141,7 +142,7 @@ export async function convertSbtToMaven({ copied.push(destPath) } catch (e) { logger.warn( - `Failed to copy \`${pomPath}\` to \`${destPath}\`: ${(e as Error).message}`, + `Failed to copy \`${pomPath}\` to \`${destPath}\`: ${getErrorCause(e)}`, ) } } From 8b757679e6a93464807f9524de3756c78f6fb21c Mon Sep 17 00:00:00 2001 From: Jeppe Fredsgaard Blaabjerg Date: Tue, 12 May 2026 22:01:42 +0200 Subject: [PATCH 3/3] docs(changelog): add 1.1.94 entry for sbt pom copy fix --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0935f632..9c52ca3a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). +## [1.1.94](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.94) - 2026-05-12 + +### Fixed +- `socket manifest scala` now copies sbt-generated `.pom` files out of each subproject's `target/` directory to the project root, so downstream SBOM and scan steps that respect `.gitignore` can see the generated manifests. + ## [1.1.93](https://github.com/SocketDev/socket-cli/releases/tag/v1.1.93) - 2026-05-08 ### Changed