Skip to content

Add --exclude-tag option #24

@codcod

Description

@codcod

You currently have only inclusive tag filtering (-t / --tag). To run a command for all repositories except those with a specific tag (e.g. legacy), minimal feature addition is recommended:

Add an --exclude-tag flag to Run so repos run keeps logging, aggregate output, etc.

Code changes (absolute minimal):

// ...existing code...
#[derive(clap::Parser)]
pub enum Commands {
    // ...existing variants...
    Run {
        command: String,
        #[clap(short, long)]
        tag: Option<String>,
        #[clap(long)]
        exclude_tag: Option<String>, // new
        #[clap(long)]
        parallel: bool,
        #[clap(long, default_value_t = true)]
        persist: bool,
        #[clap(long, default_value_t = true)]
        aggregate: bool,
        #[clap(long)]
        log_dir: Option<String>,
    },
}
// ...existing match arm...
Commands::Run { command, tag, exclude_tag, parallel, persist, aggregate, log_dir } => {
    let mut cmd = RunCommand::new(command, tag, parallel);
    cmd.exclude_tag = exclude_tag;
    cmd.persist = persist;
    cmd.aggregate = aggregate;
    cmd.log_dir = log_dir.map(Into::into);
    execute_command(Box::new(cmd), ctx).await?;
}
// ...existing code...
// ...existing code...
pub struct RunCommand {
    pub command: String,
    pub filter: Option<String>, // existing inclusive tag
    pub exclude_tag: Option<String>, // new
    pub parallel: bool,
    pub persist: bool,
    pub aggregate: bool,
    pub log_dir: Option<PathBuf>,
}
// ...existing RunCommand::new...
pub fn new(command: String, filter: Option<String>, parallel: bool) -> Self {
    Self {
        command,
        filter,
        exclude_tag: None,
        parallel,
        persist: true,
        aggregate: true,
        log_dir: None,
    }
}
// ...inside execute before iterating repositories...
let repos: Vec<&Repository> = ctx
    .config
    .repositories
    .iter()
    .filter(|r| {
        (self.filter.is_none() || r.has_tag(self.filter.as_ref().unwrap()))
            && (self.exclude_tag.is_none()
                || !r.has_tag(self.exclude_tag.as_ref().unwrap()))
    })
    .collect();
// ...existing code...

Usage after change:

# Run on all except legacy
repos run --exclude-tag legacy "cargo build"

# Run only rust and exclude legacy (intersection then exclusion)
repos run -t rust --exclude-tag legacy "cargo test"

For multiple exclusions, extend exclude_tag to Vec.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions