Skip to content

Commit

Permalink
chore(libscoop): added more doc comments
Browse files Browse the repository at this point in the history
Signed-off-by: Chawye Hsu <[email protected]>
  • Loading branch information
chawyehsu committed Jul 25, 2023
1 parent 0e296ea commit c114dc3
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 31 deletions.
76 changes: 67 additions & 9 deletions crates/libscoop/src/bucket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,19 @@ use crate::{
internal::git,
};

/// Scoop bucket representation.
///
/// A fact about Scoop bucket is that it is just a folder containing package
/// manifest files in JSON format. It could be simply a local directory or a
/// git repository.
#[derive(Clone, Debug)]
pub struct Bucket {
/// The local path of the bucket.
path: PathBuf,

/// The name of the bucket.
name: String,

/// The remote subscription url of the bucket.
///
/// A Scoop bucket is generally a subscription to a remote git repository,
Expand All @@ -19,9 +28,12 @@ pub struct Bucket {
/// Non-git bucket is also supported by Scoop, mostly it is a local directory
/// which does not have a remote url, and bucket update is not supported.
remote_url: Option<String>,

/// The directory type of the bucket.
dtype: BucketDirectoryType,
}

/// Bucket directory type.
#[derive(Clone, Copy, Debug)]
#[non_exhaustive]
pub enum BucketDirectoryType {
Expand All @@ -35,7 +47,15 @@ pub enum BucketDirectoryType {

impl Bucket {
/// Create a bucket representation from a given local path.
#[inline]
///
/// # Returns
///
/// A bucket representation.
///
/// # Errors
///
/// This method will return an error if the given path does not exist. I/O
/// errors will be returned if the bucket directory is not readable.
pub fn from(path: &Path) -> Fallible<Bucket> {
let path = path.to_owned();
let name = path
Expand All @@ -48,17 +68,23 @@ impl Bucket {

let mut remote_url = None;
if path.is_dir() && path.join(".git").exists() {
remote_url = git::remote_url_of(path.as_path(), "origin")?;
let check_git = git::remote_url_of(path.as_path(), "origin");

if let Ok(some) = check_git {
remote_url = some;
}
}

let nested_dir = path.join("bucket");
let dtype = match nested_dir.exists() {
let is_nested = nested_dir.exists() && nested_dir.is_dir();
let dtype = match is_nested {
false => BucketDirectoryType::V1,
true => {
let mut dtype = BucketDirectoryType::V2;
let entries = nested_dir.read_dir()?;

for entry in entries.flatten() {
// assume it's a v3 bucket if there is any subdirectory
if entry.path().is_dir() {
dtype = BucketDirectoryType::V3;
break;
Expand Down Expand Up @@ -90,14 +116,25 @@ impl Bucket {
}

/// Get the repository url of the bucket.
///
/// # Returns
///
/// The remote url of the bucket, none if the bucket is not a git repository
/// or it is a local git repository without remote url, or the git metadata
/// is broken.
#[inline]
pub fn remote_url(&self) -> Option<&str> {
self.remote_url.as_deref()
}

pub fn path_of_manifest(&self, name: &str) -> PathBuf {
/// Get the manifest path of the given package name.
///
/// # Returns
///
/// The path of the manifest file, none if the package is not in the bucket.
pub fn path_of_manifest(&self, name: &str) -> Option<PathBuf> {
let filename = format!("{}.json", name);
match self.dtype {
let path = match self.dtype {
BucketDirectoryType::V1 => self.path.join(filename),
BucketDirectoryType::V2 => {
let mut path = self.path.join("bucket");
Expand All @@ -117,12 +154,24 @@ impl Bucket {
path.push(filename);
path
}
};

if path.exists() {
Some(path)
} else {
None
}
}

/// Get manifests from the bucket.
///
/// Returns a list of PathBufs of these manifest files.
/// # Returns
///
/// a list of PathBufs of manifest files.
///
/// # Errors
///
/// I/O errors will be returned if the bucket directory is not readable.
pub fn manifests(&self) -> Fallible<Vec<PathBuf>> {
let json_files = match self.dtype {
BucketDirectoryType::V1 => {
Expand All @@ -133,7 +182,8 @@ impl Bucket {
.filter(|de| {
let path = de.path();
let name = path.file_name().unwrap().to_str().unwrap();
// Ignore npm package config file
// Ignore npm package config file, that said, there will
// be no package named `package`, it's a reserved name.
path.is_file() && name.ends_with(".json") && name != "package.json"
})
.map(|de| de.path())
Expand All @@ -147,7 +197,7 @@ impl Bucket {
.filter(|de| {
let path = de.path();
let name = path.file_name().unwrap().to_str().unwrap();
path.is_file() && name.ends_with(".json")
path.is_file() && name.ends_with(".json") && name != "package.json"
})
.map(|de| de.path())
.collect::<Vec<_>>()
Expand All @@ -171,7 +221,7 @@ impl Bucket {
.filter(|de| {
let path = de.path();
let name = path.file_name().unwrap().to_str().unwrap();
path.is_file() && name.ends_with(".json")
path.is_file() && name.ends_with(".json") && name != "package.json"
})
.map(|de| de.path())
.collect::<Vec<_>>();
Expand All @@ -185,6 +235,14 @@ impl Bucket {
}

/// Get manifest count of the bucket.
///
/// # Returns
///
/// The count of manifests.
///
/// # Errors
///
/// I/O errors will be returned if the bucket directory is not readable.
#[inline]
pub fn manifest_count(&self) -> Fallible<usize> {
Ok(self.manifests()?.len())
Expand Down
9 changes: 5 additions & 4 deletions crates/libscoop/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,14 @@ impl Config {
true => self.use_external_7zip = None,
false => match value.parse::<bool>() {
Ok(value) => self.use_external_7zip = Some(value),
Err(_) => return Err(Error::InvalidConfigValue(value.to_owned())),
Err(_) => return Err(Error::ConfigValueInvalid(value.to_owned())),
},
},
"aria2_enabled" | "aria2-enabled" => match is_unset {
true => self.aria2_enabled = None,
false => match value.parse::<bool>() {
Ok(value) => self.aria2_enabled = Some(value),
Err(_) => return Err(Error::InvalidConfigValue(value.to_owned())),
Err(_) => return Err(Error::ConfigValueInvalid(value.to_owned())),
},
},
"cat_style" => {
Expand All @@ -178,14 +178,14 @@ impl Config {
true => self.use_lessmsi = None,
false => match value.parse::<bool>() {
Ok(value) => self.use_lessmsi = Some(value),
Err(_) => return Err(Error::InvalidConfigValue(value.to_owned())),
Err(_) => return Err(Error::ConfigValueInvalid(value.to_owned())),
},
},
"proxy" => match value {
"" | "none" => self.proxy = None,
_ => self.proxy = Some(value.to_string()),
},
key => return Err(Error::InvalidConfigKey(key.to_owned())),
key => return Err(Error::ConfigKeyInvalid(key.to_owned())),
}

self.commit()
Expand All @@ -196,6 +196,7 @@ impl Config {
write_json(&self.config_path, self)
}

/// Pretty print the config
pub(crate) fn pretty(&self) -> Fallible<String> {
Ok(serde_json::to_string_pretty(self)?)
}
Expand Down
24 changes: 15 additions & 9 deletions crates/libscoop/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub type Fallible<T> = Result<T, Error>;
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum Error {
/// Thrown when trying to add a bucket that already exists.
#[error("bucket '{0}' already exists")]
BucketAlreadyExists(String),

Expand All @@ -22,13 +23,18 @@ pub enum Error {
#[error("bare bucket '{0}' is no longer supported")]
BareBucketFound(String),

/// A custom error.
#[error("{0}")]
Custom(String),

/// Thrown when trying to mutate config while it is in use.
#[error("Could not alter config because it is in use.")]
ConfigInUse,

/// Invalid config key error
#[error("invalid config key '{0}'")]
ConfigKeyInvalid(String),

/// Invalid config value error
#[error("invalid config value '{0}'")]
ConfigValueInvalid(String),

/// Thrown when trying to set the user agent twice.
#[error("User agent already set")]
UserAgentAlreadySet,
Expand All @@ -40,11 +46,6 @@ pub enum Error {
#[error("error")]
InvalidCacheFile { path: PathBuf },

#[error("invalid config key '{0}'")]
InvalidConfigKey(String),
#[error("invalid config value '{0}'")]
InvalidConfigValue(String),

#[error("error")]
InvalidHashValue(String),

Expand All @@ -57,6 +58,7 @@ pub enum Error {
#[error("Could not find package named '{0}'")]
PackageNotFound(String),

/// Thrown when there are multiple candidates for a package name.
#[error("Found multiple candidates for package named '{0}'")]
PackageMultipleCandidates(String),

Expand All @@ -70,6 +72,10 @@ pub enum Error {
#[error("package '{0}' is broken")]
PackageHoldBrokenInstall(String),

/// A custom error.
#[error("{0}")]
Custom(String),

/// Cycle dependency error
#[error(transparent)]
CyclicDependency(#[from] CyclicError),
Expand Down
Loading

0 comments on commit c114dc3

Please sign in to comment.