IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Keep your R code clean and consistent with Air

    Yohann Mansiaux发表于 2025-05-19 00:00:00
    love 0
    [This article was first published on Yohann's blog, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
    Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

    Consistent code formatting is a crucial aspect of collaborative development that often gets overlooked. Well-formatted code provides several significant benefits:

    • Readability: Uniform formatting makes code easier to read and understand for everyone
    • Maintainability: Consistent style reduces cognitive load when navigating through code
    • Collaboration: Standardized formatting reduces merge conflicts and makes code reviews more efficient

    Air formatter for R brings these benefits to R codebases with minimal setup effort, helping teams establish and maintain a consistent coding style automatically. While this guide focuses specifically on Air, the principles and benefits apply to any code formatter – the most important factor is having all team members use the same formatting tool with consistent settings.

    Requirements

    • Air installed
    • Depending on your IDE, you may also need to install some extensions (as as VSCode user I had to install the Air – R Language Support extension).
    • To test if the formatter is working, you can use the following command: air format . in a Terminal (not the R console) !

    Please read the following resources before starting:

    • https://posit-dev.github.io/air/formatter.html
    • https://www.tidyverse.org/blog/2025/02/air/

    Warning for VSCode users

    Before using Air I was using the REditorSupport formatter provided with the R extension for VSCode. Air was not working, because I forgot to edit correctly my settings.json file.

    If you wish Air to be used as your default formatter, please comment or remove the line "editor.defaultFormatter": "REditorSupport.r" in your settings.json file.

      "[r]": {
        // "editor.defaultFormatter": "REditorSupport.r",
        "editor.formatOnSave": true
      }
      "[rmd]": {
        // "editor.defaultFormatter": "REditorSupport.r",
        "editor.formatOnSave": true
      }
      "[quarto]": {
        // "editor.defaultFormatter": "REditorSupport.r",
        "editor.formatOnSave": true
      }

    As set in the settings.json file, Air is used as the default formatter as will be applied on save of any R file. There are other ways to use Air, the pre-commit or the Github Actions workflow.

    Pre-commit hook

    A pre-commit hook is an operation that is performed before a commit is made. If you are a R package developer, you sometimes already have been complaning about a message telling that both README-related files: README.md and README.Rmd must be staged together in a specific commit.

    This pre-commit hook is added automatically to your project when you are using usethis::use_readme_rmd() !

    How to add a pre-commit hook

    usethis::use_git_hook(
      "pre-commit",
      "air format ."
      )

    This command implies that for each commit you will make, the entire codebase of your project will be reformated.

    Pre-commit hooks are located in a hidden folder of your repository. If you want to take a look at the generated/modified file you must look for the following file (starting from the root of your project): .git/hooks/pre-commit

    The pros of pre-commit hooks are:

    • Ensures all code is formatted before it’s committed to the repository
    • Prevents unformatted code from entering the codebase
    • Enforces consistent code style across the project

    The cons of pre-commit hooks are:

    • They are local to each developer’s machine and must be set up individually
    • Can be bypassed with git commit --no-verify if a developer chooses to
    • May slow down the commit process for large codebases
    • Requires Air to be installed on each developer’s machine
    • If formatting rules change, all developers need to update their local setup

    If you are already using the option "editor.formatOnSave": true, the pre-commit hook might be useless (except for the first time you will be using it, by formatting the entire codebase), and you might be more interested in using the Github Actions workflow !

    Using Github Actions

    In the main branch of a project I want to have only “bullet-proof” code, i.e a code in which the devtools::check() returns no error, no warning, no note. Each time I’m opening a Pull Request from a branch to the main branch, I run a Github Action which calls devtools::check(). I allow merging the proposed code only if this Github Action pass.

    To ensure that the merged code has also the expected format, I’ve completed my Github Action yaml configuration file to call the Air formatter on my codebase only if the devtools::check() was successful.

    This very convenient when you are working with other colleagues on the same project, with potentially different IDE, to ensure the code format is the same between everyone and hence to avoid merge conflicts because of formatting.

    Contrary to pre-commit hooks which are “computer-specific”, Github Actions workflow will be run remotely, ensuring that any modification to the code formatter settings will be applied to any code submitted to the main codebase !

    To use this Github Actions workflow, please create the following folder: .github/workflow/ and add the following in a .yaml file.

    # Workflow derived from https://github.com/posit-dev/setup-air/tree/main/examples
    on:
      pull_request:
        branches: [main, master]
    
    name: check_and_formatting.yml
    
    permissions:
      contents: write
    
    jobs:
      R-CMD-check:
        runs-on: ${{ matrix.config.os }}
    
        name: ${{ matrix.config.os }} (${{ matrix.config.r }})
    
        strategy:
          fail-fast: false
          matrix:
            config:
              - { os: ubuntu-latest, r: "release" }
    
        env:
          GITHUB_PAT: ${{ secrets.GH_TOKEN }}
          R_KEEP_PKG_SOURCE: yes
    
        steps:
          - uses: actions/checkout@v4
    
          - uses: r-lib/actions/setup-pandoc@v2
    
          - uses: quarto-dev/quarto-actions/setup@v2
    
          - uses: r-lib/actions/setup-r@v2
            with:
              r-version: ${{ matrix.config.r }}
              http-user-agent: ${{ matrix.config.http-user-agent }}
              use-public-rspm: true
    
          - uses: r-lib/actions/setup-r-dependencies@v2
            with:
              extra-packages: any::rcmdcheck
              needs: check
    
          - uses: r-lib/actions/check-r-package@v2
            with:
              upload-snapshots: true
              build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")'
    
      format-check:
        name: format-check
        needs: R-CMD-check
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
    
          - name: Install
            uses: posit-dev/setup-air@v1
    
          - name: Check
            run: air format .
    
          - name: Commit changes
            run: |
              git config --global user.name "github-actions[bot]"
              git config --global user.email "github-actions[bot]@users.noreply.github.com"
              git add .
              git diff --cached --quiet || git commit -m "style: auto-format code via air format"
    
          - name: Push changes
            if: github.event_name == 'pull_request' && github.head_ref != ''
            run: |
              git pull --rebase origin ${{ github.head_ref }}
              git push origin HEAD:${{ github.head_ref }}

    Conclusion

    Implementing automated code formatting with Air provides immediate benefits for both individual developers and teams. Whether you choose to use the formatter through your IDE, pre-commit hooks, or GitHub Actions, the result is the same: consistently formatted code that’s easier to read, maintain, and collaborate on.

    By incorporating Air into your workflow:

    • You eliminate time-consuming style discussions and manual formatting
    • Your codebase maintains a consistent style regardless of who contributes
    • Code reviews can focus on substance rather than style
    • New team members can quickly adapt to your project’s conventions

    Don’t hesitate to ask me any question about this workflow or any idea of improvement !

    To leave a comment for the author, please follow the link and comment on their blog: Yohann's blog.

    R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
    Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
    Continue reading: Keep your R code clean and consistent with Air


沪ICP备19023445号-2号
友情链接