Skip to content

Commit 2836cb2

Browse files
aitapMichaelChirico
andcommitted
lint.R: move preprocessing to a special function
The preprocessing functions were too unwieldy to leave them on the command line. This makes it possible to run any lint check directly from the command line before committing code. Co-authored-by: Michael Chirico <[email protected]>
1 parent 281d0ca commit 2836cb2

File tree

5 files changed

+21
-35
lines changed

5 files changed

+21
-35
lines changed

.ci/README.md

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,25 +55,15 @@ Base R runner for the manual (non-`lintr`) lint checks to be run from GitHub Act
5555
1. Path to the directory containing files defining the linters. A linter is a function that accepts one argument (typically the path to the file) and signals an error if it fails the lint check.
5656
2. Path to the directory containing files to check.
5757
3. A regular expression matching the files to check.
58-
4. An R expression evaluating to a function that processes a single file path into a form understood by the lint functions. Additionally, the function may return `NULL` to indicate that the file must be skipped.
58+
59+
One of the files in the linter directory may define the `.preprocess` function, which must accept one file path and return a value that other linter functions will understand. The function may also return `NULL` to indicate that the file must be skipped.
5960

6061
Example command lines:
6162

6263
```sh
63-
# C linters expect a three-element named list, not the file path
64-
Rscript .ci/lint.R .ci/linters/c src '[.][ch]$' '
65-
function (f) list(
66-
c_obj = f, lines = readLines(f),
67-
preprocessed = system2("gcc", shQuote(c("-fpreprocessed", "-E", f)), stdout = TRUE, stderr = FALSE)
68-
)
69-
'
70-
# po linters must skip files that don't differ from master
71-
Rscript .ci/lint.R .ci/linters/po po '[.]po$' '
72-
function (f) {
73-
diff_v_master = system2("git", c("diff", "master", f), stdout=TRUE)
74-
if (length(diff_v_master)) f
75-
}
76-
'
64+
Rscript .ci/lint.R .ci/linters/c src '[.][ch]$'
65+
Rscript .ci/lint.R .ci/linters/po po '[.]po$'
66+
Rscript .ci/lint.R .ci/linters/md . '[.]R?md$'
7767
```
7868

7969
## GitLab Open Source Program

.ci/lint.R

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@ if (identical(args, '--help')) {
77
'KIND must name the directory containing the *.R files defining the linter functions.',
88
'WHERE must name the directory containing the files to lint, e.g. "po", or "src".',
99
"WHAT must contain the regular expression matching the files to lint, e.g., '[.]po$', or '[.][ch]$'.",
10-
'PREPROCESS is an optional R function that accepts a file path and returns an R object accepted by the lint functions, or NULL to skip the file.'
1110
))
1211
q('no')
1312
}
14-
stopifnot(`Invalid arguments, see .ci/lint.R --help` = length(args) %in% 3:4)
13+
stopifnot(`Invalid arguments, see .ci/lint.R --help` = length(args) == 3)
1514

16-
linter_env = new.env()
15+
linter_env = list2env(list(.preprocess = identity))
1716
for (f in list.files(args[[1]], full.names=TRUE)) sys.source(f, linter_env)
1817
if (!length(ls(linter_env))) stop(
1918
"No linters found after sourcing files in ", dQuote(args[[1]])
@@ -23,8 +22,7 @@ sources = list.files(args[[2]], pattern = args[[3]], full.names = TRUE, recursiv
2322
if (!length(sources)) stop(
2423
"No files to lint found in directory ", dQuote(args[[2]]), " for mask ", dQuote(args[[3]])
2524
)
26-
preprocess = if (length(args) == 4) eval(str2lang(args[[4]])) else identity
27-
sources = Filter(Negate(is.null), lapply(setNames(nm = sources), preprocess))
25+
sources = Filter(Negate(is.null), lapply(setNames(nm = sources), linter_env$.preprocess))
2826

2927
okay = TRUE
3028
for (src in names(sources))

.ci/linters/c/00preprocess.R

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.preprocess = function (f) list(
2+
c_obj = f, lines = readLines(f),
3+
preprocessed = system2(
4+
"gcc", shQuote(c("-fpreprocessed", "-E", f)),
5+
stdout = TRUE, stderr = FALSE
6+
)
7+
)

.ci/linters/po/00preprocess.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.preprocess = function (f) {
2+
diff_v_master = system2('git', c('diff', 'master', f), stdout=TRUE)
3+
if (length(diff_v_master)) f
4+
}

.github/workflows/code-quality.yaml

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,7 @@ jobs:
4040
run: /usr/bin/sudo apt-get -y install coccinelle
4141
- name: Lint
4242
run: |
43-
Rscript .ci/lint.R .ci/linters/c src '[.][ch]$' '
44-
function (f) list(
45-
c_obj = f, lines = readLines(f),
46-
preprocessed = system2(
47-
"gcc", shQuote(c("-fpreprocessed", "-E", f)),
48-
stdout = TRUE, stderr = FALSE
49-
)
50-
)
51-
'
43+
Rscript .ci/lint.R .ci/linters/c src '[.][ch]$'
5244
lint-po:
5345
runs-on: ubuntu-latest
5446
steps:
@@ -61,12 +53,7 @@ jobs:
6153
# until a translation is added or the blank/fuzzy translations removed. We'd
6254
# rather only have the failure on one PR, then ignore these files later.
6355
run: |
64-
Rscript .ci/lint.R .ci/linters/po po '[.]po$' "
65-
function (f) {
66-
diff_v_master = system2('git', c('diff', 'master', f), stdout=TRUE)
67-
if (length(diff_v_master)) f
68-
}
69-
"
56+
Rscript .ci/lint.R .ci/linters/po po '[.]po$'
7057
lint-md:
7158
runs-on: ubuntu-latest
7259
steps:

0 commit comments

Comments
 (0)