///|
pub(all) enum ConflictKind {
MissingPackage
NoMatchingVersion
SelectedVersionConflict
} derive(Eq)
///|
pub(all) struct ConflictReport {
kind : ConflictKind
package_name : String
requirement : String?
selected_version : String?
dependency_path : String?
available_versions : Array[Version]
} derive(Eq)
///|
pub fn build_conflict_report(
error : DepError,
registry : Registry,
) -> ConflictReport? {
match error {
PackageNotFound(name) =>
Some({
kind: MissingPackage,
package_name: name,
requirement: None,
selected_version: None,
dependency_path: None,
available_versions: [],
})
NoMatchingVersion(name, requirement) =>
Some({
kind: NoMatchingVersion,
package_name: name,
requirement: Some(requirement),
selected_version: None,
dependency_path: None,
available_versions: package_versions(registry, name),
})
VersionConflict(name, selected, requirement, path) =>
Some({
kind: SelectedVersionConflict,
package_name: name,
requirement: Some(requirement),
selected_version: Some(selected),
dependency_path: Some(path),
available_versions: package_versions(registry, name),
})
InvalidVersion(_, _) | InvalidReq(_, _) => None
}
}
///|
pub fn format_conflict_report(report : ConflictReport) -> String {
let builder = StringBuilder()
builder.write_string("conflict: ")
builder.write_string(conflict_kind_text(report.kind))
builder.write_string("\npackage: ")
builder.write_string(report.package_name)
builder.write_string("\n")
match report.requirement {
Some(value) => builder.write_string("requirement: \{value}\n")
None => ()
}
match report.selected_version {
Some(value) => builder.write_string("selected: \{value}\n")
None => ()
}
match report.dependency_path {
Some(value) => builder.write_string("path: \{value}\n")
None => ()
}
builder.write_string("available: ")
builder.write_string(report.available_versions.map(format_version).join(", "))
builder.write_string("\n")
builder.to_string()
}
///|
fn package_versions(registry : Registry, name : String) -> Array[Version] {
let versions : Array[Version] = []
for item in registry.packages {
if item.name == name {
versions.push(item.version)
}
}
versions.sort_by((left, right) => compare_version(right, left))
versions
}
///|
fn conflict_kind_text(kind : ConflictKind) -> String {
match kind {
MissingPackage => "missing package"
NoMatchingVersion => "no matching version"
SelectedVersionConflict => "selected version conflict"
}
}