Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Rapp (development version)

- Boolean switches annotated with `#| negative_alias: false` no longer include
or accept a generated `--no-*` alias (#24).

# Rapp 0.3.0

## Breaking changes
Expand All @@ -26,4 +29,3 @@
# Rapp 0.1.0

- Initial release

12 changes: 9 additions & 3 deletions R/args.R
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ process_args <- function(args, app) {
# if flag not known, maybe this is a switch flag
if (is.null(spec) && startsWith(a, "--no-")) {
alt_name <- str_drop_prefix(name, "no_")
spec <- app_opts[[alt_name]]
if (!is.null(spec)) {
alt_spec <- app_opts[[alt_name]]
if (!is.null(alt_spec) && has_negative_alias(alt_spec)) {
spec <- alt_spec
val <- "false"
name <- alt_name
}
Expand Down Expand Up @@ -198,9 +199,14 @@ process_args <- function(args, app) {
}

if (length(specs) < length(positional_args)) {
unknown_args <- if (length(specs)) {
positional_args[-seq_along(specs)]
} else {
positional_args
}
stop(
"Arguments not recognized: ",
paste0(positional_args[-seq_along(specs)], collapse = " ")
paste0(unknown_args, collapse = " ")
)
}

Expand Down
11 changes: 9 additions & 2 deletions R/help.R
Original file line number Diff line number Diff line change
Expand Up @@ -177,16 +177,23 @@ print_app_help <- function(app, yaml = TRUE, command_path = character()) {
} else if (identical(opt$arg_type, "switch")) {
default_value <- format_default_value(opt$default)
toggle_flag <- paste0("--no-", cli_name)
show_negative <- has_negative_alias(opt)
toggle_note <- if (isTRUE(opt$default)) {
sprintf("Disable with `%s`.", toggle_flag)
if (show_negative) {
sprintf("Disable with `%s`.", toggle_flag)
} else {
character()
}
} else {
sprintf("Enable with `%s`.", paste0("--", cli_name))
}
if (!is.null(default_value)) {
details <- c(details, sprintf("[default: %s]", default_value))
}
details <- c(details, toggle_note)
flag <- paste(flag, "/", toggle_flag)
if (show_negative) {
flag <- paste(flag, "/", toggle_flag)
}
}

if (identical(opt$action, "append")) {
Expand Down
2 changes: 2 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ compact <- function(x) x[lengths(x) > 0]
`%||%` <- function(x, y) if (is.null(x)) y else x
`subtract<-` <- function(x, value) x - value

has_negative_alias <- function(opt) !isFALSE(opt[["negative_alias"]])

`append<-` <- function(x, after = NULL, value) {
if (is.null(after)) c(x, value) else append(x, value, after)
}
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,15 @@ my-app --echo=false # FALSE
my-app --echo=0 # FALSE
```

To omit the generated `--no-*` alias for a boolean switch, add
`#| negative_alias: false` above the assignment:

``` r
#| description: Print version and exit.
#| negative_alias: false
version <- FALSE
```

Assigning `c()` or `list()` declares an option that can be supplied
multiple times. Use `c()` when you want to keep the exact strings
provided on the command line, and `list()` when you want Rapp to attempt
Expand Down Expand Up @@ -338,6 +347,8 @@ Other YAML fields you can supply to change the behavior of Rapp
- `arg_type`: how the input appears on the CLI (`option`, `switch`, `positional`).
- `action`: whether values replace or accumulate (`replace` vs `append` for
repeatable options and collectors).
- `negative_alias`: whether boolean switches include a generated `--no-*`
alias.

## Summary

Expand Down
57 changes: 57 additions & 0 deletions tests/testthat/test-regressions.R
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,60 @@ test_that("leading variadic positional collectors accumulate args", {

expect_output(Rapp::run(app_path, c("alpha", "beta", "gamma")), "ok")
})

test_that("boolean switches can disable negative aliases", {
app_path <- local_rapp_app(
c(
"#!/usr/bin/env Rapp",
"#| name: version-app",
"#| description: Version printer.",
"",
"#| description: Print version and exit.",
"#| negative_alias: false",
"version <- FALSE",
"",
"if (version) cat('version-app 1.0.0\\n')"
),
prefix = "rapp-no-negative-switch-"
)

expect_output(Rapp::run(app_path, "--version"), "version-app 1.0.0")

help <- capture.output(Rapp::run(app_path, "--help"))
expect_true(any(grepl("--version", help, fixed = TRUE)))
expect_false(any(grepl("--no-version", help, fixed = TRUE)))
expect_error(
Rapp::run(app_path, "--no-version"),
"Arguments not recognized: --no-version",
fixed = TRUE
)

true_default_app <- local_rapp_app(
c(
"#!/usr/bin/env Rapp",
"#| description: Keep output wrapped.",
"#| negative_alias: false",
"wrap <- TRUE"
),
prefix = "rapp-no-negative-default-true-"
)
true_default_help <- capture.output(Rapp::run(true_default_app, "--help"))
expect_false(any(grepl("--no-wrap", true_default_help, fixed = TRUE)))
expect_false(any(grepl(
"Enable with `--wrap`.",
true_default_help,
fixed = TRUE
)))

negative_app <- local_rapp_app(
c(
"#!/usr/bin/env Rapp",
"#| description: Legacy spelling is ignored.",
"#| negative: false",
"legacy <- FALSE"
),
prefix = "rapp-negative-ignored-"
)
negative_help <- capture.output(Rapp::run(negative_app, "--help"))
expect_true(any(grepl("--no-legacy", negative_help, fixed = TRUE)))
})