///|
let lock_file_name = "c-plugin-lock.json"
///|
fn current_home_dir() -> String {
@env.get_env_var("HOME").unwrap_or(".")
}
///|
fn current_working_dir() -> String {
@env.get_env_var("PWD").unwrap_or(@env.current_dir().unwrap_or("."))
}
///|
fn relative_path(from : String, to : String) -> String {
let normalized_from = if @path.Path::is_absolute(from) {
@path.Path::normalize(from).to_string()
} else {
@path.Path::join(current_working_dir(), from).normalize().to_string()
}
let normalized_to = if @path.Path::is_absolute(to) {
@path.Path::normalize(to).to_string()
} else {
@path.Path::join(current_working_dir(), to).normalize().to_string()
}
let relative = @path.Path::relative(base=normalized_from, normalized_to).to_string()
if relative == "" {
"."
} else {
relative
}
}
///|
fn expand_home(path : String) -> String {
if path == "~" {
current_home_dir()
} else if path.has_prefix("~/") {
@path.Path::join(current_home_dir(), path[2:].to_owned()).to_string()
} else {
path
}
}
///|
fn agents_dir_from_lock_file(lock_file : String) -> String {
@path.Path::join(@path.Path::dirname(lock_file), ".agents").to_string()
}
///|
fn lock_path_from_agents(agents : String) -> String {
@path.Path::join(@path.Path::dirname(agents), lock_file_name).to_string()
}
///|
async fn resolve_agents_dirs(recursive : Bool) -> Array[String] {
let nearest_lock_file = @target_file_discovery.find_parent_target_file(
lock_file_name,
current_home_dir(),
current_working_dir(),
)
if !recursive {
return [agents_dir_from_lock_file(nearest_lock_file)]
}
@target_file_discovery.collect_recursive_target_files(
@path.Path::dirname(nearest_lock_file).to_string(),
lock_file_name,
)[:].map(agents_dir_from_lock_file)
}
///|
async fn resolve_global_agents_dir() -> String {
agents_dir_from_lock_file(
@target_file_discovery.find_home_target_file(
current_home_dir(),
lock_file_name,
),
)
}
///|
async fn resolve_agents_dir() -> String {
match resolve_agents_dirs(false) {
[agents, ..] => agents
[] => fail("Could not find .agents directory with \{lock_file_name}")
}
}
///|
async fn command_agents_dir(global : Bool) -> String {
if global {
resolve_global_agents_dir()
} else {
resolve_agents_dir()
}
}
///|
fn cache_root() -> String {
@env.get_env_var("C_PLUGIN_CACHE_ROOT").unwrap_or(
(current_home_dir()
|> @path.Path::join(".c-plugin")
|> @path.Path::join("cache")).to_string(),
)
}
///|
fn repo_cache_dir(source : String) -> String {
(cache_root() |> @path.Path::join("mbt") |> @path.Path::join(source)).to_string()
}
///|
fn validate_github_source(source : String) -> Unit raise {
guard !source.contains("..") &&
!source.contains("\\") &&
!source.contains(":") &&
!source.has_prefix("/") &&
!source.has_suffix(".git") else {
fail("GitHub source must be owner/repo")
}
let parts = source.split("/").map(fn(part) { part.to_owned() }).collect()
guard parts.length() == 2 && parts[0] != "" && parts[1] != "" else {
fail("GitHub source must be owner/repo")
}
}
///|
fn is_relative_plugin_path(path : String) -> Bool {
path != "" &&
!path.has_prefix("/") &&
!path.contains("..") &&
!path.contains("\\")
}
///|
fn local_source_path(source : String, root : String) -> String {
if source.has_prefix("./") {
let path = @path.Path::join(root, source).to_string()
if @path.Path::is_absolute(path) {
@path.Path::normalize(path).to_string()
} else {
@path.Path::join(current_working_dir(), path).normalize().to_string()
}
} else {
expand_home(source)
}
}