cli: Add `--repo` option to `issue` and `patch`
Allows users to operate on a repo without a checkout.
This commit is contained in:
parent
449790e252
commit
0726754b0e
|
|
@ -13,7 +13,7 @@ use radicle::cob::issue::{CloseReason, State};
|
|||
use radicle::cob::thread;
|
||||
use radicle::crypto::Signer;
|
||||
use radicle::issue::cache::Issues as _;
|
||||
use radicle::prelude::Did;
|
||||
use radicle::prelude::{Did, RepoId};
|
||||
use radicle::profile;
|
||||
use radicle::storage;
|
||||
use radicle::storage::{ReadRepository, WriteRepository, WriteStorage};
|
||||
|
|
@ -69,6 +69,7 @@ Show options
|
|||
|
||||
Options
|
||||
|
||||
--repo <rid> Operate on the given repository (default: cwd)
|
||||
--no-announce Don't announce issue to peers
|
||||
--header Show only the issue header, hiding the comments
|
||||
-q, --quiet Don't print anything
|
||||
|
|
@ -167,6 +168,7 @@ pub struct LabelOptions {
|
|||
#[derive(Debug)]
|
||||
pub struct Options {
|
||||
pub op: Operation,
|
||||
pub repo: Option<RepoId>,
|
||||
pub announce: bool,
|
||||
pub quiet: bool,
|
||||
}
|
||||
|
|
@ -194,6 +196,7 @@ impl Args for Options {
|
|||
let mut debug = false;
|
||||
let mut assign_opts = AssignOptions::default();
|
||||
let mut label_opts = LabelOptions::default();
|
||||
let mut repo = None;
|
||||
|
||||
while let Some(arg) = parser.next()? {
|
||||
match arg {
|
||||
|
|
@ -337,6 +340,12 @@ impl Args for Options {
|
|||
Long("quiet") | Short('q') => {
|
||||
quiet = true;
|
||||
}
|
||||
Long("repo") => {
|
||||
let val = parser.value()?;
|
||||
let rid = term::args::rid(&val)?;
|
||||
|
||||
repo = Some(rid);
|
||||
}
|
||||
|
||||
Value(val) if op.is_none() => match val.to_string_lossy().as_ref() {
|
||||
"c" | "comment" => op = Some(OperationName::Comment),
|
||||
|
|
@ -412,6 +421,7 @@ impl Args for Options {
|
|||
Ok((
|
||||
Options {
|
||||
op,
|
||||
repo,
|
||||
announce,
|
||||
quiet,
|
||||
},
|
||||
|
|
@ -423,7 +433,11 @@ impl Args for Options {
|
|||
pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||
let profile = ctx.profile()?;
|
||||
let signer = term::signer(&profile)?;
|
||||
let (_, rid) = radicle::rad::cwd()?;
|
||||
let rid = if let Some(rid) = options.repo {
|
||||
rid
|
||||
} else {
|
||||
radicle::rad::cwd().map(|(_, rid)| rid)?
|
||||
};
|
||||
let repo = profile.storage.repository_mut(rid)?;
|
||||
let announce = options.announce
|
||||
&& matches!(
|
||||
|
|
|
|||
|
|
@ -16,10 +16,13 @@ pub fn run(id: Option<IssueId>, repository: &Repository, profile: &Profile) -> a
|
|||
}
|
||||
None => issues.write_all(|result, progress| {
|
||||
match result {
|
||||
Ok((id, _)) => term::success!("Successfully cached issue `{id}`"),
|
||||
Ok((id, _)) => term::success!(
|
||||
"Successfully cached issue {id} ({}/{})",
|
||||
progress.seen(),
|
||||
progress.total()
|
||||
),
|
||||
Err(e) => term::warning(format!("Failed to retrieve issue: {e}")),
|
||||
};
|
||||
term::info!("Cached {} of {}", progress.seen(), progress.total());
|
||||
ControlFlow::Continue(())
|
||||
})?,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ Checkout options
|
|||
|
||||
Other options
|
||||
|
||||
--repo <rid> Operate on the given repository (default: cwd)
|
||||
--[no-]announce Announce changes made to the network
|
||||
-q, --quiet Quiet output
|
||||
--help Print help
|
||||
|
|
@ -278,6 +279,7 @@ impl Operation {
|
|||
#[derive(Debug)]
|
||||
pub struct Options {
|
||||
pub op: Operation,
|
||||
pub repo: Option<RepoId>,
|
||||
pub announce: bool,
|
||||
pub verbose: bool,
|
||||
pub quiet: bool,
|
||||
|
|
@ -309,6 +311,7 @@ impl Args for Options {
|
|||
let mut label_opts = LabelOptions::default();
|
||||
let mut review_op = review::Operation::default();
|
||||
let mut base_id = None;
|
||||
let mut repo = None;
|
||||
|
||||
while let Some(arg) = parser.next()? {
|
||||
match arg {
|
||||
|
|
@ -503,6 +506,12 @@ impl Args for Options {
|
|||
Long("quiet") | Short('q') => {
|
||||
quiet = true;
|
||||
}
|
||||
Long("repo") => {
|
||||
let val = parser.value()?;
|
||||
let rid = term::args::rid(&val)?;
|
||||
|
||||
repo = Some(rid);
|
||||
}
|
||||
Long("help") => {
|
||||
return Err(Error::HelpManual { name: "rad-patch" }.into());
|
||||
}
|
||||
|
|
@ -631,6 +640,7 @@ impl Args for Options {
|
|||
Ok((
|
||||
Options {
|
||||
op,
|
||||
repo,
|
||||
verbose,
|
||||
quiet,
|
||||
announce,
|
||||
|
|
@ -643,11 +653,16 @@ impl Args for Options {
|
|||
}
|
||||
|
||||
pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||
let (workdir, id) = radicle::rad::cwd()
|
||||
.map_err(|_| anyhow!("this command must be run in the context of a repository"))?;
|
||||
let (workdir, rid) = if let Some(rid) = options.repo {
|
||||
(None, rid)
|
||||
} else {
|
||||
radicle::rad::cwd()
|
||||
.map(|(workdir, rid)| (Some(workdir), rid))
|
||||
.map_err(|_| anyhow!("this command must be run in the context of a repository"))?
|
||||
};
|
||||
|
||||
let profile = ctx.profile()?;
|
||||
let repository = profile.storage.repository(id)?;
|
||||
let repository = profile.storage.repository(rid)?;
|
||||
let announce = options.announce && options.op.is_announce();
|
||||
|
||||
transport::local::register(profile.storage.clone());
|
||||
|
|
@ -673,7 +688,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
options.verbose,
|
||||
&profile,
|
||||
&repository,
|
||||
&workdir,
|
||||
workdir.as_ref(),
|
||||
)?;
|
||||
}
|
||||
Operation::Diff {
|
||||
|
|
@ -697,6 +712,10 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
.as_ref()
|
||||
.map(|base| base.resolve(&repository.backend))
|
||||
.transpose()?;
|
||||
let workdir = workdir.ok_or(anyhow!(
|
||||
"this command must be run from a repository checkout"
|
||||
))?;
|
||||
|
||||
update::run(
|
||||
patch_id,
|
||||
base_id,
|
||||
|
|
@ -728,6 +747,9 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
.map(|rev| rev.resolve::<radicle::git::Oid>(&repository.backend))
|
||||
.transpose()?
|
||||
.map(patch::RevisionId::from);
|
||||
let workdir = workdir.ok_or(anyhow!(
|
||||
"this command must be run from a repository checkout"
|
||||
))?;
|
||||
checkout::run(
|
||||
&patch::PatchId::from(patch_id),
|
||||
revision_id,
|
||||
|
|
@ -798,7 +820,9 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
let patch = patches
|
||||
.get(&patch_id)?
|
||||
.ok_or_else(|| anyhow!("patch {patch_id} not found"))?;
|
||||
|
||||
let workdir = workdir.ok_or(anyhow!(
|
||||
"this command must be run from a repository checkout"
|
||||
))?;
|
||||
radicle::rad::setup_patch_upstream(&patch_id, *patch.head(), &workdir, true)?;
|
||||
}
|
||||
Operation::Cache { patch_id } => {
|
||||
|
|
@ -811,7 +835,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
|
||||
if announce {
|
||||
let mut node = Node::new(profile.socket());
|
||||
node::announce(id, &mut node)?;
|
||||
node::announce(rid, &mut node)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,10 +16,13 @@ pub fn run(id: Option<PatchId>, repository: &Repository, profile: &Profile) -> a
|
|||
}
|
||||
None => patches.write_all(|result, progress| {
|
||||
match result {
|
||||
Ok((id, _)) => term::success!("Successfully cached patch `{id}`"),
|
||||
Ok((id, _)) => term::success!(
|
||||
"Successfully cached patch {id} ({}/{})",
|
||||
progress.seen(),
|
||||
progress.total()
|
||||
),
|
||||
Err(e) => term::warning(format!("Failed to retrieve patch: {e}")),
|
||||
};
|
||||
term::info!("Cached {} of {}", progress.seen(), progress.total());
|
||||
ControlFlow::Continue(())
|
||||
})?,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,8 +30,7 @@ pub fn run(
|
|||
verbose: bool,
|
||||
profile: &Profile,
|
||||
stored: &Repository,
|
||||
// TODO: Should be optional.
|
||||
workdir: &git::raw::Repository,
|
||||
workdir: Option<&git::raw::Repository>,
|
||||
) -> anyhow::Result<()> {
|
||||
let patches = profile.patches(stored)?;
|
||||
let Some(patch) = patches.get(patch_id)? else {
|
||||
|
|
@ -42,7 +41,7 @@ pub fn run(
|
|||
println!("{:#?}", patch);
|
||||
return Ok(());
|
||||
}
|
||||
term::patch::show(&patch, patch_id, verbose, stored, Some(workdir), profile)?;
|
||||
term::patch::show(&patch, patch_id, verbose, stored, workdir, profile)?;
|
||||
|
||||
if diff {
|
||||
term::blank();
|
||||
|
|
|
|||
Loading…
Reference in New Issue