Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,21 @@ Here is an example JSON config:
}
}
```

For flake-based jobsets, `nixexprinput` can be omitted, but the config must set `type` to `1` and include `flake`:

```
{
"type": 1,
"description": "hydra-cli flake jobset",
"checkinterval": 60,
"enabled": 1,
"visible": true,
"keepnr": 3,
"flake": "github:nlewo/hydra-cli"
}
```

#### jobset-eval

The `jobset-eval` command starts the evaluation of a jobset.
Expand Down
10 changes: 6 additions & 4 deletions hydra-cli/src/hydra/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ pub fn jobset_config() -> JobsetConfig {
enabled: JobsetEnabled::Enabled,
visible: true,
keepnr: 3,
nixexprinput: "src".to_string(),
nixexprpath: "default.nix".to_string(),
inputs: {
nixexprinput: Some("src".to_string()),
nixexprpath: Some("default.nix".to_string()),
inputs: Some({
let mut map = HashMap::<String, Input>::new();
let input = Input {
value: Some("https://github.com/nlewo/hydra-cli.git master".to_string()),
Expand All @@ -22,6 +22,8 @@ pub fn jobset_config() -> JobsetConfig {
};
map.insert("src".to_string(), input);
map
},
}),
jobset_type: None,
flake: None,
}
}
16 changes: 10 additions & 6 deletions hydra-cli/src/hydra/reqwest_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,12 @@ mod tests {
checkinterval: 100,
enabled: JobsetEnabled::Enabled,
visible: true,
nixexprinput: "input".to_string(),
nixexprpath: "path".to_string(),
nixexprinput: Some("input".to_string()),
nixexprpath: Some("path".to_string()),
keepnr: 10,
inputs: HashMap::new(),
inputs: Some(HashMap::new()),
jobset_type: None,
flake: None,
};
let _m = mock("PUT", "/jobset/foo-project/foo-jobset")
.with_status(200)
Expand All @@ -315,10 +317,12 @@ mod tests {
checkinterval: 100,
enabled: JobsetEnabled::Enabled,
visible: true,
nixexprinput: "input".to_string(),
nixexprpath: "path".to_string(),
nixexprinput: Some("input".to_string()),
nixexprpath: Some("path".to_string()),
keepnr: 10,
inputs: HashMap::new(),
inputs: Some(HashMap::new()),
jobset_type: None,
flake: None,
};
let _m = mock("PUT", "/jobset/foo-project/foo-jobset")
.with_status(500)
Expand Down
13 changes: 10 additions & 3 deletions hydra-cli/src/hydra/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,16 @@ pub struct JobsetConfig {
#[serde(skip_serializing_if = "is_not_visible")]
pub visible: bool,
pub keepnr: i64,
pub nixexprinput: String,
pub nixexprpath: String,
pub inputs: HashMap<String, Input>,
#[serde(skip_serializing_if = "Option::is_none")]
pub nixexprinput: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub nixexprpath: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub inputs: Option<HashMap<String, Input>>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub jobset_type: Option<u8>,
#[serde(skip_serializing_if = "Option::is_none")]
pub flake: Option<String>,
}

fn is_not_visible(visible: &bool) -> bool {
Expand Down
92 changes: 87 additions & 5 deletions hydra-cli/src/ops/jobset_create.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,92 @@
use crate::hydra::client::{Creds, HydraClient, JobsetConfig};
use crate::ops::{ok_msg, OpResult};
use crate::ops::{ok_msg, OpError, OpResult};
use std::fs::read_to_string;

fn load_config(config_path: &str) -> JobsetConfig {
let cfg = read_to_string(config_path).expect("Failed to read config file");
serde_json::from_str(&cfg).expect("Failed to parse jobset configuration")
fn validate_config(jobset_cfg: &JobsetConfig) -> Result<(), OpError> {
if jobset_cfg.nixexprinput.is_none() {
if jobset_cfg.jobset_type != Some(1) {
return Err(OpError::Error(
"Missing nixexprinput requires `type` set to 1".to_string(),
));
}

if jobset_cfg.flake.is_none() {
return Err(OpError::Error(
"Missing nixexprinput requires a `flake` key".to_string(),
));
}
}

Ok(())
}

fn load_config(config_path: &str) -> Result<JobsetConfig, OpError> {
let cfg = read_to_string(config_path)
.map_err(|e| OpError::Error(format!("Failed to read config file: {}", e)))?;
let jobset_cfg: JobsetConfig = serde_json::from_str(&cfg)
.map_err(|e| OpError::Error(format!("Failed to parse jobset configuration: {}", e)))?;

validate_config(&jobset_cfg)?;
Ok(jobset_cfg)
}

#[cfg(test)]
mod test {
use super::validate_config;
use crate::hydra::client::JobsetConfig;

#[test]
fn accepts_legacy_nixexpr_config() {
let cfg: JobsetConfig = serde_json::from_str(
r#"{
"description": "desc",
"checkinterval": 60,
"enabled": 1,
"visible": true,
"keepnr": 3,
"nixexprinput": "src",
"nixexprpath": "default.nix",
"inputs": {}
}"#,
)
.unwrap();

assert!(validate_config(&cfg).is_ok());
}

#[test]
fn accepts_flake_config_without_nixexprinput() {
let cfg: JobsetConfig = serde_json::from_str(
r#"{
"type": 1,
"description": "desc",
"checkinterval": 60,
"enabled": 1,
"visible": true,
"keepnr": 3,
"flake": "github:org/repo"
}"#,
)
.unwrap();

assert!(validate_config(&cfg).is_ok());
}

#[test]
fn rejects_missing_nixexprinput_without_flake_type() {
let cfg: JobsetConfig = serde_json::from_str(
r#"{
"description": "desc",
"checkinterval": 60,
"enabled": 1,
"visible": true,
"keepnr": 3
}"#,
)
.unwrap();

assert!(validate_config(&cfg).is_err());
}
}

pub fn run(
Expand All @@ -15,7 +97,7 @@ pub fn run(
user: &str,
password: &str,
) -> OpResult {
let jobset_cfg = load_config(config_path);
let jobset_cfg = load_config(config_path)?;
let creds = Creds {
username: String::from(user),
password: String::from(password),
Expand Down