diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6f68febe..2cc6a265 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -65,7 +65,7 @@ jobs: submodules: true - name: Install Rust - uses: dtolnay/rust-toolchain@1.70.0 + uses: dtolnay/rust-toolchain@1.79.0 - name: Restore Rust Cache uses: actions/cache/restore@v4 diff --git a/CHANGELOG.md b/CHANGELOG.md index e0e8442d..f09a084f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ * Changed the background of the server's in-browser UI to be gray instead of white ([#1080]) * Fixed `Auto Connect Playtest Server` no longer functioning due to Roblox change ([#1066]) * Added an update indicator to the version header when a new version of the plugin is available. ([#1069]) +* Added `--absolute` flag to the sourcemap subcommand, which will emit absolute paths instead of relative paths. ([#1092]) [#1093]: https://github.com/rojo-rbx/rojo/pull/1093 [#1084]: https://github.com/rojo-rbx/rojo/pull/1084 @@ -16,6 +17,7 @@ [#1080]: https://github.com/rojo-rbx/rojo/pull/1080 [#1049]: https://github.com/rojo-rbx/rojo/pull/1066 [#1069]: https://github.com/rojo-rbx/rojo/pull/1069 +[#1092]: https://github.com/rojo-rbx/rojo/pull/1092 ## 7.5.1 - April 25th, 2025 * Fixed output spam related to `Instance.Capabilities` in the plugin diff --git a/Cargo.toml b/Cargo.toml index 286255dd..7b34dbce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rojo" version = "7.5.1" -rust-version = "1.70.0" +rust-version = "1.79.0" authors = [ "Lucien Greathouse ", "Micah Reid ", diff --git a/src/cli/sourcemap.rs b/src/cli/sourcemap.rs index 268a9724..95fe6631 100644 --- a/src/cli/sourcemap.rs +++ b/src/cli/sourcemap.rs @@ -1,7 +1,8 @@ use std::{ + borrow::Cow, io::{BufWriter, Write}, mem::forget, - path::{Path, PathBuf}, + path::{self, Path, PathBuf}, }; use clap::Parser; @@ -20,6 +21,7 @@ use crate::{ use super::resolve_path; const PATH_STRIP_FAILED_ERR: &str = "Failed to create relative paths for project file!"; +const ABSOLUTE_PATH_FAILED_ERR: &str = "Failed to turn relative path into absolute path!"; /// Representation of a node in the generated sourcemap tree. #[derive(Serialize)] @@ -32,7 +34,7 @@ struct SourcemapNode<'a> { skip_serializing_if = "Vec::is_empty", serialize_with = "crate::path_serializer::serialize_vec_absolute" )] - file_paths: Vec, + file_paths: Vec>, #[serde(skip_serializing_if = "Vec::is_empty")] children: Vec>, @@ -60,6 +62,10 @@ pub struct SourcemapCommand { /// Whether to automatically recreate a snapshot when any input files change. #[clap(long)] pub watch: bool, + + /// Whether the sourcemap should use absolute paths instead of relative paths. + #[clap(long)] + pub absolute: bool, } impl SourcemapCommand { @@ -86,7 +92,7 @@ impl SourcemapCommand { .build_global() .unwrap(); - write_sourcemap(&session, self.output.as_deref(), filter)?; + write_sourcemap(&session, self.output.as_deref(), filter, self.absolute)?; if self.watch { let rt = Runtime::new().unwrap(); @@ -97,7 +103,7 @@ impl SourcemapCommand { cursor = new_cursor; if patch_set_affects_sourcemap(&session, &patch_set, filter) { - write_sourcemap(&session, self.output.as_deref(), filter)?; + write_sourcemap(&session, self.output.as_deref(), filter, self.absolute)?; } } } @@ -163,13 +169,16 @@ fn recurse_create_node<'a>( referent: Ref, project_dir: &Path, filter: fn(&InstanceWithMeta) -> bool, + use_absolute_paths: bool, ) -> Option> { let instance = tree.get_instance(referent).expect("instance did not exist"); let children: Vec<_> = instance .children() .par_iter() - .filter_map(|&child_id| recurse_create_node(tree, child_id, project_dir, filter)) + .filter_map(|&child_id| { + recurse_create_node(tree, child_id, project_dir, filter, use_absolute_paths) + }) .collect(); // If this object has no children and doesn't pass the filter, it doesn't @@ -184,14 +193,30 @@ fn recurse_create_node<'a>( .iter() // Not all paths listed as relevant are guaranteed to exist. .filter(|path| path.is_file()) - .map(|path| path.strip_prefix(project_dir).expect(PATH_STRIP_FAILED_ERR)) - .map(|path| path.to_path_buf()) - .collect(); + .map(|path| path.as_path()); + + let mut output_file_paths: Vec> = + Vec::with_capacity(instance.metadata().relevant_paths.len()); + + if use_absolute_paths { + // It's somewhat important to note here that `path::absolute` takes in a Path and returns a PathBuf + for val in file_paths { + output_file_paths.push(Cow::Owned( + path::absolute(val).expect(ABSOLUTE_PATH_FAILED_ERR), + )); + } + } else { + for val in file_paths { + output_file_paths.push(Cow::from( + val.strip_prefix(project_dir).expect(PATH_STRIP_FAILED_ERR), + )); + } + }; Some(SourcemapNode { name: instance.name(), class_name: instance.class_name(), - file_paths, + file_paths: output_file_paths, children, }) } @@ -200,10 +225,17 @@ fn write_sourcemap( session: &ServeSession, output: Option<&Path>, filter: fn(&InstanceWithMeta) -> bool, + use_absolute_paths: bool, ) -> anyhow::Result<()> { let tree = session.tree(); - let root_node = recurse_create_node(&tree, tree.get_root_id(), session.root_dir(), filter); + let root_node = recurse_create_node( + &tree, + tree.get_root_id(), + session.root_dir(), + filter, + use_absolute_paths, + ); if let Some(output_path) = output { let mut file = BufWriter::new(File::create(output_path)?);