diff --git a/.Rbuildignore b/.Rbuildignore index acbd9da..c14b81a 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -16,3 +16,5 @@ ^pkgdown$ ^data-raw$ ^\.pre-commit-config.yaml$ +^[.]?air[.]toml$ +^\.vscode$ diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index dba3b9a..4d27e1c 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -37,13 +37,55 @@ Our procedures for contributing bigger changes, code in particular, generally fo ### Code style - New code should follow the tidyverse [style guide](https://style.tidyverse.org). - You can use the [styler](https://CRAN.R-project.org/package=styler) package to apply these styles, but please don't restyle code that has nothing to do with your PR. + We use [Air](https://posit-dev.github.io/air/) for code formatting. - We use [roxygen2](https://cran.r-project.org/package=roxygen2), with [Markdown syntax](https://cran.r-project.org/web/packages/roxygen2/vignettes/rd-formatting.html), for documentation. - We use [testthat](https://cran.r-project.org/package=testthat) for unit tests. Contributions with test cases included are easier to accept. +#### Setting up Air + +The project contains configuration files (`air.toml`, `.vscode/`) that ensure formatting is scoped to this repository only—your personal projects remain unaffected. + +**Positron** + +Air ships built-in with Positron. The project settings are already configured, so format-on-save is enabled automatically when working in this repo. + +**VS Code** + +1. Install the [Air extension](https://marketplace.visualstudio.com/items?itemName=Posit.air-vscode) +2. The project settings are already configured, so format-on-save is enabled automatically when working in this repo + +**RStudio (2024.12.0+)** + +RStudio requires manual setup. Note that RStudio does not support per-project settings, so these are global options. + +1. Install the Air CLI: + - macOS/Linux: `curl -LsSf https://github.com/posit-dev/air/releases/latest/download/air-installer.sh | sh` + - macOS (Homebrew): `brew install air` + - Windows: `powershell -ExecutionPolicy Bypass -c "irm https://github.com/posit-dev/air/releases/latest/download/air-installer.ps1 | iex"` + +2. In RStudio, go to **Tools > Global Options > Code > Formatting** and: + - Check "Use external formatter" + - Set "Reformat command:" to `{path/to/air} format` (find the path with `which air` on macOS/Linux) + - See the [RStudio setup guide](https://posit-dev.github.io/air/editor-rstudio.html) for more details + +3. Optionally, enable format-on-save globally: + - In the same settings pane, check "Format code on save" + - **Note:** This applies to all projects, not just hubverse repos + +4. If you prefer not to enable format-on-save globally, format manually before committing: + - Use **Code > Reformat Code** (Cmd/Ctrl+Shift+A) or right-click and select "Reformat Code" + - CI will check formatting on PRs and fail if code is not formatted + +**Command Line** + +Works from any terminal: +- Format entire project: `air format .` +- Check without modifying: `air format . --check` + + ## Code of Conduct Please note that the hubExamples project is released with a diff --git a/.github/workflows/format-check.yaml b/.github/workflows/format-check.yaml new file mode 100644 index 0000000..4d336f7 --- /dev/null +++ b/.github/workflows/format-check.yaml @@ -0,0 +1,23 @@ +on: + push: + branches: [main, master] + pull_request: + +name: format-check.yaml + +permissions: read-all + +jobs: + format-check: + name: format-check + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install Air + uses: posit-dev/setup-air@63e80dedb6d275c94a3841e15e5ff8691e1ab237 # v1 + + - name: Check formatting + run: air format . --check + diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..344f76e --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "Posit.air-vscode" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a9f69fe --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "[r]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "Posit.air-vscode" + }, + "[quarto]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "quarto.quarto" + } +} diff --git a/air.toml b/air.toml new file mode 100644 index 0000000..e69de29 diff --git a/data-raw/generate_example_forecast_data.R b/data-raw/generate_example_forecast_data.R index c449fca..8c8deed 100755 --- a/data-raw/generate_example_forecast_data.R +++ b/data-raw/generate_example_forecast_data.R @@ -7,7 +7,11 @@ library(readr) s3_bucket_name <- "example-complex-forecast-hub" check_bucket <- bucket_exists(s3_bucket_name) -if (isFALSE(check_bucket)) {{ stop("Aborting: ", s3_bucket_name, " S3 bucket not found") }} +if (isFALSE(check_bucket)) { + { + stop("Aborting: ", s3_bucket_name, " S3 bucket not found") + } +} hub_path <- s3_bucket(s3_bucket_name) @@ -19,7 +23,8 @@ create_forecast_outputs <- function() { dplyr::filter( .data[["location"]] %in% l_keep, .data[["output_type"]] != "quantile" | - (.data[["output_type"]] == "quantile" & .data[["output_type_id"]] %in% q_lvls_keep), + (.data[["output_type"]] == "quantile" & + .data[["output_type_id"]] %in% q_lvls_keep), .data[["reference_date"]] %in% d_keep ) |> hubData::collect_hub() @@ -34,7 +39,11 @@ create_forecast_target_ts <- function() { } create_forecast_oracle_output <- function() { - target_oracle_output_data_path <- paste("target-data", "oracle-output.csv", sep = "/") + target_oracle_output_data_path <- paste( + "target-data", + "oracle-output.csv", + sep = "/" + ) readr::read_csv( aws.s3::get_object(target_oracle_output_data_path, bucket = s3_bucket_name), show_col_types = FALSE diff --git a/data-raw/generate_example_scenario_data.R b/data-raw/generate_example_scenario_data.R index 47bc9ee..53517ce 100644 --- a/data-raw/generate_example_scenario_data.R +++ b/data-raw/generate_example_scenario_data.R @@ -9,8 +9,12 @@ library(hubEnsembles) hub_path <- "../example-complex-scenario-hub/" scenario_outputs <- hubData::connect_hub(hub_path) |> - dplyr::filter(target == "inc case", location == "US", - origin_date == "2021-03-07", output_type == "quantile") |> + dplyr::filter( + target == "inc case", + location == "US", + origin_date == "2021-03-07", + output_type == "quantile" + ) |> dplyr::collect() |> dplyr::select(-age_group, -target_date) scenario_ens <- hubEnsembles::simple_ensemble(scenario_outputs) @@ -19,8 +23,7 @@ scenario_outputs <- hubData::as_model_out_tbl(scenario_outputs) target_ts_data_path <- file.path(hub_path, "target-data", "time-series.parquet") scenario_target_ts <- arrow::read_parquet(target_ts_data_path) |> - dplyr::filter(target == "inc case", location == "US", - date > "2020-10-01") + dplyr::filter(target == "inc case", location == "US", date > "2020-10-01") usethis::use_data(scenario_outputs, overwrite = TRUE) usethis::use_data(scenario_target_ts, overwrite = TRUE) diff --git a/tests/testthat/test-generate_example_forecast_data.R b/tests/testthat/test-generate_example_forecast_data.R index 012e415..43946f1 100644 --- a/tests/testthat/test-generate_example_forecast_data.R +++ b/tests/testthat/test-generate_example_forecast_data.R @@ -11,8 +11,15 @@ source(file.path(forecast_data_path, "generate_example_forecast_data.R")) test_that("forecast_outputs dataset is generated correctly", { cols <- c( - "output_type", "reference_date", "horizon", "target_end_date", - "location", "model_id", "target", "output_type_id", "value" + "output_type", + "reference_date", + "horizon", + "target_end_date", + "location", + "model_id", + "target", + "output_type_id", + "value" ) load(test_path("testdata", "forecast_outputs.rda")) @@ -32,7 +39,14 @@ test_that("forecast_outputs dataset is generated correctly", { test_that("forecast_oracle_output dataset is generated correctly", { - cols <- c("location", "target_end_date", "target", "output_type", "output_type_id", "oracle_value") + cols <- c( + "location", + "target_end_date", + "target", + "output_type", + "output_type_id", + "oracle_value" + ) load(test_path("testdata", "forecast_oracle_output.rda")) expected_forecast_oracle_output <- forecast_oracle_output %>%