Skip to content

Commit ca0c032

Browse files
authored
Tidyverse upkeep (#673)
Do some tidy upkeep. Closes #661, closes #672.
1 parent b15040a commit ca0c032

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+406
-224
lines changed

.github/CODE_OF_CONDUCT.md

+120-19
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,126 @@
1-
# Contributor Code of Conduct
1+
# Contributor Covenant Code of Conduct
22

3-
As contributors and maintainers of this project, we pledge to respect all people who
4-
contribute through reporting issues, posting feature requests, updating documentation,
5-
submitting pull requests or patches, and other activities.
3+
## Our Pledge
64

7-
We are committed to making participation in this project a harassment-free experience for
8-
everyone, regardless of level of experience, gender, gender identity and expression,
9-
sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
5+
We as members, contributors, and leaders pledge to make participation in our
6+
community a harassment-free experience for everyone, regardless of age, body
7+
size, visible or invisible disability, ethnicity, sex characteristics, gender
8+
identity and expression, level of experience, education, socio-economic status,
9+
nationality, personal appearance, race, caste, color, religion, or sexual
10+
identity and orientation.
1011

11-
Examples of unacceptable behavior by participants include the use of sexual language or
12-
imagery, derogatory comments or personal attacks, trolling, public or private harassment,
13-
insults, or other unprofessional conduct.
12+
We pledge to act and interact in ways that contribute to an open, welcoming,
13+
diverse, inclusive, and healthy community.
1414

15-
Project maintainers have the right and responsibility to remove, edit, or reject comments,
16-
commits, code, wiki edits, issues, and other contributions that are not aligned to this
17-
Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed
18-
from the project team.
15+
## Our Standards
1916

20-
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by
21-
opening an issue or contacting one or more of the project maintainers.
17+
Examples of behavior that contributes to a positive environment for our
18+
community include:
2219

23-
This Code of Conduct is adapted from the Contributor Covenant
24-
(https://www.contributor-covenant.org), version 1.0.0, available at
25-
https://contributor-covenant.org/version/1/0/0/.
20+
* Demonstrating empathy and kindness toward other people
21+
* Being respectful of differing opinions, viewpoints, and experiences
22+
* Giving and gracefully accepting constructive feedback
23+
* Accepting responsibility and apologizing to those affected by our mistakes,
24+
and learning from the experience
25+
* Focusing on what is best not just for us as individuals, but for the overall
26+
community
27+
28+
Examples of unacceptable behavior include:
29+
30+
* The use of sexualized language or imagery, and sexual attention or advances of
31+
any kind
32+
* Trolling, insulting or derogatory comments, and personal or political attacks
33+
* Public or private harassment
34+
* Publishing others' private information, such as a physical or email address,
35+
without their explicit permission
36+
* Other conduct which could reasonably be considered inappropriate in a
37+
professional setting
38+
39+
## Enforcement Responsibilities
40+
41+
Community leaders are responsible for clarifying and enforcing our standards of
42+
acceptable behavior and will take appropriate and fair corrective action in
43+
response to any behavior that they deem inappropriate, threatening, offensive,
44+
or harmful.
45+
46+
Community leaders have the right and responsibility to remove, edit, or reject
47+
comments, commits, code, wiki edits, issues, and other contributions that are
48+
not aligned to this Code of Conduct, and will communicate reasons for moderation
49+
decisions when appropriate.
50+
51+
## Scope
52+
53+
This Code of Conduct applies within all community spaces, and also applies when
54+
an individual is officially representing the community in public spaces.
55+
Examples of representing our community include using an official e-mail address,
56+
posting via an official social media account, or acting as an appointed
57+
representative at an online or offline event.
58+
59+
## Enforcement
60+
61+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
62+
reported to the community leaders responsible for enforcement at [email protected].
63+
All complaints will be reviewed and investigated promptly and fairly.
64+
65+
All community leaders are obligated to respect the privacy and security of the
66+
reporter of any incident.
67+
68+
## Enforcement Guidelines
69+
70+
Community leaders will follow these Community Impact Guidelines in determining
71+
the consequences for any action they deem in violation of this Code of Conduct:
72+
73+
### 1. Correction
74+
75+
**Community Impact**: Use of inappropriate language or other behavior deemed
76+
unprofessional or unwelcome in the community.
77+
78+
**Consequence**: A private, written warning from community leaders, providing
79+
clarity around the nature of the violation and an explanation of why the
80+
behavior was inappropriate. A public apology may be requested.
81+
82+
### 2. Warning
83+
84+
**Community Impact**: A violation through a single incident or series of
85+
actions.
86+
87+
**Consequence**: A warning with consequences for continued behavior. No
88+
interaction with the people involved, including unsolicited interaction with
89+
those enforcing the Code of Conduct, for a specified period of time. This
90+
includes avoiding interactions in community spaces as well as external channels
91+
like social media. Violating these terms may lead to a temporary or permanent
92+
ban.
93+
94+
### 3. Temporary Ban
95+
96+
**Community Impact**: A serious violation of community standards, including
97+
sustained inappropriate behavior.
98+
99+
**Consequence**: A temporary ban from any sort of interaction or public
100+
communication with the community for a specified period of time. No public or
101+
private interaction with the people involved, including unsolicited interaction
102+
with those enforcing the Code of Conduct, is allowed during this period.
103+
Violating these terms may lead to a permanent ban.
104+
105+
### 4. Permanent Ban
106+
107+
**Community Impact**: Demonstrating a pattern of violation of community
108+
standards, including sustained inappropriate behavior, harassment of an
109+
individual, or aggression toward or disparagement of classes of individuals.
110+
111+
**Consequence**: A permanent ban from any sort of public interaction within the
112+
community.
113+
114+
## Attribution
115+
116+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
117+
version 2.1, available at
118+
<https://www.contributor-covenant.org/version/2/1/code_of_conduct.html>.
119+
120+
Community Impact Guidelines were inspired by
121+
[Mozilla's code of conduct enforcement ladder][https://github.com/mozilla/inclusion].
122+
123+
For answers to common questions about this code of conduct, see the FAQ at
124+
<https://www.contributor-covenant.org/faq>. Translations are available at <https://www.contributor-covenant.org/translations>.
125+
126+
[homepage]: https://www.contributor-covenant.org

DESCRIPTION

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,19 @@ URL: https://haven.tidyverse.org, https://github.com/tidyverse/haven,
1515
https://github.com/WizardMac/ReadStat
1616
BugReports: https://github.com/tidyverse/haven/issues
1717
Depends:
18-
R (>= 3.2)
18+
R (>= 3.4)
1919
Imports:
20+
cli (>= 3.0.0),
2021
forcats (>= 0.2.0),
2122
hms,
23+
lifecycle,
2224
methods,
2325
readr (>= 0.1.0),
2426
rlang (>= 0.4.0),
2527
tibble,
2628
tidyselect,
2729
vctrs (>= 0.3.0)
2830
Suggests:
29-
cli,
3031
covr,
3132
crayon,
3233
fs,

NAMESPACE

+3
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,11 @@ export(zap_missing)
101101
export(zap_widths)
102102
import(rlang)
103103
import(vctrs)
104+
importFrom(cli,cli_abort)
105+
importFrom(cli,cli_warn)
104106
importFrom(forcats,as_factor)
105107
importFrom(hms,hms)
108+
importFrom(lifecycle,deprecated)
106109
importFrom(methods,setOldClass)
107110
importFrom(stats,median)
108111
importFrom(stats,quantile)

NEWS.md

+7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
* Updated to ReadStat 1.1.8 RC (#650).
44

5+
* Errors and warnings now use `cli_abort()` and `cli_warning()`. cli >= 3.0.0
6+
has been added to imports to support this change (#661).
7+
8+
* R 3.4 is now the minimum supported version, in line with [tidyverse policy](https://www.tidyverse.org/blog/2019/04/r-version-support/).
9+
10+
* haven now uses the lifecycle package to manage deprecations.
11+
512
* `labelled()` vectors now throw a warning when combining two vectors with
613
conflicting labels (#667).
714

R/as_factor.R

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ as_factor.data.frame <- function(x, ..., only_labelled = TRUE) {
6060
#' @rdname as_factor
6161
#' @export
6262
as_factor.haven_labelled <- function(x, levels = c("default", "labels", "values", "both"),
63-
ordered = FALSE, ...) {
63+
ordered = FALSE, ...) {
6464
levels <- match.arg(levels)
6565
label <- attr(x, "label", exact = TRUE)
6666
labels <- attr(x, "labels")

R/haven-package.R

+4-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
## usethis namespace: start
66
#' @import rlang
77
#' @import vctrs
8-
#' @importFrom tibble tibble
8+
#' @importFrom cli cli_abort
9+
#' @importFrom cli cli_warn
910
#' @importFrom hms hms
11+
#' @importFrom lifecycle deprecated
12+
#' @importFrom tibble tibble
1013
## usethis namespace: end
1114
NULL

R/haven-sas.R

+19-18
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
#' specified columns will be read from `data_file`.
2020
#' @param skip Number of lines to skip before reading data.
2121
#' @param n_max Maximum number of lines to read.
22-
#' @param cols_only **Deprecated**: Use `col_select` instead.
22+
#' @param cols_only `r lifecycle::badge("deprecated")` `cols_only` is no longer
23+
#' supported; use `col_select` instead.
2324
#' @return A tibble, data frame variant with nice defaults.
2425
#'
2526
#' Variable labels are stored in the "label" attribute of each variable. It is
@@ -32,11 +33,10 @@
3233
#' read_sas(path)
3334
read_sas <- function(data_file, catalog_file = NULL,
3435
encoding = NULL, catalog_encoding = encoding,
35-
col_select = NULL, skip = 0L, n_max = Inf, cols_only = "DEPRECATED",
36-
.name_repair = "unique"
37-
) {
38-
if (!missing(cols_only)) {
39-
warning("`cols_only` is deprecated. Please use `col_select` instead.", call. = FALSE)
36+
col_select = NULL, skip = 0L, n_max = Inf, cols_only = deprecated(),
37+
.name_repair = "unique") {
38+
if (lifecycle::is_present(cols_only)) {
39+
lifecycle::deprecate_warn("2.2.0", "read_sas(cols_only)", "read_sas(col_select)")
4040
stopifnot(is.character(cols_only)) # used to only work with a char vector
4141

4242
# guarantee a quosure to keep NULL and tidyselect logic clean downstream
@@ -62,7 +62,7 @@ read_sas <- function(data_file, catalog_file = NULL,
6262
switch(class(spec_data)[1],
6363
source_file = df_parse_sas_file(spec_data, spec_cat, encoding = encoding, catalog_encoding = catalog_encoding, cols_skip = cols_skip, n_max = n_max, rows_skip = skip, name_repair = .name_repair),
6464
source_raw = df_parse_sas_raw(spec_data, spec_cat, encoding = encoding, catalog_encoding = catalog_encoding, cols_skip = cols_skip, n_max = n_max, rows_skip = skip, name_repair = .name_repair),
65-
stop("This kind of input is not handled", call. = FALSE)
65+
cli_abort("This kind of input is not handled.")
6666
)
6767
}
6868

@@ -96,16 +96,15 @@ write_sas <- function(data, path) {
9696
#' tmp <- tempfile(fileext = ".xpt")
9797
#' write_xpt(mtcars, tmp)
9898
#' read_xpt(tmp)
99-
read_xpt <- function(file, col_select = NULL, skip = 0, n_max = Inf, .name_repair = "unique"
100-
) {
99+
read_xpt <- function(file, col_select = NULL, skip = 0, n_max = Inf, .name_repair = "unique") {
101100
cols_skip <- skip_cols(read_xpt, {{ col_select }}, file)
102101
n_max <- validate_n_max(n_max)
103102

104103
spec <- readr::datasource(file)
105104
switch(class(spec)[1],
106105
source_file = df_parse_xpt_file(spec, cols_skip, n_max, skip, name_repair = .name_repair),
107106
source_raw = df_parse_xpt_raw(spec, cols_skip, n_max, skip, name_repair = .name_repair),
108-
stop("This kind of input is not handled", call. = FALSE)
107+
cli_abort("This kind of input is not handled.")
109108
)
110109
}
111110

@@ -121,12 +120,15 @@ read_xpt <- function(file, col_select = NULL, skip = 0, n_max = Inf, .name_repai
121120
#' Note that although SAS itself supports dataset labels up to 256 characters
122121
#' long, dataset labels in SAS transport files must be <= 40 characters.
123122
write_xpt <- function(data, path, version = 8, name = NULL, label = attr(data, "label")) {
124-
stopifnot(version %in% c(5, 8))
123+
if (!version %in% c(5, 8)) {
124+
cli_abort("SAS transport file version {.val {version}} is not currently supported.")
125+
}
125126

126127
if (is.null(name)) {
127128
name <- tools::file_path_sans_ext(basename(path))
128129
}
129130
name <- validate_xpt_name(name, version)
131+
label <- validate_xpt_label(label)
130132

131133
data <- validate_sas(data)
132134
write_xpt_(
@@ -148,27 +150,26 @@ validate_sas <- function(data) {
148150
adjust_tz(data)
149151
}
150152

151-
validate_xpt_name <- function(name, version) {
153+
validate_xpt_name <- function(name, version, call = caller_env()) {
152154
if (version == 5) {
153155
if (nchar(name) > 8) {
154-
stop("`name` must be 8 characters or fewer", call. = FALSE)
156+
cli_abort("{.arg name} must be 8 characters or fewer.", call = call)
155157
}
156-
157158
} else {
158159
if (nchar(name) > 32) {
159-
stop("`name` must be 32 characters or fewer", call. = FALSE)
160+
cli_abort("{.arg name} must be 32 characters or fewer.", call = call)
160161
}
161162
}
162163
name
163164
}
164165

165-
validate_xpt_label <- function(label) {
166+
validate_xpt_label <- function(label, call = caller_env()) {
166167
if (!is.null(label)) {
167168
stopifnot(is.character(label), length(label) == 1)
168169

169170
if (nchar(label) > 40) {
170-
stop("`label` must be 40 characters or fewer", call. = FALSE)
171+
cli_abort("{.arg label} must be 40 characters or fewer.", call = call)
171172
}
172173
}
174+
label
173175
}
174-

0 commit comments

Comments
 (0)