Make the name field in projects optional (#870)

Closes #858.

If a project is named `default.project.json`, it acts as an `init` file
and gains the name of the folder it's inside of. If it is named
something other than `default.project.json`, it gains the name of the
file with `.project.json` trimmed off. So e.g. `foo.project.json`
becomes `foo`.
This commit is contained in:
Micah
2024-02-20 17:25:57 -08:00
committed by GitHub
parent 42121a9fc9
commit 48bb760739
27 changed files with 486 additions and 32 deletions

View File

@@ -110,7 +110,7 @@ impl ServeSession {
log::debug!("Loading project file from {}", project_path.display());
let root_project = match vfs.read(&project_path).with_not_found()? {
let mut root_project = match vfs.read(&project_path).with_not_found()? {
Some(contents) => Project::load_from_slice(&contents, &project_path)?,
None => {
return Err(ServeSessionError::NoProjectFound {
@@ -118,6 +118,35 @@ impl ServeSession {
});
}
};
if root_project.name.is_none() {
if let Some(file_name) = project_path.file_name().and_then(|s| s.to_str()) {
if file_name == "default.project.json" {
let folder_name = project_path
.parent()
.and_then(Path::file_name)
.and_then(|s| s.to_str());
if let Some(folder_name) = folder_name {
root_project.name = Some(folder_name.to_string());
} else {
return Err(ServeSessionError::FolderNameInvalid {
path: project_path.to_path_buf(),
});
}
} else if let Some(trimmed) = file_name.strip_suffix(".project.json") {
root_project.name = Some(trimmed.to_string());
} else {
return Err(ServeSessionError::ProjectNameInvalid {
path: project_path.to_path_buf(),
});
}
} else {
return Err(ServeSessionError::ProjectNameInvalid {
path: project_path.to_path_buf(),
});
}
}
// Rebind it to make it no longer mutable
let root_project = root_project;
let mut tree = RojoTree::new(InstanceSnapshot::new());
@@ -190,7 +219,10 @@ impl ServeSession {
}
pub fn project_name(&self) -> &str {
&self.root_project.name
self.root_project
.name
.as_ref()
.expect("all top-level projects must have their name set")
}
pub fn project_port(&self) -> Option<u16> {
@@ -231,6 +263,14 @@ pub enum ServeSessionError {
)]
NoProjectFound { path: PathBuf },
#[error("The folder for the provided project cannot be used as a project name: {}\n\
Consider setting the `name` field on this project.", .path.display())]
FolderNameInvalid { path: PathBuf },
#[error("The file name of the provided project cannot be used as a project name: {}.\n\
Consider setting the `name` field on this project.", .path.display())]
ProjectNameInvalid { path: PathBuf },
#[error(transparent)]
Io {
#[from]