diff --git a/CHANGELOG.md b/CHANGELOG.md index 18df81e..fc72011 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Add dev only installs in #32 by @Stefanuk12 - Add `PESDE_HOME` variable (defaults to $HOME/.pesde) to override pesde's directory's location by @daimond113 +- Add `--target` argument to execute command by @daimond113 ### Fixed - Download engines in install step rather than lazily by @daimond113 diff --git a/src/cli/commands/execute.rs b/src/cli/commands/execute.rs index 0a55b99..2cc6cbe 100644 --- a/src/cli/commands/execute.rs +++ b/src/cli/commands/execute.rs @@ -12,7 +12,7 @@ use fs_err::tokio as fs; use indicatif::MultiProgress; use pesde::{ download_and_link::{DownloadAndLinkOptions, InstallDependenciesMode}, - linking::generator::generate_bin_linking_module, + linking::generator::{generate_bin_linking_module, get_bin_require_path}, manifest::target::TargetKind, names::{PackageName, PackageNames}, source::{ @@ -35,10 +35,14 @@ use std::{ #[derive(Debug, Args)] pub struct ExecuteCommand { - /// The package name, script name, or path to a script to run + /// The package to run #[arg(index = 1)] package: VersionedPackageName, + /// The target of the package to run + #[arg(short, long, default_value_t = TargetKind::Luau)] + target: TargetKind, + /// The index URL to use for the package #[arg(short, long, value_parser = crate::cli::parse_gix_url)] index: Option, @@ -50,6 +54,10 @@ pub struct ExecuteCommand { impl ExecuteCommand { pub async fn run(self, project: Project, reqwest: reqwest::Client) -> anyhow::Result<()> { + if !self.target.has_bin() { + anyhow::bail!("{} doesn't support bin exports!", self.target); + } + let multi_progress = MultiProgress::new(); crate::PROGRESS_BARS .lock() @@ -93,7 +101,7 @@ impl ExecuteCommand { }, &ResolveOptions { project: project.clone(), - target: TargetKind::Luau, + target: self.target, refreshed_sources: refreshed_sources.clone(), loose_target: true, }, @@ -208,7 +216,7 @@ impl ExecuteCommand { .write_all( generate_bin_linking_module( tempdir.path(), - &format!("{:?}", bin_path.to_path(tempdir.path())), + &get_bin_require_path(tempdir.path(), &bin_path, tempdir.path()), ) .as_bytes(), ) diff --git a/src/cli/commands/run.rs b/src/cli/commands/run.rs index 0cd6924..b903088 100644 --- a/src/cli/commands/run.rs +++ b/src/cli/commands/run.rs @@ -6,14 +6,14 @@ use futures::{StreamExt as _, TryStreamExt as _}; use pesde::{ engine::runtime::Runtime, errors::{ManifestReadError, WorkspaceMembersError}, - linking::generator::generate_bin_linking_module, + linking::generator::{generate_bin_linking_module, get_bin_require_path}, manifest::{Alias, Manifest}, names::{PackageName, PackageNames}, scripts::parse_script, source::traits::{GetTargetOptions, PackageRef as _, PackageSource as _, RefreshOptions}, Project, MANIFEST_FILE_NAME, }; -use relative_path::RelativePathBuf; +use relative_path::{RelativePath, RelativePathBuf}; use std::{ collections::HashSet, env::current_dir, ffi::OsString, io::Write as _, path::Path, sync::Arc, }; @@ -39,12 +39,30 @@ impl RunCommand { let engines = Arc::new(get_project_engines(&manifest, &reqwest).await?); let run = async |runtime: Runtime, root: &Path, file_path: &Path| -> ! { - let mut caller = tempfile::NamedTempFile::new().expect("failed to create tempfile"); + let dir = project.cas_dir().join(".tmp"); + fs::create_dir_all(&dir) + .await + .expect("failed to create temporary directory"); + + let mut caller = + tempfile::NamedTempFile::new_in(dir).expect("failed to create tempfile"); + caller .write_all( generate_bin_linking_module( root, - &format!("{:?}", file_path.to_string_lossy()), + &get_bin_require_path( + caller.path(), + RelativePath::from_path( + file_path + .file_name() + .unwrap() + .to_str() + .expect("path contains invalid characters"), + ) + .unwrap(), + file_path.parent().unwrap(), + ), ) .as_bytes(), ) @@ -135,7 +153,7 @@ impl RunCommand { .get_target( &node.pkg_ref, &GetTargetOptions { - project, + project: project.clone(), path: container_folder.as_path().into(), id: id.into(), engines: engines.clone(), diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 6e98be3..76f7c8f 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -374,6 +374,7 @@ pub async fn get_project_engines( reqwest: &reqwest::Client, ) -> anyhow::Result> { use tokio::task::JoinSet; + use version::get_installed_versions; crate::cli::reporters::run_with_reporter(|_, root_progress, reporter| async { let root_progress = root_progress; @@ -383,16 +384,21 @@ pub async fn get_project_engines( root_progress.reset(); root_progress.set_message("update engines"); - let mut tasks = manifest - .engines + let mut tasks = EngineKind::VARIANTS .iter() - .map(|(engine, req)| { - let engine = *engine; - let req = req.clone(); + .copied() + .map(|engine| { + let req = manifest.engines.get(&engine).cloned(); let reqwest = reqwest.clone(); let reporter = reporter.clone(); async move { + let Some(req) = req else { + return get_installed_versions(engine) + .await + .map(|mut vers| vers.pop_last().map(|v| (engine, v))); + }; + let version = crate::cli::version::get_or_download_engine( &reqwest, engine, req, reporter, ) @@ -404,7 +410,7 @@ pub async fn get_project_engines( .await .context("failed to make engine linker")?; - Ok::<_, anyhow::Error>((engine, version)) + Ok::<_, anyhow::Error>(Some((engine, version))) } }) .collect::>(); @@ -412,7 +418,9 @@ pub async fn get_project_engines( let mut resolved_engine_versions = HashMap::new(); while let Some(task) = tasks.join_next().await { - let (engine, version) = task.unwrap()?; + let Some((engine, version)) = task.unwrap()? else { + continue; + }; resolved_engine_versions.insert(engine, version); } diff --git a/src/cli/version.rs b/src/cli/version.rs index 4cb89a6..04b1a91 100644 --- a/src/cli/version.rs +++ b/src/cli/version.rs @@ -117,7 +117,7 @@ pub async fn check_for_updates(reqwest: &reqwest::Client) -> anyhow::Result<()> } #[instrument(level = "trace")] -async fn get_installed_versions(engine: EngineKind) -> anyhow::Result> { +pub async fn get_installed_versions(engine: EngineKind) -> anyhow::Result> { let source = engine.source(); let path = engines_dir()?.join(source.directory()); let mut installed_versions = BTreeSet::new(); diff --git a/src/engine/mod.rs b/src/engine/mod.rs index cf1f3c6..c20417f 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -40,6 +40,9 @@ impl FromStr for EngineKind { } impl EngineKind { + /// All [EngineKind]s + pub const VARIANTS: &'static [EngineKind] = &[EngineKind::Pesde, EngineKind::Lune]; + /// Returns the source to get this engine from #[must_use] pub fn source(self) -> EngineSources {