From 90516e035dc1902a9076cdbfb0b7b5b1a6d467be Mon Sep 17 00:00:00 2001 From: Lucien Greathouse Date: Wed, 12 Jun 2019 15:11:19 -0700 Subject: [PATCH] Refactor project to start making a little more sense --- server/src/commands/build.rs | 7 +- server/src/commands/serve.rs | 7 +- server/src/commands/upload.rs | 7 +- server/src/project.rs | 122 +++++++++++------- .../{legacy => legacy-0.4.x}/rojo.json | 0 .../legacy-old-0.5.x/roblox-project.json | 6 + 6 files changed, 89 insertions(+), 60 deletions(-) rename test-projects/{legacy => legacy-0.4.x}/rojo.json (100%) create mode 100644 test-projects/legacy-old-0.5.x/roblox-project.json diff --git a/server/src/commands/build.rs b/server/src/commands/build.rs index ab353662..fbbb2e2f 100644 --- a/server/src/commands/build.rs +++ b/server/src/commands/build.rs @@ -9,7 +9,7 @@ use failure::Fail; use crate::{ imfs::{Imfs, FsError}, - project::{Project, ProjectLoadFuzzyError}, + project::{Project, ProjectLoadError}, rbx_session::construct_oneoff_tree, rbx_snapshot::SnapshotError, }; @@ -47,7 +47,7 @@ pub enum BuildError { UnknownOutputKind, #[fail(display = "Project load error: {}", _0)] - ProjectLoadError(#[fail(cause)] ProjectLoadFuzzyError), + ProjectLoadError(#[fail(cause)] ProjectLoadError), #[fail(display = "IO error: {}", _0)] IoError(#[fail(cause)] io::Error), @@ -66,7 +66,7 @@ pub enum BuildError { } impl_from!(BuildError { - ProjectLoadFuzzyError => ProjectLoadError, + ProjectLoadError => ProjectLoadError, io::Error => IoError, rbx_xml::EncodeError => XmlModelEncodeError, rbx_binary::EncodeError => BinaryModelEncodeError, @@ -89,7 +89,6 @@ pub fn build(options: &BuildOptions) -> Result<(), BuildError> { info!("Looking for project at {}", options.fuzzy_project_path.display()); let project = Project::load_fuzzy(&options.fuzzy_project_path)?; - project.check_compatibility(); info!("Found project at {}", project.file_location.display()); info!("Using project {:#?}", project); diff --git a/server/src/commands/serve.rs b/server/src/commands/serve.rs index 896bbc1b..567c35ef 100644 --- a/server/src/commands/serve.rs +++ b/server/src/commands/serve.rs @@ -7,7 +7,7 @@ use log::info; use failure::Fail; use crate::{ - project::{Project, ProjectLoadFuzzyError}, + project::{Project, ProjectLoadError}, web::LiveServer, imfs::FsError, live_session::{LiveSession, LiveSessionError}, @@ -24,7 +24,7 @@ pub struct ServeOptions { #[derive(Debug, Fail)] pub enum ServeError { #[fail(display = "Project load error: {}", _0)] - ProjectLoadError(#[fail(cause)] ProjectLoadFuzzyError), + ProjectLoadError(#[fail(cause)] ProjectLoadError), #[fail(display = "{}", _0)] FsError(#[fail(cause)] FsError), @@ -34,7 +34,7 @@ pub enum ServeError { } impl_from!(ServeError { - ProjectLoadFuzzyError => ProjectLoadError, + ProjectLoadError => ProjectLoadError, FsError => FsError, LiveSessionError => LiveSessionError, }); @@ -43,7 +43,6 @@ pub fn serve(options: &ServeOptions) -> Result<(), ServeError> { info!("Looking for project at {}", options.fuzzy_project_path.display()); let project = Arc::new(Project::load_fuzzy(&options.fuzzy_project_path)?); - project.check_compatibility(); info!("Found project at {}", project.file_location.display()); info!("Using project {:#?}", project); diff --git a/server/src/commands/upload.rs b/server/src/commands/upload.rs index 6c80485a..c8c0650c 100644 --- a/server/src/commands/upload.rs +++ b/server/src/commands/upload.rs @@ -10,7 +10,7 @@ use reqwest::header::{ACCEPT, USER_AGENT, CONTENT_TYPE, COOKIE}; use crate::{ imfs::{Imfs, FsError}, - project::{Project, ProjectLoadFuzzyError}, + project::{Project, ProjectLoadError}, rbx_session::construct_oneoff_tree, rbx_snapshot::SnapshotError, }; @@ -24,7 +24,7 @@ pub enum UploadError { InvalidKind(String), #[fail(display = "Project load error: {}", _0)] - ProjectLoadError(#[fail(cause)] ProjectLoadFuzzyError), + ProjectLoadError(#[fail(cause)] ProjectLoadError), #[fail(display = "IO error: {}", _0)] IoError(#[fail(cause)] io::Error), @@ -43,7 +43,7 @@ pub enum UploadError { } impl_from!(UploadError { - ProjectLoadFuzzyError => ProjectLoadError, + ProjectLoadError => ProjectLoadError, io::Error => IoError, reqwest::Error => HttpError, rbx_xml::EncodeError => XmlModelEncodeError, @@ -65,7 +65,6 @@ pub fn upload(options: &UploadOptions) -> Result<(), UploadError> { info!("Looking for project at {}", options.fuzzy_project_path.display()); let project = Project::load_fuzzy(&options.fuzzy_project_path)?; - project.check_compatibility(); info!("Found project at {}", project.file_location.display()); info!("Using project {:#?}", project); diff --git a/server/src/project.rs b/server/src/project.rs index 87361dd4..ae2662ec 100644 --- a/server/src/project.rs +++ b/server/src/project.rs @@ -197,34 +197,37 @@ impl SourcePlugin { } } -/// Error returned by Project::load_exact #[derive(Debug, Fail)] -pub enum ProjectLoadExactError { - #[fail(display = "IO error: {}", _0)] - IoError(#[fail(cause)] io::Error), - - #[fail(display = "JSON error: {}", _0)] - JsonError(#[fail(cause)] serde_json::Error), -} - -/// Error returned by Project::load_fuzzy -#[derive(Debug, Fail)] -pub enum ProjectLoadFuzzyError { - #[fail(display = "Project not found")] +pub enum ProjectLoadError { NotFound, - #[fail(display = "IO error: {}", _0)] - IoError(#[fail(cause)] io::Error), + Io { + #[fail(cause)] + inner: io::Error, + path: PathBuf, + }, - #[fail(display = "JSON error: {}", _0)] - JsonError(#[fail(cause)] serde_json::Error), + Json { + #[fail(cause)] + inner: serde_json::Error, + path: PathBuf, + }, } -impl From for ProjectLoadFuzzyError { - fn from(error: ProjectLoadExactError) -> ProjectLoadFuzzyError { - match error { - ProjectLoadExactError::IoError(inner) => ProjectLoadFuzzyError::IoError(inner), - ProjectLoadExactError::JsonError(inner) => ProjectLoadFuzzyError::JsonError(inner), +impl fmt::Display for ProjectLoadError { + fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + use self::ProjectLoadError::*; + + match self { + NotFound => { + write!(formatter, "Project file not found") + } + Io { inner, path } => { + write!(formatter, "I/O error: {} in path {}", inner, path.display()) + } + Json { inner, path } => { + write!(formatter, "JSON error: {} in path {}", inner, path.display()) + } } } } @@ -333,11 +336,17 @@ pub struct Project { impl Project { pub fn init_place(project_fuzzy_path: &Path) -> Result { - let project_path = Project::init_pick_path(project_fuzzy_path)?; + let project_path = Project::pick_path_for_init(project_fuzzy_path)?; + let project_name = if project_fuzzy_path == project_path { - project_fuzzy_path.parent().unwrap().file_name().unwrap().to_str().unwrap() + project_fuzzy_path + .parent().expect("Path did not have a parent directory") + .file_name().expect("Path did not have a file name") + .to_str().expect("Path had invalid Unicode") } else { - project_fuzzy_path.file_name().unwrap().to_str().unwrap() + project_fuzzy_path + .file_name().expect("Path did not have a file name") + .to_str().expect("Path had invalid Unicode") }; let mut project = Project::load_from_str(DEFAULT_PLACE, &project_path) @@ -352,14 +361,22 @@ impl Project { } pub fn init_model(project_fuzzy_path: &Path) -> Result { - let project_path = Project::init_pick_path(project_fuzzy_path)?; - let project_folder_path = project_path.parent().unwrap(); + let project_path = Project::pick_path_for_init(project_fuzzy_path)?; + let project_name = if project_fuzzy_path == project_path { - project_fuzzy_path.parent().unwrap().file_name().unwrap().to_str().unwrap() + project_fuzzy_path + .parent().expect("Path did not have a parent directory") + .file_name().expect("Path did not have a file name") + .to_str().expect("Path had invalid Unicode") } else { - project_fuzzy_path.file_name().unwrap().to_str().unwrap() + project_fuzzy_path + .file_name().expect("Path did not have a file name") + .to_str().expect("Path had invalid Unicode") }; + let project_folder_path = project_path + .parent().expect("Path did not have a parent directory"); + let tree = ProjectNode { path: Some(project_folder_path.join("src")), ..Default::default() @@ -380,7 +397,7 @@ impl Project { Ok(project_path) } - fn init_pick_path(project_fuzzy_path: &Path) -> Result { + fn pick_path_for_init(project_fuzzy_path: &Path) -> Result { let is_exact = project_fuzzy_path.extension().is_some(); let project_path = if is_exact { @@ -400,7 +417,7 @@ impl Project { Ok(project_path) } - pub fn locate(start_location: &Path) -> Option { + fn locate(start_location: &Path) -> Option { // TODO: Check for specific error kinds, convert 'not found' to Result. let location_metadata = fs::metadata(start_location).ok()?; @@ -437,26 +454,35 @@ impl Project { Ok(parsed.into_project(project_file_location)) } - pub fn load_fuzzy(fuzzy_project_location: &Path) -> Result { - let project_path = match Self::locate(fuzzy_project_location) { - Some(path) => path, - None => { - Project::warn_if_4x_project_present(fuzzy_project_location); - return Err(ProjectLoadFuzzyError::NotFound); - } - }; - - Self::load_exact(&project_path).map_err(From::from) + pub fn load_fuzzy(fuzzy_project_location: &Path) -> Result { + if let Some(project_path) = Self::locate(fuzzy_project_location) { + Self::load_exact(&project_path) + } else { + Project::warn_if_4x_project_present(fuzzy_project_location); + Err(ProjectLoadError::NotFound) + } } - pub fn load_exact(project_file_location: &Path) -> Result { + pub fn load_exact(project_file_location: &Path) -> Result { let contents = fs::read_to_string(project_file_location) - .map_err(ProjectLoadExactError::IoError)?; + .map_err(|error| match error.kind() { + io::ErrorKind::NotFound => ProjectLoadError::NotFound, + _ => ProjectLoadError::Io { + inner: error, + path: project_file_location.to_path_buf(), + } + })?; let parsed: SourceProject = serde_json::from_str(&contents) - .map_err(ProjectLoadExactError::JsonError)?; + .map_err(|error| ProjectLoadError::Json { + inner: error, + path: project_file_location.to_path_buf(), + })?; - Ok(parsed.into_project(project_file_location)) + let project = parsed.into_project(project_file_location); + project.check_compatibility(); + + Ok(project) } pub fn save(&self) -> Result<(), ProjectSaveError> { @@ -472,10 +498,10 @@ impl Project { /// Checks if there are any compatibility issues with this project file and /// warns the user if there are any. - pub fn check_compatibility(&self) { + fn check_compatibility(&self) { let file_name = self.file_location - .file_name().unwrap() - .to_str().expect("Project file path was not valid Unicode!"); + .file_name().expect("Project file path did not have a file name") + .to_str().expect("Project file path was not valid Unicode"); if file_name == COMPAT_PROJECT_FILENAME { warn!("Rojo's default project file name changed in 0.5.0-alpha3."); diff --git a/test-projects/legacy/rojo.json b/test-projects/legacy-0.4.x/rojo.json similarity index 100% rename from test-projects/legacy/rojo.json rename to test-projects/legacy-0.4.x/rojo.json diff --git a/test-projects/legacy-old-0.5.x/roblox-project.json b/test-projects/legacy-old-0.5.x/roblox-project.json new file mode 100644 index 00000000..4fcf72e3 --- /dev/null +++ b/test-projects/legacy-old-0.5.x/roblox-project.json @@ -0,0 +1,6 @@ +{ + "name": "Foo", + "tree": { + "$className": "Folder" + } +} \ No newline at end of file