diff --git a/CHANGELOG.md b/CHANGELOG.md index c4af646..b4def0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Allow multiple, user selectable scripts packages to be selected (& custom packages inputted) in `init` command by @daimond113 + ### Performance - Use `exec` in Unix bin linking to reduce the number of processes by @daimond113 diff --git a/src/cli/commands/init.rs b/src/cli/commands/init.rs index d77d254..c3b9a47 100644 --- a/src/cli/commands/init.rs +++ b/src/cli/commands/init.rs @@ -16,11 +16,26 @@ use pesde::{ Project, DEFAULT_INDEX_NAME, SCRIPTS_LINK_FOLDER, }; use semver::VersionReq; -use std::{collections::HashSet, str::FromStr}; +use std::{collections::HashSet, fmt::Display, str::FromStr}; #[derive(Debug, Args)] pub struct InitCommand {} +#[derive(Debug)] +enum PackageNameOrCustom { + PackageName(PackageName), + Custom, +} + +impl Display for PackageNameOrCustom { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + PackageNameOrCustom::PackageName(n) => write!(f, "{n}"), + PackageNameOrCustom::Custom => write!(f, "custom"), + } + } +} + impl InitCommand { pub async fn run(self, project: Project) -> anyhow::Result<()> { match project.read_manifest().await { @@ -127,7 +142,45 @@ impl InitCommand { .await .context("failed to get source config")?; - if let Some(scripts_pkg_name) = config.scripts_package { + let scripts_package = inquire::Select::new( + "which scripts package do you want to use?", + config + .scripts_packages + .into_iter() + .map(PackageNameOrCustom::PackageName) + .chain(std::iter::once(PackageNameOrCustom::Custom)) + .collect(), + ) + .prompt() + .unwrap(); + + let scripts_package = match scripts_package { + PackageNameOrCustom::PackageName(p) => Some(p), + PackageNameOrCustom::Custom => { + let name = inquire::Text::new("which package to use?") + .with_validator(|name: &str| { + if name.is_empty() { + return Ok(Validation::Valid); + } + + Ok(match PackageName::from_str(name) { + Ok(_) => Validation::Valid, + Err(e) => Validation::Invalid(e.to_string().into()), + }) + }) + .with_help_message("leave empty for none") + .prompt() + .unwrap(); + + if name.is_empty() { + None + } else { + Some(PackageName::from_str(&name).unwrap()) + } + } + }; + + if let Some(scripts_pkg_name) = scripts_package { let (v_id, pkg_ref) = source .resolve( &PesdeDependencySpecifier { @@ -185,7 +238,7 @@ impl InitCommand { } else { println!( "{}", - "configured index hasn't a configured scripts package".red() + "no scripts package configured, this can cause issues with Roblox compatibility".red() ); if !inquire::prompt_confirmation("initialize regardless?").unwrap() { return Ok(()); diff --git a/src/source/pesde/mod.rs b/src/source/pesde/mod.rs index a0b8c65..7895521 100644 --- a/src/source/pesde/mod.rs +++ b/src/source/pesde/mod.rs @@ -316,9 +316,9 @@ pub struct IndexConfig { /// The maximum size of an archive in bytes #[serde(default = "default_archive_size")] pub max_archive_size: usize, - /// The package to use for default script implementations + /// The packages to display in the CLI for default script implementations #[serde(default)] - pub scripts_package: Option, + pub scripts_packages: Vec, } impl IndexConfig {