Skip to content

Commit

Permalink
erlang core plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
jdx committed Dec 13, 2023
1 parent 9160c4f commit bd0e8ea
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 2 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/test-plugins.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,17 @@ jobs:
command: rtx exec direnv@latest -- direnv --version
- plugin: erlang
command: rtx exec erlang@latest -- erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().' -noshell
env:
RTX_EXPERIMENTAL: 1
- plugin: elixir
command: |
rtx use --global erlang@latest
eval "$(rtx env bash)"
rtx use --global elixir@latest
eval "$(rtx env bash)"
rtx exec -- elixir --version
env:
RTX_EXPERIMENTAL: 1
- plugin: golang
command: rtx exec golang@latest -- go version
- plugin: java
Expand Down
8 changes: 8 additions & 0 deletions e2e/test_erlang
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
# shellcheck source-path=SCRIPTDIR
source "$(dirname "$0")/assert.sh"

export RTX_EXPERIMENTAL=1

assert_contains "rtx x [email protected] -- erl -eval 'erlang:display(erlang:system_info(otp_release)), halt().' -noshell" "24"
122 changes: 122 additions & 0 deletions src/plugins/core/erlang.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
use std::path::PathBuf;

use color_eyre::eyre::Result;

use crate::config::Settings;

use crate::file::display_path;
use crate::install_context::InstallContext;
use crate::lock_file::LockFile;
use crate::plugins::core::CorePlugin;
use crate::plugins::{Plugin, HTTP};
use crate::toolset::ToolVersionRequest;
use crate::{cmd, file};

#[derive(Debug)]
pub struct ErlangPlugin {
core: CorePlugin,
}

const KERL_VERSION: &str = "4.0.0";

impl ErlangPlugin {
pub fn new() -> Self {
Self {
core: CorePlugin::new("erlang"),
}
}

fn kerl_path(&self) -> PathBuf {
self.core.cache_path.join(format!("kerl-{}", KERL_VERSION))
}

fn lock_build_tool(&self) -> Result<fslock::LockFile> {
LockFile::new(&self.kerl_path())
.with_callback(|l| {
trace!("install_or_update_kerl {}", l.display());
})
.lock()
}

fn update_kerl(&self) -> Result<()> {
let _lock = self.lock_build_tool();
if self.kerl_path().exists() {
return Ok(());
}
self.install_kerl()?;
cmd!(self.kerl_path(), "update", "releases")
.env("KERL_BASE_DIR", self.core.cache_path.join("kerl"))
.run()?;
Ok(())
}

fn install_kerl(&self) -> Result<()> {
debug!("Installing kerl to {}", display_path(&self.kerl_path()));
HTTP.download_file(
format!("https://raw.githubusercontent.com/kerl/kerl/{KERL_VERSION}/kerl"),
&self.kerl_path(),
)?;
file::make_executable(&self.kerl_path())?;
Ok(())
}

fn fetch_remote_versions(&self) -> Result<Vec<String>> {
match self.core.fetch_remote_versions_from_rtx() {
Ok(Some(versions)) => return Ok(versions),
Ok(None) => {}
Err(e) => warn!("failed to fetch remote versions: {}", e),
}
self.update_kerl()?;
let versions = CorePlugin::run_fetch_task_with_timeout(move || {
let output = cmd!(self.kerl_path(), "list", "releases", "all")
.env("KERL_BASE_DIR", self.core.cache_path.join("kerl"))
.read()?;
let versions = output
.split('\n')
.filter(|s| regex!(r"^[0-9].+$").is_match(s))
.map(|s| s.to_string())
.collect();
Ok(versions)
})?;
Ok(versions)
}
}

impl Plugin for ErlangPlugin {
fn name(&self) -> &str {
self.core.name
}

fn list_remote_versions(&self, _settings: &Settings) -> Result<Vec<String>> {
self.core
.remote_version_cache
.get_or_try_init(|| self.fetch_remote_versions())
.cloned()
}

fn install_version_impl(&self, ctx: &InstallContext) -> Result<()> {
self.update_kerl()?;

file::remove_all(ctx.tv.install_path())?;
let build_name = format!("rtx_{}", ctx.tv.version);
match &ctx.tv.request {
ToolVersionRequest::Ref(..) => {
unimplemented!("erlang does not yet support refs");
}
ToolVersionRequest::Version(..) => {
cmd!(
self.kerl_path(),
"build-install",
&ctx.tv.version,
&build_name,
ctx.tv.install_path()
)
.env("KERL_BASE_DIR", self.core.cache_path.join("kerl"))
.run()?;
}
_ => unimplemented!(),
}

Ok(())
}
}
9 changes: 7 additions & 2 deletions src/plugins/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::cache::CacheManager;
use crate::env::RTX_NODE_BUILD;
use crate::plugins::core::bun::BunPlugin;
use crate::plugins::core::deno::DenoPlugin;
use crate::plugins::core::erlang::ErlangPlugin;
use crate::plugins::core::go::GoPlugin;
use crate::plugins::core::java::JavaPlugin;
use crate::plugins::core::node::NodePlugin;
Expand All @@ -26,6 +27,7 @@ use crate::{dirs, env};

mod bun;
mod deno;
mod erlang;
mod go;
mod java;
mod node;
Expand Down Expand Up @@ -54,8 +56,11 @@ pub static CORE_PLUGINS: Lazy<PluginMap> = Lazy::new(|| {
});

pub static EXPERIMENTAL_CORE_PLUGINS: Lazy<PluginMap> = Lazy::new(|| {
let plugins: Vec<Arc<dyn Plugin>> =
vec![Arc::new(BunPlugin::new()), Arc::new(DenoPlugin::new())];
let plugins: Vec<Arc<dyn Plugin>> = vec![
Arc::new(BunPlugin::new()),
Arc::new(DenoPlugin::new()),
Arc::new(ErlangPlugin::new()),
];
plugins
.into_iter()
.map(|plugin| (plugin.name().to_string(), plugin))
Expand Down

0 comments on commit bd0e8ea

Please sign in to comment.