Skip to content

Commit 4a4b364

Browse files
ptrthomasclaude
andcommitted
Add --karate-version flag and fix project config filename
- Add --karate-version flag to `karate setup` for explicit JAR version selection without writing karate-cli.json (used by VS Code extension) - Fix project config filename from karate.json to karate-cli.json (consistent naming at both global and project levels) - Smart JAR check: when --karate-version is specified, only skip download if that exact version exists (not just any JAR) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ca1862f commit 4a4b364

4 files changed

Lines changed: 48 additions & 25 deletions

File tree

docs/spec.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ karate --cp /path/to/a.jar --cp /path/to/b.jar run features/
191191
### **F. Config Management**
192192

193193
* Global: `~/.karate/karate-cli.json`
194-
* Project: `./.karate/karate.json`
194+
* Project: `./.karate/karate-cli.json`
195195
* CLI precedence: command flag → project config → global config → defaults
196196

197197
* `karate config`:
@@ -282,7 +282,7 @@ Runtime Commands (JAR-delegated):
282282
### **setup**
283283

284284
```
285-
karate setup [--all] [--item <name>] [--force] [--java-version <ver>]
285+
karate setup [--all] [--item <name>] [--force] [--karate-version <ver>] [--java-version <ver>]
286286
```
287287

288288
Interactive first-run wizard. Downloads JRE and Karate JAR, offers PATH setup.
@@ -291,15 +291,17 @@ Interactive first-run wizard. Downloads JRE and Karate JAR, offers PATH setup.
291291
* `--all` — Install all components (JAR + JRE) non-interactively
292292
* `--item <name>` — Install specific item: jar, jre
293293
* `--force` — Force download even if components already installed
294+
* `--karate-version <ver>` — Specific Karate JAR version to install (e.g., 1.5.2, 2.0.0)
294295
* `--java-version <ver>` — Specific Java major version (default: 21)
295296

296297
**Examples:**
297298
```
298-
karate setup # Interactive wizard
299-
karate setup --all # Install everything non-interactively
300-
karate setup --item jar # JAR only (use system JRE)
301-
karate setup --item jre # JRE only
302-
karate setup --item jar --force # Force re-download JAR
299+
karate setup # Interactive wizard
300+
karate setup --all # Install everything non-interactively
301+
karate setup --item jar # JAR only (use system JRE)
302+
karate setup --item jre # JRE only
303+
karate setup --item jar --force # Force re-download JAR
304+
karate setup --item jar --karate-version 2.0.0 # Install specific Karate version
303305
```
304306

305307
---
@@ -328,7 +330,7 @@ Manage configuration files.
328330

329331
**Flags:**
330332
* `--global` — Edit `~/.karate/karate-cli.json`
331-
* `--local` — Edit `./.karate/karate.json` (creates if needed)
333+
* `--local` — Edit `./.karate/karate-cli.json` (creates if needed)
332334
* `--show` — Print resolved (merged) config as JSON
333335

334336
---
@@ -461,16 +463,16 @@ This allows:
461463
```
462464
my-project/
463465
└── .karate/
464-
└── karate.json # Project-specific config overrides
466+
└── karate-cli.json # Project-specific config overrides
465467
```
466468

467-
Note: A `.karate` folder with only `karate.json` is treated as config-only, not a karate home.
469+
Note: A `.karate` folder with only `karate-cli.json` is treated as config-only, not a karate home.
468470

469471
---
470472

471473
## **7.4 Configuration Schema**
472474

473-
### **karate-cli.json (Global) / karate.json (Project)**
475+
### **karate-cli.json (Global and Project)**
474476

