mirror of
https://github.com/SkyfallWasTaken/dinopkg.git
synced 2025-05-22 06:53:06 +00:00
Add package.json discovery
This commit is contained in:
parent
7117a31926
commit
450e02e54b
5 changed files with 54 additions and 6 deletions
|
@ -2,6 +2,8 @@ use std::collections::HashMap;
|
|||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
mod util;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PackageJson {
|
||||
|
@ -21,6 +23,18 @@ pub type Dependencies = HashMap<String, String>;
|
|||
pub enum Error {
|
||||
#[error("deserialization error: {0}")]
|
||||
Serde(#[from] serde_json::Error),
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
#[error("package.json not found")]
|
||||
NotFound,
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
#[error("I/O error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
#[error("file is invalid utf-8")]
|
||||
Utf8(#[from] std::string::FromUtf8Error),
|
||||
}
|
||||
|
||||
impl PackageJson {
|
||||
|
@ -29,8 +43,12 @@ impl PackageJson {
|
|||
}
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
pub async fn from_file() -> Result<Self, Error> {
|
||||
let file = tokio::fs::read("package.json").await?;
|
||||
pub async fn from_file(max_attempts: usize) -> Result<Self, Error> {
|
||||
let path = util::find_package_json(max_attempts).await?;
|
||||
let Some(path) = path else {
|
||||
return Err(Error::NotFound);
|
||||
};
|
||||
let file = tokio::fs::read(path).await?;
|
||||
let file = String::from_utf8(file)?;
|
||||
Self::parse(&file)
|
||||
}
|
||||
|
|
21
crates/dinopkg-package-json/src/util.rs
Normal file
21
crates/dinopkg-package-json/src/util.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use tokio::fs;
|
||||
|
||||
use crate::Error;
|
||||
|
||||
#[cfg(feature = "tokio")]
|
||||
pub async fn find_package_json(max_attempts: usize) -> Result<Option<PathBuf>, Error> {
|
||||
let mut current_dir = env::current_dir()?;
|
||||
for _ in 0..max_attempts {
|
||||
let package_json_path = current_dir.join("package.json");
|
||||
if fs::metadata(&package_json_path).await.is_ok() {
|
||||
return Ok(Some(package_json_path));
|
||||
}
|
||||
if !current_dir.pop() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue