Skip to content

Commit

Permalink
feat: implement post installation
Browse files Browse the repository at this point in the history
Signed-off-by: Chawye Hsu <su+git@chawyehsu.com>
  • Loading branch information
chawyehsu committed Jul 15, 2024
1 parent 751fe1f commit e4a14b8
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 13 deletions.
23 changes: 19 additions & 4 deletions src/bin/shim.rs → src/bin/moonup-shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,27 @@ fn run() -> Result<()> {
.file_name()
.map(|name| name.to_string_lossy().to_ascii_lowercase());

if let None = current_exe_name {
eprintln!("can't get shim executable name");
std::process::exit(1);
let shim_name = current_exe_name.unwrap_or_default();

if shim_name.is_empty() {
return Err(anyhow::anyhow!("bad shim name"));
}

let shim_itself = {
#[cfg(target_os = "windows")]
{
shim_name == "moonup-shim.exe"
}
#[cfg(not(target_os = "windows"))]
{
shim_name == "moonup-shim"
}
};

if shim_itself {
return Err(anyhow::anyhow!("cannot run moonup-shim directly"));
}

let shim_name = current_exe_name.unwrap();
let toolchain_root = detect_toolchain_version();
let actual_exe = toolchain_root.join("bin").join(&shim_name);

Expand Down
93 changes: 91 additions & 2 deletions src/cli/install.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use clap::Parser;
use miette::IntoDiagnostic;
use std::path::PathBuf;
use std::{env, process::Command};

use crate::toolchain::{index::retrieve_release, package::populate_package};
use crate::toolchain::{
index::{retrieve_release, ReleaseCombined},
package::populate_package,
};

/// Install or update a MoonBit toolchain
#[derive(Parser, Debug)]
Expand All @@ -14,9 +20,92 @@ pub async fn execute(args: Args) -> miette::Result<()> {
let version = args.toolchain.as_str();
let release = retrieve_release(version).await?;

populate_package(release).await?;
populate_package(&release).await?;
post_install(&release)?;

println!("Installed toolchain version '{}'", version);

Ok(())
}

// Post installation: pour shims and build the core library
fn post_install(release: &ReleaseCombined) -> miette::Result<()> {
let args = env::args_os().collect::<Vec<_>>();
let mut moonup_shim_exe = env::current_exe().unwrap_or_else(|_| PathBuf::from(&args[0]));
moonup_shim_exe.set_file_name({
#[cfg(target_os = "windows")]
{
"moonup-shim.exe"
}
#[cfg(not(target_os = "windows"))]
{
"moonup-shim"
}
});

let version = match release.latest {
true => "latest".to_string(),
false => release
.toolchain
.as_ref()
.map(|r| r.version.to_string())
.unwrap_or(
release
.core
.as_ref()
.map(|r| r.version.to_string())
.expect("no version found"),
),
};

let toolchain_dir = crate::moonup_home().join("toolchains").join(&version);
let bin_dir = toolchain_dir.join("bin");
let bins = bin_dir
.read_dir()
.into_diagnostic()?
.into_iter()
.filter_map(std::io::Result::ok)
.filter_map(|e| {
let is_file = e
.file_type()
.into_diagnostic()
.map(|t| t.is_file())
.unwrap_or(false);
if is_file {
Some(e.file_name())
} else {
None
}
})
.collect::<Vec<_>>();

let moon_home_bin = crate::moon_home().join("bin");

for bin in bins {
tracing::debug!("Pouring shim for '{}'", bin.to_string_lossy());
let dest = moon_home_bin.join(&bin);
std::fs::copy(&moonup_shim_exe, &dest).into_diagnostic()?;
}

// Build core library
let corelib_dir = toolchain_dir.join("lib/core");
let actual_moon_exe = bin_dir.join({
#[cfg(target_os = "windows")]
{
"moon.exe"
}
#[cfg(not(target_os = "windows"))]
{
"moon"
}
});

let mut cmd = Command::new(actual_moon_exe);
cmd.arg("bundle");
cmd.arg("--all");
cmd.arg("--source-dir");
cmd.arg(&corelib_dir);
cmd.status().into_diagnostic()?;

Ok(())
}
10 changes: 6 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ pub mod utils;
/// # Returns
///
/// The MoonBit home directory
pub fn moon_home() -> Option<PathBuf> {
pub fn moon_home() -> PathBuf {
if let Some(path) = std::env::var_os("MOON_HOME") {
Some(PathBuf::from(path))
PathBuf::from(path)
} else {
dirs::home_dir().map(|path| path.join(constant::MOON_DIR))
dirs::home_dir()
.map(|path| path.join(constant::MOON_DIR))
.expect("cannot determine MoonBit home directory")
}
}

Expand All @@ -36,6 +38,6 @@ pub fn moonup_home() -> PathBuf {
} else {
dirs::home_dir()
.map(|path| path.join(constant::MOONUP_DIR))
.unwrap()
.expect("cannot determine moonup home directory")
}
}
6 changes: 3 additions & 3 deletions src/toolchain/package.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ use crate::{

use super::index::ReleaseCombined;

pub async fn populate_package(release: ReleaseCombined) -> miette::Result<()> {
pub async fn populate_package(release: &ReleaseCombined) -> miette::Result<()> {
if release.core.is_none() && release.toolchain.is_none() {
return Ok(());
}

let downloads_dir = crate::moonup_home().join("downloads");
let toolchain_dir = crate::moonup_home().join("toolchains");

if let Some(toolchain) = release.toolchain {
if let Some(toolchain) = release.toolchain.as_ref() {
let version = toolchain.version.as_str();

let downloads_version_dir = downloads_dir.join(version);
Expand Down Expand Up @@ -71,7 +71,7 @@ pub async fn populate_package(release: ReleaseCombined) -> miette::Result<()> {
}
}

if let Some(core) = release.core {
if let Some(core) = release.core.as_ref() {
let version = core.version.as_str();

let downloads_version_dir = downloads_dir.join(version);
Expand Down

0 comments on commit e4a14b8

Please sign in to comment.