From 6bdf7c904c9c018a08c0315445cf6cd539bb156b Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Thu, 5 Dec 2024 16:21:35 -0800
Subject: [PATCH 1/6] chore(deps): update dependency gradle to v8.11.1 (#266)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This PR contains the following updates:
| Package | Update | Change |
|---|---|---|
| [gradle](https://gradle.org)
([source](https://redirect.github.com/gradle/gradle)) | patch | `8.11`
-> `8.11.1` |
---
### Release Notes
gradle/gradle (gradle)
###
[`v8.11.1`](https://redirect.github.com/gradle/gradle/compare/v8.11.0...v8.11.1)
[Compare
Source](https://redirect.github.com/gradle/gradle/compare/v8.11.0...v8.11.1)
---
### Configuration
📅 **Schedule**: Branch creation - At any time (no schedule defined),
Automerge - At any time (no schedule defined).
🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.
â™» **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/quiltdata/nf-quilt).
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
gradle/wrapper/gradle-wrapper.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 94113f20..e2847c82 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
From 30c77364cbf49a446403a074ae4b82c189bfc870 Mon Sep 17 00:00:00 2001
From: "Dr. Ernie Prabhakar"
Date: Thu, 5 Dec 2024 16:25:19 -0800
Subject: [PATCH 2/6] 80 support config (#272)
Validate use of config information
Add IntelliJ support
Check v24.10 compatibility
---------
Co-authored-by: Dr. Ernie Prabhakar <19791+drernie@users.noreply.github.com>
---
.github/workflows/mega-linter.yml | 4 +-
.github/workflows/test.yml | 79 ++--
.gitignore | 3 +
.groovylintrc.json | 180 +++++-----
.vscode/settings.json | 6 +-
CHANGELOG.md | 22 +-
README-DEV.md | 14 +-
README.md | 88 +++--
nextflow.config | 4 +-
.../quilt/QuiltObserverFactory.groovy | 5 +-
.../main/nextflow/quilt/QuiltPathify.groovy | 2 +-
.../main/nextflow/quilt/QuiltProduct.groovy | 336 +++++++++++-------
.../main/nextflow/quilt/jep/QuiltID.groovy | 3 -
.../nextflow/quilt/jep/QuiltPackage.groovy | 48 +--
.../nextflow/quilt/jep/QuiltParser.groovy | 56 ++-
.../quilt/nio/QuiltFileAttributesView.groovy | 2 +-
.../nextflow/quilt/nio/QuiltFileSystem.groovy | 18 +-
.../quilt/nio/QuiltFileSystemProvider.groovy | 33 +-
.../main/nextflow/quilt/nio/QuiltPath.groovy | 4 +-
.../nextflow/quilt/QuiltObserverTest.groovy | 15 +-
.../test/nextflow/quilt/QuiltPkgTest.groovy | 7 +-
.../nextflow/quilt/QuiltProductTest.groovy | 181 ++++++----
.../nextflow/quilt/QuiltSpecification.groovy | 2 +-
.../quilt/jep/QuiltPackageTest.groovy | 25 +-
.../nextflow/quilt/jep/QuiltParserTest.groovy | 16 +-
25 files changed, 621 insertions(+), 532 deletions(-)
diff --git a/.github/workflows/mega-linter.yml b/.github/workflows/mega-linter.yml
index f24067b7..be248a1b 100644
--- a/.github/workflows/mega-linter.yml
+++ b/.github/workflows/mega-linter.yml
@@ -17,7 +17,7 @@ env: # Comment env block if you do not want to apply fixes
#APPLY_FIXES_MODE: pull_request # If APPLY_FIXES is used, defines if the fixes are directly committed (commit) or posted in a PR (pull_request)
DISABLE_LINTERS: SPELL_CSPELL,COPYPASTE_JSCPD,REPOSITORY_GITLEAKS,GROOVY_NPM_GROOVY_LINT
FILTER_REGEX_EXCLUDE: .*/.*gradle
-
+
concurrency:
group: ${{ github.ref }}-${{ github.workflow }}
cancel-in-progress: true
@@ -31,7 +31,7 @@ jobs:
- name: Checkout Code
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
- token: ${{ secrets.GITHUB_TOKEN }} # secrets.PAT ||
+ token: ${{ secrets.GITHUB_TOKEN }} # secrets.PAT ||
fetch-depth: 0 # If you use VALIDATE_ALL_CODEBASE = true, you can remove this line to improve performances
# MegaLinter
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 0e60e793..496e8055 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -25,49 +25,48 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- # Git Checkout
- - name: Checkout Code
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- with:
- token: ${{ secrets.GITHUB_TOKEN }}
- fetch-depth: 0
+ # Git Checkout
+ - name: Checkout Code
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
+ with:
+ token: ${{ secrets.GITHUB_TOKEN }}
+ fetch-depth: 0
- - name: Configure AWS Credentials
- uses: aws-actions/configure-aws-credentials@v4
- with:
- role-to-assume: arn:aws:iam::712023778557:role/github/GitHub-Testing-NF-Quilt
- aws-region: us-east-1
+ - name: Configure AWS Credentials
+ uses: aws-actions/configure-aws-credentials@v4
+ with:
+ role-to-assume: arn:aws:iam::712023778557:role/github/GitHub-Testing-NF-Quilt
+ aws-region: us-east-1
- - name: Setup Java ${{matrix.java_version}}
- uses: actions/setup-java@v4
- with:
- java-version: ${{matrix.java_version}}
- distribution: 'temurin'
- architecture: x64
- cache: gradle
-
- - name: Setup Gradle
- uses: gradle/actions/setup-gradle@v4
+ - name: Setup Java ${{matrix.java_version}}
+ uses: actions/setup-java@v4
+ with:
+ java-version: ${{matrix.java_version}}
+ distribution: "temurin"
+ architecture: x64
+ cache: gradle
- - name: Run Gradle Tests
- run: make test
- env:
- LOG4J_DEBUG: true
+ - name: Setup Gradle
+ uses: gradle/actions/setup-gradle@v4
- - name: Archive production artifacts (Windows only)
- uses: actions/upload-artifact@v4
- if: ${{ always() && matrix.os == 'windows-latest' }}
- with:
- name: nf-quilt-test-reports-${{ matrix.os }}-${{ matrix.java_version }}
- path: |
+ - name: Run Gradle Tests
+ run: make test
+ env:
+ LOG4J_DEBUG: true
+
+ - name: Archive production artifacts (Windows only)
+ uses: actions/upload-artifact@v4
+ if: ${{ always() && matrix.os == 'windows-latest' }}
+ with:
+ name: nf-quilt-test-reports-${{ matrix.os }}-${{ matrix.java_version }}
+ path: |
D:\a\nf-quilt\nf-quilt\plugins\nf-quilt\build\reports\
- overwrite: true
- - name: Archive production artifacts (Linux and MacOS)
- uses: actions/upload-artifact@v4
- if: ${{ always() && matrix.os != 'windows-latest' }}
- with:
- name: nf-quilt-test-reports-${{ matrix.os }}-${{ matrix.java_version }}
- path: |
+ overwrite: true
+ - name: Archive production artifacts (Linux and MacOS)
+ uses: actions/upload-artifact@v4
+ if: ${{ always() && matrix.os != 'windows-latest' }}
+ with:
+ name: nf-quilt-test-reports-${{ matrix.os }}-${{ matrix.java_version }}
+ path: |
${{ github.workspace }}/plugins/nf-quilt/build/reports/
- overwrite: true
-
+ overwrite: true
diff --git a/.gitignore b/.gitignore
index d2b24865..ea9f81ed 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,8 @@ work
out
results
bin
+/bin/
+plugins/nf-quilt/bin
# Ignore Gradle GUI config
gradle-app.setting
@@ -32,3 +34,4 @@ params.yaml
null
# quilt+*
# nextflow
+.aider*
diff --git a/.groovylintrc.json b/.groovylintrc.json
index 536acf30..e4b536a6 100644
--- a/.groovylintrc.json
+++ b/.groovylintrc.json
@@ -1,92 +1,92 @@
{
- "extends": "recommended",
- "rules": {
- "CatchException": {
- "enabled": false
- },
- "CatchThrowable": {
- "enabled": false
- },
- "ClassJavadoc": {
- "enabled": false
- },
- "ClosureAsLastMethodParameter": {
- "enabled": false
- },
- "DuplicateNumberLiteral": {
- "enabled": false
- },
- "DuplicateStringLiteral": {
- "enabled": false
- },
- "FieldTypeRequired": {
- "enabled": false
- },
- "ImplicitClosureParameter": {
- "enabled": false
- },
- "JUnitPublicNonTestMethod": {
- "enabled": false
- },
- "JUnitTestMethodWithoutAssert": {
- "enabled": false
- },
- "JavaIoPackageAccess": {
- "enabled": false
- },
- "JavadocEmptyFirstLine": {
- "enabled": false
- },
- "JavadocEmptyReturnTag": {
- "enabled": false
- },
- "JavadocMissingParamDescription": {
- "enabled": false
- },
- "JavadocMissingThrowsDescription": {
- "enabled": false
- },
- "MethodCount": {
- "enabled": false
- },
- "MethodParameterTypeRequired": {
- "enabled": false
- },
- "MethodSize": {
- "enabled": false
- },
- "NoDef": {
- "enabled": false
- },
- "PrintStackTrace": {
- "enabled": false
- },
- "PropertyName": {
- "enabled": false
- },
- "SpaceAroundMapEntryColon": {
- "enabled": false
- },
- "SpaceAroundOperator": {
- "enabled": false
- },
- "SystemExit": {
- "enabled": false
- },
- "UnnecessaryGetter": {
- "enabled": false
- },
- "UnnecessaryObjectReferences": {
- "enabled": false
- },
- "UnnecessarySetter": {
- "enabled": false
- },
- "VariableName": {
- "enabled": false
- },
- "VariableTypeRequired": {
- "enabled": false
- }
+ "extends": "recommended",
+ "rules": {
+ "CatchException": {
+ "enabled": false
+ },
+ "CatchThrowable": {
+ "enabled": false
+ },
+ "ClassJavadoc": {
+ "enabled": false
+ },
+ "ClosureAsLastMethodParameter": {
+ "enabled": false
+ },
+ "DuplicateNumberLiteral": {
+ "enabled": false
+ },
+ "DuplicateStringLiteral": {
+ "enabled": false
+ },
+ "FieldTypeRequired": {
+ "enabled": false
+ },
+ "ImplicitClosureParameter": {
+ "enabled": false
+ },
+ "JUnitPublicNonTestMethod": {
+ "enabled": false
+ },
+ "JUnitTestMethodWithoutAssert": {
+ "enabled": false
+ },
+ "JavaIoPackageAccess": {
+ "enabled": false
+ },
+ "JavadocEmptyFirstLine": {
+ "enabled": false
+ },
+ "JavadocEmptyReturnTag": {
+ "enabled": false
+ },
+ "JavadocMissingParamDescription": {
+ "enabled": false
+ },
+ "JavadocMissingThrowsDescription": {
+ "enabled": false
+ },
+ "MethodCount": {
+ "enabled": false
+ },
+ "MethodParameterTypeRequired": {
+ "enabled": false
+ },
+ "MethodSize": {
+ "enabled": false
+ },
+ "NoDef": {
+ "enabled": false
+ },
+ "PrintStackTrace": {
+ "enabled": false
+ },
+ "PropertyName": {
+ "enabled": false
+ },
+ "SpaceAroundMapEntryColon": {
+ "enabled": false
+ },
+ "SpaceAroundOperator": {
+ "enabled": false
+ },
+ "SystemExit": {
+ "enabled": false
+ },
+ "UnnecessaryGetter": {
+ "enabled": false
+ },
+ "UnnecessaryObjectReferences": {
+ "enabled": false
+ },
+ "UnnecessarySetter": {
+ "enabled": false
+ },
+ "VariableName": {
+ "enabled": false
+ },
+ "VariableTypeRequired": {
+ "enabled": false
}
-}
\ No newline at end of file
+ }
+}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 78b61df5..75441df0 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,4 +1,4 @@
{
- "java.compile.nullAnalysis.mode": "disabled",
- "java.configuration.updateBuildConfiguration": "disabled"
-}
\ No newline at end of file
+ "java.compile.nullAnalysis.mode": "disabled",
+ "java.configuration.updateBuildConfiguration": "disabled"
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3fca9e5c..2bcf6393 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,9 +8,16 @@
- Improve handling of dynamically-specified URIs
- Rewrite README.md, splitting out developer documentation to README_DEV.md
+## [0.8.12] 2024-12-03 UNPUBLISHED
+
+- Extract flags and metadata from `nextflow.config`
+- Remove unused methods and keys
+- Remove support for propertyName
+- Use IntelliJ to fix types and lint
+
## [0.8.11] 2024-11-5 UNPUBLISHED
-- Catch *all* toJson errors
+- Catch _all_ toJson errors
## [0.8.10] 2024-11-4 UNPUBLISHED
@@ -27,8 +34,8 @@
## [0.8.7] 2024-10-23 UNPUBLISHED
-- Use package cache instead of `params` to find output URIs
- (in order to support dynamic URIs set by, e.g. `main.nf`)
+- Use package cache instead of `params` to find output URIs (in order to support
+ dynamic URIs set by, e.g. `main.nf`)
- Allow setting metadata from inside the workflow
## [0.8.6] 2024-09-11
@@ -52,7 +59,8 @@
## [0.8.2] 2024-09-07
-- Use copyFile rather than writeString for overlay files [requires NextFlow 23 or later]
+- Use copyFile rather than writeString for overlay files [requires NextFlow 23
+ or later]
- Restore README and quilt_summarize to output
## [0.8.1] 2024-09-05
@@ -198,7 +206,8 @@ Beta release (not yet on nextflow-io/plugins)
- Use `msg` fragment parameter as commit message when writing packages
- Removed Benchling support (will add back in a future release)
-- Don't crash when writing to Quilt+ URIs with `&path=` fragments (by ignoring that part)
+- Don't crash when writing to Quilt+ URIs with `&path=` fragments (by ignoring
+ that part)
## [0.3.5] 2023-04-05
@@ -219,5 +228,6 @@ Beta release (not yet on nextflow-io/plugins)
## [0.3.2] 2023-02-24
-- First official release on [nextflow-io/plugins](https://github.com/nextflow-io/plugins/commits/main/plugins.json)
+- First official release on
+ [nextflow-io/plugins](https://github.com/nextflow-io/plugins/commits/main/plugins.json)
- Read and write from Quilt+ URIs
diff --git a/README-DEV.md b/README-DEV.md
index 33058904..5ccf2969 100644
--- a/README-DEV.md
+++ b/README-DEV.md
@@ -2,10 +2,14 @@
## Using Pre-Release Versions
-Occasionally we will release beta versions of the plugin that are not yet available in the Nextflow plugin registry. You can help test these versions as follows:
+Occasionally we will release beta versions of the plugin that are not yet
+available in the Nextflow plugin registry. You can help test these versions as
+follows:
-- Set the `NXF_PLUGINS_TEST_REPOSITORY` environment variable to the URL of the plugin's metadata file
-- Specify the plugin version in the `plugins` section of your `nextflow.config` file
+- Set the `NXF_PLUGINS_TEST_REPOSITORY` environment variable to the URL of the
+ plugin's metadata file
+- Specify the plugin version in the `plugins` section of your `nextflow.config`
+ file
From the command-line, do, e.g.:
@@ -51,7 +55,7 @@ To quickly run `nf-quilt` from this GitHub repository:
# install and compiles dependencies, then test
make test-all
# create "test/hurdat" package on s3://$WRITE_BUCKET
-make pkg-test WRITE_BUCKET=your-writeablebucket
+make pkg-test WRITE_BUCKET=your-writeablebucket
```
This ensures you have properly installed Nextflow and configured your local
@@ -77,7 +81,7 @@ file (be sure to rename the `outdir` parameter if you use different convention).
For example:
```bash
- ./launch.sh run ./main.nf -profile standard -plugins $(PROJECT) --outdir "quilt+s3://bucket#package=test/hurdat"
+./launch.sh run ./main.nf -profile standard -plugins $(PROJECT) --outdir "quilt+s3://bucket#package=test/hurdat"
```
### Unit Testing
diff --git a/README.md b/README.md
index e53c4e30..35905f60 100644
--- a/README.md
+++ b/README.md
@@ -3,17 +3,17 @@
Nextflow plugin for reading and writing Quilt packages
[`nf-quilt`](https://github.com/quiltdata/nf-quilt) is a Nextflow
-[plugin](https://www.nextflow.io/docs/latest/plugins.html) developed by [Quilt
-Data, Inc.](https://quiltdata.com/) that enables you read and write directly to
-Quilt packages wherever your Nextflow pipeline currently uses `s3` URIs. It
-works with any Amazon S3-compatible object store, as long as you have the
-appropriate
+[plugin](https://www.nextflow.io/docs/latest/plugins.html) developed by
+[Quilt Data, Inc.](https://quiltdata.com/) that enables you read and write
+directly to Quilt packages wherever your Nextflow pipeline currently uses `s3`
+URIs. It works with any Amazon S3-compatible object store, as long as you have
+the appropriate
[credentials](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html).
Quilt packages are versioned, immutable, and shareable data containers that
store data, metadata, and documentation as a single atomic unit. They are
-accessible even by non-technical users via the Quilt Platfrom, a graphical
-web catalog which runs either in your private AWS cloud or on
+accessible even by non-technical users via the Quilt Platfrom, a graphical web
+catalog which runs either in your private AWS cloud or on
[open.quiltdata.com](https://open.quiltdata.com).
## Writing to Quilt Packages
@@ -36,7 +36,8 @@ metadata from that run.
## Use nextflow.config to configure the plugin
-To avoid having to manually specify the plugin, you can add it to your `nextflow.config` file:
+To avoid having to manually specify the plugin, you can add it to your
+`nextflow.config` file:
```groovy
plugins {
@@ -49,7 +50,8 @@ This also works with Nextflow Tower, where you can add the plugin to the
![Example Tower Configuration](./images/tower-config.png)
-As of v0.9+, you can also add a `quilt` section to your `nextflow.config` file to specify the metadata and other plugin behaviors:
+As of v0.9, you can also add a `quilt` section to your `nextflow.config` file to
+specify the metadata and other plugin behaviors:
```groovy
quilt {
@@ -73,19 +75,23 @@ quilt+s3://$WRITE_BUCKET#package=nf_quilt/rnaseq
### Input URIs
-Versioned Quilt+ URIs can be used as input URIs in your Nextflow pipeline, to ensure you know precisely which data you are using. For example, this is a specific version of the output from `nf-core/sarek`:
+Versioned Quilt+ URIs can be used as input URIs in your Nextflow pipeline, to
+ensure you know precisely which data you are using. For example, this is a
+specific version of the output from `nf-core/sarek`:
```shell
quilt+s3://$READ_BUCKET#package=nf-core/sarek@8a2164f48be8e0d6385f64b76b74a8543e9fb1b12a8eff6daeaffa653d52fcf7
```
-If are using the Quilt Platform, you can find the Quilt+ URI for a package in the `<> CODE | URI` section at the top of the package page.
+If are using the Quilt Platform, you can find the Quilt+ URI for a package in
+the `<> CODE | URI` section at the top of the package page.
![Example Quilt+ URI](./images/quilt-uri.png)
### Output URIs
-You can specify a Quilt+ URI as the `--outdir` parameter in your Nextflow pipeline if you want to specify the package name and metadata for the output,
+You can specify a Quilt+ URI as the `--outdir` parameter in your Nextflow
+pipeline if you want to specify the package name and metadata for the output,
but don't care about the precise location in S3. For example:
```shell
@@ -94,52 +100,66 @@ nextflow run nf-core/rnaseq --outdir "quilt+s3://$WRITE_BUCKET?key=value#package
The `key=value` part is optional, and can be used to specify metadata for the
package, which will be added to the metadata automatically generated by the
-plugin. This is particularly when working with [Quilt
-workflows](https://docs.quiltdata.com/workflows), which require specific
+plugin. This is particularly when working with
+[Quilt workflows](https://docs.quiltdata.com/workflows), which require specific
metadata to be present before a package can be created.
### CLI Usage
-If your workflow supports `--input` and `--outdir` parameters, you can use them to specify the Quilt+ URIs. For example:
+If your workflow supports `--input` and `--outdir` parameters, you can use them
+to specify the Quilt+ URIs. For example:
```shell
nextflow run main.nf --input "quilt+s3://$READ_BUCKET#package=nf-core/sarek@8a2164f48be8e0d6385f64b76b74a8543e9fb1b12a8eff6daeaffa653d52fcf7" --outdir "quilt+s3://$WRITE_BUCKET?key=value#package=test/my-sarek-processor"
```
-Note that you need to quote the URIs to prevent the shell from interpreting the `?` and `#` characters.
+Note that you need to quote the URIs to prevent the shell from interpreting the
+`?` and `#` characters.
## Configurations
There are a number of additional parameters you can set in order to customize
the behavior of the plugin:
-* **catalog**: specify the DNS hostname of the Quilt catalog to use (default: `open.quiltdata.com`)
-* **force**: completely replace the existing package, rather than updating it (default: `false`)
-* **meta**: specify a map of metadata to add to the package (default: `{}`)
-* **msg**: specify the commit message template to use when saving the package
-* **pkg**: specify the name of the package to read or write, when using an S3 URI (default: the first two path components)
-* **readme**: specify a template string for the package README_NF_QUILT.md file
-* **workflow**: specify the name of a Quilt workflow on that bucket to use for metadata validation (default: None)
+- **catalog**: specify the DNS hostname of the Quilt catalog to use (default:
+ None)
+- **force**: completely replace the existing package, rather than updating it
+ (default: `false`)
+- **meta**: specify a map of metadata to add to the package (default: `{}`)
+- **message**: specify the commit message template to use when saving the
+ package
+- **package**: specify the name of the package to read or write, when using an
+ S3 URI (default: the first two path components)
+- **readme**: specify a template string for the package README_NF_QUILT.md file
+- **summarize**: which files to display on the "front page" of the package via
+ `quilt_summarize.json` (default:
+ `*.md,*.html,*.?sv,*.pdf,igv.json,**/multiqc_report.html`); use `false` to
+ disable.
+- **workflow**: specify the name of a Quilt workflow on that bucket to use for
+ metadata validation (default: None)
NOTE: These configurations were previously specified as part of the Quilt+ URI.
-That functionality has been deprecated, and may be removed in a future release.
+That functionality has mostly been removed. The Quilt+ URI fragment (`#`) is now
+only used to specify the package and (optionally) the path and workflow. You may
+continue to use the query string (`?`) to specify metadata, including the
+`catalog`.
### Template Strings
-Version 0.3.4 and later allow you to customize both the `msg`
-and `readme` via template strings that use these `${variables}`:
+You can customize both the `msg` and `readme` via template strings that use
+these `${variables}`:
-* `cmd`: the current command line
-* `meta`: the complete metadata
-* `msg`: the current commit message
-* `nextflow`: the current Nextflow configuration
-* `now`: the ISO 8601 date and time
-* `pkg`: the package name
+- `cmd`: the current command line
+- `meta`: the complete metadata
+- `msg`: the current commit message
+- `nextflow`: the current Nextflow configuration
+- `now`: the ISO 8601 date and time
+- `pkg`: the package name
Note that the full `meta` is usually extremely large. You should use conditional
keys to extract only the metadata you need, if present. For example:
-```groovy
+````groovy
quilt {
meta = [pipeline: 'nf-core/rnaseq']
msg = "${meta['config']?.get('runName')}: ${meta['cmd']}"
@@ -169,4 +189,4 @@ ${nextflow}
`${meta['workflow']?.get('stats')?.getAt('processes')}`
'''
}
-```
+````
diff --git a/nextflow.config b/nextflow.config
index e128c083..bc2e527a 100644
--- a/nextflow.config
+++ b/nextflow.config
@@ -3,7 +3,7 @@ plugins {
}
quilt {
- catalog = 'open.quiltdata.com'
- meta = [pipeline: 'nf-core/rnaseq']
+ catalog = 'nightly.quilttest.com'
+ meta = [pipeline: 'nf-core/rnaseq', key4: 2+2]
force = false
}
diff --git a/plugins/nf-quilt/src/main/nextflow/quilt/QuiltObserverFactory.groovy b/plugins/nf-quilt/src/main/nextflow/quilt/QuiltObserverFactory.groovy
index a475ad4f..92db5024 100644
--- a/plugins/nf-quilt/src/main/nextflow/quilt/QuiltObserverFactory.groovy
+++ b/plugins/nf-quilt/src/main/nextflow/quilt/QuiltObserverFactory.groovy
@@ -33,7 +33,10 @@ class QuiltObserverFactory implements TraceObserverFactory {
@Override
Collection create(Session session) {
//log.debug("`create` ${this}")
- return (Collection) [new QuiltObserver()]
+ Collection quiltObservers = new ArrayList<>()
+ quiltObservers.add(new QuiltObserver())
+
+ return quiltObservers as Collection
}
}
diff --git a/plugins/nf-quilt/src/main/nextflow/quilt/QuiltPathify.groovy b/plugins/nf-quilt/src/main/nextflow/quilt/QuiltPathify.groovy
index b07f5182..6523e71c 100644
--- a/plugins/nf-quilt/src/main/nextflow/quilt/QuiltPathify.groovy
+++ b/plugins/nf-quilt/src/main/nextflow/quilt/QuiltPathify.groovy
@@ -51,7 +51,7 @@ class QuiltPathify {
Files.copy(source, dest)
}
catch (Exception e) {
- log.error("writeString: cannot write `$source` to `$dest` in `${destRoot}`")
+ log.error("writeString: cannot write `$source` to `$dest` in `${destRoot}`\n$e")
}
}
diff --git a/plugins/nf-quilt/src/main/nextflow/quilt/QuiltProduct.groovy b/plugins/nf-quilt/src/main/nextflow/quilt/QuiltProduct.groovy
index 392337e2..5240bbe1 100644
--- a/plugins/nf-quilt/src/main/nextflow/quilt/QuiltProduct.groovy
+++ b/plugins/nf-quilt/src/main/nextflow/quilt/QuiltProduct.groovy
@@ -16,6 +16,7 @@
package nextflow.quilt
import nextflow.quilt.jep.QuiltPackage
+import nextflow.quilt.jep.QuiltParser
import nextflow.quilt.nio.QuiltPath
import nextflow.Session
@@ -31,8 +32,8 @@ import java.nio.file.SimpleFileVisitor
import java.time.LocalDateTime
import groovy.transform.CompileStatic
-import groovy.util.logging.Slf4j
import groovy.text.GStringTemplateEngine
+import groovy.util.logging.Slf4j
import groovy.json.JsonOutput
/**
@@ -47,12 +48,18 @@ class QuiltProduct {
public final static String README_FILE = 'README_NF_QUILT.md'
public final static String SUMMARY_FILE = 'quilt_summarize.json'
- private final static String KEY_META = 'metadata'
- private final static String KEY_README = 'readme'
- private final static String KEY_SKIP = 'SKIP'
- private final static String KEY_SUMMARIZE = 'summarize'
+ public final static String KEY_META = 'meta'
+ public final static String KEY_MSG = 'message'
+ public final static String KEY_QUILT = 'quilt'
+ public final static String KEY_README = 'readme'
+ public final static String KEY_SUMMARIZE = 'summarize'
+
+/* groovylint-disable-next-line GStringExpressionWithinString */
+ private final static String DEFAULT_MSG = '''
+${config.get('runName')}: ${meta.get('cmd')}
+'''
- /* groovylint-disable-next-line GStringExpressionWithinString */
+/* groovylint-disable-next-line GStringExpressionWithinString */
private final static String DEFAULT_README = '''
# ${pkg}
@@ -80,6 +87,7 @@ ${nextflow}
`${meta['workflow']?.get('stats')?.getAt('processes')}`
'''
+
private final static String DEFAULT_SUMMARIZE = '*.md,*.html,*.?sv,*.pdf,igv.json,**/multiqc_report.html'
private final static String[] BIG_KEYS = [
@@ -88,12 +96,17 @@ ${nextflow}
]
static void printMap(Map map, String title) {
- log.info("\n\n\n# $title")
+ log.info("\n\n\n# $title ${map.keySet()}")
map.each {
key, value -> log.info("\n## ${key}: ${value}")
}
}
+ static Map extractMap(Map map, String key) {
+ def child = map.remove(key)
+ return (child instanceof Map) ? child : [:]
+ }
+
static void writeString(String text, QuiltPackage pkg, String filepath) {
String dir = pkg.packageDest()
Path path = Paths.get(dir, filepath.split('/') as String[])
@@ -102,7 +115,7 @@ ${nextflow}
Files.write(path, text.bytes)
}
catch (Exception e) {
- log.error("writeString: cannot write `$text` to `$path` for `${pkg}`")
+ log.error("writeString: cannot write `$text` to `$path` for `${pkg}`\n$e")
}
}
@@ -113,7 +126,7 @@ ${nextflow}
Files.copy(source, dest)
}
catch (Exception e) {
- log.error("writeString: cannot write `$source` to `$dest` in `${destRoot}`")
+ log.error("writeString: cannot write `$source` to `$dest` in `${destRoot}`\n$e.message()")
}
}
@@ -122,124 +135,75 @@ ${nextflow}
return time.toString().replace(':', '-').replace('T', 't')
}
- private final QuiltPath path
- private final QuiltPackage pkg
- private final Session session
- private String msg
- private Map meta
+ protected final QuiltPath path
+ protected final QuiltPackage pkg
+ protected final Session session
+ protected final Map> config
+
+ protected final Map metadata
+ protected final Expando flags = new Expando([
+ catalog: false,
+ force: false,
+ message: DEFAULT_MSG,
+ meta: true,
+ readme: DEFAULT_README,
+ summarize: DEFAULT_SUMMARIZE,
+ workflow: false,
+ ])
QuiltProduct(QuiltPathify pathify, Session session) {
+ println("Creating QuiltProduct: ${pathify}")
+ this.session = session
+ this.config = session.config ?: [:]
this.path = pathify.path
+ println('QuiltProduct.path')
this.pkg = pathify.pkg
- this.msg = pkg.toString()
- this.meta = pkg.meta + [pkg: msg, time_start: now()]
- this.session = session
- println("QuiltProduct: ${pkg.toUriString()}")
- println("\tQuiltProduct.pkg: ${pkg}")
- println("\tQuiltProduct.path: ${path}")
-
- if (session.isSuccess() || pkg.is_force()) {
+ println('QuiltProduct.pkg')
+ this.metadata = collectMetadata()
+ println('QuiltProduct.metadata')
+ // println("QuiltProduct.flags: ${flags}")
+ if (session.isSuccess() || flags.getProperty(QuiltParser.P_FORCE) == true) {
publish()
} else {
log.info("not publishing: ${pkg} [unsuccessful session]")
}
}
- void publish() {
- log.debug("publish($msg)")
- addSessionMeta()
- setupReadme()
- setupSummarize()
- try {
- log.info("publish.pushing: ${pkg}")
- def m = pkg.push(msg, meta)
- log.info("publish.pushed: ${m}")
- }
- catch (Exception e) {
- log.error("Exception: ${e}")
- print("FAILED: $pkg\n")
- e.printStackTrace()
- /* groovylint-disable-next-line ThrowRuntimeException */
- throw new RuntimeException(e)
- }
- print("SUCCESS: $pkg\n")
- }
-
- boolean shouldSkip(key) {
- return pkg.meta.containsKey(key) && pkg.meta[key] == KEY_SKIP
- }
-
- boolean addSessionMeta() {
- println("addSessionMeta: ${session}")
+ Map collectMetadata() {
if (shouldSkip(KEY_META)) {
- return false
- }
-
- Map> cf = session.config
- println("addSessionMeta.cf: ${cf}")
- if (cf == null) {
- log.error('addSessionMeta: no config found', pkg.meta)
- return false
+ log.info("SKIP: metadata for ${pkg}")
+ return [:]
}
- Map qf = cf.navigate('quilt') as Map ?: [:]
- qf['package_id'] = pkg.toString()
- qf['uri'] = path.toUriString()
- println("addSessionMeta.qf: ${qf}")
- Map cmeta = qf.navigate('meta') as Map
- qf.remove('meta')
- println("addSessionMeta.cmeta: ${cmeta}")
-
- try {
- Map smeta = getMetadata(cf)
- // println("addSessionMeta.smeta: ${smeta}")
- smeta['quilt'] = qf
- smeta.remove('config')
- meta += smeta + cmeta
- msg = "${cf.get('runName')}: ${meta['cmd']}"
- } catch (Exception e) {
- println("addSessionMeta.getMetadata failed: $e")
- log.error("addSessionMeta.getMetadata failed: ${e.getMessage()}", pkg.meta)
- return false
- }
- writeNextflowMetadata(meta, 'metadata')
- return true
- }
-
- String writeNextflowMetadata(Map map, String suffix) {
- String filename = "nf-quilt/${suffix}.json"
- log.debug("writeNextflowMetadata[$suffix]: ${filename}")
- try {
- writeString(QuiltPackage.toJson(map), pkg, filename)
- } catch (Exception e) {
- log.error("writeNextflowMetadata.toJson failed: ${e.getMessage()}", map)
- }
- return filename
- }
-
- Map getMetadata(Map cf) {
- // add metadata from quilt and URI
- if (cf != null) {
- cf.remove('executor')
- cf.remove('params')
- cf.remove('session')
- writeNextflowMetadata(cf, 'config')
- cf.remove('process')
- printMap(cf, 'config')
- }
- Map params = session.getParams()
+ println("collectMetadata.config: ${config}")
+ config.remove('executor')
+ config.remove('params')
+ config.remove('session')
+ writeMapToPackage(config, 'config')
+ config.remove('process')
+ printMap(config, 'config')
+
+ Map quilt_cf = extractMap(config, KEY_QUILT)
+ println("collectMetadata.quilt_cf: ${quilt_cf}")
+ Map pkg_meta = pkg.getMetadata()
+ println("collectMetadata.pkg_meta: ${pkg_meta}")
+ updateFlags(pkg_meta, quilt_cf)
+
+ Map params = session.getParams()
+ println("collectMetadata.params: ${params}")
if (params != null) {
- writeNextflowMetadata(params, 'params')
+ writeMapToPackage(params, 'params')
params.remove('genomes')
params.remove('test_data')
printMap(params, 'params')
}
- Map wf = session.getWorkflowMetadata().toMap()
- String start = wf['start']
- String complete = wf['complete']
- String cmd = wf['commandLine']
+ Map wf = session.getWorkflowMetadata()?.toMap()
+ println("collectMetadata.wf: ${wf}")
+ String start = wf?.get('start')
+ String complete = wf?.get('complete')
+ String cmd = wf?.get('commandLine')
if (wf != null) {
BIG_KEYS.each { k -> wf[k] = "${wf[k]}" }
- writeNextflowMetadata(wf, 'workflow')
+ writeMapToPackage(wf, 'workflow')
wf.remove('container')
wf.remove('start')
wf.remove('complete')
@@ -249,56 +213,154 @@ ${nextflow}
log.info("\npublishing: ${wf['runName']}")
}
- return [
+ Map cf_meta = extractMap(quilt_cf, KEY_META) // remove after setting flags
+ println("getMetadata.cf_meta: ${cf_meta}")
+ Map base_meta = cf_meta + pkg_meta
+ log.info("getMetadata.base_meta: ${base_meta}")
+ return base_meta + [
cmd: cmd,
- config: cf,
+ now: now(),
params: params,
+ quilt: quilt_cf,
time_start: start,
time_complete: complete,
+ uri: path.toUriString(),
workflow: wf,
]
}
- String setupReadme() {
- String text = 'Stub README'
+ Map getTemplateArgs() {
+ Map params = [
+ cmd: metadata.get('cmd'),
+ config: config,
+ meta: metadata,
+ now: metadata.get('now'),
+ pkg: flags.getProperty(QuiltParser.P_PKG)
+ ]
+ return params
+ }
+
+ boolean shouldSkip(String key) {
+ return flags.getProperty(key) == false
+ }
+
+ /**
+ * Update flags from default values
+ * Use metadata if available, otherwise use config
+ *
+ * @param meta Map of package metadata
+ * @param cf Map of config (from nextflow.config)`
+ */
+ void updateFlags(Map pkg_meta, Map cf_meta) {
+ println("updateFlags.pkg_meta: ${pkg_meta}")
+ println("updateFlags.cf_meta: ${cf_meta}")
+ for (String key : flags.getProperties().keySet()) {
+ if (pkg_meta.containsKey(key)) {
+ flags.setProperty(key, pkg_meta[key])
+ } else if (cf_meta.containsKey(key)) {
+ flags.setProperty(key, cf_meta[key])
+ }
+ }
+ // TODO: should this only work for names inferred from S3 URIs?
+ String pkgName = cf_meta.containsKey(QuiltParser.P_PKG) ? cf_meta[QuiltParser.P_PKG] : pkg.packageName
+ flags.setProperty(QuiltParser.P_PKG, pkgName)
+ }
+
+ String writeMapToPackage(Map map, String prefix) {
+ String filename = "nf-quilt/${prefix}.json"
+ log.debug("writeMapToPackage[$prefix]: ${filename}")
try {
- text = makeReadme()
+ writeString(QuiltPackage.toJson(map), pkg, filename)
+ } catch (Exception e) {
+ log.error("writeMapToPackage.toJson failed: ${e.getMessage()}", map)
+ }
+ return filename
+ }
+
+/*
+ * Publish the package to the Quilt catalog
+ */
+
+ void publish() {
+ log.info("publish.pushing: ${pkg}")
+ try {
+ String message = compileMessage()
+ writeReadme(message)
+ writeSummarize()
+ def rc = pkg.push(message, metadata)
+ log.info("publish.pushed: ${rc}")
}
catch (Exception e) {
- log.error("setupReadme failed: ${e.getMessage()}\n{$e}", pkg.meta)
+ log.error("Exception: ${e}")
+ print("publish.FAILED: $pkg\n")
+ e.printStackTrace()
+ return
}
- if (text != null && text.length() > 0) {
- log.debug("setupReadme: ${text.length()} bytes")
- writeString(text, pkg, README_FILE)
+ print("\nSUCCESS: ${displayName()}\n")
+ }
+
+ String displayName() {
+ Object catalog = flags.getProperty(QuiltParser.P_CAT)
+ return catalog ? pkg.toCatalogURL(catalog.toString()) : pkg.toUriString()
+ }
+
+ String compileMessage() {
+ String msg = flags.getProperty(KEY_MSG)
+ GStringTemplateEngine engine = new GStringTemplateEngine()
+ println("compileMessage: ${msg}")
+ try {
+ String output = engine.createTemplate(msg).make(getTemplateArgs())
+ log.debug("compileMessage.output: ${output}")
+ return output
}
- return text
+ catch (Exception e) {
+ log.error("compileMessage failed: ${e.getMessage()}\n{$e}", flags)
+ }
+ return "compileMessage.FAILED\n$msg"
}
- String makeReadme() {
+ String compileReadme(String msg) {
if (shouldSkip(KEY_README)) {
- log.info("readme=SKIP for ${pkg}")
+ log.info("SKIP: readme for ${pkg}")
return null
}
- GStringTemplateEngine engine = new GStringTemplateEngine()
- String raw_readme = pkg.meta_overrides(KEY_README, DEFAULT_README)
- String cmd = "${meta['cmd']}".replace(' -', ' \\\n -')
- String nf = meta['workflow']?['nextflow']
+ String raw_readme = flags.getProperty(KEY_README)
+ String nf = metadata['workflow']?['nextflow']
String nextflow = nf?.replace(', ', '```\n - **')\
?.replace('nextflow.NextflowMeta(', ' - **')\
?.replace(')', '```')
?.replace(':', '**: ```')
- Map params = [
- cmd: cmd,
- meta: meta,
+ Map params = getTemplateArgs()
+ params += [
msg: msg,
nextflow: nextflow,
- now: now(),
- pkg: pkg.packageName,
]
- log.debug("makeReadme.params: ${params}")
- String template = engine.createTemplate(raw_readme).make(params)
- log.debug("makeReadme.template: ${template}")
- return template
+ log.debug("compileReadme.params: ${params}")
+ try {
+ GStringTemplateEngine engine = new GStringTemplateEngine()
+ String output = engine.createTemplate(raw_readme).make(params)
+ log.debug("compileReadme.output: ${output}")
+ return output
+ }
+ catch (Exception e) {
+ log.error("compileReadme failed: ${e.getMessage()}\n{$e}", flags)
+ }
+ return "compileReadme.FAILED\n$raw_readme"
+ }
+
+ String writeReadme(String message) {
+ String text = 'Stub README'
+ try {
+ text = compileReadme(message)
+ }
+ catch (Exception e) {
+ log.error("writeReadme failed: ${e.getMessage()}\n{$e}", flags)
+ }
+ if (text != null && text.length() > 0) {
+ log.debug("writeReadme: ${text.length()} bytes")
+ writeString(text, pkg, README_FILE)
+ }
+ return text
}
List match(String glob) throws IOException {
@@ -330,15 +392,17 @@ ${nextflow}
return matches
}
- List