475477
```json
476478
{

src/cli.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ pub struct SetupArgs {
7171
#[arg(long = "java-version")]
7272
pub java_version: Option<String>,
7373

74+
/// Karate JAR version to install (e.g., 1.5.2, 2.0.0)
75+
#[arg(long = "karate-version")]
76+
pub karate_version: Option<String>,
77+
7478
/// Release channel: stable or beta (overrides config)
7579
#[arg(long)]
7680
pub channel: Option<String>,

src/commands/setup.rs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,15 @@ pub async fn run(args: SetupArgs) -> Result<ExitCode> {
4040
};
4141

4242
// Non-interactive install of specified items
43-
run_setup_items(&items, args.force, args.java_version, args.channel).await
43+
run_setup_items(&items, args.force, args.java_version, args.karate_version, args.channel).await
4444
}
4545

4646
/// Non-interactive setup of specified items.
4747
async fn run_setup_items(
4848
items: &HashSet<String>,
4949
force: bool,
5050
java_version: Option<String>,
51+
version_override: Option<String>,
5152
channel_override: Option<String>,
5253
) -> Result<ExitCode> {
5354
let platform = Platform::detect()?;
@@ -129,14 +130,27 @@ async fn run_setup_items(
129130
style(format!("[{}/{}]", step, total_steps)).bold().dim()
130131
);
131132

132-
let existing_jar = find_karate_jar(&paths.dist);
133-
if existing_jar.is_some() && !force {
134-
println!(" {} Karate JAR already installed", style("✓").green());
133+
// If a specific version is requested, check for that version; otherwise check for any JAR
134+
let should_download = if let Some(ref ver) = version_override {
135+
let target_jar = paths.dist.join(format!("karate-{}.jar", ver));
136+
if target_jar.exists() && !force {
137+
println!(" {} Karate {} already installed", style("✓").green(), ver);
138+
false
139+
} else {
140+
true
141+
}
135142
} else {
136-
if force && existing_jar.is_some() {
137-
println!(" {} Force mode: re-downloading JAR", style("!").yellow());
143+
let existing_jar = find_karate_jar(&paths.dist);
144+
if existing_jar.is_some() && !force {
145+
println!(" {} Karate JAR already installed", style("✓").green());
146+
false
147+
} else {
148+
if force { println!(" {} Force mode: re-downloading JAR", style("!").yellow()); }
149+
true
138150
}
139-
download_karate_jar(&paths, channel_override.as_deref()).await?;
151+
};
152+
if should_download {
153+
download_karate_jar(&paths, version_override.as_deref(), channel_override.as_deref()).await?;
140154
}
141155
println!();
142156
}
@@ -208,7 +222,7 @@ async fn run_setup_wizard() -> Result<ExitCode> {
208222
if existing_jar.is_some() {
209223
println!(" {} Karate JAR already installed", style("✓").green());
210224
} else {
211-
download_karate_jar(&paths, None).await?;
225+
download_karate_jar(&paths, None, None).await?;
212226
}
213227

214228
println!();
@@ -257,7 +271,7 @@ async fn download_jre(platform: &Platform, paths: &KaratePaths, java_version: u8
257271
}
258272

259273
/// Download Karate JAR using manifest from karate.sh
260-
async fn download_karate_jar(paths: &KaratePaths, channel_override: Option<&str>) -> Result<()> {
274+
async fn download_karate_jar(paths: &KaratePaths, version_override: Option<&str>, channel_override: Option<&str>) -> Result<()> {
261275
// Load config to get channel and version preferences
262276
let config = load_merged_config()?;
263277
let channel = channel_override.unwrap_or(&config.channel);
@@ -273,9 +287,12 @@ async fn download_karate_jar(paths: &KaratePaths, channel_override: Option<&str>
273287
)
274288
})?;
275289

276-
// Determine version: use config if pinned, otherwise get latest from channel
277-
let version = if config.karate_version != "latest" {
278-
// User pinned a specific version
290+
// Determine version: CLI flag → config pin → latest from channel
291+
let version = if let Some(v) = version_override {
292+
println!(" Requested version: {}", style(v).cyan());
293+
v.to_string()
294+
} else if config.karate_version != "latest" {
295+
// User pinned a specific version in config
279296
println!(
280297
" Using pinned version: {}",
281298
style(&config.karate_version).cyan()

src/platform.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,12 @@ impl KaratePaths {
208208
global.join(subdir)
209209
}
210210

211-
/// Get the project-local config path (.karate/karate.json in cwd).
211+
/// Get the project-local config path (.karate/karate-cli.json in cwd).
212212
pub fn local_config() -> PathBuf {
213213
std::env::current_dir()
214214
.expect("Could not determine current directory")
215215
.join(".karate")
216-
.join("karate.json")
216+
.join("karate-cli.json")
217217
}
218218

219219
/// Ensure all directories exist (creates in resolved locations).

0 commit comments

Comments
 (0)