Skip to content

Commit 5f2aba1

Browse files
authored
Merge pull request #9 from r-lib/use-air
Use `air`
2 parents 5f2e089 + be59ade commit 5f2aba1

14 files changed

Lines changed: 244 additions & 172 deletions

File tree

.Rbuildignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
^CRAN-SUBMISSION$
66
^tools$
77
^cran-comments\.md$
8+
^[.]?air[.]toml$
9+
^\.vscode$

.git-blame-ignore-revs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
# air format .
3+
b96b1802be0baa14f653ff14c53c898327724d89

R/app.R

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
21
as_app <- function(x, complete = TRUE) {
3-
if(inherits(x, "Rapp"))
2+
if (inherits(x, "Rapp")) {
43
return(x)
4+
}
55

66
# TODO: present a nice error message in case of parse errors
77
filepath <- x
88
lines <- readLines(filepath)
99
exprs <- parse(
10-
text = lines, keep.source = TRUE,
11-
srcfile = srcfilecopy(filepath, lines,
12-
file.mtime(filepath), isFile = TRUE))
10+
text = lines,
11+
keep.source = TRUE,
12+
srcfile = srcfilecopy(filepath, lines, file.mtime(filepath), isFile = TRUE)
13+
)
1314

1415
app <- new.env(parent = emptyenv())
1516
attr(app, "class") <- "Rapp"
@@ -19,7 +20,7 @@ as_app <- function(x, complete = TRUE) {
1920
app$line_is_hashpipe <- startsWith(lines, "#| ")
2021
app$exprs <- exprs
2122

22-
if(complete) {
23+
if (complete) {
2324
app$data <- get_app_data(app)
2425
inputs <- get_app_inputs(app)
2526
app$opts <- inputs$opts
@@ -31,29 +32,28 @@ as_app <- function(x, complete = TRUE) {
3132

3233

3334
get_app_data <- function(app) {
34-
3535
app <- as_app(app, complete = FALSE)
3636

3737
data <-
38-
if (app$line_is_hashpipe[1] ||
39-
startsWith(app$lines[1], "#!/") && app$line_is_hashpipe[2]) {
38+
if (
39+
app$line_is_hashpipe[1] ||
40+
startsWith(app$lines[1], "#!/") && app$line_is_hashpipe[2]
41+
) {
4042
# allow frontmatter to start on 2nd line if first line is a shebang
4143

4244
hashpipe_start <- which.max(app$line_is_hashpipe)
43-
hashpipe_end <- which.min(c(TRUE, app$line_is_hashpipe[-1L])) -1L
45+
hashpipe_end <- which.min(c(TRUE, app$line_is_hashpipe[-1L])) - 1L
4446

4547
parse_hashpipe_yaml(app$lines[hashpipe_start:hashpipe_end])
4648
} else {
4749
as_yaml(list())
4850
}
4951

50-
5152
data
5253
}
5354

5455

5556
get_app_inputs <- function(app) {
56-
5757
app <- as_app(app, complete = FALSE)
5858
lines <- app$lines
5959
exprs <- app$exprs
@@ -66,47 +66,58 @@ get_app_inputs <- function(app) {
6666
for (i in seq_along(exprs)) {
6767
e <- exprs[[i]]
6868

69-
if (!is.call(e))
69+
if (!is.call(e)) {
7070
next
71+
}
7172

7273
op <- e[[1L]]
73-
if (op != quote(`=`) && op != quote(`<-`))
74+
if (op != quote(`=`) && op != quote(`<-`)) {
7475
next
76+
}
7577

76-
if (typeof(e[[2L]]) != "symbol")
78+
if (typeof(e[[2L]]) != "symbol") {
7779
next
80+
}
7881

7982
name <- as.character(e[[2L]])
8083

8184
# already encountered this same symbol as a flag earlier
82-
if (name %in% names(args) ||
83-
name %in% names(opts))
85+
if (name %in% names(args) || name %in% names(opts)) {
8486
next
87+
}
8588

8689
default <- e[[3L]]
8790
if (is.call(default)) {
88-
89-
if(!is.symbol(call_sym <- default[[1]]))
91+
if (!is.symbol(call_sym <- default[[1]])) {
9092
next
93+
}
9194

9295
call_sym <- as.character(call_sym)
9396

94-
if(!call_sym %in% c("c", "character", "+"))
97+
if (!call_sym %in% c("c", "character", "+")) {
9598
next
99+
}
96100

97-
if(all.names(default) %in% c("c", "character", "-", "+"))
101+
if (all.names(default) %in% c("c", "character", "-", "+")) {
98102
default <- eval(default, envir = baseenv())
103+
}
99104
## TODO: complex are `+` calls, eval, all else, next
100105
## TODO: special syntax for var len values? `vals <- c("a", "b")`, injected as `[a,b]`
101106
}
102107

103-
if (!typeof(default) %in%
104-
c("double", "integer", "character", "logical", "NULL"))
108+
if (
109+
!typeof(default) %in%
110+
c("double", "integer", "character", "logical", "NULL")
111+
) {
105112
next
113+
}
106114

107-
if (!(identical(length(default), 1L) ||
108-
identical(length(default), 0L)))
115+
if (
116+
!(identical(length(default), 1L) ||
117+
identical(length(default), 0L))
118+
) {
109119
next
120+
}
110121

111122
## three types of cli args:
112123
## --foo bar (option: option that takes a val)
@@ -125,40 +136,43 @@ get_app_inputs <- function(app) {
125136
"integer" = "integer",
126137
"NULL" = "string"
127138
),
128-
arg_type =
129-
if (isTRUE(default) || isFALSE(default)) "switch"
130-
else if (length(default)) "option"
131-
else "positional",
139+
arg_type = if (isTRUE(default) || isFALSE(default)) {
140+
"switch"
141+
} else if (length(default)) {
142+
"option"
143+
} else {
144+
"positional"
145+
},
132146
.val_pos_in_exprs = c(i, 3L) # pos 3 in call expr: `<-`(name, 'val')
133147
)
134148

135149
lineno <- utils::getSrcLocation(exprs[i], "line")
136150
# look for adjacent anno hints about this flag
137151
if (is_hashpipe[lineno - 1L]) {
138152
anno_start <- anno_end <- lineno - 1L
139-
while (is_hashpipe[anno_start - 1L])
153+
while (is_hashpipe[anno_start - 1L]) {
140154
subtract(anno_start) <- 1L
155+
}
141156

142-
anno <- parse_hashpipe_yaml(lines[anno_start:anno_end],
143-
handlers = list("bool#yes"= identity,
144-
"bool#no" = identity))
157+
anno <- parse_hashpipe_yaml(
158+
lines[anno_start:anno_end],
159+
handlers = list("bool#yes" = identity, "bool#no" = identity)
160+
)
145161

146162
arg <- utils::modifyList(arg, anno)
147163
}
148164

149-
if (arg$arg_type == "positional")
165+
if (arg$arg_type == "positional") {
150166
args[[name]] <- arg
151-
else
167+
} else {
152168
opts[[name]] <- arg
153-
169+
}
154170
}
155171

156-
157172
list(args = args, opts = opts)
158173
}
159174

160175

161-
162176
#' Run an R app.
163177
#'
164178
#' @param app A filepath to an Rapp.
@@ -201,13 +215,15 @@ get_app_inputs <- function(app) {
201215
#' Sys.setenv(PATH = old_path)
202216
run <- function(app, args = commandArgs(TRUE)) {
203217
args <- textConnection(args)
204-
if(missing(app))
218+
if (missing(app)) {
205219
app <- readLines(args, 1L)
220+
}
206221

207222
app <- as_app(app)
208223

209-
if (process_args(args, app))
224+
if (process_args(args, app)) {
210225
eval(app$exprs, new.env(parent = globalenv()))
226+
}
211227

212228
invisible()
213229
}

0 commit comments

Comments
 (0)