mirror of
https://github.com/openai/codex.git
synced 2026-05-01 09:56:37 +00:00
## Summary - Port marketplace source support into the shared core marketplace-add flow - Support local marketplace directory sources - Support direct `marketplace.json` URL sources - Persist the new source types in config/schema and cover them in CLI and app-server tests ## Validation - `cargo test -p codex-core marketplace_add` - `cargo test -p codex-cli marketplace_add` - `cargo test -p codex-app-server marketplace_add` - `just write-config-schema` - `just fmt` - `just fix -p codex-core` - `just fix -p codex-cli` ## Context Current `main` moved marketplace-add behavior into shared core code and still assumed only git-backed sources. This change keeps that structure but restores support for local directories and direct manifest URLs in the shared path.
90 lines
2.7 KiB
Rust
90 lines
2.7 KiB
Rust
use anyhow::Result;
|
|
use codex_config::CONFIG_TOML_FILE;
|
|
use codex_core::plugins::marketplace_install_root;
|
|
use predicates::str::contains;
|
|
use pretty_assertions::assert_eq;
|
|
use std::path::Path;
|
|
use tempfile::TempDir;
|
|
|
|
fn codex_command(codex_home: &Path) -> Result<assert_cmd::Command> {
|
|
let mut cmd = assert_cmd::Command::new(codex_utils_cargo_bin::cargo_bin("codex")?);
|
|
cmd.env("CODEX_HOME", codex_home);
|
|
Ok(cmd)
|
|
}
|
|
|
|
fn write_marketplace_source(source: &Path, marker: &str) -> Result<()> {
|
|
std::fs::create_dir_all(source.join(".agents/plugins"))?;
|
|
std::fs::create_dir_all(source.join("plugins/sample/.codex-plugin"))?;
|
|
std::fs::write(
|
|
source.join(".agents/plugins/marketplace.json"),
|
|
r#"{
|
|
"name": "debug",
|
|
"plugins": [
|
|
{
|
|
"name": "sample",
|
|
"source": {
|
|
"source": "local",
|
|
"path": "./plugins/sample"
|
|
}
|
|
}
|
|
]
|
|
}"#,
|
|
)?;
|
|
std::fs::write(
|
|
source.join("plugins/sample/.codex-plugin/plugin.json"),
|
|
r#"{"name":"sample"}"#,
|
|
)?;
|
|
std::fs::write(source.join("plugins/sample/marker.txt"), marker)?;
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn marketplace_add_local_directory_source() -> Result<()> {
|
|
let codex_home = TempDir::new()?;
|
|
let source = TempDir::new()?;
|
|
write_marketplace_source(source.path(), "local ref")?;
|
|
let source_parent = source.path().parent().unwrap();
|
|
let source_arg = format!("./{}", source.path().file_name().unwrap().to_string_lossy());
|
|
|
|
codex_command(codex_home.path())?
|
|
.current_dir(source_parent)
|
|
.args(["marketplace", "add", source_arg.as_str()])
|
|
.assert()
|
|
.success();
|
|
|
|
let installed_root = marketplace_install_root(codex_home.path()).join("debug");
|
|
assert!(!installed_root.exists());
|
|
|
|
let config = std::fs::read_to_string(codex_home.path().join(CONFIG_TOML_FILE))?;
|
|
let config: toml::Value = toml::from_str(&config)?;
|
|
let expected_source = source.path().canonicalize()?.display().to_string();
|
|
assert_eq!(
|
|
config["marketplaces"]["debug"]["source_type"].as_str(),
|
|
Some("local")
|
|
);
|
|
assert_eq!(
|
|
config["marketplaces"]["debug"]["source"].as_str(),
|
|
Some(expected_source.as_str())
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn marketplace_add_rejects_local_manifest_file_source() -> Result<()> {
|
|
let codex_home = TempDir::new()?;
|
|
let source = TempDir::new()?;
|
|
write_marketplace_source(source.path(), "local ref")?;
|
|
let manifest_path = source.path().join(".agents/plugins/marketplace.json");
|
|
|
|
codex_command(codex_home.path())?
|
|
.args(["marketplace", "add", manifest_path.to_str().unwrap()])
|
|
.assert()
|
|
.failure()
|
|
.stderr(contains(
|
|
"local marketplace source must be a directory, not a file",
|
|
));
|
|
|
|
Ok(())
|
|
}
|