Skip to content

Fix Issue #200: Generate command fails with workflow.onComplete/onError lifecycle hooks#363

Merged
nvnieuwk merged 2 commits into
askimed:mainfrom
MikeWLloyd:fix-200
Apr 27, 2026
Merged

Fix Issue #200: Generate command fails with workflow.onComplete/onError lifecycle hooks#363
nvnieuwk merged 2 commits into
askimed:mainfrom
MikeWLloyd:fix-200

Conversation

@MikeWLloyd

Copy link
Copy Markdown
Contributor

Description

Fixes an issue where nf-test generate command would fail when a workflow contains Nextflow lifecycle hook calls like workflow.onComplete, workflow.onError, or workflow.onSuccess. The command would incorrectly identify these lifecycle hook blocks as separate named workflows, causing the generator to skip test file creation.

Root Cause

The regex pattern in NextflowScript.getWorkflowNames() was too greedy:

// OLD - matches both "workflow myName" AND "workflow.onComplete"
String pattern = "(?i)^\\s*workflow\\s*(.+)(\\s*\\{|\\{)";

When parsing a file with lifecycle hooks, it would match both the actual workflow definition and the lifecycle hook blocks, incorrectly counting them as multiple workflows. The generator would then skip generation because it expects exactly one named workflow per file.

Solution

Updated the regex pattern to only match valid workflow identifiers (not dot notation):

// NEW - only matches valid identifiers like "myWorkflow", not ".onComplete"
String pattern = "(?i)^\\s*workflow\\s+([a-zA-Z_][a-zA-Z0-9_]*)(\\s*\\{|\\{)";

This pattern:

  • Requires at least one space after workflow keyword
  • Only captures valid identifiers (letters, digits, underscores)
  • Excludes dot notation like .onComplete, .onError, .onSuccess

Changes

Core Fix:

NextflowScript.java- Updated getWorkflowNames() regex pattern

Tests:

NextflowScriptTest.java - Added 4 unit tests:
testGetWorkflowNamesIgnoresOnComplete()
testGetWorkflowNamesIgnoresOnError()
testGetWorkflowNamesIgnoresOnSuccess()
testGetWorkflowNamesIgnoresMultipleLifecycleHooks()

Test Data:

lifecycle_hooks.nf- Example workflow with lifecycle hooks
lifecycle_hooks.nf.test - Test case for the workflow

Testing

✅ Unit Tests: All 34 NextflowScriptTest tests pass (including 4 new tests for this fix)
✅ Integration Tests: GenerateTestsCommandTest passes (6/6)
✅ Manual Verification: Confirmed the generate command now successfully handles workflows with lifecycle hooks

Example

Before (would fail):

workflow myWorkflow {
  // workflow logic
}

workflow.onComplete {
  println "Done!"
}

workflow.onError {
  println "Error!"
}

After (works):

$ nf-test generate workflow example.nf
Load source file 'example.nf'
Found 1 workflow: [myWorkflow]
Wrote workflow test file 'tests/example.nf.test'
SUCCESS: Generated 1 test files.

Related Issues

Fixes #200

Co-authored-by: Copilot <copilot@github.com>

@nvnieuwk nvnieuwk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution! Could you also update the patterns for process (getProcessNames) and function (getFunctionNames) name fetching?

Co-authored-by: Copilot <copilot@github.com>
@MikeWLloyd

MikeWLloyd commented Apr 24, 2026

Copy link
Copy Markdown
Contributor Author

@nvnieuwk sure thing. I just pushed the requested changes, here is a summary:

  1. Process Pattern Update
// OLD
String pattern = "(?i)^\\s*process\\s*(.+)(\\s*\\{|\\{)";

// NEW - only matches valid identifiers
String pattern = "(?i)^\\s*process\\s+([a-zA-Z_][a-zA-Z0-9_]*)(\\s*\\{|\\{)";
  1. Function Pattern Update
// OLD
String pattern = "(?i)^\\s*def\\s*(.+)(\\s*\\(|\\()";

// NEW - only matches valid identifiers
String pattern = "(?i)^\\s*def\\s+([a-zA-Z_][a-zA-Z0-9_]*)(\\s*\\(|\\()";
  1. Added 4 New Tests

testGetProcessNamesIgnoresDotNotation() - Verifies process.ext is not matched
testGetFunctionNamesIgnoresDotNotation() - Verifies def.extension is not matched
testGetProcessNamesRequiresSpace() - Ensures space is required after keyword
testGetFunctionNamesRequiresSpace() - Ensures space is required after keyword

Test Results:

  • NextflowScriptTest: 38/38 PASS (34 original + 4 new)
  • GenerateTestsCommandTest: 6/6 PASS

All three regex patterns (process, function, workflow) now consistently:

  • Require a space between keyword and name
  • Only match valid identifiers (letters, digits, underscores)
  • Exclude dot notation (e.g., .onComplete, .ext)

@nvnieuwk nvnieuwk left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, I'll merge once the tests pass

Thank you so much for this contribution!

@nvnieuwk nvnieuwk merged commit b1ae051 into askimed:main Apr 27, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Test file not created for workflow when workflow.onComplete is in main.nf

2 participants