fix: install dev packages and remove them after use
Some checks failed
Debug / Get build version (push) Has been cancelled
Test & Lint / lint (push) Has been cancelled
Debug / Build for linux-x86_64 (push) Has been cancelled
Debug / Build for macos-aarch64 (push) Has been cancelled
Debug / Build for macos-x86_64 (push) Has been cancelled
Debug / Build for windows-x86_64 (push) Has been cancelled

This commit is contained in:
daimond113 2025-01-03 00:05:32 +01:00
parent de43d2ce42
commit ca5a8f108d
No known key found for this signature in database
GPG key ID: 3A8ECE51328B513C
3 changed files with 159 additions and 58 deletions

View file

@ -14,6 +14,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Inherit pesde-managed scripts from workspace root by @daimond113
- Allow using binaries from workspace root in member packages by @daimond113
### Fixed
- Install dev packages in prod mode and remove them after use to allow them to be used in scripts by @daimond113
### Changed
- Change handling of graphs to a flat structure by @daimond113
- Store dependency over downloaded graphs in the lockfile by @daimond113

View file

@ -189,10 +189,6 @@ impl Project {
let container_folder =
node.container_folder_from_project(&id, self, manifest.target.kind());
if prod && node.resolved_ty == DependencyType::Dev {
continue;
}
downloaded_graph.insert(id, node);
let cas_dir = self.cas_dir().to_path_buf();
@ -308,7 +304,50 @@ impl Project {
.map_err(errors::DownloadAndLinkError::Hook)?;
}
Ok(Arc::into_inner(graph).unwrap())
let mut graph = Arc::into_inner(graph).unwrap();
if prod {
let (dev_graph, prod_graph) = graph
.into_iter()
.partition::<DependencyGraphWithTarget, _>(|(_, node)| {
node.node.resolved_ty == DependencyType::Dev
});
graph = prod_graph;
let dev_graph = Arc::new(dev_graph);
let manifest_target_kind = manifest.target.kind();
// the `true` argument means it'll remove the dependencies linkers
self.link(
&dev_graph,
&Arc::new(manifest),
&Arc::new(Default::default()),
false,
true,
)
.await?;
let mut tasks = dev_graph
.iter()
.map(|(id, node)| {
let container_folder =
node.node
.container_folder_from_project(id, self, manifest_target_kind);
async move {
fs::remove_dir_all(&container_folder)
.await
.map_err(errors::DownloadAndLinkError::Io)
}
})
.collect::<JoinSet<_>>();
while let Some(task) = tasks.join_next().await {
task.unwrap()?;
}
}
Ok(graph)
}
}

View file

