Tighten marketplace source parsing

This commit is contained in:
xli-oai
2026-04-10 11:51:24 -07:00
parent 53deb35f09
commit cdac5ef786
3 changed files with 53 additions and 11 deletions
+22 -9
View File
@@ -91,8 +91,13 @@ async fn run_add(args: AddMarketplaceArgs) -> Result<()> {
sparse_paths,
} = args;
let has_explicit_ref = ref_name.is_some();
let source = parse_marketplace_source(&source, ref_name)?;
if !sparse_paths.is_empty() && !matches!(source, MarketplaceSource::Git { .. }) {
let source_is_git = matches!(source, MarketplaceSource::Git { .. });
if has_explicit_ref && !source_is_git {
bail!("--ref can only be used with git marketplace sources");
}
if !sparse_paths.is_empty() && !source_is_git {
bail!("--sparse can only be used with git marketplace sources");
}
@@ -281,12 +286,6 @@ fn parse_marketplace_source(
return Ok(MarketplaceSource::Git { url, ref_name });
}
if base_source.starts_with("http://") || base_source.starts_with("https://") {
bail!(
"URL marketplace manifests are not supported yet; pass a git repository URL or a local marketplace directory"
);
}
bail!("invalid marketplace source format: {source}");
}
@@ -340,8 +339,7 @@ fn is_ssh_git_url(source: &str) -> bool {
}
fn is_http_git_url(source: &str) -> bool {
(source.starts_with("http://") || source.starts_with("https://"))
&& (source.ends_with(".git") || source.starts_with("https://github.com/"))
source.starts_with("http://") || source.starts_with("https://")
}
fn looks_like_github_shorthand(source: &str) -> bool {
@@ -522,6 +520,21 @@ mod tests {
);
}
#[test]
fn non_github_https_source_parses_as_git_url() {
assert_eq!(
parse_marketplace_source(
"https://gitlab.com/owner/repo",
/* explicit_ref */ None
)
.unwrap(),
MarketplaceSource::Git {
url: "https://gitlab.com/owner/repo".to_string(),
ref_name: None,
}
);
}
#[test]
fn utc_timestamp_formats_unix_epoch_as_rfc3339_utc() {
assert_eq!(format_utc_timestamp(0), "1970-01-01T00:00:00Z");
+2 -2
View File
@@ -14,7 +14,7 @@ pub(super) fn clone_git_source(
) -> Result<()> {
let destination = destination.to_string_lossy().to_string();
if sparse_paths.is_empty() {
run_git(&["clone", url, destination.as_str()], None)?;
run_git(&["clone", url, destination.as_str()], /*cwd*/ None)?;
if let Some(ref_name) = ref_name {
run_git(&["checkout", ref_name], Some(Path::new(&destination)))?;
}
@@ -29,7 +29,7 @@ pub(super) fn clone_git_source(
url,
destination.as_str(),
],
None,
/*cwd*/ None,
)?;
let mut sparse_args = vec!["sparse-checkout", "set"];
sparse_args.extend(sparse_paths.iter().map(String::as_str));
+29
View File
@@ -255,3 +255,32 @@ async fn marketplace_add_sparse_flag_parses_before_and_after_source() -> Result<
Ok(())
}
#[tokio::test]
async fn marketplace_add_rejects_ref_for_local_directory() -> Result<()> {
let codex_home = TempDir::new()?;
let source = TempDir::new()?;
write_marketplace_source(source.path(), "local ref")?;
codex_command(codex_home.path())?
.args([
"marketplace",
"add",
"--ref",
"main",
source.path().to_str().unwrap(),
])
.assert()
.failure()
.stderr(contains(
"--ref can only be used with git marketplace sources",
));
assert!(
!marketplace_install_root(codex_home.path())
.join("debug")
.exists()
);
Ok(())
}