Skip to content
This repository was archived by the owner on Sep 27, 2023. It is now read-only.
Draft
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
72 changes: 72 additions & 0 deletions crates/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ use url::Url;
use ahash::{HashMap, HashMapExt};
use clap::Parser;
use owo_colors::{OwoColorize, Stream};
use reqwest::header::{USER_AGENT, ACCEPT};
use semver::Version;
use std::io::{BufRead, BufReader};
use tokio::{io::AsyncWriteExt, process::Command};

use crate::{
Expand Down Expand Up @@ -214,6 +217,73 @@ pub fn resolve_pipeline(pipeline: impl AsRef<Path>) -> Result<PathBuf> {
Err(anyhow::anyhow!("Could not find pipeline"))
}

pub async fn check_pipeline_compatibility(pipeline_path: impl AsRef<Path>) -> Result<String> {
// Open file and read its lines into a vector
let pipeline = std::fs::File::open(pipeline_path)?;
let reader = BufReader::new(pipeline);
let mut lines = vec![];
for line in reader.lines() {
lines.push(line?.trim().to_string());
}

// Find the Cicada import line
let cicada_import_regex =
regex::Regex::new(r#"https://deno.land/x/cicada(?:@v?(\d+\.\d+\.\d+))?[^"]*"#)?;

let cicada_import_line = lines
.iter()
.filter(|line| !line.trim_start().starts_with("//")) // ignore commented-out lines
.find(|line| cicada_import_regex.is_match(line));

// Extract the version number or set it to "latest"
if let Some(import_line) = cicada_import_line {
let cicada_import_capture = cicada_import_regex
.captures(import_line)
.expect("Unable to capture the version from the Pipeline Cicada import with regex.");

// If able to get the pipeline version from regex, use that. If not query the API for the latest version.
let pipeline_cicada_version = if let Some(ts_module_version) = cicada_import_capture.get(1)
{
semver::Version::parse(ts_module_version.as_str())?
} else {
eprintln!("No version number found. Defaulting to latest");
get_latest_cicada_version().await?
};

if pipeline_cicada_version == semver::Version::parse(clap::crate_version!())? {
Ok(format!(
"The CLI ({}) and the slated Pipeline ({}) have compatible versions.",
clap::crate_version!(),
pipeline_cicada_version
))
} else {
Ok(format!("The CLI ({}) and the slated Pipeline ({}) have different versions. This may lead to incompatibility in future versions of Cicada.", clap::crate_version!(), pipeline_cicada_version))
}
} else {
Err(anyhow::anyhow!(
"Could not find the Cicada import line in the Pipeline."
))
}
}

async fn get_latest_cicada_version() -> Result<Version> {
let url = "https://api.github.com/repos/cicadahq/cicada/releases/latest";
let client = reqwest::Client::new();
let resp = client
.get(url)
.header(USER_AGENT, "reqwest")
.header(ACCEPT, "application/vnd.github.v3+json")
.send()
.await?
.json::<serde_json::Value>()
.await?;
let version_str = resp["tag_name"]
.as_str()
.expect("Unable to read tag_name from response.");

Ok(Version::parse(version_str)?)
}

#[derive(Parser, Debug)]
#[command(name = "cicada", bin_name = "cicada", author, version, about)]
#[allow(clippy::large_enum_variant)]
Expand Down Expand Up @@ -434,6 +504,8 @@ impl Commands {

info!("Building pipeline: {}", pipeline_path.display().bold());

info!("{}", check_pipeline_compatibility(&pipeline_path).await?);

let out = {
let tmp_file = tempfile::NamedTempFile::new()?;

Expand Down