cli: Remove rad-inspect `tree' dependency
Hard code output similar to the 'tree' command in rust to avoid having to shell out.
This commit is contained in:
parent
f91ef2963e
commit
67a8ee9e86
|
|
@ -31,28 +31,27 @@ Let's check that we have all the namespaces in storage:
|
|||
|
||||
```
|
||||
$ rad inspect --refs
|
||||
.
|
||||
|-- z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
| `-- refs
|
||||
| |-- heads
|
||||
| | `-- master
|
||||
| `-- rad
|
||||
| |-- id
|
||||
| `-- sigrefs
|
||||
|-- z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
|
||||
| `-- refs
|
||||
| |-- heads
|
||||
| | `-- master
|
||||
| `-- rad
|
||||
| |-- id
|
||||
| `-- sigrefs
|
||||
`-- z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z
|
||||
`-- refs
|
||||
|-- heads
|
||||
| `-- master
|
||||
`-- rad
|
||||
|-- id
|
||||
`-- sigrefs
|
||||
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
└── refs
|
||||
├── heads
|
||||
│ └── master
|
||||
└── rad
|
||||
├── id
|
||||
└── sigrefs
|
||||
z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
|
||||
└── refs
|
||||
├── heads
|
||||
│ └── master
|
||||
└── rad
|
||||
├── id
|
||||
└── sigrefs
|
||||
z6Mkux1aUQD2voWWukVb5nNUR7thrHveQG4pDQua8nVhib7Z
|
||||
└── refs
|
||||
├── heads
|
||||
│ └── master
|
||||
└── rad
|
||||
├── id
|
||||
└── sigrefs
|
||||
```
|
||||
|
||||
We can then setup a git remote for `bob`:
|
||||
|
|
|
|||
|
|
@ -5,14 +5,13 @@ NID. This is demonstrated below where our NID is
|
|||
|
||||
```
|
||||
$ rad inspect rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --refs
|
||||
.
|
||||
`-- z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
`-- refs
|
||||
|-- heads
|
||||
| `-- master
|
||||
`-- rad
|
||||
|-- id
|
||||
`-- sigrefs
|
||||
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
└── refs
|
||||
├── heads
|
||||
│ └── master
|
||||
└── rad
|
||||
├── id
|
||||
└── sigrefs
|
||||
```
|
||||
|
||||
To remedy this, we can use the `rad fork` command for the project we
|
||||
|
|
@ -28,21 +27,20 @@ have a copy of the main set of refs:
|
|||
|
||||
```
|
||||
$ rad inspect rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --refs
|
||||
.
|
||||
|-- z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
| `-- refs
|
||||
| |-- heads
|
||||
| | `-- master
|
||||
| `-- rad
|
||||
| |-- id
|
||||
| `-- sigrefs
|
||||
`-- z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
|
||||
`-- refs
|
||||
|-- heads
|
||||
| `-- master
|
||||
`-- rad
|
||||
|-- id
|
||||
`-- sigrefs
|
||||
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
└── refs
|
||||
├── heads
|
||||
│ └── master
|
||||
└── rad
|
||||
├── id
|
||||
└── sigrefs
|
||||
z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk
|
||||
└── refs
|
||||
├── heads
|
||||
│ └── master
|
||||
└── rad
|
||||
├── id
|
||||
└── sigrefs
|
||||
```
|
||||
|
||||
We are now able to setup a remote in our own working copy of the
|
||||
|
|
|
|||
|
|
@ -17,14 +17,13 @@ It's also possible to display all of the repository's git references:
|
|||
|
||||
```
|
||||
$ rad inspect --refs
|
||||
.
|
||||
`-- z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
`-- refs
|
||||
|-- heads
|
||||
| `-- master
|
||||
`-- rad
|
||||
|-- id
|
||||
`-- sigrefs
|
||||
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
└── refs
|
||||
├── heads
|
||||
│ └── master
|
||||
└── rad
|
||||
├── id
|
||||
└── sigrefs
|
||||
```
|
||||
|
||||
Or display the repository identity's payload:
|
||||
|
|
|
|||
|
|
@ -30,21 +30,20 @@ And some remote refs:
|
|||
|
||||
```
|
||||
$ rad inspect --refs
|
||||
.
|
||||
`-- z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
`-- refs
|
||||
|-- cobs
|
||||
| `-- xyz.radicle.patch
|
||||
| |-- 0ec956c94256fa101db4c32956ce195a1aa0edf2
|
||||
| `-- 928d76e22ef98a8406f2e4e4bcc8878533bbdfe0
|
||||
|-- heads
|
||||
| |-- master
|
||||
| `-- patches
|
||||
| |-- 0ec956c94256fa101db4c32956ce195a1aa0edf2
|
||||
| `-- 928d76e22ef98a8406f2e4e4bcc8878533bbdfe0
|
||||
`-- rad
|
||||
|-- id
|
||||
`-- sigrefs
|
||||
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
└── refs
|
||||
├── cobs
|
||||
│ └── xyz.radicle.patch
|
||||
│ ├── 0ec956c94256fa101db4c32956ce195a1aa0edf2
|
||||
│ └── 928d76e22ef98a8406f2e4e4bcc8878533bbdfe0
|
||||
├── heads
|
||||
│ ├── master
|
||||
│ └── patches
|
||||
│ ├── 0ec956c94256fa101db4c32956ce195a1aa0edf2
|
||||
│ └── 928d76e22ef98a8406f2e4e4bcc8878533bbdfe0
|
||||
└── rad
|
||||
├── id
|
||||
└── sigrefs
|
||||
```
|
||||
|
||||
Then let's merge the changes into `master`.
|
||||
|
|
@ -86,16 +85,15 @@ And so were the remote branches:
|
|||
|
||||
```
|
||||
$ rad inspect --refs
|
||||
.
|
||||
`-- z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
`-- refs
|
||||
|-- cobs
|
||||
| `-- xyz.radicle.patch
|
||||
| |-- 0ec956c94256fa101db4c32956ce195a1aa0edf2
|
||||
| `-- 928d76e22ef98a8406f2e4e4bcc8878533bbdfe0
|
||||
|-- heads
|
||||
| `-- master
|
||||
`-- rad
|
||||
|-- id
|
||||
`-- sigrefs
|
||||
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
└── refs
|
||||
├── cobs
|
||||
│ └── xyz.radicle.patch
|
||||
│ ├── 0ec956c94256fa101db4c32956ce195a1aa0edf2
|
||||
│ └── 928d76e22ef98a8406f2e4e4bcc8878533bbdfe0
|
||||
├── heads
|
||||
│ └── master
|
||||
└── rad
|
||||
├── id
|
||||
└── sigrefs
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#![allow(clippy::or_fun_call)]
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::OsString;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::{anyhow, Context as _};
|
||||
|
|
@ -11,6 +11,7 @@ use json_color::{Color, Colorizer};
|
|||
use radicle::crypto::{Unverified, Verified};
|
||||
use radicle::identity::Untrusted;
|
||||
use radicle::identity::{Doc, Id};
|
||||
use radicle::storage::git::Storage;
|
||||
use radicle::storage::{ReadRepository, ReadStorage};
|
||||
|
||||
use crate::terminal as term;
|
||||
|
|
@ -34,7 +35,7 @@ Options
|
|||
|
||||
--id Return the repository identifier (RID)
|
||||
--payload Inspect the repository's identity payload
|
||||
--refs Inspect the repository's refs on the local device (requires `tree`)
|
||||
--refs Inspect the repository's refs on the local device
|
||||
--history Show the history of the repository identity document
|
||||
--help Print help
|
||||
"#,
|
||||
|
|
@ -127,15 +128,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
|
||||
match options.target {
|
||||
Target::Refs => {
|
||||
let path = storage.path_of(&id).join("refs").join("namespaces");
|
||||
|
||||
Command::new("tree")
|
||||
.current_dir(path)
|
||||
.args(["--noreport", "--prune"])
|
||||
.stdout(Stdio::inherit())
|
||||
.stderr(Stdio::inherit())
|
||||
.spawn()?
|
||||
.wait()?;
|
||||
refs(storage, id)?;
|
||||
}
|
||||
Target::Payload => {
|
||||
println!(
|
||||
|
|
@ -216,3 +209,116 @@ fn colorizer() -> Colorizer {
|
|||
.key(Color::Blue)
|
||||
.build()
|
||||
}
|
||||
|
||||
fn refs(storage: &Storage, id: Id) -> anyhow::Result<()> {
|
||||
let repo = storage.repository(id)?;
|
||||
let mut refs = Vec::new();
|
||||
for r in repo.references()? {
|
||||
let r = r?;
|
||||
if let Some(namespace) = r.namespace {
|
||||
refs.push(format!("{}/{}", namespace, r.name));
|
||||
}
|
||||
}
|
||||
|
||||
print!("{}", tree(refs));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Show the list of given git references as a newline terminated tree `String` similar to the tree command.
|
||||
fn tree(mut refs: Vec<String>) -> String {
|
||||
refs.sort();
|
||||
|
||||
// List of references with additional unique entries for each 'directory'.
|
||||
//
|
||||
// i.e. "refs/heads/master" becomes ["refs"], ["refs", "heads"], and ["refs", "heads",
|
||||
// "master"].
|
||||
let mut refs_expanded: Vec<Vec<String>> = Vec::new();
|
||||
// Number of entries per Git 'directory'.
|
||||
let mut ref_entries: HashMap<Vec<String>, usize> = HashMap::new();
|
||||
let mut last: Vec<String> = Vec::new();
|
||||
|
||||
for r in refs {
|
||||
let r: Vec<String> = r.split('/').map(|s| s.to_string()).collect();
|
||||
|
||||
for (i, v) in r.iter().enumerate() {
|
||||
let last_v = last.get(i);
|
||||
if Some(v) != last_v {
|
||||
last = r.clone().iter().take(i + 1).map(String::from).collect();
|
||||
|
||||
refs_expanded.push(last.clone());
|
||||
|
||||
let mut dir = last.clone();
|
||||
dir.pop();
|
||||
if dir.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if let Some(num) = ref_entries.get_mut(&dir) {
|
||||
*num += 1;
|
||||
} else {
|
||||
ref_entries.insert(dir, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut tree = String::default();
|
||||
|
||||
for mut ref_components in refs_expanded {
|
||||
// Better to explode when things do not go as expected.
|
||||
let name = ref_components.pop().expect("non-empty vector");
|
||||
if ref_components.is_empty() {
|
||||
tree.push_str(&format!("{name}\n"));
|
||||
continue;
|
||||
}
|
||||
|
||||
for i in 1..ref_components.len() {
|
||||
let parent: Vec<String> = ref_components.iter().take(i).cloned().collect();
|
||||
|
||||
let num = ref_entries.get(&parent).unwrap_or(&0);
|
||||
if *num == 0 {
|
||||
tree.push_str(" ");
|
||||
} else {
|
||||
tree.push_str("│ ");
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(num) = ref_entries.get_mut(&ref_components) {
|
||||
if *num == 1 {
|
||||
tree.push_str(&format!("└── {name}\n"));
|
||||
} else {
|
||||
tree.push_str(&format!("├── {name}\n"));
|
||||
}
|
||||
*num -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
tree
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_tree() {
|
||||
let arg = vec![
|
||||
String::from("z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/refs/heads/master"),
|
||||
String::from("z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/refs/rad/id"),
|
||||
String::from("z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi/refs/rad/sigrefs"),
|
||||
];
|
||||
let exp = r#"
|
||||
z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
|
||||
└── refs
|
||||
├── heads
|
||||
│ └── master
|
||||
└── rad
|
||||
├── id
|
||||
└── sigrefs
|
||||
"#
|
||||
.trim_start();
|
||||
|
||||
assert_eq!(tree(arg), exp);
|
||||
assert_eq!(tree(vec![String::new()]), "\n");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue