Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .syncweaver-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"sources": {
"code/MOSuite": {
"repo_url": "https://github.com/CCBR/MOSuite",
"ref": "v0.4.1",
"git_sha": "4e85d49ab155618d9f6beafd327b6fb87dfa8609"
"ref": "v0.4.2",
"git_sha": "c06ecdff1292eefca106aa83112b579c8b509689"
}
}
}
1 change: 1 addition & 0 deletions code/MOSuite/.Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
^Rplots\.pdf$
^SECURITY\.md$
^tests/figures$
^tests/testthat/figures/var
^vignettes/cli\.Rmd$
^vignettes/figures/$
^vignettes/memory\.Rmd$
Expand Down
79 changes: 69 additions & 10 deletions code/MOSuite/.github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,52 @@ If you've decided to work on an issue,
[assign yourself to the issue](https://docs.github.com/en/issues/tracking-your-work-with-issues/assigning-issues-and-pull-requests-to-other-github-users#assigning-an-individual-issue-or-pull-request)
so others will know you're working on it.

## AI Use

Generative AI usage is welcome for generating code, documentation, and other text in this repository.
Please remember that this project is maintained by humans; every discussion,
issue, and pull request is read and reviewed by humans (and sometimes machines,
too).
Therefore, there are guidelines to make sure contributors' AI usage is helpful,
productive, and responsible:

- **The human-in-the-loop must fully understand and approve all code and content.**
You must evaluate the output of AI tools.
Do not assume that AI-generated output is correct, accurate, or complete.
You must be able to explain what your changes do and how they interact with the
greater system in your own words.

From the [NIH AI Policy](https://nih.sharepoint.com/sites/NIH-ai/SitePages/Responsible-AI.aspx):
> Do not rely on the technology to be a software developer by proxy: All
> well-written code must adhere to security design and ethical principles.
> **All code output needs to be reviewed** for completeness, quality,
> efficiency, and, most of all, security.
> Leverage manual and automated validation tools and testing technologies to
> help ensure these factors.
> **If you cannot identify or understand what a piece of AI generated code
> does, you should not use it.**

- **Issues and discussions can use AI assistance but must have a full human-in-the-loop.**
This means that any content generated with AI must have been reviewed _and
edited_ by a human before submission. AI is very good at being overly verbose
and including noise that distracts from the main point. Humans must do their
research and trim this down to be concise and precise.

- **All AI usage should be disclosed.**
In the footer of commit messages and in Pull Request descriptions:
- State the tool and model version used
(e.g. Claude Code w/ Claude Sonnet 5, Codex w/ GPT-5.6 Sol, Copilot w/ GPT-5.6 Terra, etc.)
- Include a brief description of how AI assistance was used
(e.g. writing code, writing unit tests, troubleshooting problems, software design discussion, commit messages, preparing pull requests).


<sub>
_These AI usage guidelines were adapted from
[ghostty](https://github.com/ghostty-org/ghostty/blob/22d13172cde98a0a4dda05d3d6a3fcb0dd8ed018/AI_POLICY.md)
and the
[NIH AI Policy](https://nih.sharepoint.com/sites/NIH-ai/SitePages/Responsible-AI.aspx)._
</sub>

## Pull request process

We use [GitHub Flow](https://docs.github.com/en/get-started/using-github/github-flow)
Expand Down Expand Up @@ -50,20 +96,29 @@ cd MOSuite

### If this is your first time cloning the repo, install dependencies

#### R dependencies

- In an R console, install the R development dependencies with
`devtools::install_dev_deps()`, and then make sure the package passes R CMD
check by running `devtools::check()`. If R CMD check doesn't pass cleanly,
it's a good idea to ask for help before continuing.
`devtools::install_dev_deps()`.
- Alternatively, we have a docker container available with MOSuite's dependencies installed:
[`docker://nciccbr/mosuite-minmal:latest`](https://hub.docker.com/r/nciccbr/mosuite-minimal).
You can launch the container using your preferred engine (e.g. Docker, Podman, apptainer/singularity)
with your clone of the repo mounted while developing your contributions.

- Install [`pre-commit`](https://pre-commit.com/#install) if you don't already
have it. Then from the repo's root directory, run
Before you make any changes, make sure the package passes R CMD check by running `devtools::check()`.
If R CMD check doesn't pass cleanly, it's a good idea to **ask for help before continuing**.

```sh
pre-commit install
```
#### Pre-commit

This will install the repo's pre-commit hooks.
You'll only need to do this step the first time you clone the repo.
Install [`pre-commit`](https://pre-commit.com/#install) if you don't already
have it. Then from the repo's root directory, run

```sh
pre-commit install
```

This will install the repo's pre-commit hooks.
You'll only need to do this step the first time you clone the repo.

### Create a branch

Expand Down Expand Up @@ -109,6 +164,10 @@ Test files are organized as described in
<https://style.tidyverse.org/tests.html>.
Take a look at the existing code in this package for examples.

Ensure your tests cover all of the code changes you make, including various
parameter options and edge cases.
Do not skip tests unless you can give a strong reason for doing so.

#### document

If you have written a new function or changed the API of an existing function,
Expand Down
14 changes: 14 additions & 0 deletions code/MOSuite/.github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

<!--
Provide a brief summary of what is included in this Pull Request (PR).
If the PR contains complex changes, include a brief description of the rationale
behind the implementation decisions.
-->

## Issues
Expand All @@ -13,6 +15,18 @@ If this PR fixes any issues,
when referring to the issue so it will be closed automatically when the PR is merged.
-->

<!-- Uncomment the below header if including an AI usage statement:
## Generative AI Usage Statement
-->
<!--
Include a brief description of how AI assistance was used to generate any of the code or content included in this PR,
e.g. writing code, writing unit tests, troubleshooting problems, software design discussion, commit messages, or preparing the PR.
Disclose the tool and model version used, e.g. Claude Code w/ Claude Sonnet 5, Codex w/ GPT-5.6 Sol, Copilot w/ GPT-5.6 Terra, etc.

If generative AI tools were not used in any way whatsoever, uncomment the following line:
_No generative AI tools were used_
-->

## PR Checklist

(~Strikethrough~ any points that are not applicable.)
Expand Down
18 changes: 15 additions & 3 deletions code/MOSuite/.github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@

## CI & enforcement suggestions (automatable)

1. **PR template**: include optional AI-assistance disclosure fields (model used, high-level prompt intent, manual review confirmation).
1. **Pull Request template**: include optional AI-assistance disclosure fields (model used, high-level prompt intent, manual review confirmation).
2. **Pre-merge check (GitHub Action)**: verify `.github/copilot-instructions.md` is present in the repository and that new pipeline files include a `# CRAFT:` header.
3. **Lint jobs**: `ruff` for Python, `shellcheck` for shell, `lintr` for R, and `nf-core lint` or Snakemake lint checks where applicable.
3. **Lint jobs**: `ruff` for Python, `shellcheck` for shell, `lintr` for R, `nf-core lint` for Nextflow, or Snakemake lint checks where applicable.
4. **Secrets scan**: run `TruffleHog` or `Gitleaks` on PRs to detect accidental credentials.
5. **AI usage label**: if AI usage is declared, an Action should add `generated-by-AI` label (create this label if it does not exist); the PR body should end with the italicized Markdown line: _Generated using AI_, and any associated commit messages should end with the plain footer line: `Generated using AI`.

Expand Down Expand Up @@ -108,7 +108,7 @@ Rules:

## Pull Requests

When opening a pull request, use the repository's pull request template (usually it is `.github/PULL_REQUEST_TEMPLATE.md`).
When opening a pull request, agents and authors must use the repository's pull request template (`.github/PULL_REQUEST_TEMPLATE.md`).
Different repos have different PR templates depending on their needs.
Ensure that the pull request follows the repository's PR template and includes all required information.
Do not allow the developer to proceed with opening a PR if it does not fill out all sections of the template.
Expand Down Expand Up @@ -138,6 +138,18 @@ Example:
- Fix bug in `detect_absolute_paths()` to ignore comments. (#123, @username)
```

## Release Process

To cut a new release in a repo, first use the draft-release workflow
(`.github/workflows/draft-release.yml`) to draft the release.
Then the human developer must review the draft release and ensure it meets
quality standards, then publish the release.
AI agents must not publish a release, it can only be done by human developers.
When the release is published, the post-release workflow (`.github/workflows/post-release.yml`)
will run automatically and open a new Pull Request.
The human developer must then review the PR, and approve & merge it if the PR
meets quality standards.

## Onboarding checklist for new developers

- [ ] Read `.github/CONTRIBUTING.md` and `.github/copilot-instructions.md`.
Expand Down
23 changes: 19 additions & 4 deletions code/MOSuite/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ multi-omic experiments.
Development of MOSuite follows the R packages 2nd edition (https://r-pkgs.org/),
with a few minor exceptions noted below.
Helper functions from `usethis` and `devtools` are used extensively for development tasks.
Human developers should refer to the [contributing guidelines](./.github/CONTRIBUTING.md)
for detailed instructions on how to contribute to MOSuite.

## Package conventions

Expand All @@ -18,6 +20,7 @@ Helper functions from `usethis` and `devtools` are used extensively for developm
- The package must pass `devtools::check()`.
- R code should adhere to the tidyverse style guide. https://style.tidyverse.org/
- Only include one return statement at the end of a function. Explicit returns are preferred but not required for R functions.
- `NAMESPACE` and `man/` are generated by `devtools::document()`; never edit these files directly.

## Commit messages

Expand All @@ -27,18 +30,30 @@ Helper functions from `usethis` and `devtools` are used extensively for developm
- If mixed changes are present, split into multiple logical commits; the number of commits does not need to equal the number of files changed.
- Subject format must be: `<type>(optional-scope): short imperative summary` (<=72 chars), e.g., `fix(profile): update release table parser`.
- Add a body only when needed to explain **why** and notable impact; never include secrets, tokens, PHI, or large diffs.
- For AI-assisted commits, add this final italicized footer line in the commit message body: _commit message is ai-generated_
- For commits containing any AI-generated code, commit messages, or any other AI-generated content,
add this final italicized footer line in the commit message body: "_AI assistance: [model]_".
Replace [model] with the actual model version used, e.g. Claude Sonnet 5, GPT-5.6 Sol, etc.

## Pull request (PR) process

- PR titles must follow Conventional Commits format (see "Commit messages" section).
- When opening a PR, use the request template (`.github/PULL_REQUEST_TEMPLATE.md`) and fill out all sections of the template in the PR description.
- Do not allow the developer to proceed with opening a PR if it does not fill out all sections of the template.
- Before a PR can be moved from draft to "ready for review", all of the relevant checklist items must be checked, and any
irrelevant checklist items should be crossed out.
- If code is AI-generated, the PR should be labeled `generated-by-AI`. There should be a brief, concise statement in the PR description of how AI was used in creating the PR (model used, high-level prompt intent, manual review confirmation).
- When new features, bug fixes, or other behavioral changes are introduced to the code,
unit tests must be added or updated to cover the new or changed functionality.
- If the PR contains any code or other content that was generated with AI
assistance, including AI assistance for opening the PR itself, the PR should
be labeled `AI-assisted`. In the PR description, uncomment the heading
"Generative AI Usage Statement" and add a brief, concise statement of how AI
was used in creating the PR (model used, high-level prompt intent, manual
review confirmation, etc.).
- When new features, bug fixes, or other behavioral changes are introduced to
the code, unit tests must be added or updated to cover the new or changed
functionality.
- Unit tests should cover all of the code that is added or modified in a PR.
- Unit tests should not be skipped without a strong reason.
- If there are any API or other user-facing changes, the documentation must be updated both inline via roxygen comments and long-form docs in the `vignettes/` directory as R Markdown files.
- If there are merge conflicts, a human developer must resolve them. AI agents must not agree to assist with resolving merge conflicts. Human developers who are unsure how to proceed should reach out to the lead maintainer or code owner.
- The `R-CMD-check` github actions workflow must pass before the PR can be approved.

### Changelog
Expand Down
4 changes: 2 additions & 2 deletions code/MOSuite/CITATION.cff

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions code/MOSuite/DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: MOSuite
Title: R package for differential multi-omics analysis
Version: 0.4.1
Version: 0.4.2
Authors@R: c(
person("Kelly", "Sovacool", , "kelly.sovacool@nih.gov", role = c("aut", "cre"),
comment = c(ORCID = "0000-0003-3283-829X")),
Expand Down Expand Up @@ -85,11 +85,10 @@ VignetteBuilder:
biocViews:
Config/Needs/dev: cffr, covr, here, lintr, pkgdown,
rcmdcheck, xml2
Config/roxygen2/version: 8.0.0
Config/roxygen2/version: 8.1.0
Config/testthat/edition: 3
Config/testthat/parallel: true
Encoding: UTF-8
LazyData: true
LazyDataCompression: xz
Roxygen: list(markdown = TRUE)
RoxygenNote: 8.0.0
10 changes: 6 additions & 4 deletions code/MOSuite/NAMESPACE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions code/MOSuite/NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## MOSuite 0.4.2

- Align Volcano Plot threshold comparisons across labeling, coloring, and summary filtering, and use resolved column names for classification. (#266, @TJoshMeyer)
- `normalize_counts()` now uses normalized counts instead of filtered counts for
the correlation heatmap so it matches the PCA and histogram outputs. (#269,
@phoman14)

## MOSuite 0.4.1

- Fix how `plot_volcano_summary()` & `plot_volcano_enhanced` handle detecting column names for features, significance, and fold-change. `plot_volcano_summary()` plot now uses `plot_volcano_enhanced()` for rendering. (#239, @phoman14)
Expand Down
49 changes: 49 additions & 0 deletions code/MOSuite/R/cli.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ cli_exec <- function(clargs = commandArgs(trailingOnly = TRUE)) {
return(invisible(cli_exec_impl(clargs)))
}

#' Internal implementation of CLI execution
#'
#' Parses command-line arguments and dispatches to the appropriate MOSuite
#' function. Called by [cli_exec()].
#'
#' @param clargs character vector of command-line arguments.
#'
#' @return result of the dispatched MOSuite function call.
#' @keywords internal
cli_exec_impl <- function(clargs) {
# check for tool called without arguments, or called with '--help'
usage <- length(clargs) == 0 || clargs[1L] %in% c("help", "--help")
Expand Down Expand Up @@ -77,6 +86,15 @@ cli_exec_impl <- function(clargs) {
return(do.call(args[[1L]], args[-1L], envir = globalenv()))
}

#' Print CLI usage information
#'
#' Writes a usage summary for the `mosuite` command-line tool to a connection,
#' typically `stderr()`.
#'
#' @param con connection to write usage text to. Defaults to `stderr()`.
#'
#' @return invisibly returns `NULL`.
#' @keywords internal
cli_usage <- function(con = stderr()) {
usage <- "
Usage: mosuite [function] [--json=path/to/args.json]
Expand Down Expand Up @@ -104,10 +122,29 @@ Main functions:
return(writeLines(usage, con = con))
}

#' Print help for a CLI method
#'
#' Displays the R help page for the named MOSuite function in the `MOSuite`
#' package.
#'
#' @param method name of the MOSuite function to show help for.
#'
#' @return result of `print(utils::help(...))`, invisibly.
#' @keywords internal
cli_help <- function(method) {
return(print(utils::help(method, package = "MOSuite")))
}

#' Build an unknown-command error message
#'
#' Constructs an error message for an unrecognised CLI method name, optionally
#' suggesting similar exported function names based on edit distance.
#'
#' @param method the unrecognised method name supplied by the user.
#' @param exports character vector of exported function names from MOSuite.
#'
#' @return character string with the error message.
#' @keywords internal
cli_unknown <- function(method, exports) {
# report unknown command
msg <- glue::glue("MOSuite: {method} is not a known function.")
Expand All @@ -125,6 +162,18 @@ cli_unknown <- function(method, exports) {
return(msg)
}

#' Parse a single CLI argument string
#'
#' Converts a raw CLI argument string to an R value. Logical-like strings
#' (`"true"`, `"false"`, etc.) are returned as `TRUE`/`FALSE`. Other strings
#' are parsed as R expressions; if the result is a language object, the
#' original string is returned as-is.
#'
#' @param text character string to parse.
#'
#' @return parsed R value, or `text` unchanged if parsing yields a language
#' object.
#' @keywords internal
cli_parse <- function(text) {
# handle logical-like values up-front
if (text %in% c("true", "True", "TRUE")) {
Expand Down
Loading
Loading