@@ -695,16 +695,25 @@ process COWPY {
695695```
696696
697697Notice how all three patterns you applied manually are already there!
698- The template also includes several additional nf-core conventions that we didn't cover in the hands-on section:
698+ The template also includes several additional nf-core conventions.
699+ Some of these work out of the box, while others are placeholders we'll need to fill in:
700+
701+ ** Features that work as-is:**
699702
700703- ** ` tag "$meta.id" ` ** : Adds sample ID to process names in logs for easier tracking
701704- ** ` label 'process_single' ` ** : Resource label for configuring CPU/memory requirements
702705- ** ` when: ` block** : Allows conditional execution via ` task.ext.when ` configuration
703- - ** ` stub: ` block** : Provides a fast mock implementation for testing pipeline logic without running the actual tool
704- - ** ` versions.yml ` output** : Captures software version information for reproducibility
705- - ** Container placeholders** : Template structure for Singularity and Docker containers
706706
707- These additional conventions make modules more maintainable and provide better visibility into pipeline execution.
707+ These features are already functional and make modules more maintainable.
708+
709+ ** Placeholders we'll customize below:**
710+
711+ - ** ` input: ` and ` output: ` blocks** : Generic declarations we'll update to match our tool
712+ - ** ` script: ` block** : Contains a comment where we'll add the cowpy command
713+ - ** ` stub: ` block** : Template we'll update to produce the correct outputs
714+ - ** Container and environment** : Placeholders we'll fill with package information
715+
716+ The next sections walk through completing these customizations.
708717
709718#### 2.1.2. Completing the environment and container setup
710719
@@ -732,7 +741,131 @@ container "community.wave.seqera.io/library/cowpy:1.1.5--3db457ae1977a273"
732741
733742 Most bioinformatics tools are in Bioconda, but for conda-forge tools, Seqera Containers provides an easy solution for containerization.
734743
735- Once you've completed the environment setup and filled in the command logic, the module is ready to test!
744+ #### 2.1.3. Defining inputs and outputs
745+
746+ The generated template includes generic input and output declarations that you'll need to customize for your specific tool.
747+ Looking back at our manual cowpy module from section 1, we can use that as a guide.
748+
749+ Update the input and output blocks:
750+
751+ === "After"
752+
753+ ```groovy title="modules/local/cowpy/main.nf" linenums="8" hl_lines="2 5"
754+ input:
755+ tuple val(meta), path(input_file)
756+
757+ output:
758+ tuple val(meta), path("${prefix}.txt"), emit: cowpy_output
759+ path "versions.yml" , emit: versions
760+ ```
761+
762+ === "Before"
763+
764+ ```groovy title="modules/local/cowpy/main.nf" linenums="8" hl_lines="2 5"
765+ input:
766+ tuple val(meta), path(input)
767+
768+ output:
769+ tuple val(meta), path("*"), emit: output
770+ path "versions.yml" , emit: versions
771+ ```
772+
773+ This specifies:
774+ - The input file parameter name (` input_file ` instead of generic ` input ` )
775+ - The output filename using the configurable prefix pattern (` ${prefix}.txt ` instead of wildcard ` * ` )
776+ - A descriptive emit name (` cowpy_output ` instead of generic ` output ` )
777+
778+ #### 2.1.4. Writing the script block
779+
780+ The template provides a comment placeholder where you add the actual tool command.
781+ We can reference our manual module from section 1.3.2 for the command logic:
782+
783+ === "After"
784+
785+ ```groovy title="modules/local/cowpy/main.nf" linenums="15" hl_lines="3 6"
786+ script:
787+ def args = task.ext.args ?: ''
788+ prefix = task.ext.prefix ?: "${meta.id}"
789+
790+ """
791+ cat $input_file | cowpy $args > ${prefix}.txt
792+
793+ cat <<-END_VERSIONS > versions.yml
794+ "${task.process}":
795+ cowpy: \$(cowpy --version)
796+ END_VERSIONS
797+ """
798+ ```
799+
800+ === "Before"
801+
802+ ```groovy title="modules/local/cowpy/main.nf" linenums="15" hl_lines="6"
803+ script:
804+ def args = task.ext.args ?: ''
805+ def prefix = task.ext.prefix ?: "${meta.id}"
806+
807+ """
808+ // Add your tool command here
809+
810+ cat <<-END_VERSIONS > versions.yml
811+ "${task.process}":
812+ cowpy: \$(cowpy --version)
813+ END_VERSIONS
814+ """
815+ ```
816+
817+ Key changes:
818+ - Change ` def prefix ` to just ` prefix ` (without ` def ` ) so it's accessible in the output block
819+ - Replace the comment with the actual cowpy command that uses both ` $args ` and ` ${prefix}.txt `
820+
821+ #### 2.1.5. Implementing the stub block
822+
823+ The stub block provides a fast mock implementation for testing pipeline logic without running the actual tool.
824+ It must produce the same output files as the script block:
825+
826+ === "After"
827+
828+ ```groovy title="modules/local/cowpy/main.nf" linenums="27" hl_lines="3 5"
829+ stub:
830+ def args = task.ext.args ?: ''
831+ prefix = task.ext.prefix ?: "${meta.id}"
832+
833+ """
834+ touch ${prefix}.txt
835+
836+ cat <<-END_VERSIONS > versions.yml
837+ "${task.process}":
838+ cowpy: \$(cowpy --version)
839+ END_VERSIONS
840+ """
841+ ```
842+
843+ === "Before"
844+
845+ ```groovy title="modules/local/cowpy/main.nf" linenums="27" hl_lines="5-6"
846+ stub:
847+ def args = task.ext.args ?: ''
848+ def prefix = task.ext.prefix ?: "${meta.id}"
849+
850+ """
851+ echo $args
852+ touch ${prefix}.txt
853+
854+ cat <<-END_VERSIONS > versions.yml
855+ "${task.process}":
856+ cowpy: \$(cowpy --version)
857+ END_VERSIONS
858+ """
859+ ```
860+
861+ Key changes:
862+ - Change ` def prefix ` to just ` prefix ` to match the script block
863+ - Remove the ` echo $args ` line (which was just template placeholder code)
864+ - The stub creates an empty ` ${prefix}.txt ` file matching what the script block produces
865+
866+ This allows you to test workflow logic and file handling without waiting for the actual tool to run.
867+
868+ Once you've completed the environment setup (section 2.1.2), inputs/outputs (section 2.1.3), script block (section 2.1.4), and stub block (section 2.1.5), the module is ready to test!
736869
737870### 2.2. Contributing modules back to nf-core
738871
0 commit comments