Skip to content

Commit

Permalink
Merge pull request #100 from lixitrixi/find-conjure
Browse files Browse the repository at this point in the history
Function for finding and checking conjure executable
  • Loading branch information
ozgurakgun authored Nov 23, 2023
2 parents d71ed0d + 455f080 commit b27d0bc
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 1 deletion.
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions conjure_oxide/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ anyhow = "1.0.75"
clap = { version = "4.4.8", features = ["derive"] }
strum_macros = "0.25.3"
strum = "0.25.0"
versions = "5.0.1"

[lints]
workspace = true
49 changes: 49 additions & 0 deletions conjure_oxide/src/find_conjure.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use anyhow::{anyhow, bail, Result};
use versions::Versioning;

const CONJURE_MIN_VERSION: &str = "2.5.1";
const CORRECT_FIRST_LINE: &str = "Conjure: The Automated Constraint Modelling Tool";

/// Checks if the conjure executable is present in PATH and if it is the correct version.
/// Returns () on success and an error on failure.
pub fn conjure_executable() -> Result<()> {
let mut cmd = std::process::Command::new("conjure");
let output = cmd.arg("--version").output()?;
let stdout = String::from_utf8(output.stdout)?;
let stderr = String::from_utf8(output.stderr)?;

if !stderr.is_empty() {
bail!("'conjure' results in error: ".to_string() + &stderr);
}
let first = stdout
.lines()
.next()
.ok_or(anyhow!("Could not read stdout"))?;
if first != CORRECT_FIRST_LINE {
let path = std::env::var("PATH")?;
let paths = std::env::split_paths(&path);
let num_conjures = paths.filter(|path| path.join("conjure").exists()).count();
if num_conjures > 1 {
bail!(
"Conjure may be present in PATH after a conflicting name. \
Make sure to prepend the correct path to Conjure to PATH."
)
} else {
bail!("The correct Conjure executable is not present in PATH.")
}
}
let version = stdout
.lines()
.nth(1)
.ok_or(anyhow!("Could not read Conjure's stdout"))?
.strip_prefix("Release version ")
.ok_or(anyhow!("Could not read Conjure version"))?;
if Versioning::new(version) < Versioning::new(CONJURE_MIN_VERSION) {
bail!(
"Conjure version is too old (< {}): {}",
CONJURE_MIN_VERSION,
version
);
}
Ok(())
}
3 changes: 2 additions & 1 deletion conjure_oxide/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
pub mod ast;
pub mod error;
pub mod find_conjure;
pub mod parse;
mod solvers;

pub use ast::Model;
pub use error::Error;
mod solvers;
4 changes: 4 additions & 0 deletions conjure_oxide/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use std::path::PathBuf;

use anyhow::Result as AnyhowResult;
use clap::{arg, command, Parser};
use conjure_oxide::find_conjure::conjure_executable;
use conjure_oxide::parse::parse_json;

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
Expand All @@ -27,6 +29,8 @@ pub fn main() -> AnyhowResult<()> {
/* Parse essence to json using Conjure */
/******************************************************/

conjure_executable()
.map_err(|e| anyhow!("Could not find correct conjure executable: {}", e))?;
let mut cmd = std::process::Command::new("conjure");
let output = cmd
.arg("pretty")
Expand Down
5 changes: 5 additions & 0 deletions conjure_oxide/tests/generated_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,9 @@ fn sort_json_variables(value: &Value) -> Value {
}
}

#[test]
fn assert_conjure_present() {
conjure_oxide::find_conjure::conjure_executable().unwrap();
}

include!(concat!(env!("OUT_DIR"), "/gen_tests.rs"));

0 comments on commit b27d0bc

Please sign in to comment.