Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flag to follow refs in info command #994

Merged
merged 1 commit into from
Mar 13, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 26 additions & 21 deletions crates/spfs-cli/main/src/cmd_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
// https://github.com/imageworks/spk

use std::collections::VecDeque;

use clap::Args;
use colored::*;
use miette::Result;
Expand Down Expand Up @@ -40,31 +42,36 @@ pub struct CmdInfo {
/// Use shortened digests in the output (nicer, but slower)
#[clap(long)]
short: bool,

/// Follow and show child objects, depth-first
#[clap(long)]
follow: bool,

/// Remaining refs to process, used to handle recursive
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Recursive" got me thinking. Is it possible to craft a chain of objects with a cycle? You'll need a already_visited set to break cycles.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of the way we hash, I don't think a cycle is possible

/// --follow behavior at runtime
#[clap(skip)]
to_process: VecDeque<String>,
}

impl CmdInfo {
pub async fn run(&mut self, config: &spfs::Config) -> Result<i32> {
let repo = spfs::config::open_repository_from_string(config, self.remote.as_ref()).await?;

if self.refs.is_empty() {
self.to_process.extend(self.refs.iter().cloned());

if self.to_process.is_empty() {
self.print_global_info(&repo).await?;
} else {
let number_refs = self.refs.len();
for (index, reference) in self.refs.iter().enumerate() {
while let Some(reference) = self.to_process.pop_front() {
if reference.starts_with(spfs::env::SPFS_DIR) {
self.pretty_print_file(
reference,
&repo,
self.logging.verbose as usize,
number_refs,
)
.await?;
self.pretty_print_file(&reference, &repo, self.logging.verbose as usize)
.await?;
} else {
let item = repo.read_ref(reference.as_str()).await?;
self.pretty_print_ref(item, &repo, self.logging.verbose as usize)
.await?;
}
if index + 1 < number_refs {
if !self.to_process.is_empty() {
println!();
}
}
Expand Down Expand Up @@ -92,7 +99,7 @@ impl CmdInfo {

/// Display the spfs object locations that provide the given file
async fn pretty_print_ref(
&self,
&mut self,
obj: spfs::graph::Object,
repo: &spfs::storage::RepositoryHandle,
verbosity: usize,
Expand All @@ -112,6 +119,9 @@ impl CmdInfo {
println!("{}:", "stack (top-down)".bright_blue());
for reference in obj.stack.to_top_down() {
println!(" - {}", self.format_digest(reference, repo).await?);
if self.follow {
self.to_process.push_back(reference.to_string());
}
}
}

Expand All @@ -131,6 +141,9 @@ impl CmdInfo {
"manifest:".bright_blue(),
self.format_digest(obj.manifest, repo).await?
);
if self.follow {
self.to_process.push_back(obj.manifest.to_string());
}
}

Object::Manifest(obj) => {
Expand Down Expand Up @@ -224,7 +237,6 @@ impl CmdInfo {
filepath: &str,
repo: &spfs::storage::RepositoryHandle,
verbosity: usize,
number_refs: usize,
) -> Result<()> {
let mut in_a_runtime = true;
let found = match spfs::find_path::find_path_providers_in_spfs_runtime(filepath, repo).await
Expand All @@ -251,16 +263,9 @@ impl CmdInfo {
if let Some(first_path) = found.first() {
if let Some(ObjectPathEntry::FilePath(file_entry)) = first_path.last() {
let number = found.len();
let query = if number_refs > 1 {
format!("{filepath}: ")
} else {
"".to_string()
};
println!(
"{}{} (in {} {}{})",
query,
"{} (in {number} {}{})",
file_entry.kind.to_string().green(),
number,
"layer".pluralize(number),
if verbosity < 1 && number > 1 {
", topmost 1 shown, use -v to see all"
Expand Down
Loading