Add package.json discovery

This commit is contained in:
SkyfallWasTaken 2024-07-09 21:16:17 +01:00
parent 7117a31926
commit 450e02e54b
5 changed files with 54 additions and 6 deletions

View file

@ -9,4 +9,6 @@ color-eyre = "0.6.3"
owo-colors = "4.0.0" owo-colors = "4.0.0"
reqwest = "0.12.5" reqwest = "0.12.5"
tokio = { version = "1.38.0", features = ["macros", "rt-multi-thread"] } tokio = { version = "1.38.0", features = ["macros", "rt-multi-thread"] }
dinopkg-package-json = { path = "../dinopkg-package-json" } dinopkg-package-json = { path = "../dinopkg-package-json", features = [
"tokio",
] }

View file

@ -1,3 +1,8 @@
use color_eyre::Result;
use dinopkg_package_json::PackageJson; use dinopkg_package_json::PackageJson;
pub async fn run(script_name: Option<String>) {} pub async fn run(script_name: Option<String>) -> Result<()> {
let package_json = PackageJson::from_file(10).await?;
println!("Running script: {:?} {}", script_name, package_json.name);
Ok(())
}

View file

@ -1,12 +1,14 @@
use clap::Parser; use clap::Parser;
mod command; mod command;
use color_eyre::Result;
use command::{Cli, Command}; use command::{Cli, Command};
#[tokio::main] #[tokio::main]
async fn main() { async fn main() -> Result<()> {
let cli = Cli::parse(); let cli = Cli::parse();
match cli.command { match cli.command {
Command::Run { script_name } => command::run::run(script_name).await, Command::Run { script_name } => command::run::run(script_name).await?,
} }
Ok(())
} }

View file

@ -2,6 +2,8 @@ use std::collections::HashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
mod util;
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct PackageJson { pub struct PackageJson {
@ -21,6 +23,18 @@ pub type Dependencies = HashMap<String, String>;
pub enum Error { pub enum Error {
#[error("deserialization error: {0}")] #[error("deserialization error: {0}")]
Serde(#[from] serde_json::Error), 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 { impl PackageJson {
@ -29,8 +43,12 @@ impl PackageJson {
} }
#[cfg(feature = "tokio")] #[cfg(feature = "tokio")]
pub async fn from_file() -> Result<Self, Error> { pub async fn from_file(max_attempts: usize) -> Result<Self, Error> {
let file = tokio::fs::read("package.json").await?; 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)?; let file = String::from_utf8(file)?;
Self::parse(&file) Self::parse(&file)
} }

View 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)
}