Skip to content

XRAY-140550 - Onboarding uv for jf curation-audit#798

Open
Phavya-jfrog wants to merge 4 commits into
jfrog:devfrom
Phavya-jfrog:feature/XRAY-140550-jfca-uv
Open

XRAY-140550 - Onboarding uv for jf curation-audit#798
Phavya-jfrog wants to merge 4 commits into
jfrog:devfrom
Phavya-jfrog:feature/XRAY-140550-jfca-uv

Conversation

@Phavya-jfrog

@Phavya-jfrog Phavya-jfrog commented Jul 7, 2026

Copy link
Copy Markdown
Contributor
  • The pull request is targeting the dev branch.
  • The code has been validated to compile successfully by running go vet ./....
  • The code has been formatted properly using go fmt ./....
  • All static analysis checks passed.
  • All tests have passed. If this feature is not already covered by the tests, new tests have been added.
  • Updated the Contributing page / ReadMe page / CI Workflow files if needed.
  • All changes are detailed at the description. if not already covered at JFrog Documentation, new documentation have been added.

Onboards uv as a supported package manager for jf curation-audit, plus support for auditing standalone PEP 723 inline scripts. Registry details are read from pyproject.toml's [[tool.uv.index]] or ~/.config/uv/uv.toml (however Artifactory's "Set Me Up" configures it) — no jf uv-config step needed. Resolution always goes through Artifactory's curation pass-through endpoint: uv.lock is regenerated in a temp dir unless it's both up-to-date and verified as already resolved from Artifactory, in which case it's reused as-is.

New --script flag audits a single PEP 723 inline script directly instead of scanning the working directory. When a uv project has an un-audited sibling script, jf ca surfaces a one-line hint to use --script.

Changes

  • Add techutils.Uv to curation-audit's supported technologies, with a minimum-version gate (uv >= 0.6.17).
  • Add GetNativeUvRegistryConfig/setRepoFromUvToml for registry detection, and generateUvLockInTempDir/generateUvLock to resolve uv.lock through the curation pass-through endpoint.
  • Add parseUvLock, buildUvDepTree, and buildUvDownloadUrlsMap to build the dependency tree and download URLs from the lock file, including multi-version marker forks and workspace members.
  • Add buildDependencyTreeForScript/generateUvScriptLockForCuration and the --script flag for auditing PEP 723 inline scripts standalone.
  • Add WrapUvCurationErr/classifyUvCurationLockError so CVS-stripped versions route through the existing metadata-API fallback table instead of a bare error.
  • Fix Poetry's CVS-fallback to recover range-constrained transitive dependencies via poetryDependsOnParentRegex (previously only exact pins were caught).
  • Fix promotePipToUv so a pip-exclusive file (requirements.txt, Pipfile, etc.) always wins over a stray uv.lock, and vice versa.

@Phavya-jfrog
Phavya-jfrog force-pushed the feature/XRAY-140550-jfca-uv branch from 6f420f7 to cd04ca3 Compare July 7, 2026 10:38
@Phavya-jfrog
Phavya-jfrog force-pushed the feature/XRAY-140550-jfca-uv branch from 40b19e4 to 7299624 Compare July 11, 2026 15:41
@Phavya-jfrog
Phavya-jfrog force-pushed the feature/XRAY-140550-jfca-uv branch from 37647c8 to 6a6a2a3 Compare July 13, 2026 06:11
@Phavya-jfrog
Phavya-jfrog force-pushed the feature/XRAY-140550-jfca-uv branch from d9b118d to f99aedc Compare July 14, 2026 03:27
@Phavya-jfrog
Phavya-jfrog force-pushed the feature/XRAY-140550-jfca-uv branch from f99aedc to 3082d8d Compare July 14, 2026 08:00
return errorutils.CheckErrorf("uv: no 'jf c' server configured")
}
copied := *base
copied.ArtifactoryUrl = registryConfig.ArtifactoryUrl

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A project-local pyproject.toml can replace the configured Artifactory origin while retaining its credentials. Running jf ca can therefore send credentials for the configured JPD to another host.


Review generated by xray-pr-review

var buildErr error
artiIndexUrl, buildErr = buildUvCurationIndexUrl(params.ServerDetails, params.DependenciesRepository)
if buildErr != nil {
log.Warn(fmt.Sprintf("uv: failed to build curation index URL: %v — will fall back to public PyPI", buildErr))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If curation-index URL construction fails, this continues with an empty UV_DEFAULT_INDEX, so uv lock resolves through ambient/public configuration and the audit can bypass curation. Consider returning buildErr here so the audit fails closed.

This regression test currently fails with An error is expected but got nil:

func TestScriptAuditFailsClosedWhenCurationIndexCannotBeBuilt(t *testing.T) {
	fakeBinDir := t.TempDir()
	writeFakeUvExecutableForScriptLock(t, fakeBinDir, "https://ambient.example", "repo")

	scriptPath := filepath.Join(t.TempDir(), "demo.py")
	require.NoError(t, os.WriteFile(scriptPath, []byte(pep723ScriptContent), 0o644))

	params := technologies.BuildInfoBomGeneratorParams{
		ScriptPath:             scriptPath,
		ServerDetails:          &config.ServerDetails{ArtifactoryUrl: ":// malformed"},
		DependenciesRepository: "repo",
	}

	_, _, _, err := buildDependencyTreeForScript(params)
	require.Error(t, err, "curation audit must not run uv against an ambient index")
}

Review generated by xray-pr-review

if !hasPw || pw == "" {
return s
}
return strings.ReplaceAll(s, pw, "***")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

u.User.Password() returns the decoded password, while uv can echo its percent-encoded userinfo, leaving credentials such as p%40ss%2Fword in logs and returned errors. Consider redacting the encoded userinfo as well as the decoded secret.

This regression test currently fails because the encoded password remains in masked:

func TestMaskPasswordMasksPercentEncodedPassword(t *testing.T) {
	u := &url.URL{
		Scheme: "https",
		Host:   "host.example",
		Path:   "/artifactory/api/pypi/repo/simple",
		User:   url.UserPassword("user", "p@ss/word"),
	}
	encodedSecret := "p%40ss%2Fword"
	out := "uv failed while fetching " + u.String()

	masked := maskPassword(out, u.String())

	assert.NotContains(t, masked, encodedSecret)
}

Review generated by xray-pr-review

@gineshkumar

Copy link
Copy Markdown

Could you add a description covering the uv project and PEP 723 script flows, registry/auth behavior, validation performed, and the Poetry CVS fallback changes? The current body is only the unchecked template, so reviewers cannot verify the intended scope or design trade-offs.


Review generated by xray-pr-review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants