Skip to content

Commit b4a6bf5

Browse files
Merge pull request #6 from thunderstore-io/TS-2038/improve-proj-init-errs
[TS-2038] Introduce simplistic project validation
2 parents 3d1c4df + c967aad commit b4a6bf5

File tree

1 file changed

+36
-7
lines changed

1 file changed

+36
-7
lines changed

src/project/mod.rs

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,20 +51,49 @@ pub struct Project {
5151
}
5252

5353
impl Project {
54-
pub fn open(project_dir: &Path) -> Result<Self, Error> {
55-
// TODO: Validate that the following paths exist.
56-
let project_dir = project_dir.canonicalize()?;
57-
let project = Project {
54+
/// Open the directory as a project but perform no additional tasks.
55+
pub fn open_unchecked(project_dir: &Path) -> Self {
56+
Self {
5857
base_dir: project_dir.to_path_buf(),
5958
state_dir: project_dir.join(".tcli/project_state"),
6059
staging_dir: project_dir.join(".tcli/staging"),
6160
manifest_path: project_dir.join("Thunderstore.toml"),
6261
lockfile_path: project_dir.join("Thunderstore.lock"),
6362
game_registry_path: project_dir.join(".tcli/game_registry.json"),
6463
statefile_path: project_dir.join(".tcli/state.json"),
65-
};
64+
}
65+
}
6666

67-
let pid_files = proc::get_pid_files(&project_dir.join(".tcli"))?;
67+
/// Open the directory as a project, performing validation and housekeeping tasks.
68+
pub fn open(project_dir: &Path) -> Result<Self, Error> {
69+
// TODO: Validate that the following paths exist.
70+
let project = Project::open_unchecked(project_dir);
71+
project.validate()?;
72+
project.prune_pids()?;
73+
74+
Ok(project)
75+
}
76+
77+
/// Validate that the project's state is correct and in working order.
78+
pub fn validate(&self) -> Result<(), Error> {
79+
// A directory without a manifest is *not* a project.
80+
if !self.manifest_path.is_file() {
81+
Err(Error::NoProjectFile(self.manifest_path.to_path_buf()))?;
82+
}
83+
84+
// Everything within .tcli is assumed to be replacable. Therefore we only care
85+
// about whether or not .tcli itself exists.
86+
let dotdir = self.base_dir.join(".tcli");
87+
if !dotdir.is_dir() {
88+
fs::create_dir(dotdir)?;
89+
}
90+
91+
Ok(())
92+
}
93+
94+
/// Prune pid files that refer to processes that no longer exist.
95+
pub fn prune_pids(&self) -> Result<(), Error> {
96+
let pid_files = proc::get_pid_files(&self.base_dir.join(".tcli"))?;
6897
let pid_files = pid_files
6998
.iter()
7099
.filter_map(|x| fs::read_to_string(x).map(|inner| (x, inner)).ok())
@@ -79,7 +108,7 @@ impl Project {
79108
fs::remove_file(pid_file)?;
80109
}
81110

82-
Ok(project)
111+
Ok(())
83112
}
84113

85114
/// Create a new project within the given directory.

0 commit comments

Comments
 (0)