summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cli.rs18
-rw-r--r--src/commands/source.rs55
-rw-r--r--src/repository/repository.rs30
-rw-r--r--src/source/mod.rs24
4 files changed, 103 insertions, 24 deletions
diff --git a/src/cli.rs b/src/cli.rs
index f2f5bf0..e797079 100644
--- a/src/cli.rs
+++ b/src/cli.rs
@@ -701,6 +701,24 @@ pub fn cli<'a>() -> App<'a> {
.about("Overwrite existing cache entry")
)
)
+ .subcommand(App::new("of")
+ .version(crate_version!())
+ .about("Get the pathes of the sources of a package")
+ .arg(Arg::new("package_name")
+ .required(false)
+ .multiple(false)
+ .index(1)
+ .value_name("PKG")
+ .about("Get the source file pathes for this package")
+ )
+ .arg(Arg::new("package_version")
+ .required(false)
+ .multiple(false)
+ .index(2)
+ .value_name("VERSION")
+ .about("Get the source file pathes for the package in this version")
+ )
+ )
)
.subcommand(App::new("release")
diff --git a/src/commands/source.rs b/src/commands/source.rs
index 7f4a1bb..792c036 100644
--- a/src/commands/source.rs
+++ b/src/commands/source.rs
@@ -42,6 +42,7 @@ pub async fn source(
Some(("list-missing", matches)) => list_missing(matches, config, repo).await,
Some(("url", matches)) => url(matches, repo).await,
Some(("download", matches)) => download(matches, config, repo, progressbars).await,
+ Some(("of", matches)) => of(matches, config, repo).await,
Some((other, _)) => return Err(anyhow!("Unknown subcommand: {}", other)),
None => return Err(anyhow!("No subcommand")),
}
@@ -154,7 +155,7 @@ pub async fn list_missing(_: &ArgMatches, config: &Configuration, repo: Reposito
repo.packages().try_for_each(|p| {
for source in sc.sources_for(p) {
- if !source.exists() {
+ if !source.path().exists() {
writeln!(
outlock,
"{} {} -> {}",
@@ -244,7 +245,8 @@ pub async fn download(
let bar = multi.add(progressbars.spinner());
bar.set_message(&format!("Downloading {}", source.url()));
async move {
- if !source.exists() && source.download_manually() {
+ let source_path_exists = source.path().exists();
+ if !source_path_exists && source.download_manually() {
return Err(anyhow!(
"Cannot download source that is marked for manual download"
))
@@ -253,10 +255,10 @@ pub async fn download(
.map_err(Error::from);
}
- if source.exists() && !force {
+ if source_path_exists && !force {
Err(anyhow!("Source exists: {}", source.path().display()))
} else {
- if source.exists() {
+ if source_path_exists {
let _ = source.remove_file().await?;
}
@@ -306,3 +308,48 @@ pub async fn download(
let (r, _) = tokio::join!(r, multibar_block);
r
}
+
+async fn of(
+ matches: &ArgMatches,
+ config: &Configuration,
+ repo: Repository,
+) -> Result<()> {
+ let cache = PathBuf::from(config.source_cache_root());
+ let sc = SourceCache::new(cache);
+ let pname = matches
+ .value_of("package_name")
+ .map(String::from)
+ .map(PackageName::from);
+ let pvers = matches
+ .value_of("package_version")
+ .map(PackageVersionConstraint::try_from)
+ .transpose()?;
+
+ repo.packages()
+ .filter(|p| pname.as_ref().map(|n| p.name() == n).unwrap_or(true))
+ .filter(|p| {
+ pvers
+ .as_ref()
+ .map(|v| v.matches(p.version()))
+ .unwrap_or(true)
+ })
+ .map(|p| {
+ let pathes = sc.sources_for(p)
+ .into_iter()
+ .map(|source| source.path())
+ .collect::<Vec<PathBuf>>();
+
+ (p, pathes)
+ })
+ .fold(Ok(std::io::stdout()), |out, (package, pathes)| {
+ out.and_then(|mut out| {
+ writeln!(out, "{} {}", package.name(), package.version())?;
+ for path in pathes {
+ writeln!(out, "\t{}", path.display())?;
+ }
+
+ Ok(out)
+ })
+ })
+ .map(|_| ())
+}
diff --git a/src/repository/repository.rs b/src/repository/repository.rs
index e01c28f..170c2b0 100644
--- a/src/repository/repository.rs
+++ b/src/repository/repository.rs
@@ -18,6 +18,7 @@ use anyhow::Error;
use anyhow::Result;
use log::trace;
use resiter::AndThen;
+use resiter::FilterMap;
use resiter::Map;
use crate::package::Package;
@@ -107,7 +108,16 @@ impl Repository {
// This is either the patches array from the last recursion or the newly set one,
// that doesn't matter here.
let patches_before_merge = match config.get_array("patches") {
- Ok(v) => v,
+ Ok(v) => {
+ v.into_iter()
+ .map(|p| {
+ p.into_str()
+ .map(PathBuf::from)
+ .with_context(|| anyhow!("patches must be strings"))
+ .map_err(Error::from)
+ })
+ .collect::<Result<Vec<_>>>()?
+ },
Err(config::ConfigError::NotFound(_)) => vec![],
Err(e) => return Err(e).map_err(Error::from),
};
@@ -145,22 +155,34 @@ impl Repository {
// Otherwise we have an error here, because we're refering to a non-existing file.
.and_then_ok(|patch| if patch.exists() {
trace!("Path to patch exists: {}", patch.display());
- Ok(config::Value::from(patch.display().to_string()))
+ Ok(Some(patch))
+ } else if patches_before_merge.iter().any(|pb| pb.file_name() == patch.file_name()) {
+ // We have a patch already in the array that is named equal to the patch
+ // we have in the current recursion.
+ // It seems like this patch was already in the list and we re-found it
+ // because we loaded a deeper pkg.toml file.
+ Ok(None)
} else {
trace!("Path to patch does not exist: {}", patch.display());
Err(anyhow!("Patch does not exist: {}", patch.display()))
})
+ .filter_map_ok(|o| o)
.collect::<Result<Vec<_>>>()?;
// If we found any patches, use them. Otherwise use the array from before the merge
// (which already has the correct pathes from the previous recursion).
- let patches = if !patches.is_empty() {
+ let patches = if !patches.is_empty() && patches.iter().all(|p| p.exists()) {
patches
} else {
patches_before_merge
};
trace!("Patches after postprocessing merge: {:?}", patches);
+ let patches = patches
+ .into_iter()
+ .map(|p| p.display().to_string())
+ .map(config::Value::from)
+ .collect::<Vec<_>>();
config.set_once("patches", config::Value::from(patches))?;
}
@@ -191,7 +213,7 @@ impl Repository {
vec.and_then(|mut v| {
trace!("Recursing into {}", dir.display());
let mut loaded = load_recursive(root, &dir, config.clone(), progress)
- .with_context(|| format!("Recursing for {}", pkg_file.display()))?;
+ .with_context(|| format!("Reading package from {}", pkg_file.display()))?;
v.append(&mut loaded);
Ok(v)
diff --git a/src/source/mod.rs b/src/source/mod.rs
index ec0e2e2..7b84c30 100644
--- a/src/source/mod.rs
+++ b/src/source/mod.rs
@@ -47,14 +47,6 @@ pub struct SourceEntry {
}
impl SourceEntry {
- fn source_file_path(&self) -> PathBuf {
- self.source_file_directory().join(format!(
- "{}-{}.source",
- self.package_source_name,
- self.package_source.hash().value()
- ))
- }
-
fn source_file_directory(&self) -> PathBuf {
self.cache_root
.join(format!("{}-{}", self.package_name, self.package_version))
@@ -75,12 +67,12 @@ impl SourceEntry {
.collect()
}
- pub fn exists(&self) -> bool {
- self.source_file_path().exists()
- }
-
pub fn path(&self) -> PathBuf {
- self.source_file_path()
+ self.source_file_directory().join(format!(
+ "{}-{}.source",
+ self.package_source_name,
+ self.package_source.hash().value()
+ ))
}
pub fn url(&self) -> &Url {
@@ -92,13 +84,13 @@ impl SourceEntry {
}
pub async fn remove_file(&self) -> Result<()> {
- let p = self.source_file_path();
+ let p = self.path();
tokio::fs::remove_file(&p).await?;
Ok(())
}
pub async fn verify_hash(&self) -> Result<()> {
- let p = self.source_file_path();
+ let p = self.path();
trace!("Verifying : {}", p.display());
let reader = tokio::fs::OpenOptions::new()
@@ -118,7 +110,7 @@ impl SourceEntry {
}
pub async fn create(&self) -> Result<tokio::fs::File> {
- let p = self.source_file_path();
+ let p = self.path();
trace!("Creating source file: {}", p.display());
if !self.cache_root.is_dir() {