Skip to content

Commit ca1862f

Browse files
ptrthomasclaude
andcommitted
Add --cp flag for external classpath contributions
Allow extensions and plugins to inject proprietary JARs into the JVM classpath via a global --cp flag on delegated commands. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent b042247 commit ca1862f

4 files changed

Lines changed: 38 additions & 7 deletions

File tree

docs/spec.md

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,15 +167,27 @@ Everything else passes through to the JVM:
167167
* Delegated to Karate JAR
168168
* Launcher constructs JVM command:
169169
* JRE path
170-
* Classpath (fatjar + plugins + ext/*.jar)
170+
* Classpath (fatjar + ext/*.jar + --cp entries)
171171
* JVM opts from config
172172

173-
### **E. Extensions Support**
173+
### **E. Extensions & Classpath**
174174

175175
* **User extensions:** `~/.karate/ext/` — manually dropped JARs, always added to classpath
176+
* **`--cp` flag:** Additional classpath entries appended after ext JARs. Can be specified multiple times. Useful for IDE integrations and proprietary JARs.
176177
* For v1, extensions are managed manually by dropping JAR files into the `ext/` folder
177178
* Future versions may add managed plugin installation via manifest
178179

180+
**Classpath order:** karate fatjar → `~/.karate/ext/*.jar``.karate/ext/*.jar``--cp` entries
181+
182+
**Example:**
183+
```bash
184+
# Add a proprietary debug adapter JAR
185+
karate --cp /path/to/karate-ide-v2.jar run features/
186+
187+
# Multiple extra JARs
188+
karate --cp /path/to/a.jar --cp /path/to/b.jar run features/
189+
```
190+
179191
### **F. Config Management**
180192

181193
* Global: `~/.karate/karate-cli.json`
@@ -240,7 +252,11 @@ Everything else passes through to the JVM:
240252
## **5.1 Command Overview**
241253

242254
```text
243-
karate <command> [options]
255+
karate [global-options] <command> [options]
256+
257+
Global Options:
258+
--no-color Disable colored output
259+
--cp <path> Additional classpath entry (repeatable)
244260
245261
Management Commands (Rust-native):
246262
setup [subcommand] First-run wizard or targeted setup

src/cli.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ pub struct Cli {
1212
#[arg(long, global = true, env = "NO_COLOR")]
1313
pub no_color: bool,
1414

15+
/// Additional classpath entries (JAR files or directories) appended to the JVM classpath.
16+
/// Can be specified multiple times. Only applies to JAR-delegated commands.
17+
#[arg(long = "cp", global = true, num_args = 1)]
18+
pub extra_classpath: Vec<String>,
19+
1520
#[command(subcommand)]
1621
pub command: Command,
1722
}

src/delegate.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::path::{Path, PathBuf};
99
use std::process::Command;
1010

1111
/// Run a delegated command through the JVM.
12-
pub async fn run(args: Vec<String>) -> Result<ExitCode> {
12+
pub async fn run(args: Vec<String>, extra_classpath: &[String]) -> Result<ExitCode> {
1313
let paths = KaratePaths::new();
1414
let config = load_merged_config()?;
1515

@@ -30,7 +30,7 @@ pub async fn run(args: Vec<String>) -> Result<ExitCode> {
3030
let jar_path = find_karate_jar(&dist_dir)?;
3131

3232
// Build classpath
33-
let classpath = build_classpath(&paths, &jar_path)?;
33+
let classpath = build_classpath(&paths, &jar_path, extra_classpath)?;
3434

3535
// Build JVM command
3636
let mut cmd = Command::new(&java_executable);
@@ -112,7 +112,12 @@ fn find_karate_jar(dist_dir: &Path) -> Result<PathBuf> {
112112
}
113113

114114
/// Build the classpath string.
115-
fn build_classpath(paths: &KaratePaths, jar_path: &Path) -> Result<String> {
115+
/// Order: karate jar → ext jars (global + local) → extra classpath (--cp flags)
116+
fn build_classpath(
117+
paths: &KaratePaths,
118+
jar_path: &Path,
119+
extra_classpath: &[String],
120+
) -> Result<String> {
116121
let mut classpath_parts = vec![jar_path.to_string_lossy().to_string()];
117122

118123
// Add extensions from both global and local ext directories
@@ -128,6 +133,11 @@ fn build_classpath(paths: &KaratePaths, jar_path: &Path) -> Result<String> {
128133
}
129134
}
130135

136+
// Add extra classpath entries from --cp flags
137+
for entry in extra_classpath {
138+
classpath_parts.push(entry.clone());
139+
}
140+
131141
// Join with platform-appropriate separator
132142
let separator = if cfg!(windows) { ";" } else { ":" };
133143
Ok(classpath_parts.join(separator))

src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ async fn run() -> ExitCode {
4545
Command::Version(args) => commands::version::run(args).await,
4646

4747
// JAR-delegated commands
48-
Command::External(args) => delegate::run(args).await,
48+
Command::External(args) => delegate::run(args, &cli.extra_classpath).await,
4949
};
5050

5151
match result {

0 commit comments

Comments
 (0)