///|
fn config_base_dir(path : String) -> String {
let raw_dirname = dirname_string(project_path_for_host(path))
let config_dir : @mbpath.Path = raw_dirname
config_dir.resolve().to_string()
}
///|
fn rebase_project_path(
path : String,
base_dir : String,
label : String,
) -> String raise ProjectConfigError {
validate_relative_project_path(path, label)
let base : @mbpath.Path = project_path_for_host(base_dir)
base.join(project_path_for_host(path)).normalize().to_string()
}
///|
/// Converts portable project separators before entering the host path API.
fn project_path_for_host(path : String) -> String {
if @mbpath.sep == '\\' {
path.replace_all(old="/", new="\\")
} else {
path
}
}
///|
fn validate_relative_project_path(
path : String,
label : String,
) -> Unit raise ProjectConfigError {
let field = if label.has_prefix("proton.project.json.") {
label
} else {
"proton.project.json." + label
}
guard !project_path_has_root(path) else {
raise InvalidField(
path=field,
expectation="must be a relative path; absolute paths and drive prefixes are not allowed",
)
}
guard !path.contains("\\") else {
raise InvalidField(
path=field,
expectation="must use '/' separators; backslashes are not allowed in portable project paths",
)
}
}
///|
fn project_path_has_root(path : String) -> Bool {
if path.has_prefix("/") || path.has_prefix("\\") {
return true
}
guard path.length() >= 2 else { return false }
let drive = path[0]
((drive >= 'A' && drive <= 'Z') || (drive >= 'a' && drive <= 'z')) &&
path[1] == ':'
}
///|
fn join_path_string(base : String, child : String) -> String {
let base_path : @mbpath.Path = project_path_for_host(base)
base_path.join(project_path_for_host(child)).normalize().to_string()
}
///|
fn dirname_string(path : String) -> String {
let native_path : @mbpath.Path = project_path_for_host(path)
native_path.dirname().to_string()
}
///|
fn normalize_keyword(raw : String) -> String {
raw.trim().to_owned().to_lower()
}