diff --git a/docs/reference/cli.md b/docs/reference/cli.md index a524d94ed..eb4f05fe0 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -340,39 +340,9 @@ $ nextflow console ### `drop` -Delete the local copy of a project. - -**Usage** - -```console -$ nextflow drop [options] [project] -``` - -**Description** - -The `drop` command is used to remove the projects which have been downloaded into the global cache. Please refer the `list` command for generating a list of downloaded pipelines. - -**Options** - -`-f` -: Delete the repository without taking care of local changes. - -`-h, -help` -: Print the command usage. - -**Examples** - -Drop the `nextflow-io/hello` project. - -```console -$ nextflow drop nextflow-io/hello -``` - -Forcefully drop the `nextflow-io/hello` pipeline, ignoring any local changes. - -```console -$ nextflow drop nextflow-io/hello -f -``` +:::{versionchanged} 25.04.0 +The `nextflow drop` command has been replaced with `nextflow pipelines drop`. +::: ### `fs` @@ -737,33 +707,9 @@ $ nextflow lint -format -spaces 2 . ### `list` -List all downloaded projects. - -**Usage** - -```console -$ nextflow list [options] -``` - -**Description** - -The `list` commands prints a list of the projects which are already downloaded into the global cache `~/.nextflow/assets`. - -**Options** - -`-h, -help` -: Print the command usage. - -**Examples** - -List the downloaded pipelines. - -```console -$ nextflow list - -nextflow-io/hello -nextflow-hub/fastqc -``` +:::{versionchanged} 25.04.0 +The `nextflow list` command has been replaced with `nextflow pipelines list`. +::: (cli-log)= @@ -896,6 +842,82 @@ $ nextflow log tiny_leavitt -F 'process =~ /splitLetters/' work/1f/f1ea9158fb23b53d5083953121d6b6 ``` +### `pipelines` + +:::{versionadded} 25.04.0 +::: + +Manage pipeline projects. + +```console +$ nextflow pipelines [options] +``` + +The `pipelines` command provides several subcommands for managing the pipeline cache (used by the `pull` and `run` commands). The cache is stored in `~/.nextflow/assets` by default. + +`drop ` + +: Delete a project from the pipeline cache. + +`list` + +: List all projects in the pipeline cache. + +`view ` + +: View information about a project. + +**Examples** + +List all downloaded pipelines. + +```console +$ nextflow list + +nextflow-io/hello +nextflow-io/rnaseq-nf +``` + +View the contents of a downloaded pipeline. + +```console +$ nextflow view nextflow-io/hello + +== content of main directory: .nextflow/assets/nextflow-io/hello +.git +.gitignore +.travis.yml +LICENSE +README.md +circle.yml +main.nf +nextflow.config + +== content of main script: .nextflow/assets/nextflow-io/hello/main.nf +#!/usr/bin/env nextflow + +process sayHello { + input: + val x + output: + stdout + script: + """ + echo '$x world!' + """ +} + +workflow { + Channel.of('Bonjour', 'Ciao', 'Hello', 'Hola') | sayHello | view +} +``` + +Drop the `nextflow-io/hello` project. + +```console +$ nextflow drop nextflow-io/hello +``` + (cli-plugin)= ### `plugin` @@ -1262,91 +1284,6 @@ Nextflow installation completed. Please note: ### `view` -View a project's script file(s). - -**Usage** - -```console -$ nextflow view [options] [project] -``` - -**Description** - -The `view` command is used to inspect the pipelines that are already stored in the global nextflow cache. For downloading a pipeline into the global cache `~/.nextflow/assets`, refer to the `pull` command. - -**Options** - -`-h, -help` -: Print the command usage. - -`-l` -: List repository content. - -`-q` -: Hide header line. - -**Examples** - -Viewing the contents of a downloaded pipeline. - -```console -$ nextflow view nextflow-io/hello - -== content of file: .nextflow/assets/nextflow-io/hello/main.nf -#!/usr/bin/env nextflow - -process sayHello { - input: - val x - output: - stdout - script: - """ - echo '$x world!' - """ -} - -workflow { - Channel.of('Bonjour', 'Ciao', 'Hello', 'Hola') | sayHello | view -} -``` - -List the folder structure of the downloaded pipeline: - -```console -$ nextflow view -l nextflow-io/hello - -== content of path: .nextflow/assets/nextflow-io/hello -LICENSE -README.md -nextflow.config -.gitignore -circle.yml -foo.nf -.git -.travis.yml -main.nf -``` - -View the contents of a downloaded pipeline without omitting the header: - -```console -$ nextflow view -q nextflow-io/hello - -#!/usr/bin/env nextflow - -process sayHello { - input: - val x - output: - stdout - script: - """ - echo '$x world!' - """ -} - -workflow { - Channel.of('Bonjour', 'Ciao', 'Hello', 'Hola') | sayHello | view -} -``` +:::{versionchanged} 25.04.0 +The `nextflow view` command has been replaced with `nextflow pipelines view`. +::: diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/CmdDrop.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdDrop.groovy deleted file mode 100644 index 9d67190a5..000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/CmdDrop.groovy +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2013-2024, Seqera Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package nextflow.cli - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import groovy.util.logging.Slf4j -import nextflow.exception.AbortOperationException -import nextflow.plugin.Plugins -import nextflow.scm.AssetManager - -/** - * CLI sub-command DROP - * - * @author Paolo Di Tommaso - */ -@Slf4j -@CompileStatic -@Parameters(commandDescription = "Delete the local copy of a project") -class CmdDrop extends CmdBase { - - static final public NAME = 'drop' - - @Parameter(required=true, description = 'name of the project to drop') - List args - - @Parameter(names='-f', description = 'Delete the repository without taking care of local changes') - boolean force - - @Override - final String getName() { NAME } - - @Override - void run() { - Plugins.init() - def manager = new AssetManager(args[0]) - if( !manager.localPath.exists() ) { - throw new AbortOperationException("No match found for: ${args[0]}") - } - - if( this.force || manager.isClean() ) { - manager.close() - if( !manager.localPath.deleteDir() ) - throw new AbortOperationException("Unable to delete project `${manager.project}` -- Check access permissions for path: ${manager.localPath}") - return - } - - throw new AbortOperationException("Local project repository contains uncommitted changes -- won't drop it") - } -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/CmdList.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdList.groovy deleted file mode 100644 index 5b08be249..000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/CmdList.groovy +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2013-2024, Seqera Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package nextflow.cli - -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import groovy.util.logging.Slf4j -import nextflow.scm.AssetManager - -/** - * CLI sub-command LIST. Prints a list of locally installed pipelines - * - * @author Paolo Di Tommaso - */ -@Slf4j -@CompileStatic -@Parameters(commandDescription = "List all downloaded projects") -class CmdList extends CmdBase { - - static final public NAME = 'list' - - @Override - final String getName() { NAME } - - @Override - void run() { - - def all = AssetManager.list() - if( !all ) { - log.info '(none)' - return - } - - all.each { println it } - } - -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/CmdPipelines.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdPipelines.groovy new file mode 100644 index 000000000..63ada50dd --- /dev/null +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdPipelines.groovy @@ -0,0 +1,193 @@ +/* + * Copyright 2013-2024, Seqera Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package nextflow.cli + +import com.beust.jcommander.Parameter +import com.beust.jcommander.Parameters +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j +import nextflow.exception.AbortOperationException +import nextflow.plugin.Plugins +import nextflow.scm.AssetManager +import nextflow.util.TestOnly + +/** + * CLI sub-command PIPELINES. Manage locally installed pipelines + * + * @author Paolo Di Tommaso + */ +@Slf4j +@CompileStatic +@Parameters(commandDescription = "Manage pipeline projects") +class CmdPipelines extends CmdBase implements UsageAware { + + private static final List commands = [ + new CmdDrop(), + new CmdList(), + new CmdView() + ] + + static interface SubCmd { + String getName() + String getDescription() + void apply(String pipeline) + String usage() + } + + static class CmdDrop implements SubCmd { + + @Override + String getName() { 'drop' } + + @Override + String getDescription() { 'Delete the local copy of a project' } + + @Override + void apply(String pipeline) { + if( !pipeline ) + throw new AbortOperationException("No project name was specified") + + Plugins.init() + + final manager = new AssetManager(pipeline) + if( !manager.localPath.exists() ) + throw new AbortOperationException("No match found for: ${pipeline}") + + if( !manager.isClean() ) + throw new AbortOperationException("Local project repository contains uncommitted changes -- won't drop it") + + manager.close() + if( !manager.localPath.deleteDir() ) + throw new AbortOperationException("Unable to delete project `${manager.project}` -- Check access permissions for path: ${manager.localPath}") + } + + @Override + String usage() { + "Usage: nextflow pipelines drop " + } + } + + static class CmdList implements SubCmd { + + @Override + String getName() { 'list' } + + @Override + String getDescription() { 'List all downloaded projects' } + + @Override + void apply(String nope) { + final all = AssetManager.list() + if( !all ) { + log.info '(none)' + return + } + + all.each { println it } + } + + @Override + String usage() { + "Usage: nextflow pipelines list" + } + } + + static class CmdView implements SubCmd { + + @Override + String getName() { 'view' } + + @Override + String getDescription() { 'View project script file(s)' } + + @Override + void apply(String pipeline) { + if( !pipeline ) + throw new AbortOperationException("No project name was specified") + + Plugins.init() + final manager = new AssetManager(pipeline) + if( !manager.isLocal() ) + throw new AbortOperationException("Project `${pipeline}` is not doenloaded locally") + + // list repository content + println "== content of pipeline directory: ${manager.localPath}" + manager.localPath.eachFile { File it -> + println it.name + } + + // print the main script + final script = manager.getMainScriptFile() + if( !script.exists() ) + throw new AbortOperationException("Missing script file: '${script}'") + + println() + println "== content of main script: $script" + script.readLines().each { println it } + } + + @Override + String usage() { + "Usage: nextflow pipelines view " + } + } + + @Parameter + List args + + @Override + final String getName() { 'pipelines' } + + @Override + void run() { + if( !args ) { + usage() + return + } + + final cmd = findCmd(args.pop()) + if( !cmd ) { + throw new AbortOperationException("Unknown pipelines sub-command: `$cmd`") + } + + final pipeline = args ? args.first() : null + cmd.apply(pipeline) + } + + @Override + void usage() { + final result = [] + result << 'Usage: nextflow pipelines ' + result << '' + result << 'Commands:' + commands.each { + result << " ${it.name}\t${it.description}" + } + result << '' + println result.join('\n').toString() + } + + @Override + void usage(List args) { + usage() + } + + private SubCmd findCmd(String name) { + commands.find { it.name == name } + } + +} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/CmdView.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdView.groovy deleted file mode 100644 index dcdcfcae6..000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/CmdView.groovy +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2013-2024, Seqera Labs - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package nextflow.cli - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import groovy.util.logging.Slf4j -import nextflow.exception.AbortOperationException -import nextflow.plugin.Plugins -import nextflow.scm.AssetManager - -/** - * CLI sub-command VIEW -- Print a pipeline script to console - * - * @author Paolo Di Tommaso - */ -@Slf4j -@CompileStatic -@Parameters(commandDescription = "View project script file(s)") -class CmdView extends CmdBase { - - static final public NAME = 'view' - - @Override - String getName() { NAME } - - @Parameter(description = 'project name', required = true) - List args = [] - - @Parameter(names = '-q', description = 'Hide header line', arity = 0) - boolean quiet - - @Parameter(names = '-l', description = 'List repository content', arity = 0) - boolean all - - @Override - void run() { - Plugins.init() - def manager = new AssetManager(args[0]) - if( !manager.isLocal() ) - throw new AbortOperationException("Unknown project name `${args[0]}`") - - if( all ) { - if( !quiet ) - println "== content of path: ${manager.localPath}" - - manager.localPath.eachFile { File it -> - println it.name - } - } - - else { - /* - * prints the script main file - */ - final script = manager.getMainScriptFile() - if( !script.exists() ) - throw new AbortOperationException("Missing script file: '${script}'") - - if( !quiet ) - println "== content of file: $script" - - script.readLines().each { println it } - } - - } -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/Launcher.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/Launcher.groovy index 9d4d64292..c7eeb37a4 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/Launcher.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/Launcher.groovy @@ -94,20 +94,18 @@ class Launcher { new CmdConsole(), new CmdFs(), new CmdInfo(), - new CmdList(), new CmdLog(), new CmdPull(), new CmdRun(), new CmdKubeRun(), - new CmdDrop(), new CmdConfig(), new CmdNode(), - new CmdView(), new CmdHelp(), new CmdSelfUpdate(), new CmdPlugin(), new CmdInspect(), - new CmdLint() + new CmdLint(), + new CmdPipelines() ] if(SecretsLoader.isEnabled()) diff --git a/modules/nextflow/src/test/groovy/nextflow/cli/LauncherTest.groovy b/modules/nextflow/src/test/groovy/nextflow/cli/LauncherTest.groovy index 2527d1bac..34ed5179b 100644 --- a/modules/nextflow/src/test/groovy/nextflow/cli/LauncherTest.groovy +++ b/modules/nextflow/src/test/groovy/nextflow/cli/LauncherTest.groovy @@ -483,12 +483,12 @@ class LauncherTest extends Specification { given: def launcher = new Launcher() when: - launcher.printCommands( [new CmdInfo(), new CmdRun(), new CmdList()] ) + launcher.printCommands( [new CmdInfo(), new CmdRun(), new CmdLint()] ) then: capture.toString() == ''' Commands: info Print project and system runtime information - list List all downloaded projects + lint Lint Nextflow scripts and config files run Execute a pipeline project '''