cli: Improve `rad ls`
Distinguish between repos that are simply tracked, vs. repos that are cloned (and thus forked). By default, we don't show repos that don't have a local fork.
This commit is contained in:
parent
2917198d1c
commit
53013f306f
|
|
@ -58,3 +58,13 @@ Date: Mon Jan 1 14:39:16 2018 +0000
|
||||||
|
|
||||||
Second commit
|
Second commit
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Cloned repositories show up in `rad ls`:
|
||||||
|
```
|
||||||
|
$ rad ls
|
||||||
|
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||||
|
│ Name RID Visibility Head Description │
|
||||||
|
├───────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ heartwood rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji public f2de534 Radicle Heartwood Protocol & Stack │
|
||||||
|
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
Given a private repo `rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu` belonging to Alice,
|
Given a private repo `rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu` belonging to Alice,
|
||||||
Bob tries to clone it, and even though he's connected to Alice, it fails.
|
Bob tries to fetch it, and even though he's connected to Alice, it fails.
|
||||||
|
|
||||||
``` ~bob
|
``` ~bob
|
||||||
$ rad track rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu
|
$ rad track rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu
|
||||||
|
|
@ -28,10 +28,17 @@ Bob can now fetch the private repo:
|
||||||
$ rad sync rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu --fetch
|
$ rad sync rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu --fetch
|
||||||
✓ Fetching rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu from z6MknSL…StBU8Vi..
|
✓ Fetching rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu from z6MknSL…StBU8Vi..
|
||||||
✓ Fetched repository from 1 seed(s)
|
✓ Fetched repository from 1 seed(s)
|
||||||
$ rad ls --private
|
$ rad ls --private --all
|
||||||
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
╭───────────────────────────────────────────────────────────────────────────────────────────────────────────╮
|
||||||
│ Name RID Visibility Head Description │
|
│ Name RID Visibility Head Description │
|
||||||
├───────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
├───────────────────────────────────────────────────────────────────────────────────────────────────────────┤
|
||||||
│ heartwood rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu private f2de534 radicle heartwood protocol & stack │
|
│ heartwood rad:z2ug5mwNKZB8KGpBDRTrWHAMbvHCu private f2de534 radicle heartwood protocol & stack │
|
||||||
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Note that since we don't have our own fork of this repo, omitting the `--all` flag shows nothing:
|
||||||
|
|
||||||
|
``` ~bob
|
||||||
|
$ rad ls --private
|
||||||
|
Nothing to show.
|
||||||
|
```
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,14 @@ Usage
|
||||||
|
|
||||||
rad ls [<option>...]
|
rad ls [<option>...]
|
||||||
|
|
||||||
|
By default, this command shows you all repositories that you have forked or initialized.
|
||||||
|
If you wish to see all tracked repositories, use the `--all` option.
|
||||||
|
|
||||||
Options
|
Options
|
||||||
|
|
||||||
--private Show only private repositories
|
--private Show only private repositories
|
||||||
--public Show only public repositories
|
--public Show only public repositories
|
||||||
|
--all Show all repositories in storage
|
||||||
--verbose, -v Verbose output
|
--verbose, -v Verbose output
|
||||||
--help Print help
|
--help Print help
|
||||||
"#,
|
"#,
|
||||||
|
|
@ -30,6 +34,7 @@ pub struct Options {
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
public: bool,
|
public: bool,
|
||||||
private: bool,
|
private: bool,
|
||||||
|
all: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Args for Options {
|
impl Args for Options {
|
||||||
|
|
@ -40,12 +45,16 @@ impl Args for Options {
|
||||||
let mut verbose = false;
|
let mut verbose = false;
|
||||||
let mut private = false;
|
let mut private = false;
|
||||||
let mut public = false;
|
let mut public = false;
|
||||||
|
let mut all = false;
|
||||||
|
|
||||||
while let Some(arg) = parser.next()? {
|
while let Some(arg) = parser.next()? {
|
||||||
match arg {
|
match arg {
|
||||||
Long("help") | Short('h') => {
|
Long("help") | Short('h') => {
|
||||||
return Err(Error::Help.into());
|
return Err(Error::Help.into());
|
||||||
}
|
}
|
||||||
|
Long("all") => {
|
||||||
|
all = true;
|
||||||
|
}
|
||||||
Long("private") => {
|
Long("private") => {
|
||||||
private = true;
|
private = true;
|
||||||
}
|
}
|
||||||
|
|
@ -62,6 +71,7 @@ impl Args for Options {
|
||||||
verbose,
|
verbose,
|
||||||
private,
|
private,
|
||||||
public,
|
public,
|
||||||
|
all,
|
||||||
},
|
},
|
||||||
vec![],
|
vec![],
|
||||||
))
|
))
|
||||||
|
|
@ -71,32 +81,34 @@ impl Args for Options {
|
||||||
pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
let profile = ctx.profile()?;
|
let profile = ctx.profile()?;
|
||||||
let storage = &profile.storage;
|
let storage = &profile.storage;
|
||||||
let mut table = term::Table::new(term::TableOptions::bordered());
|
|
||||||
let repos = storage.repositories()?;
|
let repos = storage.repositories()?;
|
||||||
|
let mut table = term::Table::new(term::TableOptions::bordered());
|
||||||
|
let mut rows = Vec::new();
|
||||||
|
|
||||||
if repos.is_empty() {
|
if repos.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
table.push([
|
|
||||||
"Name".into(),
|
|
||||||
"RID".into(),
|
|
||||||
"Visibility".into(),
|
|
||||||
"Head".into(),
|
|
||||||
"Description".into(),
|
|
||||||
]);
|
|
||||||
table.divider();
|
|
||||||
|
|
||||||
for RepositoryInfo { rid, head, doc } in repos {
|
for RepositoryInfo {
|
||||||
|
rid,
|
||||||
|
head,
|
||||||
|
doc,
|
||||||
|
refs,
|
||||||
|
} in repos
|
||||||
|
{
|
||||||
if doc.visibility.is_public() && options.private && !options.public {
|
if doc.visibility.is_public() && options.private && !options.public {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if !doc.visibility.is_public() && !options.private && options.public {
|
if !doc.visibility.is_public() && !options.private && options.public {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if refs.is_none() && !options.all {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let proj = doc.project()?;
|
let proj = doc.project()?;
|
||||||
let head = term::format::oid(head).into();
|
let head = term::format::oid(head).into();
|
||||||
|
|
||||||
table.push([
|
rows.push([
|
||||||
term::format::bold(proj.name().to_owned()),
|
term::format::bold(proj.name().to_owned()),
|
||||||
term::format::tertiary(rid.urn()),
|
term::format::tertiary(rid.urn()),
|
||||||
term::format::visibility(&doc.visibility).into(),
|
term::format::visibility(&doc.visibility).into(),
|
||||||
|
|
@ -104,7 +116,22 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||||
term::format::italic(proj.description().to_owned()),
|
term::format::italic(proj.description().to_owned()),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
table.print();
|
rows.sort();
|
||||||
|
|
||||||
|
if rows.is_empty() {
|
||||||
|
term::print(term::format::italic("Nothing to show."));
|
||||||
|
} else {
|
||||||
|
table.push([
|
||||||
|
"Name".into(),
|
||||||
|
"RID".into(),
|
||||||
|
"Visibility".into(),
|
||||||
|
"Head".into(),
|
||||||
|
"Description".into(),
|
||||||
|
]);
|
||||||
|
table.divider();
|
||||||
|
table.extend(rows);
|
||||||
|
table.print();
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,12 @@ impl<const W: usize, T: Cell> Table<W, T> {
|
||||||
self.rows.push(Row::Data(row));
|
self.rows.push(Row::Data(row));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn extend(&mut self, rows: impl IntoIterator<Item = [T; W]>) {
|
||||||
|
for row in rows.into_iter() {
|
||||||
|
self.push(row);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn inner(&self, c: Constraint) -> Size {
|
fn inner(&self, c: Constraint) -> Size {
|
||||||
let mut outer = self.outer(c);
|
let mut outer = self.outer(c);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,9 @@ pub struct RepositoryInfo<V> {
|
||||||
pub head: Oid,
|
pub head: Oid,
|
||||||
/// Identity document.
|
/// Identity document.
|
||||||
pub doc: Doc<V>,
|
pub doc: Doc<V>,
|
||||||
|
/// Local signed refs, if any.
|
||||||
|
/// Repositories with this set to `None` are ones that are tracked but not forked.
|
||||||
|
pub refs: Option<refs::SignedRefsAt>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A parsed Git reference.
|
/// A parsed Git reference.
|
||||||
|
|
@ -226,7 +229,15 @@ impl Storage {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
repos.push(RepositoryInfo { rid, head, doc });
|
// Nb. This will be `None` if they were not found.
|
||||||
|
let refs = refs::SignedRefsAt::load(self.info.key, &repo)?;
|
||||||
|
|
||||||
|
repos.push(RepositoryInfo {
|
||||||
|
rid,
|
||||||
|
head,
|
||||||
|
doc,
|
||||||
|
refs,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
Ok(repos)
|
Ok(repos)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue