From 8e4b6dfeaa62245ff973477cee7476cb9f654fed Mon Sep 17 00:00:00 2001 From: Philip Metzger Date: Tue, 2 May 2023 16:30:25 +0200 Subject: [PATCH] run: Teach `run` to resolve revsets and about `jobs`. This also adds `jobs`, the argument reading the thread count to use and `shell_command`. While we're at it, make `execute` a no-op and teach `run` to resolve the passed revsets. I also fixed my misunderstanding of `Clap` which makes `jj run 'echo hello world' -r 'mine() & ~origin@remote' --jobs 4` parse correctly. Also contains a small fix in the `pre-commit` example for it. --- cli/src/commands/run.rs | 43 +++++++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/cli/src/commands/run.rs b/cli/src/commands/run.rs index de6fe13563..8c205cb008 100644 --- a/cli/src/commands/run.rs +++ b/cli/src/commands/run.rs @@ -12,7 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. -use crate::cli_util::{user_error, CommandError, CommandHelper, RevisionArg}; +//! This file contains the internal implementation of `run`. + +use std::num::NonZeroUsize; + +use crate::cli_util::{ + resolve_multiple_nonempty_revsets, user_error, CommandError, CommandHelper, RevisionArg, +}; use crate::ui::Ui; /// Run a command across a set of revisions. @@ -24,24 +30,41 @@ use crate::ui::Ui; /// # Example /// /// # Run pre-commit on your local work -/// $ jj run 'pre-commit.py .github/pre-commit.yaml' -r (main..@) -j 4 +/// $ jj run 'pre-commit run .github/pre-commit.yaml' -r (trunk()..@) -j 4 /// /// This allows pre-commit integration and other funny stuff. #[derive(clap::Args, Clone, Debug)] #[command(verbatim_doc_comment)] -pub(crate) struct RunArgs { +pub struct RunArgs { /// The command to run across all selected revisions. - #[arg(long, short, alias = "x")] - command: String, + shell_command: String, /// The revisions to change. + /// Multiple revsets are accepted and the work will be done on a + /// intersection of them. #[arg(long, short, default_value = "@")] revisions: Vec, + /// A no-op option to match the interface of `git rebase -x`. + #[arg(short = 'x', hide = true)] + unused_command: bool, + /// How many processes should run in parallel, uses by default all cores. + #[arg(long, short)] + jobs: Option, } -pub(crate) fn cmd_run( - _ui: &mut Ui, - _command: &CommandHelper, - _args: &RunArgs, -) -> Result<(), CommandError> { +pub fn cmd_run(ui: &mut Ui, command: &CommandHelper, args: &RunArgs) -> Result<(), CommandError> { + let workspace_command = command.workspace_helper(ui)?; + let _resolved_commits = + resolve_multiple_nonempty_revsets(&args.revisions, &workspace_command, ui)?; + let _jobs = if let Some(_jobs) = args.jobs { + _jobs + } else { + // Use all available cores + + // SAFETY: + // We use a internal constant of 4 threads, if it fails + let available = std::thread::available_parallelism() + .unwrap_or(unsafe { NonZeroUsize::new_unchecked(4) }); + available.into() + }; Err(user_error("This is a stub, do not use")) }