Skip to content

Commit

Permalink
standardize all version check messages
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronvg committed Jul 17, 2024
1 parent abb0e2a commit 7a07a15
Show file tree
Hide file tree
Showing 9 changed files with 272 additions and 225 deletions.
2 changes: 2 additions & 0 deletions engine/baml-schema-wasm/src/runtime_wasm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,7 @@ impl WasmRuntime {
generator_type: &str,
version_check_mode: &str,
generator_language: &str,
is_diagnostic: bool,
) -> Option<String> {
// Convert string parameters to enums
let generator_type = match generator_type {
Expand Down Expand Up @@ -944,6 +945,7 @@ impl WasmRuntime {
generator_type,
version_check_mode,
generator_language,
is_diagnostic,
)
.map(|error| error.msg)
}
Expand Down
3 changes: 2 additions & 1 deletion engine/language-client-codegen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,12 @@ fn version_check_with_error(
client_type: GeneratorOutputType,
) -> Result<()> {
let res = check_version(
runtime_version,
gen_version,
runtime_version,
generator_type,
mode,
client_type,
true,
);
match res {
Some(e) => Err(anyhow::anyhow!("Version mismatch: {}", e.msg)),
Expand Down
199 changes: 105 additions & 94 deletions engine/language-client-codegen/src/version_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,108 +18,119 @@ pub enum VersionCheckMode {
Strict,
None,
}

pub fn check_version(
generator_version: &str,
current_version: &str,
generator_type: GeneratorType,
version_check_mode: VersionCheckMode,
generator_language: GeneratorOutputType,
) -> Option<VersionCheckError> {
if version_check_mode == VersionCheckMode::None {
return None;
}

let gen_version = match Version::parse(generator_version) {
Ok(v) => v,
Err(_) => return Some(VersionCheckError {
msg: format!("Invalid generator version in BAML config: {}", generator_version),
}),
};

let runtime_version = match Version::parse(current_version) {
Ok(v) => v,
Err(_) => return Some(VersionCheckError {
msg: format!("Invalid current version: {}", current_version),
}),
};

if generator_version == "0.0.0" {
return Some(VersionCheckError {
msg: format!("You must now add a 'version' to the generator config. Please add 'version \"{}\"' to continue generating baml_client\n. Make sure your installed baml package dependency and VSCode are the same version. \n\nSee https://github.com/BoundaryML/baml/pull/791", current_version).to_string(),
});
}

if gen_version.major != runtime_version.major || gen_version.minor != runtime_version.minor {
let base_message = format!(
"Version mismatch: Generator version ({}) does not match the {} version ({}). Major and minor versions must match.",
gen_version,
match generator_type {
GeneratorType::VSCodeCLI | GeneratorType::VSCode => "VSCode extension",
GeneratorType::CLI => "installed BAML CLI",
},
runtime_version
);

let (update_message, docs_link) = if runtime_version > gen_version {
(
match generator_type {
GeneratorType::VSCodeCLI | GeneratorType::VSCode =>
format!("Update the 'version' in your BAML generator config to '{}' to match the VSCode extension version.", runtime_version),
GeneratorType::CLI =>
format!("Update the 'version' in your BAML generator config to '{}' to match the installed BAML CLI version.", runtime_version),
},
"https://docs.boundaryml.com/docs/calling-baml/generate-baml-client#troubleshooting-version-conflicts"
)
} else {
let update_instruction = match generator_language {
GeneratorOutputType::PythonPydantic => format!("pip install --upgrade baml-py=={}", gen_version),
GeneratorOutputType::Typescript => format!("npm install --save-dev @boundaryml/baml@{}", gen_version),
GeneratorOutputType::RubySorbet => format!("gem install baml -v {}", gen_version),
};
(
match generator_type {
GeneratorType::VSCodeCLI | GeneratorType::VSCode =>
format!("Update your VSCode extension to version '{}' to match the version in the BAML generator config. Also update your BAML package: {}", gen_version, update_instruction),
GeneratorType::CLI =>
format!("Update your installed BAML CLI package to version '{}' to match the version in the BAML generator config: {}", gen_version, update_instruction),
},
"https://docs.boundaryml.com/docs/calling-baml/generate-baml-client#troubleshooting-version-conflicts"
)
};

let formatted_link = match generator_type {
GeneratorType::VSCodeCLI | GeneratorType::VSCode => format!("[documentation]({})", docs_link),
GeneratorType::CLI => docs_link.to_string(),
};

let error_message = format!(
"{}\n\nAction required: {}\n\nFor more information, see: {}",
base_message, update_message, formatted_link
);

return Some(VersionCheckError { msg: error_message });
}

None
generator_version: &str,
current_version: &str,
generator_type: GeneratorType,
version_check_mode: VersionCheckMode,
generator_language: GeneratorOutputType,
is_diagnostic: bool,
) -> Option<VersionCheckError> {
if version_check_mode == VersionCheckMode::None {
return None;
}

let gen_version = match Version::parse(generator_version) {
Ok(v) => v,
Err(_) => return Some(VersionCheckError {
msg: format!("Invalid generator version in BAML config: {}", generator_version),
}),
};

let runtime_version = match Version::parse(current_version) {
Ok(v) => v,
Err(_) => return Some(VersionCheckError {
msg: format!("Invalid current version: {}", current_version),
}),
};

if generator_version == "0.0.0" {
let error_message = format!("A 'version' is now required in generator config. Please add 'version \"{}\"' inside the generator to continue generating baml_client.\n\nMake sure your installed baml package dependency and VSCode are also version {} \n\nSee https://docs.boundaryml.com/docs/calling-baml/generate-baml-client", current_version, current_version);
return Some(VersionCheckError {
msg: if !is_diagnostic {
format!("⚠️⚠️⚠️ BAML GENERATION DISABLED: {}", error_message)
} else {
error_message
},
});
}

if gen_version.major != runtime_version.major || gen_version.minor != runtime_version.minor {
let base_message = format!(
"Version mismatch: Generator version ({}) does not match the {} version ({}). Major and minor versions must match.",
gen_version,
match generator_type {
GeneratorType::VSCode => "VSCode extension",
GeneratorType::CLI | GeneratorType::VSCodeCLI => "installed baml package",
},
runtime_version
);

let (update_message, docs_link) = if runtime_version > gen_version {
(
match generator_type {
GeneratorType::VSCode =>
format!("Update the 'version' in your BAML generator config to '{}' to match the VSCode extension version.", runtime_version),
GeneratorType::CLI | GeneratorType::VSCodeCLI =>
format!("Update the 'version' in your BAML generator config to '{}' to match the installed baml package version.", runtime_version),
},
"https://docs.boundaryml.com/docs/calling-baml/generate-baml-client#troubleshooting-version-conflicts"
)
} else {
let update_instruction = match generator_language {
GeneratorOutputType::PythonPydantic => format!("pip install --upgrade baml-py=={}", gen_version),
GeneratorOutputType::Typescript => format!("npm install --save-dev @boundaryml/baml@{}", gen_version),
GeneratorOutputType::RubySorbet => format!("gem install baml -v {}", gen_version),
};
(
match generator_type {
GeneratorType::VSCode =>
format!("Update your VSCode extension to version '{}' to match the version in the BAML generator config. Also update your BAML package: {}", gen_version, update_instruction),
GeneratorType::VSCodeCLI | GeneratorType::CLI =>
format!("Update your installed BAML CLI package to version '{}' to match the version in the BAML generator config: {}", gen_version, update_instruction),
},
"https://docs.boundaryml.com/docs/calling-baml/generate-baml-client#troubleshooting-version-conflicts"
)
};

let formatted_link = match is_diagnostic {
false => format!("[documentation]({})", docs_link),
_ => docs_link.to_string(),
};

let error_message = format!(
"{}\n\nAction required: {}\n\nTo prevent this issue, see: {}",
base_message, update_message, formatted_link
);

return Some(VersionCheckError {
msg: if !is_diagnostic {
format!("⚠️⚠️⚠️ BAML GENERATION DISABLED: {}", error_message)
} else {
error_message
},
});
}

None
}


#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_vscode_link_formatting() {
let result = check_version("1.3.0", "1.2.0", GeneratorType::VSCode, VersionCheckMode::Strict, GeneratorOutputType::Typescript);
let result = check_version("1.3.0", "1.2.0", GeneratorType::VSCode, VersionCheckMode::Strict, GeneratorOutputType::Typescript, false);
assert!(result.is_some());
let error_msg = result.unwrap().msg;
assert!(error_msg.contains("[documentation](https://docs.boundaryml.com/docs/calling-baml/generate-baml-client#updating-baml-package)"));
}

#[test]
fn test_cli_link_formatting() {
let result = check_version("1.3.0", "1.2.0", GeneratorType::CLI, VersionCheckMode::Strict, GeneratorOutputType::PythonPydantic);
let result = check_version("1.3.0", "1.2.0", GeneratorType::CLI, VersionCheckMode::Strict, GeneratorOutputType::PythonPydantic, false);
assert!(result.is_some());
let error_msg = result.unwrap().msg;
assert!(error_msg.contains("https://docs.boundaryml.com/docs/calling-baml/generate-baml-client#updating-baml-package"));
Expand All @@ -128,36 +139,36 @@ mod tests {
#[test]
fn test_version_check_none() {
assert_eq!(
check_version("1.0.0", "2.0.0", GeneratorType::CLI, VersionCheckMode::None, GeneratorOutputType::PythonPydantic),
check_version("1.0.0", "2.0.0", GeneratorType::CLI, VersionCheckMode::None, GeneratorOutputType::PythonPydantic, false),
None
);
}

#[test]
fn test_invalid_generator_version() {
let result = check_version("invalid", "1.0.0", GeneratorType::CLI, VersionCheckMode::Strict, GeneratorOutputType::PythonPydantic);
let result = check_version("invalid", "1.0.0", GeneratorType::CLI, VersionCheckMode::Strict, GeneratorOutputType::PythonPydantic, false);
assert!(result.is_some());
assert!(result.unwrap().msg.contains("Invalid generator version"));
}

#[test]
fn test_invalid_current_version() {
let result = check_version("1.0.0", "invalid", GeneratorType::CLI, VersionCheckMode::Strict, GeneratorOutputType::PythonPydantic);
let result = check_version("1.0.0", "invalid", GeneratorType::CLI, VersionCheckMode::Strict, GeneratorOutputType::PythonPydantic, false);
assert!(result.is_some());
assert!(result.unwrap().msg.contains("Invalid current version"));
}

#[test]
fn test_matching_versions() {
assert_eq!(
check_version("1.2.3", "1.2.4", GeneratorType::CLI, VersionCheckMode::Strict, GeneratorOutputType::PythonPydantic),
check_version("1.2.3", "1.2.4", GeneratorType::CLI, VersionCheckMode::Strict, GeneratorOutputType::PythonPydantic, false),
None
);
}

#[test]
fn test_mismatched_major_version_cli_python() {
let result = check_version("2.0.0", "1.0.0", GeneratorType::CLI, VersionCheckMode::Strict, GeneratorOutputType::PythonPydantic);
let result = check_version("2.0.0", "1.0.0", GeneratorType::CLI, VersionCheckMode::Strict, GeneratorOutputType::PythonPydantic, false);
assert!(result.is_some());
let error_msg = result.unwrap().msg;
assert!(error_msg.contains("Version mismatch"));
Expand All @@ -167,7 +178,7 @@ mod tests {

#[test]
fn test_mismatched_minor_version_vscode_typescript() {
let result = check_version("1.3.0", "1.2.0", GeneratorType::VSCode, VersionCheckMode::Strict, GeneratorOutputType::Typescript);
let result = check_version("1.3.0", "1.2.0", GeneratorType::VSCode, VersionCheckMode::Strict, GeneratorOutputType::Typescript, false);
assert!(result.is_some());
let error_msg = result.unwrap().msg;
assert!(error_msg.contains("Version mismatch"));
Expand All @@ -177,7 +188,7 @@ mod tests {

#[test]
fn test_older_vscode_version_ruby() {
let result = check_version("1.3.0", "1.2.0", GeneratorType::VSCodeCLI, VersionCheckMode::Strict, GeneratorOutputType::RubySorbet);
let result = check_version("1.3.0", "1.2.0", GeneratorType::VSCodeCLI, VersionCheckMode::Strict, GeneratorOutputType::RubySorbet, false);
assert!(result.is_some());
let error_msg = result.unwrap().msg;
assert!(error_msg.contains("Version mismatch"));
Expand All @@ -188,7 +199,7 @@ mod tests {
#[test]
fn test_patch_version_difference() {
assert_eq!(
check_version("1.2.3", "1.2.4", GeneratorType::CLI, VersionCheckMode::Strict, GeneratorOutputType::PythonPydantic),
check_version("1.2.3", "1.2.4", GeneratorType::CLI, VersionCheckMode::Strict, GeneratorOutputType::PythonPydantic, false),
None
);
}
Expand Down
13 changes: 12 additions & 1 deletion typescript/playground-common/src/baml_wasm_web/EventListener.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const envKeyValueStorage = atomWithStorage<[string, string][]>(
defaultEnvKeyValues,
vscodeLocalStorageStore,
)
export const bamlCliVersionAtom = atom<string | null>(null)

export const resetEnvKeyValuesAtom = atom(null, (get, set) => {
set(envKeyValueStorage, [])
Expand Down Expand Up @@ -482,6 +483,7 @@ export const EventListener: React.FC<{ children: React.ReactNode }> = ({ childre
const wasm = useAtomValue(wasmAtom)
const [selectedFunc, setSelectedFunction] = useAtom(selectedFunctionAtom)
const envVars = useAtomValue(envVarsAtom)
const [bamlCliVersion, setBamlCliVersion] = useAtom(bamlCliVersionAtom)

useEffect(() => {
if (wasm) {
Expand Down Expand Up @@ -561,6 +563,10 @@ export const EventListener: React.FC<{ children: React.ReactNode }> = ({ childre
port: number
}
}
| {
command: 'baml_cli_version'
content: string
}
>,
) => {
const { command, content } = event.data
Expand Down Expand Up @@ -589,6 +595,10 @@ export const EventListener: React.FC<{ children: React.ReactNode }> = ({ childre
updateCursor(content.cursor)
}
break
case 'baml_cli_version':
console.log('Setting baml cli version', content)

Check warning

Code scanning / CodeQL

Log injection Medium

Log entry depends on a
user-provided value
.
setBamlCliVersion(content)
break

case 'remove_project':
removeProject((content as { root_path: string }).root_path)
Expand Down Expand Up @@ -630,7 +640,8 @@ export const EventListener: React.FC<{ children: React.ReactNode }> = ({ childre
return (
<>
<div className='absolute z-50 flex flex-row gap-2 text-xs bg-transparent right-2 bottom-2'>
<ErrorCount /> <span>Runtime Version: {version}</span>
<div className='pr-4 whitespace-nowrap'>{bamlCliVersion ? 'baml-cli ' + bamlCliVersion : ''}</div>
<ErrorCount /> <span>VSCode Runtime Version: {version}</span>
</div>
{selectedProject === null ? (
availableProjects.length === 0 ? (
Expand Down
Loading

0 comments on commit 7a07a15

Please sign in to comment.