Refactor project to start making a little more sense

This commit is contained in:
Lucien Greathouse
2019-06-12 15:11:19 -07:00
parent c77c754f6d
commit 90516e035d
6 changed files with 89 additions and 60 deletions

View File

@@ -9,7 +9,7 @@ use failure::Fail;
use crate::{ use crate::{
imfs::{Imfs, FsError}, imfs::{Imfs, FsError},
project::{Project, ProjectLoadFuzzyError}, project::{Project, ProjectLoadError},
rbx_session::construct_oneoff_tree, rbx_session::construct_oneoff_tree,
rbx_snapshot::SnapshotError, rbx_snapshot::SnapshotError,
}; };
@@ -47,7 +47,7 @@ pub enum BuildError {
UnknownOutputKind, UnknownOutputKind,
#[fail(display = "Project load error: {}", _0)] #[fail(display = "Project load error: {}", _0)]
ProjectLoadError(#[fail(cause)] ProjectLoadFuzzyError), ProjectLoadError(#[fail(cause)] ProjectLoadError),
#[fail(display = "IO error: {}", _0)] #[fail(display = "IO error: {}", _0)]
IoError(#[fail(cause)] io::Error), IoError(#[fail(cause)] io::Error),
@@ -66,7 +66,7 @@ pub enum BuildError {
} }
impl_from!(BuildError { impl_from!(BuildError {
ProjectLoadFuzzyError => ProjectLoadError, ProjectLoadError => ProjectLoadError,
io::Error => IoError, io::Error => IoError,
rbx_xml::EncodeError => XmlModelEncodeError, rbx_xml::EncodeError => XmlModelEncodeError,
rbx_binary::EncodeError => BinaryModelEncodeError, 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()); info!("Looking for project at {}", options.fuzzy_project_path.display());
let project = Project::load_fuzzy(&options.fuzzy_project_path)?; let project = Project::load_fuzzy(&options.fuzzy_project_path)?;
project.check_compatibility();
info!("Found project at {}", project.file_location.display()); info!("Found project at {}", project.file_location.display());
info!("Using project {:#?}", project); info!("Using project {:#?}", project);

View File

@@ -7,7 +7,7 @@ use log::info;
use failure::Fail; use failure::Fail;
use crate::{ use crate::{
project::{Project, ProjectLoadFuzzyError}, project::{Project, ProjectLoadError},
web::LiveServer, web::LiveServer,
imfs::FsError, imfs::FsError,
live_session::{LiveSession, LiveSessionError}, live_session::{LiveSession, LiveSessionError},
@@ -24,7 +24,7 @@ pub struct ServeOptions {
#[derive(Debug, Fail)] #[derive(Debug, Fail)]
pub enum ServeError { pub enum ServeError {
#[fail(display = "Project load error: {}", _0)] #[fail(display = "Project load error: {}", _0)]
ProjectLoadError(#[fail(cause)] ProjectLoadFuzzyError), ProjectLoadError(#[fail(cause)] ProjectLoadError),
#[fail(display = "{}", _0)] #[fail(display = "{}", _0)]
FsError(#[fail(cause)] FsError), FsError(#[fail(cause)] FsError),
@@ -34,7 +34,7 @@ pub enum ServeError {
} }
impl_from!(ServeError { impl_from!(ServeError {
ProjectLoadFuzzyError => ProjectLoadError, ProjectLoadError => ProjectLoadError,
FsError => FsError, FsError => FsError,
LiveSessionError => LiveSessionError, LiveSessionError => LiveSessionError,
}); });
@@ -43,7 +43,6 @@ pub fn serve(options: &ServeOptions) -> Result<(), ServeError> {
info!("Looking for project at {}", options.fuzzy_project_path.display()); info!("Looking for project at {}", options.fuzzy_project_path.display());
let project = Arc::new(Project::load_fuzzy(&options.fuzzy_project_path)?); let project = Arc::new(Project::load_fuzzy(&options.fuzzy_project_path)?);
project.check_compatibility();
info!("Found project at {}", project.file_location.display()); info!("Found project at {}", project.file_location.display());
info!("Using project {:#?}", project); info!("Using project {:#?}", project);

View File

@@ -10,7 +10,7 @@ use reqwest::header::{ACCEPT, USER_AGENT, CONTENT_TYPE, COOKIE};
use crate::{ use crate::{
imfs::{Imfs, FsError}, imfs::{Imfs, FsError},
project::{Project, ProjectLoadFuzzyError}, project::{Project, ProjectLoadError},
rbx_session::construct_oneoff_tree, rbx_session::construct_oneoff_tree,
rbx_snapshot::SnapshotError, rbx_snapshot::SnapshotError,
}; };
@@ -24,7 +24,7 @@ pub enum UploadError {
InvalidKind(String), InvalidKind(String),
#[fail(display = "Project load error: {}", _0)] #[fail(display = "Project load error: {}", _0)]
ProjectLoadError(#[fail(cause)] ProjectLoadFuzzyError), ProjectLoadError(#[fail(cause)] ProjectLoadError),
#[fail(display = "IO error: {}", _0)] #[fail(display = "IO error: {}", _0)]
IoError(#[fail(cause)] io::Error), IoError(#[fail(cause)] io::Error),
@@ -43,7 +43,7 @@ pub enum UploadError {
} }
impl_from!(UploadError { impl_from!(UploadError {
ProjectLoadFuzzyError => ProjectLoadError, ProjectLoadError => ProjectLoadError,
io::Error => IoError, io::Error => IoError,
reqwest::Error => HttpError, reqwest::Error => HttpError,
rbx_xml::EncodeError => XmlModelEncodeError, 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()); info!("Looking for project at {}", options.fuzzy_project_path.display());
let project = Project::load_fuzzy(&options.fuzzy_project_path)?; let project = Project::load_fuzzy(&options.fuzzy_project_path)?;
project.check_compatibility();
info!("Found project at {}", project.file_location.display()); info!("Found project at {}", project.file_location.display());
info!("Using project {:#?}", project); info!("Using project {:#?}", project);

View File

@@ -197,34 +197,37 @@ impl SourcePlugin {
} }
} }
/// Error returned by Project::load_exact
#[derive(Debug, Fail)] #[derive(Debug, Fail)]
pub enum ProjectLoadExactError { pub enum ProjectLoadError {
#[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")]
NotFound, NotFound,
#[fail(display = "IO error: {}", _0)] Io {
IoError(#[fail(cause)] io::Error), #[fail(cause)]
inner: io::Error,
path: PathBuf,
},
#[fail(display = "JSON error: {}", _0)] Json {
JsonError(#[fail(cause)] serde_json::Error), #[fail(cause)]
inner: serde_json::Error,
path: PathBuf,
},
} }
impl From<ProjectLoadExactError> for ProjectLoadFuzzyError { impl fmt::Display for ProjectLoadError {
fn from(error: ProjectLoadExactError) -> ProjectLoadFuzzyError { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match error { use self::ProjectLoadError::*;
ProjectLoadExactError::IoError(inner) => ProjectLoadFuzzyError::IoError(inner),
ProjectLoadExactError::JsonError(inner) => ProjectLoadFuzzyError::JsonError(inner), 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 { impl Project {
pub fn init_place(project_fuzzy_path: &Path) -> Result<PathBuf, ProjectInitError> { pub fn init_place(project_fuzzy_path: &Path) -> Result<PathBuf, ProjectInitError> {
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 { 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 { } 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) 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<PathBuf, ProjectInitError> { pub fn init_model(project_fuzzy_path: &Path) -> Result<PathBuf, ProjectInitError> {
let project_path = Project::init_pick_path(project_fuzzy_path)?; let project_path = Project::pick_path_for_init(project_fuzzy_path)?;
let project_folder_path = project_path.parent().unwrap();
let project_name = if project_fuzzy_path == project_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 { } 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 { let tree = ProjectNode {
path: Some(project_folder_path.join("src")), path: Some(project_folder_path.join("src")),
..Default::default() ..Default::default()
@@ -380,7 +397,7 @@ impl Project {
Ok(project_path) Ok(project_path)
} }
fn init_pick_path(project_fuzzy_path: &Path) -> Result<PathBuf, ProjectInitError> { fn pick_path_for_init(project_fuzzy_path: &Path) -> Result<PathBuf, ProjectInitError> {
let is_exact = project_fuzzy_path.extension().is_some(); let is_exact = project_fuzzy_path.extension().is_some();
let project_path = if is_exact { let project_path = if is_exact {
@@ -400,7 +417,7 @@ impl Project {
Ok(project_path) Ok(project_path)
} }
pub fn locate(start_location: &Path) -> Option<PathBuf> { fn locate(start_location: &Path) -> Option<PathBuf> {
// TODO: Check for specific error kinds, convert 'not found' to Result. // TODO: Check for specific error kinds, convert 'not found' to Result.
let location_metadata = fs::metadata(start_location).ok()?; let location_metadata = fs::metadata(start_location).ok()?;
@@ -437,26 +454,35 @@ impl Project {
Ok(parsed.into_project(project_file_location)) Ok(parsed.into_project(project_file_location))
} }
pub fn load_fuzzy(fuzzy_project_location: &Path) -> Result<Project, ProjectLoadFuzzyError> { pub fn load_fuzzy(fuzzy_project_location: &Path) -> Result<Project, ProjectLoadError> {
let project_path = match Self::locate(fuzzy_project_location) { if let Some(project_path) = Self::locate(fuzzy_project_location) {
Some(path) => path, Self::load_exact(&project_path)
None => { } else {
Project::warn_if_4x_project_present(fuzzy_project_location); Project::warn_if_4x_project_present(fuzzy_project_location);
return Err(ProjectLoadFuzzyError::NotFound); Err(ProjectLoadError::NotFound)
} }
};
Self::load_exact(&project_path).map_err(From::from)
} }
pub fn load_exact(project_file_location: &Path) -> Result<Project, ProjectLoadExactError> { pub fn load_exact(project_file_location: &Path) -> Result<Project, ProjectLoadError> {
let contents = fs::read_to_string(project_file_location) 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) 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> { pub fn save(&self) -> Result<(), ProjectSaveError> {
@@ -472,10 +498,10 @@ impl Project {
/// Checks if there are any compatibility issues with this project file and /// Checks if there are any compatibility issues with this project file and
/// warns the user if there are any. /// warns the user if there are any.
pub fn check_compatibility(&self) { fn check_compatibility(&self) {
let file_name = self.file_location let file_name = self.file_location
.file_name().unwrap() .file_name().expect("Project file path did not have a file name")
.to_str().expect("Project file path was not valid Unicode!"); .to_str().expect("Project file path was not valid Unicode");
if file_name == COMPAT_PROJECT_FILENAME { if file_name == COMPAT_PROJECT_FILENAME {
warn!("Rojo's default project file name changed in 0.5.0-alpha3."); warn!("Rojo's default project file name changed in 0.5.0-alpha3.");

View File

@@ -0,0 +1,6 @@
{
"name": "Foo",
"tree": {
"$className": "Folder"
}
}