@ -68,7 +68,13 @@ impl Project {
// step 1. link all non-wally packages (and their dependencies) temporarily without types
// we do this separately to allow the required tools for the scripts to be installed
self.link(&graph, &manifest, &Arc::new(PackageTypes::default()), false)
self.link(
&graph,
&manifest,
&Arc::new(PackageTypes::default()),
false,
false,
)
.await?;
if !with_types {
@ -150,7 +156,7 @@ impl Project {
}
// step 3. link all packages (and their dependencies), this time with types
self.link(&graph, &manifest, &Arc::new(package_types), true)
self.link(&graph, &manifest, &Arc::new(package_types), true, false)
.await
}
@ -164,12 +170,30 @@ impl Project {
node: &DependencyGraphNodeWithTarget,
package_id: &PackageId,
alias: &str,
package_types: &PackageTypes,
manifest: &Manifest,
package_types: &Arc<PackageTypes>,
manifest: &Arc<Manifest>,
remove: bool,
is_root: bool,
) -> Result<(), errors::LinkingError> {
static NO_TYPES: Vec<String> = Vec::new();
#[allow(clippy::result_large_err)]
fn into_link_result(res: std::io::Result<()>) -> Result<(), errors::LinkingError> {
match res {
Ok(_) => Ok(()),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()),
Err(e) => Err(e.into()),
}
}
let mut tasks = JoinSet::<Result<(), errors::LinkingError>>::new();
if let Some(lib_file) = node.target.lib_path() {
let destination = base_folder.join(format!("{alias}.luau"));
if remove {
tasks.spawn(async move { into_link_result(fs::remove_file(destination).await) });
} else {
let lib_module = generator::generate_lib_linking_module(
&generator::get_lib_require_path(
node.target.kind(),
@ -183,60 +207,91 @@ impl Project {
)?,
package_types.get(package_id).unwrap_or(&NO_TYPES),
);
let cas_dir = self.cas_dir().to_path_buf();
write_cas(
base_folder.join(format!("{alias}.luau")),
self.cas_dir(),
&lib_module,
)
.await?;
tasks.spawn(async move {
write_cas(destination, &cas_dir, &lib_module)
.await
.map_err(Into::into)
});
}
}
if let Some(bin_file) = node.target.bin_path() {
let destination = base_folder.join(format!("{alias}.bin.luau"));
if remove {
tasks.spawn(async move { into_link_result(fs::remove_file(destination).await) });
} else {
let bin_module = generator::generate_bin_linking_module(
container_folder,
&generator::get_bin_require_path(base_folder, bin_file, container_folder),
);
let cas_dir = self.cas_dir().to_path_buf();
write_cas(
base_folder.join(format!("{alias}.bin.luau")),
self.cas_dir(),
&bin_module,
)
.await?;
tasks.spawn(async move {
write_cas(destination, &cas_dir, &bin_module)
.await
.map_err(Into::into)
});
}
}
if let Some(scripts) = node.target.scripts().filter(|s| !s.is_empty()) {
let scripts_base =
create_and_canonicalize(self.package_dir().join(SCRIPTS_LINK_FOLDER).join(alias))
.await?;
if let Some(scripts) = node
.target
.scripts()
.filter(|s| !s.is_empty() && node.node.direct.is_some() && is_root)
{
let scripts_container = self.package_dir().join(SCRIPTS_LINK_FOLDER);
let scripts_base = create_and_canonicalize(scripts_container.join(alias)).await?;
if remove {
tasks.spawn(async move {
fs::remove_dir_all(scripts_base).await?;
if let Ok(mut entries) = fs::read_dir(&scripts_container).await {
if entries.next_entry().await.transpose().is_none() {
drop(entries);
fs::remove_dir(&scripts_container).await?;
}
}
Ok(())
});
} else {
for (script_name, script_path) in scripts {
let script_module =
generator::generate_script_linking_module(&generator::get_script_require_path(
let destination = scripts_base.join(format!("{script_name}.luau"));
let script_module = generator::generate_script_linking_module(
&generator::get_script_require_path(
&scripts_base,
script_path,
container_folder,
));
),
);
let cas_dir = self.cas_dir().to_path_buf();
write_cas(
scripts_base.join(format!("{script_name}.luau")),
self.cas_dir(),
&script_module,
)
.await?;
tasks.spawn(async move {
write_cas(destination, &cas_dir, &script_module)
.await
.map_err(Into::into)
});
}
}
}
while let Some(task) = tasks.join_next().await {
task.unwrap()?;
}
Ok(())
}
async fn link(
pub(crate) async fn link(
&self,
graph: &Arc<DependencyGraphWithTarget>,
manifest: &Arc<Manifest>,
package_types: &Arc<PackageTypes>,
is_complete: bool,
remove: bool,
) -> Result<(), errors::LinkingError> {
let mut tasks = graph
.iter()
@ -278,6 +333,8 @@ impl Project {
alias,
&package_types,
&manifest,
remove,
true,
)
.await?;
}
@ -330,6 +387,8 @@ impl Project {
dependency_alias,
&package_types,
&manifest,
remove,
false,
)
.await?;
}