diff --git a/launch-v1.sh b/launch-v1.sh index 631c6fa748..344e33ea81 100755 --- a/launch-v1.sh +++ b/launch-v1.sh @@ -14,4 +14,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -MAIN_CLASS="nextflow.cli.v1.Launcher" ./launch.sh "$@" +MAIN_CLASS="nextflow.cli.Launcher" ./launch.sh "$@" diff --git a/launch.sh b/launch.sh index b7c67d58db..5f95d01d41 100755 --- a/launch.sh +++ b/launch.sh @@ -57,7 +57,7 @@ fi declare -a args=() DEBUG='' COLUMNS=${COLUMNS:-`tput cols 2> /dev/tty`} -MAIN_CLASS=${MAIN_CLASS:-'nextflow.cli.v1.Launcher'} +MAIN_CLASS=${MAIN_CLASS:-'nextflow.cli.Launcher'} JAVA_VER="$($JAVA_BIN -version 2>&1)" if [ $? -ne 0 ]; then echo "${JAVA_VER:-Failed to launch the Java virtual machine}" diff --git a/modules/nextflow/build.gradle b/modules/nextflow/build.gradle index eb5cfde9b6..3f825bab27 100644 --- a/modules/nextflow/build.gradle +++ b/modules/nextflow/build.gradle @@ -65,7 +65,7 @@ test { } application { - mainClass = 'nextflow.cli.v1.Launcher' + mainClass = 'nextflow.cli.Launcher' } run{ diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/CacheBase.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CacheBase.groovy index 22a31aa58f..87fda154f1 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/CacheBase.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CacheBase.groovy @@ -28,7 +28,7 @@ import nextflow.util.HistoryFile import static nextflow.util.HistoryFile.Record /** - * Common cache operations shared by {@link LogImpl} and {@link CleanImpl} + * Common cache operations shared by {@link CmdLog} and {@link CmdClean} * * @author Paolo Di Tommaso */ diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/AbstractCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdBase.groovy similarity index 93% rename from modules/nextflow/src/main/groovy/nextflow/cli/v1/AbstractCmd.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdBase.groovy index cbff11dbd3..5212aa3bf1 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/AbstractCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdBase.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package nextflow.cli.v1 +package nextflow.cli import com.beust.jcommander.Parameter import groovy.transform.CompileStatic @@ -25,7 +25,7 @@ import groovy.transform.CompileStatic * @author Paolo Di Tommaso */ @CompileStatic -abstract class AbstractCmd implements Runnable { +abstract class CmdBase implements Runnable { private Launcher launcher diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/CleanImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdClean.groovy similarity index 83% rename from modules/nextflow/src/main/groovy/nextflow/cli/CleanImpl.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdClean.groovy index 26ffd3816d..dad1f9cf3f 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/CleanImpl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdClean.groovy @@ -15,7 +15,6 @@ */ package nextflow.cli - import java.nio.file.FileVisitResult import java.nio.file.FileVisitor import java.nio.file.Files @@ -24,6 +23,8 @@ import java.nio.file.Path import java.nio.file.Paths import java.nio.file.attribute.BasicFileAttributes +import com.beust.jcommander.Parameter +import com.beust.jcommander.Parameters import com.google.common.hash.HashCode import groovy.transform.CompileStatic import groovy.util.logging.Slf4j @@ -39,14 +40,14 @@ import nextflow.trace.TraceRecord import nextflow.util.HistoryFile.Record /** - * CLI `clean` sub-command + * Implements cache clean up command * * @author Paolo Di Tommaso * @author Lorenz Gerber */ @Slf4j @CompileStatic -class CleanImpl implements CacheBase { +class CmdClean implements CacheBase { interface Options { String getAfter() @@ -61,6 +62,48 @@ class CleanImpl implements CacheBase { ILauncherOptions getLauncherOptions() } + @Parameters(commandDescription = 'Clean up project cache and work directories') + static class V1 extends CmdBase implements Options { + + @Parameter(names=['-q', '-quiet'], description = 'Do not print names of files removed', arity = 0) + boolean quiet + + @Parameter(names=['-f', '-force'], description = 'Force clean command', arity = 0) + boolean force + + @Parameter(names=['-n', '-dry-run'], description = 'Print names of file to be removed without deleting them' , arity = 0) + boolean dryRun + + @Parameter(names='-after', description = 'Clean up runs executed after the specified one') + String after + + @Parameter(names='-before', description = 'Clean up runs executed before the specified one') + String before + + @Parameter(names='-but', description = 'Clean up all runs except the specified one') + String but + + @Parameter(names=['-k', '-keep-logs'], description = 'Removes only temporary files but retains execution log entries and metadata') + boolean keepLogs + + @Parameter + List args + + @Override + ILauncherOptions getLauncherOptions() { + launcher.options + } + + @Override + String getName() { 'clean' } + + @Override + void run() { + new CmdClean(this).run() + } + + } + @Delegate private Options options @@ -68,7 +111,7 @@ class CleanImpl implements CacheBase { private Map dryHash = new HashMap<>() - CleanImpl(Options options) { + CmdClean(Options options) { this.options = options } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/CloneImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdClone.groovy similarity index 68% rename from modules/nextflow/src/main/groovy/nextflow/cli/CloneImpl.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdClone.groovy index bceb715366..2bab613963 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/CloneImpl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdClone.groovy @@ -15,21 +15,21 @@ */ 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 `clone` sub-command + * CLI sub-command clone * * @author Paolo Di Tommaso */ @Slf4j @CompileStatic -class CloneImpl { +class CmdClone { interface Options extends IHubOptions { String getPipeline() @@ -38,10 +38,39 @@ class CloneImpl { String getRevision() } + @Parameters(commandDescription = 'Clone a project into a folder') + static class V1 extends CmdBase implements Options, HubOptions { + + @Parameter(required=true, description = 'name of the project to clone') + List args + + @Parameter(names='-r', description = 'Revision to clone - It can be a git branch, tag or revision number') + String revision + + @Parameter(names=['-d','-deep'], description = 'Create a shallow clone of the specified depth') + Integer deep + + @Override + String getPipeline() { args[0] } + + @Override + String getTargetName() { + args.size() > 1 ? args[1] : null + } + + @Override + String getName() { 'clone' } + + @Override + void run() { + new CmdClone(this).run() + } + } + @Delegate private Options options - CloneImpl(Options options) { + CmdClone(Options options) { this.options = options } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/ConfigImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdConfig.groovy similarity index 78% rename from modules/nextflow/src/main/groovy/nextflow/cli/ConfigImpl.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdConfig.groovy index 44e7cdb97d..29fa27ea12 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/ConfigImpl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdConfig.groovy @@ -19,6 +19,8 @@ package nextflow.cli import java.nio.file.Path import java.nio.file.Paths +import com.beust.jcommander.Parameter +import com.beust.jcommander.Parameters import groovy.transform.CompileStatic import groovy.transform.PackageScope import groovy.util.logging.Slf4j @@ -27,15 +29,14 @@ import nextflow.exception.AbortOperationException import nextflow.plugin.Plugins import nextflow.scm.AssetManager import nextflow.util.ConfigHelper - /** - * CLI `config` sub-command + * Prints the pipeline configuration * * @author Paolo Di Tommaso */ @Slf4j @CompileStatic -class ConfigImpl { +class CmdConfig { interface Options { String getPipeline() @@ -48,17 +49,58 @@ class ConfigImpl { ILauncherOptions getLauncherOptions() } + @Parameters(commandDescription = 'Print a project configuration') + static class V1 extends CmdBase implements Options { + + @Parameter(description = 'project name') + List args = [] + + @Parameter(names=['-a','-show-profiles'], description = 'Show all configuration profiles') + boolean showAllProfiles + + @Parameter(names=['-profile'], description = 'Choose a configuration profile') + String profile + + @Parameter(names = '-properties', description = 'Prints config using Java properties notation') + boolean printProperties + + @Parameter(names = '-flat', description = 'Print config using flat notation') + boolean printFlatten + + @Parameter(names = '-sort', description = 'Sort config attributes') + boolean sort + + @Override + String getPipeline() { + args.size() > 0 ? args[0] : null + } + + @Override + ILauncherOptions getLauncherOptions() { + launcher.options + } + + @Override + String getName() { 'config' } + + @Override + void run() { + new CmdConfig(this).run() + } + + } + private OutputStream stdout = System.out @Delegate private Options options - ConfigImpl(Options options) { + CmdConfig(Options options) { this.options = options } /* For testing purposes only */ - ConfigImpl() {} + CmdConfig() {} void run() { Plugins.init() diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/ConsoleImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdConsole.groovy similarity index 65% rename from modules/nextflow/src/main/groovy/nextflow/cli/ConsoleImpl.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdConsole.groovy index fd10b114fb..b520cc505e 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/ConsoleImpl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdConsole.groovy @@ -16,26 +16,48 @@ package nextflow.cli +import com.beust.jcommander.Parameter +import com.beust.jcommander.Parameters import groovy.transform.CompileStatic import nextflow.plugin.Plugins import nextflow.ui.console.ConsoleExtension /** - * CLI `console` sub-command + * Launch the Nextflow Console plugin * * @author Paolo Di Tommaso */ @CompileStatic -class ConsoleImpl { +class CmdConsole { interface Options { String getScript() } + @Parameters(commandDescription = 'Launch Nextflow interactive console') + static class V1 extends CmdBase implements Options { + + @Parameter(description = 'Nextflow console arguments') + List args + + @Override + String getScript() { + args.size() > 0 ? args[0] : null + } + + @Override + String getName() { 'console' } + + @Override + void run() { + new CmdConsole(this).run() + } + } + @Delegate private Options options - ConsoleImpl(Options options) { + CmdConsole(Options options) { this.options = options } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/DropImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdDrop.groovy similarity index 70% rename from modules/nextflow/src/main/groovy/nextflow/cli/DropImpl.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdDrop.groovy index a60d4747af..7f4d6dda0a 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/DropImpl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdDrop.groovy @@ -16,6 +16,8 @@ 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 @@ -23,23 +25,44 @@ import nextflow.plugin.Plugins import nextflow.scm.AssetManager /** - * CLI `drop` sub-command + * CLI sub-command DROP * * @author Paolo Di Tommaso */ @Slf4j @CompileStatic -class DropImpl { +class CmdDrop { interface Options { String getPipeline() boolean getForce() } + @Parameters(commandDescription = 'Delete the local copy of a project') + static class V1 extends CmdBase implements Options { + + @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 + String getPipeline() { args[0] } + + @Override + String getName() { 'drop' } + + @Override + void run() { + new CmdDrop(this).run() + } + } + @Delegate private Options options - DropImpl(Options options) { + CmdDrop(Options options) { this.options = options } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/CmdFs.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdFs.groovy new file mode 100644 index 0000000000..83736ceb46 --- /dev/null +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdFs.groovy @@ -0,0 +1,242 @@ +/* + * Copyright 2020-2022, Seqera Labs + * Copyright 2013-2019, Centre for Genomic Regulation (CRG) + * + * 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 java.nio.charset.Charset +import java.nio.file.Files +import java.nio.file.Path + +import com.beust.jcommander.Parameter +import com.beust.jcommander.Parameters +import groovy.transform.CompileStatic +import nextflow.exception.AbortOperationException +import nextflow.extension.FilesEx +import nextflow.file.FileHelper +import nextflow.file.FilePatternSplitter +import nextflow.plugin.Plugins + +/** + * CLI `fs` sub-command + * + * @author Paolo Di Tommaso + */ +@CompileStatic +class CmdFs { + + @Parameters(commandDescription = 'Perform basic filesystem operations') + static class V1 extends CmdBase implements UsageAware { + + trait SubCmd { + abstract String getName() + abstract int getArity() + abstract String getDescription() + abstract Command getCommand() + + String usage() { + "Usage: nextflow fs ${name} " + (arity==1 ? "" : "source_file target_file") + } + } + + private List commands = (List)[ + new CmdCopy(), + new CmdMove(), + new CmdList(), + new CmdCat(), + new CmdRemove() + ] + + @Parameter(hidden = true) + List args = [] + + @Override + String getName() { 'fs' } + + @Override + void run() { + if( !args ) { + usage() + return + } + + final cmd = commands.find { it.name == args[0] } + if( !cmd ) { + def matches = commands.collect{ it.name }.closest(args[0]) + def msg = "Unknown fs sub-command: ${args[0]}" + if( matches ) + msg += " -- Did you mean one of these?\n" + matches.collect { " $it"}.join('\n') + throw new AbortOperationException(msg) + } + + if( args.size() - 1 != cmd.getArity() ) + throw new AbortOperationException(cmd.usage()) + + new CmdFs().run(cmd.getCommand(), args.drop(1)) + } + + /** + * Print the command usage help + */ + void usage() { + usage(args) + } + + /** + * Print the command usage help + * + * @param args The arguments as entered by the user + */ + void usage(List args) { + + def result = [] + if( !args ) { + result << 'Usage: nextflow fs [args]' + result << '' + result << 'Commands:' + commands.each { + result << " ${it.name}\t${it.description}" + } + result << '' + println result.join('\n').toString() + } + else { + def sub = commands.find { it.name == args[0] } + if( sub ) + println sub.usage() + else { + throw new AbortOperationException("Unknown fs sub-command: ${args[0]}") + } + } + + } + + static class CmdCopy implements SubCmd { + @Override String getName() { 'cp' } + @Override int getArity() { 2 } + @Override String getDescription() { 'Copy a file' } + @Override Command getCommand() { Command.COPY } + } + + static class CmdMove implements SubCmd { + @Override String getName() { 'mv' } + @Override int getArity() { 2 } + @Override String getDescription() { 'Move a file' } + @Override Command getCommand() { Command.MOVE } + } + + static class CmdList implements SubCmd { + @Override String getName() { 'ls' } + @Override int getArity() { 1 } + @Override String getDescription() { 'List the contents of a folder' } + @Override Command getCommand() { Command.LIST } + } + + static class CmdCat implements SubCmd { + @Override String getName() { 'cat' } + @Override int getArity() { 1 } + @Override String getDescription() { 'Print a file to stdout' } + @Override Command getCommand() { Command.CAT } + } + + static class CmdRemove implements SubCmd { + @Override String getName() { 'rm' } + @Override int getArity() { 1 } + @Override String getDescription() { 'Remove a file' } + @Override Command getCommand() { Command.REMOVE } + } + + } + + enum Command { + COPY, + MOVE, + LIST, + CAT, + REMOVE + } + + void run(Command command, List args) { + Plugins.setup() + + try { + switch( command ) { + case COPY: + traverse(args[0]) { Path path -> copy(path, args[1] as Path) } + break + case MOVE: + traverse(args[0]) { Path path -> move(path, args[1] as Path) } + break + case LIST: + traverse(args[0]) { Path path -> list(path) } + break + case CAT: + traverse(args[0]) { Path path -> cat(path) } + break + case REMOVE: + traverse(args[0]) { Path path -> remove(path) } + break + } + } + finally { + Plugins.stop() + } + } + + private void traverse( String source, Closure op ) { + // if it isn't a glob pattern simply return it a normalized absolute Path object + def splitter = FilePatternSplitter.glob().parse(source) + if( splitter.isPattern() ) { + final scheme = splitter.scheme + final folder = splitter.parent + final pattern = splitter.fileName + final fs = FileHelper.fileSystemForScheme(scheme) + + def opts = [:] + opts.type = 'file' + + FileHelper.visitFiles(opts, fs.getPath(folder), pattern, op) + } + else { + def normalised = splitter.strip(source) + op.call(FileHelper.asPath(normalised)) + } + } + + void copy(Path source, Path target) { + FilesEx.copyTo(source, target) + } + + void move(Path source, Path target) { + FilesEx.moveTo(source, target) + } + + void list(Path source) { + println source.name + } + + void cat(Path source) { + String line + def reader = Files.newBufferedReader(source, Charset.defaultCharset()) + while( line = reader.readLine() ) + println line + } + + void remove(Path source) { + Files.isDirectory(source) ? FilesEx.deleteDir(source) : FilesEx.delete(source) + } + +} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/HelpCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdHelp.groovy similarity index 96% rename from modules/nextflow/src/main/groovy/nextflow/cli/v1/HelpCmd.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdHelp.groovy index f67c3c6a00..a554d02301 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/HelpCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdHelp.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package nextflow.cli.v1 +package nextflow.cli import com.beust.jcommander.Parameter import com.beust.jcommander.Parameters @@ -27,7 +27,7 @@ import groovy.transform.CompileStatic */ @CompileStatic @Parameters(commandDescription = 'Print the usage help for a command') -class HelpCmd extends AbstractCmd { +class CmdHelp extends CmdBase { @Override String getName() { 'help' } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/InfoImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdInfo.groovy similarity index 91% rename from modules/nextflow/src/main/groovy/nextflow/cli/InfoImpl.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdInfo.groovy index ffa44a31d6..211ce598ab 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/InfoImpl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdInfo.groovy @@ -19,6 +19,8 @@ package nextflow.cli import java.lang.management.ManagementFactory import java.nio.file.spi.FileSystemProvider +import com.beust.jcommander.Parameter +import com.beust.jcommander.Parameters import com.sun.management.OperatingSystemMXBean import groovy.json.JsonOutput import groovy.transform.CompileStatic @@ -31,15 +33,14 @@ import nextflow.scm.AssetManager import nextflow.util.MemoryUnit import nextflow.util.Threads import org.yaml.snakeyaml.Yaml - /** - * CLI `info` sub-command + * CLI sub-command INFO * * @author Paolo Di Tommaso */ @Slf4j @CompileStatic -class InfoImpl { +class CmdInfo { interface Options { abstract String getPipeline() @@ -49,17 +50,50 @@ class InfoImpl { abstract boolean getCheckForUpdates() } + @Parameters(commandDescription = 'Print project and system runtime information') + static class V1 extends CmdBase implements Options { + + @Parameter(description = 'project name') + List args + + @Parameter(names='-d',description = 'Show detailed information', arity = 0) + boolean detailed + + @Parameter(names='-dd', hidden = true, arity = 0) + boolean moreDetailed + + @Parameter(names='-o', description = 'Output format, either: text (default), json, yaml') + String format + + @Parameter(names=['-u','-check-updates'], description = 'Check for remote updates') + boolean checkForUpdates + + @Override + String getPipeline() { + args.size() > 0 ? args[0] : null + } + + @Override + String getName() { 'info' } + + @Override + void run() { + new CmdInfo(this).run() + } + + } + private PrintStream out = System.out @Delegate private Options options - InfoImpl(Options options) { + CmdInfo(Options options) { this.options = options } /* For testing purposes only */ - InfoImpl() {} + CmdInfo() {} void run() { diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/KubeRunCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdKubeRun.groovy similarity index 98% rename from modules/nextflow/src/main/groovy/nextflow/cli/v1/KubeRunCmd.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdKubeRun.groovy index 55ab40fe83..818c6b271e 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/KubeRunCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdKubeRun.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package nextflow.cli.v1 +package nextflow.cli import java.util.regex.Pattern @@ -33,7 +33,7 @@ import nextflow.util.HistoryFile @Slf4j @CompileStatic @Parameters(commandDescription = "Execute a workflow in a Kubernetes cluster (experimental)") -class KubeRunCmd extends RunCmd { +class CmdKubeRun extends CmdRun.V1 { static private String POD_NAME = /[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/ @@ -101,7 +101,7 @@ class KubeRunCmd extends RunCmd { runName = runName.replace('_','-') } - /* copied from {@code RunImpl} */ + /* copied from {@code CmdRun} */ protected void checkRunName0() { if( runName == 'last' ) diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/ListImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdList.groovy similarity index 71% rename from modules/nextflow/src/main/groovy/nextflow/cli/ListImpl.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdList.groovy index 5abed76f78..97cf426ad3 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/ListImpl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdList.groovy @@ -16,25 +16,39 @@ package nextflow.cli +import com.beust.jcommander.Parameters import groovy.transform.CompileStatic import groovy.util.logging.Slf4j import nextflow.scm.AssetManager /** - * CLI `list` sub-command + * CLI sub-command LIST. Prints a list of locally installed pipelines * * @author Paolo Di Tommaso */ @Slf4j @CompileStatic -class ListImpl { +class CmdList { interface Options {} + @Parameters(commandDescription = 'List all downloaded projects') + static class V1 extends CmdBase implements Options { + + @Override + String getName() { 'list' } + + @Override + void run() { + new CmdList(this).run() + } + + } + @Delegate private Options options - ListImpl(Options options) { + CmdList(Options options) { this.options = options } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/LogImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdLog.groovy similarity index 80% rename from modules/nextflow/src/main/groovy/nextflow/cli/LogImpl.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdLog.groovy index e4b22973d6..ab777302b7 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/LogImpl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdLog.groovy @@ -15,10 +15,11 @@ */ package nextflow.cli - import java.nio.file.Path import ch.artecat.grengine.Grengine +import com.beust.jcommander.Parameter +import com.beust.jcommander.Parameters import com.google.common.hash.HashCode import groovy.text.Template import groovy.transform.CompileStatic @@ -34,13 +35,13 @@ import nextflow.ui.TableBuilder import static nextflow.cli.CmdHelper.fixEqualsOp /** - * CLI `log` sub-command + * Implements the `log` command to print tasks runtime information of an execute pipeline * * @author Paolo Di Tommaso */ @Slf4j @CompileStatic -class LogImpl implements CacheBase { +class CmdLog implements CacheBase { static private List ALL_FIELDS @@ -68,6 +69,49 @@ class LogImpl implements CacheBase { List getArgs() } + @Parameters(commandDescription = 'Print executions log and runtime info') + static class V1 extends CmdBase implements Options { + + @Parameter(names = ['-s'], description='Character used to separate column values') + String separator = '\\t' + + @Parameter(names=['-f','-fields'], description = 'Comma separated list of fields to include in the printed log -- Use the `-l` option to show the list of available fields') + String fields + + @Parameter(names = ['-t','-template'], description = 'Text template used to each record in the log ') + String templateStr + + @Parameter(names=['-l','-list-fields'], description = 'Show all available fields', arity = 0) + boolean listFields + + @Parameter(names=['-F','-filter'], description = "Filter log entries by a custom expression e.g. process =~ /foo.*/ && status == 'COMPLETED'") + String filterStr + + @Parameter(names='-after', description = 'Show log entries for runs executed after the specified one') + String after + + @Parameter(names='-before', description = 'Show log entries for runs executed before the specified one') + String before + + @Parameter(names='-but', description = 'Show log entries of all runs except the specified one') + String but + + @Parameter(names=['-q','-quiet'], description = 'Show only run names', arity = 0) + boolean quiet + + @Parameter(description = 'Run name or session id') + List args + + @Override + String getName() { 'log' } + + @Override + void run() { + new CmdLog(this).run() + } + + } + @Delegate private Options options @@ -79,38 +123,12 @@ class LogImpl implements CacheBase { private Map printed = new HashMap<>() - LogImpl(Options options) { + CmdLog(Options options) { this.options = options } /* For testing purposes only */ - LogImpl() {} - - void run() { - Plugins.init() - init() - - // -- show the list of expected fields and exit - if( listFields ) { - ALL_FIELDS.each { println " $it" } - return - } - - // -- show the current history and exit - if( showHistory ) { - quiet ? printQuiet() : printHistory() - return - } - - // -- main - listIds().each { entry -> - cacheFor(entry) - .openForRead() - .eachRecord(this.&printRecord) - .close() - } - - } + CmdLog() {} void init() { CacheBase.super.init() @@ -150,6 +168,37 @@ class LogImpl implements CacheBase { templateScript = new TaskTemplateEngine().createTemplate(templateStr0) } + /** + * Implements the `log` command + */ + void run() { + Plugins.init() + init() + + // -- show the list of expected fields and exit + if( listFields ) { + ALL_FIELDS.each { println " $it" } + return + } + + // -- show the current history and exit + if( showHistory ) { + quiet ? printQuiet() : printHistory() + return + } + + // -- main + listIds().each { entry -> + + cacheFor(entry) + .openForRead() + .eachRecord(this.&printRecord) + .close() + + } + + } + /** * Print a log {@link TraceRecord} the the standard output by using the specified {@link #templateStr} * diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/NodeImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdNode.groovy similarity index 80% rename from modules/nextflow/src/main/groovy/nextflow/cli/NodeImpl.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdNode.groovy index 612d2c4ae2..20e731566e 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/NodeImpl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdNode.groovy @@ -15,7 +15,9 @@ */ package nextflow.cli - +import com.beust.jcommander.DynamicParameter +import com.beust.jcommander.Parameter +import com.beust.jcommander.Parameters import groovy.transform.CompileStatic import groovy.util.logging.Slf4j import nextflow.config.ConfigBuilder @@ -23,15 +25,13 @@ import nextflow.daemon.DaemonLauncher import nextflow.plugin.Plugins import nextflow.util.ServiceName import nextflow.util.ServiceDiscover - /** - * CLI `node` sub-command - * + * CLI-command NODE * @author Paolo Di Tommaso */ @Slf4j @CompileStatic -class NodeImpl { +class CmdNode { interface Options { Map getClusterOptions() @@ -40,10 +40,44 @@ class NodeImpl { ILauncherOptions getLauncherOptions() } + @Parameters(commandDescription = 'Launch Nextflow in deamon mode') + static class V1 extends CmdBase implements Options { + + @DynamicParameter(names ='-cluster.', description='Define cluster config options') + Map clusterOptions = [:] + + @Parameter(names = ['-bg'], arity = 0, description = 'Start the cluster node daemon in background') + void setBackground(boolean value) { + launcher.options.background = value + } + + @Parameter + List args + + @Override + String getProvider() { + args.size() ? args[0] : null + } + + @Override + ILauncherOptions getLauncherOptions() { + launcher.options + } + + @Override + String getName() { 'node' } + + @Override + void run() { + new CmdNode(this).run() + } + + } + @Delegate private Options options - NodeImpl(Options options) { + CmdNode(Options options) { this.options = options } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/PluginImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdPlugin.groovy similarity index 62% rename from modules/nextflow/src/main/groovy/nextflow/cli/PluginImpl.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdPlugin.groovy index 814f482c9e..e74a4254b3 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/PluginImpl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdPlugin.groovy @@ -18,6 +18,8 @@ package nextflow.cli +import com.beust.jcommander.Parameter +import com.beust.jcommander.Parameters import groovy.transform.CompileStatic import nextflow.exception.AbortOperationException import nextflow.plugin.Plugins @@ -29,7 +31,40 @@ import static nextflow.cli.PluginExecAware.CMD_SEP * @author Paolo Di Tommaso */ @CompileStatic -class PluginImpl { +class CmdPlugin { + + @Parameters(commandDescription = 'Manage plugins and execute custom plugin commands') + static class V1 extends CmdBase { + + @Parameter(hidden = true) + List args = [] + + @Override + String getName() { 'plugin' } + + @Override + void run() { + if( !args ) + throw new AbortOperationException("Missing plugin command - usage: nextflow plugin install ") + + // plugin install command + if( args[0] == 'install' ) { + if( args.size()!=2 ) + throw new AbortOperationException("Missing plugin install target - usage: nextflow plugin install ") + CmdPlugin.install(args[1].tokenize(',')) + } + + // plugin run command + else if( args[0].contains(CMD_SEP) ) { + CmdPlugin.exec(args.pop(), args, launcher.options) + } + + else { + throw new AbortOperationException("Invalid plugin command: ${args[0]}") + } + } + + } static void install(List ids) { Plugins.setup() diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/PluginsCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdPlugins.groovy similarity index 94% rename from modules/nextflow/src/main/groovy/nextflow/cli/v1/PluginsCmd.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdPlugins.groovy index 0f220dab3d..415d666508 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/PluginsCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdPlugins.groovy @@ -15,7 +15,7 @@ * */ -package nextflow.cli.v1 +package nextflow.cli import groovy.transform.CompileStatic import groovy.util.logging.Slf4j @@ -28,7 +28,7 @@ import groovy.util.logging.Slf4j @Slf4j @Deprecated @CompileStatic -class PluginsCmd extends PluginCmd { +class CmdPlugins extends CmdPlugin.V1 { @Override String getName() { 'plugins' } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/PullImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdPull.groovy similarity index 63% rename from modules/nextflow/src/main/groovy/nextflow/cli/PullImpl.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdPull.groovy index 089743407e..7431ca4f7d 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/PullImpl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdPull.groovy @@ -15,21 +15,21 @@ */ 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 `pull` sub-command + * CLI sub-command PULL * * @author Paolo Di Tommaso */ @Slf4j @CompileStatic -class PullImpl { +class CmdPull { interface Options extends IHubOptions { String getPipeline() @@ -38,23 +38,51 @@ class PullImpl { String getRevision() } + @Parameters(commandDescription = 'Download or update a project') + static class V1 extends CmdBase implements Options, HubOptions { + + @Parameter(description = 'project name or repository url to pull', arity = 1) + List args + + @Parameter(names='-all', description = 'Update all downloaded projects', arity = 0) + boolean all + + @Parameter(names=['-r','-revision'], description = 'Revision of the project to run (either a git branch, tag or commit SHA number)') + String revision + + @Parameter(names=['-d','-deep'], description = 'Create a shallow clone of the specified depth') + Integer deep + + @Override + String getPipeline() { args[0] } + + @Override + String getName() { 'pull' } + + @Override + void run() { + new CmdPull(this).run() + } + + } + @Delegate private Options options /* only for testing purpose */ protected File root - PullImpl(Options options) { + CmdPull(Options options) { this.options = options } void run() { if( !pipeline && !all ) - throw new AbortOperationException('Project name or option `all` is required') + throw new AbortOperationException('Project name or option `-all` is required') - def pipelines = all ? AssetManager.list() : [pipeline] - if( !pipelines ) { + def list = all ? AssetManager.list() : [pipeline] + if( !list ) { log.info "(nothing to do)" return } @@ -67,7 +95,7 @@ class PullImpl { // init plugin system Plugins.init() - pipelines.each { + list.each { log.info "Checking $it ..." def manager = new AssetManager(it, this) diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/RunImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdRun.groovy similarity index 67% rename from modules/nextflow/src/main/groovy/nextflow/cli/RunImpl.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdRun.groovy index 9f9c7a282a..74f6bcda4c 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/RunImpl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdRun.groovy @@ -20,6 +20,10 @@ import java.nio.file.NoSuchFileException import java.nio.file.Path import java.util.regex.Pattern +import com.beust.jcommander.DynamicParameter +import com.beust.jcommander.IStringConverter +import com.beust.jcommander.Parameter +import com.beust.jcommander.Parameters import groovy.json.JsonSlurper import groovy.transform.CompileStatic import groovy.transform.Memoized @@ -39,17 +43,17 @@ import nextflow.script.ScriptFile import nextflow.script.ScriptRunner import nextflow.secret.SecretsLoader import nextflow.util.CustomPoolFactory +import nextflow.util.Duration import nextflow.util.HistoryFile import org.yaml.snakeyaml.Yaml - /** - * CLI `run` sub-command + * CLI sub-command RUN * * @author Paolo Di Tommaso */ @Slf4j @CompileStatic -class RunImpl { +class CmdRun { interface Options extends IHubOptions { String getPipeline() @@ -128,17 +132,245 @@ class RunImpl { GParsConfig.poolFactory = new CustomPoolFactory() } + @Parameters(commandDescription = 'Execute a pipeline project') + static class V1 extends CmdBase implements Options, HubOptions { + + static class DurationConverter implements IStringConverter { + @Override + Long convert(String value) { + if( !value ) throw new IllegalArgumentException() + if( value.isLong() ) { return value.toLong() } + return Duration.of(value).toMillis() + } + } + + @Parameter(names=['-name'], description = 'Assign a mnemonic name to the a pipeline run') + String runName + + @Parameter(names=['-lib'], description = 'Library extension path') + String libPath + + @Parameter(names=['-cache'], description = 'Enable/disable processes caching', arity = 1) + Boolean cacheable + + @Parameter(names=['-resume'], description = 'Execute the script using the cached results, useful to continue executions that was stopped by an error') + String resume + + @Parameter(names=['-ps','-pool-size'], description = 'Number of threads in the execution pool', hidden = true) + Integer poolSize + + @Parameter(names=['-pi','-poll-interval'], description = 'Executor poll interval (duration string ending with ms|s|m)', converter = DurationConverter, hidden = true) + long pollInterval + + @Parameter(names=['-qs','-queue-size'], description = 'Max number of processes that can be executed in parallel by each executor') + Integer queueSize + + @Parameter(names=['-test'], description = 'Test a script function with the name specified') + String test + + @Parameter(names=['-w', '-work-dir'], description = 'Directory where intermediate result files are stored') + String workDir + + @Parameter(names=['-bucket-dir'], description = 'Remote bucket where intermediate result files are stored') + String bucketDir + + /** + * Defines the parameters to be passed to the pipeline script + */ + @DynamicParameter(names = '--', description = 'Set a parameter used by the pipeline', hidden = true) + Map params = new LinkedHashMap<>() + + @Parameter(names='-params-file', description = 'Load script parameters from a JSON/YAML file') + String paramsFile + + @DynamicParameter(names = ['-process.'], description = 'Set process options' ) + Map processOptions = [:] + + @DynamicParameter(names = ['-e.'], description = 'Add the specified variable to execution environment') + Map env = [:] + + @Parameter(names = ['-E'], description = 'Exports all current system environment') + boolean exportSysEnv + + @DynamicParameter(names = ['-executor.'], description = 'Set executor options', hidden = true ) + Map executorOptions = [:] + + @Parameter(description = 'Project name or repository url') + List args + + @Parameter(names=['-r','-revision'], description = 'Revision of the project to run (either a git branch, tag or commit SHA number)') + String revision + + @Parameter(names=['-d','-deep'], description = 'Create a shallow clone of the specified depth') + Integer deep + + @Parameter(names=['-latest'], description = 'Pull latest changes before run') + boolean latest + + @Parameter(names='-stdin', hidden = true) + boolean stdin + + @Parameter(names = ['-ansi'], hidden = true, arity = 0) + void setAnsi(boolean value) { + launcher.options.ansiLog = value + } + + @Parameter(names = ['-ansi-log'], description = 'Enable/disable ANSI console logging', arity = 1) + void setAnsiLog(boolean value) { + launcher.options.ansiLog = value + } + + @Parameter(names = ['-with-tower'], description = 'Monitor workflow execution with Seqera Tower service') + String withTower + + @Parameter(names = ['-with-wave'], hidden = true) + String withWave + + @Parameter(names = ['-with-fusion'], hidden = true) + String withFusion + + @Parameter(names = ['-with-weblog'], description = 'Send workflow status messages via HTTP to target URL') + String withWebLog + + @Parameter(names = ['-with-trace'], description = 'Create processes execution tracing file') + String withTrace + + @Parameter(names = ['-with-report'], description = 'Create processes execution html report') + String withReport + + @Parameter(names = ['-with-timeline'], description = 'Create processes execution timeline file') + String withTimeline + + @Parameter(names = '-with-charliecloud', description = 'Enable process execution in a Charliecloud container runtime') + String withCharliecloud + + @Parameter(names = '-with-singularity', description = 'Enable process execution in a Singularity container') + String withSingularity + + @Parameter(names = '-with-apptainer', description = 'Enable process execution in a Apptainer container') + String withApptainer + + @Parameter(names = '-with-podman', description = 'Enable process execution in a Podman container') + String withPodman + + @Parameter(names = '-without-podman', description = 'Disable process execution in a Podman container') + boolean withoutPodman + + @Parameter(names = '-with-docker', description = 'Enable process execution in a Docker container') + String withDocker + + @Parameter(names = '-without-docker', description = 'Disable process execution with Docker', arity = 0) + boolean withoutDocker + + @Parameter(names = '-with-mpi', hidden = true) + boolean withMpi + + @Parameter(names = '-with-dag', description = 'Create pipeline DAG file') + String withDag + + @Parameter(names = ['-bg'], arity = 0, hidden = true) + void setBackground(boolean value) { + launcher.options.background = value + } + + @Parameter(names=['-c','-config'], hidden = true ) + List runConfig + + @DynamicParameter(names = ['-cluster.'], description = 'Set cluster options', hidden = true ) + Map clusterOptions = [:] + + @Parameter(names=['-profile'], description = 'Choose a configuration profile') + String profile + + @Parameter(names=['-dump-hashes'], description = 'Dump task hash keys for debugging purpose') + boolean dumpHashes + + @Parameter(names=['-dump-channels'], description = 'Dump channels for debugging purpose') + String dumpChannels + + @Parameter(names=['-N','-with-notification'], description = 'Send a notification email on workflow completion to the specified recipients') + String withNotification + + @Parameter(names=['-with-conda'], description = 'Use the specified Conda environment package or file (must end with .yml|.yaml suffix)') + String withConda + + @Parameter(names=['-without-conda'], description = 'Disable the use of Conda environments') + Boolean withoutConda + + @Parameter(names=['-with-spack'], description = 'Use the specified Spack environment package or file (must end with .yaml suffix)') + String withSpack + + @Parameter(names=['-without-spack'], description = 'Disable the use of Spack environments') + Boolean withoutSpack + + @Parameter(names=['-offline'], description = 'Do not check for remote project updates') + boolean offline = System.getenv('NXF_OFFLINE')=='true' + + @Parameter(names=['-entry'], description = 'Entry workflow name to be executed', arity = 1) + String entryName + + @Parameter(names=['-dsl1'], description = 'Execute the workflow using DSL1 syntax') + boolean dsl1 + + @Parameter(names=['-dsl2'], description = 'Execute the workflow using DSL2 syntax') + boolean dsl2 + + @Parameter(names=['-main-script'], description = 'The script file to be executed when launching a project directory or repository' ) + String mainScript + + @Parameter(names=['-stub-run','-stub'], description = 'Execute the workflow replacing process scripts with command stubs') + boolean stubRun + + @Parameter(names=['-preview'], description = "Run the workflow script skipping the execution of all processes") + boolean preview + + @Parameter(names=['-plugins'], description = 'Specify the plugins to be applied for this run e.g. nf-amazon,nf-tower') + String plugins + + @Parameter(names=['-disable-jobs-cancellation'], description = 'Prevent the cancellation of child jobs on execution termination') + Boolean disableJobsCancellation + + @Override + String getPipeline() { + stdin ? '-' : args[0] + } + + @Override + List getArgs() { + args.size() > 1 ? args[1..-1] : [] + } + + @Override + String getLauncherCliString() { + launcher.cliString + } + + @Override + ILauncherOptions getLauncherOptions() { + launcher.options + } + + @Override + String getName() { 'run' } + + @Override + void run() { + new CmdRun(this).run() + } + + } + private Map sysEnv = System.getenv() @Delegate private Options options - RunImpl(Options options) { + CmdRun(Options options) { this.options = options } /* For testing purposes only */ - RunImpl() {} + CmdRun() {} Boolean getDisableJobsCancellation() { options.disableJobsCancellation != null @@ -233,7 +465,7 @@ class RunImpl { return } - def info = InfoImpl.status( log.isTraceEnabled() ) + def info = CmdInfo.status( log.isTraceEnabled() ) log.debug( '\n'+info ) // -- add this run to the local history diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/CmdSecrets.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdSecrets.groovy new file mode 100644 index 0000000000..9296d47a08 --- /dev/null +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdSecrets.groovy @@ -0,0 +1,289 @@ +/* + * Copyright 2020-2022, 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.secret.SecretsLoader +import nextflow.secret.SecretsProvider + +/** + * CLI `secrets` sub-command + * + * @author Paolo Di Tommaso + */ +@Slf4j +@CompileStatic +class CmdSecrets { + + enum Command { + GET, + SET, + LIST, + DELETE + } + + @Parameters(commandDescription = 'Manage pipeline secrets (preview)') + static class V1 extends CmdBase implements UsageAware { + + interface SubCmd { + String getName() + void apply(List args) + void usage(List args) + } + + private List commands = (List)[ + new GetCmd(), + new SetCmd(), + new ListCmd(), + new DeleteCmd() + ] + + @Parameter(hidden = true) + List args = [] + + @Override + String getName() { 'secrets' } + + @Override + void run() { + if( !args ) { + usage() + return + } + + final cmd = commands.find { it.name == args[0] } + if( !cmd ) { + def matches = commands.collect{ it.name }.closest(args[0]) + def msg = "Unknown secrets sub-command: ${args[0]}" + if( matches ) + msg += " -- Did you mean one of these?\n" + matches.collect { " $it"}.join('\n') + throw new AbortOperationException(msg) + } + + cmd.apply(args.drop(1)) + } + + /** + * Print the command usage help + */ + @Override + void usage() { + usage(args) + } + + /** + * Print the command usage help + * + * @param args The arguments as entered by the user + */ + @Override + void usage(List args) { + + List result = [] + if( !args ) { + result << this.getClass().getAnnotation(Parameters).commandDescription() + result << 'Usage: nextflow secrets [options]' + result << '' + result << 'Commands:' + commands.collect{ it.name }.sort().each { result << " $it".toString() } + result << '' + } + else { + def sub = commands.find { it.name == args[0] } + if( sub ) + sub.usage(result) + else { + throw new AbortOperationException("Unknown secrets sub-command: ${args[0]}") + } + } + + println result.join('\n').toString() + } + + private void addOption(String fieldName, List args) { + def annot = this.class.getDeclaredField(fieldName)?.getAnnotation(Parameter) + if( annot ) { + args << ' ' + annot.names().join(', ') + args << ' ' + annot.description() + } + else { + log.debug "Unknown help field: $fieldName" + } + } + + @Deprecated + class PutCmd extends SetCmd { + @Override + String getName() { 'put' } + + void apply(List args) { + log.warn "Put command is deprecated - use 'set' instead'" + super.apply(args) + } + } + + class SetCmd implements SubCmd { + @Override + String getName() { 'set' } + + @Override + void apply(List args) { + if( args.size() < 1 ) + throw new AbortOperationException("Missing secret name") + if( args.size() < 2 ) + throw new AbortOperationException("Missing secret value") + + new CmdSecrets().run(Command.SET, args) + } + + @Override + void usage(List args) { + args << 'Set a key-pair in the secrets store' + args << "Usage: nextflow secrets $name ".toString() + args << '' + args << '' + } + } + + class GetCmd implements SubCmd { + @Override + String getName() { 'get' } + + @Override + void apply(List args) { + if( args.size() != 1 ) + throw new AbortOperationException("Wrong number of arguments") + + if( !args[0] ) + throw new AbortOperationException("Missing secret name") + + new CmdSecrets().run(Command.GET, args) + } + + @Override + void usage(List args) { + args << 'Get a secret value with the name' + args << "Usage: nextflow secrets $name ".toString() + args << '' + } + } + + class ListCmd implements SubCmd { + @Override + String getName() { 'list' } + + @Override + void apply(List args) { + if( args.size() > 0 ) + throw new AbortOperationException("Wrong number of arguments") + + new CmdSecrets().run(Command.LIST, args) + } + + @Override + void usage(List args) { + args << 'List all names in the secrets store' + args << "Usage: nextflow secrets $name".toString() + args << '' + } + } + + class DeleteCmd implements SubCmd { + @Override + String getName() { 'delete' } + + @Override + void apply(List args) { + if( args.size() != 1 ) + throw new AbortOperationException("Wrong number of arguments") + + if( !args[0] ) + throw new AbortOperationException("Missing secret name") + + new CmdSecrets().run(Command.DELETE, args) + } + + @Override + void usage(List args) { + args << 'Delete an entry from the secrets store' + args << "Usage: nextflow secrets $name".toString() + args << '' + addOption('secretName', args) + args << '' + } + } + } + + private SecretsProvider provider + + void run(Command command, List args) { + // setup the plugins system and load the secrets provider + Plugins.setup() + provider = SecretsLoader.instance.load() + + // run the command + try { + switch( command ) { + case GET: + get(args[0]) + break + case SET: + set(args[0], args[1]) + break + case LIST: + list() + break + case DELETE: + delete(args[0]) + break + } + } + finally { + // close the provider + provider?.close() + } + } + + void get(String name) { + println provider.getSecret(name)?.value + } + + void set(String name, String value) { + provider.putSecret(name, value) + } + + void list() { + final names = new ArrayList(provider.listSecretsNames()).sort() + if( names.size() == 0 ) { + println "no secrets available" + } + + for( String it : names ) { + println it + } + } + + void delete(String name) { + provider.removeSecret(name) + } +} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/SelfUpdateCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdSelfUpdate.groovy similarity index 94% rename from modules/nextflow/src/main/groovy/nextflow/cli/v1/SelfUpdateCmd.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdSelfUpdate.groovy index c970f22afe..2aa9c6e67c 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/SelfUpdateCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdSelfUpdate.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package nextflow.cli.v1 +package nextflow.cli import com.beust.jcommander.Parameters @@ -24,7 +24,7 @@ import com.beust.jcommander.Parameters * @author Paolo Di Tommaso */ @Parameters(commandDescription = 'Update nextflow runtime to the latest available version') -class SelfUpdateCmd extends AbstractCmd { +class CmdSelfUpdate extends CmdBase { @Override String getName() { 'self-update' } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/ViewImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/CmdView.groovy similarity index 69% rename from modules/nextflow/src/main/groovy/nextflow/cli/ViewImpl.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/CmdView.groovy index 248a1758e3..e0d637ab8d 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/ViewImpl.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/CmdView.groovy @@ -16,6 +16,8 @@ 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 @@ -23,13 +25,13 @@ import nextflow.plugin.Plugins import nextflow.scm.AssetManager /** - * CLI `view` sub-command + * CLI sub-command VIEW -- Print a pipeline script to console * * @author Paolo Di Tommaso */ @Slf4j @CompileStatic -class ViewImpl { +class CmdView { interface Options { String getPipeline() @@ -37,10 +39,36 @@ class ViewImpl { boolean getAll() } + @Parameters(commandDescription = 'View project script file(s)') + static class V1 extends CmdBase implements Options { + + @Override + String getName() { 'view' } + + @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 + String getPipeline() { + args.size() > 0 ? args[0] : null + } + + @Override + void run() { + new CmdView(this).run() + } + } + @Delegate private Options options - ViewImpl(Options options) { + CmdView(Options options) { this.options = options } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/FsImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/FsImpl.groovy deleted file mode 100644 index 8d77ab88d1..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/FsImpl.groovy +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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 java.nio.charset.Charset -import java.nio.file.Files -import java.nio.file.Path - -import groovy.transform.CompileStatic -import nextflow.extension.FilesEx -import nextflow.file.FileHelper -import nextflow.file.FilePatternSplitter -import nextflow.plugin.Plugins - -/** - * CLI `fs` sub-command - * - * @author Paolo Di Tommaso - */ -@CompileStatic -class FsImpl { - - enum Command { - COPY, - MOVE, - LIST, - CAT, - REMOVE - } - - void run(Command command, List args) { - Plugins.setup() - - try { - switch( command ) { - case COPY: - traverse(args[0]) { Path path -> copy(path, args[1] as Path) } - break - case MOVE: - traverse(args[0]) { Path path -> move(path, args[1] as Path) } - break - case LIST: - traverse(args[0]) { Path path -> list(path) } - break - case CAT: - traverse(args[0]) { Path path -> cat(path) } - break - case REMOVE: - traverse(args[0]) { Path path -> remove(path) } - break - } - } - finally { - Plugins.stop() - } - } - - private void traverse( String source, Closure op ) { - // if it isn't a glob pattern simply return it a normalized absolute Path object - def splitter = FilePatternSplitter.glob().parse(source) - if( splitter.isPattern() ) { - final scheme = splitter.scheme - final folder = splitter.parent - final pattern = splitter.fileName - final fs = FileHelper.fileSystemForScheme(scheme) - - def opts = [:] - opts.type = 'file' - - FileHelper.visitFiles(opts, fs.getPath(folder), pattern, op) - } - else { - def normalised = splitter.strip(source) - op.call(FileHelper.asPath(normalised)) - } - } - - void copy(Path source, Path target) { - FilesEx.copyTo(source, target) - } - - void move(Path source, Path target) { - FilesEx.moveTo(source, target) - } - - void list(Path source) { - println source.name - } - - void cat(Path source) { - String line - def reader = Files.newBufferedReader(source, Charset.defaultCharset()) - while( line = reader.readLine() ) - println line - } - - void remove(Path source) { - Files.isDirectory(source) ? FilesEx.deleteDir(source) : FilesEx.delete(source) - } - -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/HubOptions.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/HubOptions.groovy similarity index 98% rename from modules/nextflow/src/main/groovy/nextflow/cli/v1/HubOptions.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/HubOptions.groovy index fc8f3bb301..b797bf80a7 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/HubOptions.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/HubOptions.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package nextflow.cli.v1 +package nextflow.cli import com.beust.jcommander.Parameter import groovy.transform.CompileStatic diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/Launcher.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/Launcher.groovy similarity index 93% rename from modules/nextflow/src/main/groovy/nextflow/cli/v1/Launcher.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/Launcher.groovy index c1a67abb69..75105ef492 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/Launcher.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/Launcher.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package nextflow.cli.v1 +package nextflow.cli import java.lang.reflect.Field @@ -54,11 +54,11 @@ class Launcher { private LauncherOptions options - private AbstractCmd command + private CmdBase command private String cliString - private List allCommands + private List allCommands private List normalizedArgs @@ -76,29 +76,29 @@ class Launcher { } protected void init() { - allCommands = (List)[ - new CleanCmd(), - new CloneCmd(), - new ConfigCmd(), - new ConsoleCmd(), - new DropCmd(), - new FsCmd(), - new HelpCmd(), - new InfoCmd(), - new KubeRunCmd(), - new ListCmd(), - new LogCmd(), - new NodeCmd(), - new PluginCmd(), - new PluginsCmd(), - new PullCmd(), - new RunCmd(), - new SelfUpdateCmd(), - new ViewCmd() + allCommands = (List)[ + new CmdClean.V1(), + new CmdClone.V1(), + new CmdConfig.V1(), + new CmdConsole.V1(), + new CmdDrop.V1(), + new CmdFs.V1(), + new CmdHelp(), + new CmdInfo.V1(), + new CmdKubeRun(), + new CmdList.V1(), + new CmdLog.V1(), + new CmdNode.V1(), + new CmdPlugin.V1(), + new CmdPlugins(), + new CmdPull.V1(), + new CmdRun.V1(), + new CmdSelfUpdate(), + new CmdView.V1() ] if( SecretsLoader.isEnabled() ) - allCommands.add(new SecretsCmd()) + allCommands.add(new CmdSecrets.V1()) // legacy command final cmdCloud = SpuriousDeps.cmdCloud() @@ -130,7 +130,7 @@ class Launcher { jcommander.parse( normalizedArgs as String[] ) command = allCommands.find { it.name == jcommander.getParsedCommand() } // whether is running a daemon - daemonMode = command instanceof NodeCmd + daemonMode = command instanceof CmdNode.V1 // set the log file name checkLogFileName() @@ -156,7 +156,7 @@ class Launcher { if( !options.logFile ) { if( isDaemon() ) options.logFile = System.getenv('NXF_LOG_FILE') ?: '.node-nextflow.log' - else if( command instanceof RunCmd || options.debug || options.trace ) + else if( command instanceof CmdRun.V1 || options.debug || options.trace ) options.logFile = System.getenv('NXF_LOG_FILE') ?: ".nextflow.log" } } @@ -337,7 +337,7 @@ class Launcher { !x.startsWith('-') || x.isNumber() || x.contains(' ') } - AbstractCmd findCommand( String cmdName ) { + CmdBase findCommand( String cmdName ) { allCommands.find { it.name == cmdName } } @@ -388,12 +388,12 @@ class Launcher { } } - protected void printCommands(List commands) { + protected void printCommands(List commands) { println "\nCommands:" int len = 0 def all = new TreeMap() - new ArrayList(commands).each { + new ArrayList(commands).each { def description = it.getClass().getAnnotation(Parameters)?.commandDescription() if( description ) { all[it.name] = description @@ -448,9 +448,9 @@ class Launcher { // replace the current command with the `help` command def target = command?.name - command = allCommands.find { it instanceof HelpCmd } + command = allCommands.find { it instanceof CmdHelp } if( target ) { - (command as HelpCmd).args = [target] + (command as CmdHelp).args = [target] } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/LauncherOptions.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/LauncherOptions.groovy similarity index 99% rename from modules/nextflow/src/main/groovy/nextflow/cli/v1/LauncherOptions.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/LauncherOptions.groovy index 5fa0219fe6..b185f4885e 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/LauncherOptions.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/LauncherOptions.groovy @@ -15,7 +15,7 @@ * limitations under the License. */ -package nextflow.cli.v1 +package nextflow.cli import com.beust.jcommander.DynamicParameter import com.beust.jcommander.Parameter diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/SecretsImpl.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/SecretsImpl.groovy deleted file mode 100644 index c437086f74..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/SecretsImpl.groovy +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2020-2022, 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 groovy.transform.CompileStatic -import nextflow.plugin.Plugins -import nextflow.secret.SecretsLoader -import nextflow.secret.SecretsProvider - -/** - * CLI `secrets` sub-command - * - * @author Paolo Di Tommaso - */ -@CompileStatic -class SecretsImpl { - - enum Command { - GET, - SET, - LIST, - DELETE - } - - private SecretsProvider provider - - void run(Command command, List args) { - // setup the plugins system and load the secrets provider - Plugins.setup() - provider = SecretsLoader.instance.load() - - // run the command - try { - switch( command ) { - case GET: - get(args[0]) - break - case SET: - set(args[0], args[1]) - break - case LIST: - list() - break - case DELETE: - delete(args[0]) - break - } - } - finally { - // close the provider - provider?.close() - } - } - - void get(String name) { - println provider.getSecret(name)?.value - } - - void set(String name, String value) { - provider.putSecret(name, value) - } - - void list() { - final names = new ArrayList(provider.listSecretsNames()).sort() - if( names.size() == 0 ) { - println "no secrets available" - } - - for( String it : names ) { - println it - } - } - - void delete(String name) { - provider.removeSecret(name) - } -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/UsageAware.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/UsageAware.groovy similarity index 97% rename from modules/nextflow/src/main/groovy/nextflow/cli/v1/UsageAware.groovy rename to modules/nextflow/src/main/groovy/nextflow/cli/UsageAware.groovy index eb3fb8a1f9..e12d3bdb3d 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/UsageAware.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/UsageAware.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package nextflow.cli.v1 +package nextflow.cli /** * Command can implement this interface to provide a diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/CleanCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/CleanCmd.groovy deleted file mode 100644 index 059a2725fc..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/CleanCmd.groovy +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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.v1 - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.CleanImpl -import nextflow.cli.ILauncherOptions - -/** - * CLI `clean` sub-command (v1) - * - * @author Paolo Di Tommaso - * @author Lorenz Gerber - */ -@CompileStatic -@Parameters(commandDescription = 'Clean up project cache and work directories') -class CleanCmd extends AbstractCmd implements CleanImpl.Options { - - @Parameter(names = ['-after'], description = 'Clean up runs executed after the specified one') - String after - - @Parameter(names = ['-before'], description = 'Clean up runs executed before the specified one') - String before - - @Parameter(names = ['-but'], description = 'Clean up all runs except the specified one') - String but - - @Parameter(names = ['-n', '-dry-run'], arity = 0, description = 'Print names of file to be removed without deleting them') - boolean dryRun - - @Parameter(names = ['-f', '-force'], arity = 0, description = 'Force clean command') - boolean force - - @Parameter(names = ['-k', '-keep-logs'], description = 'Removes only temporary files but retains execution log entries and metadata') - boolean keepLogs - - @Parameter(names = ['-q', '-quiet'], arity = 0, description = 'Do not print names of files removed') - boolean quiet - - @Parameter(description = 'Session IDs or run names') - List args = [] - - @Override - ILauncherOptions getLauncherOptions() { - launcher.options - } - - @Override - String getName() { 'clean' } - - @Override - void run() { - new CleanImpl(this).run() - } - -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/CloneCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/CloneCmd.groovy deleted file mode 100644 index 32c6b652be..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/CloneCmd.groovy +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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.v1 - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.CloneImpl - -/** - * CLI `clone` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@CompileStatic -@Parameters(commandDescription = 'Clone a project into a folder') -class CloneCmd extends AbstractCmd implements CloneImpl.Options, HubOptions { - - @Parameter(required = true, description = 'name of the project to clone') - List args - - @Parameter(names=['-d','-deep'], description = 'Create a shallow clone of the specified depth') - Integer deep - - @Parameter(names = ['-r','-revision'], description = 'Revision to clone - It can be a git branch, tag or revision number') - String revision - - @Override - String getPipeline() { args[0] } - - @Override - String getTargetName() { - args.size() > 1 ? args[1] : null - } - - @Override - String getName() { 'clone' } - - @Override - void run() { - new CloneImpl(this).run() - } -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/ConfigCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/ConfigCmd.groovy deleted file mode 100644 index dc180b9397..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/ConfigCmd.groovy +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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.v1 - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.ConfigImpl -import nextflow.cli.ILauncherOptions - -/** - * CLI `config` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@CompileStatic -@Parameters(commandDescription = 'Print a project configuration') -class ConfigCmd extends AbstractCmd implements ConfigImpl.Options { - - @Parameter(description = 'project name') - List args = [] - - @Parameter(names = ['-a','-show-profiles'], description = 'Show all configuration profiles') - boolean showAllProfiles - - @Parameter(names = ['-profile'], description = 'Choose a configuration profile') - String profile - - @Parameter(names = ['-properties'], description = 'Prints config using Java properties notation') - boolean printProperties - - @Parameter(names = ['-flat'], description = 'Print config using flat notation') - boolean printFlatten - - @Parameter(names = ['-sort'], description = 'Sort config attributes') - boolean sort - - @Override - String getPipeline() { - args.size() > 0 ? args[0] : null - } - - @Override - ILauncherOptions getLauncherOptions() { - launcher.options - } - - @Override - String getName() { 'config' } - - @Override - void run() { - new ConfigImpl(this).run() - } - -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/ConsoleCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/ConsoleCmd.groovy deleted file mode 100644 index 283f1824e8..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/ConsoleCmd.groovy +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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.v1 - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.ConsoleImpl - -/** - * CLI `console` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@CompileStatic -@Parameters(commandDescription = 'Launch Nextflow interactive console') -class ConsoleCmd extends AbstractCmd implements ConsoleImpl.Options { - - @Parameter(description = 'Nextflow console arguments') - List args = [] - - @Override - String getScript() { - args.size() > 0 ? args[0] : null - } - - @Override - String getName() { 'console' } - - @Override - void run() { - new ConsoleImpl(this).run() - } -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/DropCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/DropCmd.groovy deleted file mode 100644 index 75379e78f8..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/DropCmd.groovy +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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.v1 - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.DropImpl - -/** - * CLI `drop` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@CompileStatic -@Parameters(commandDescription = 'Delete the local copy of a project') -class DropCmd extends AbstractCmd implements DropImpl.Options { - - @Parameter(required = true, description = 'name of the project to drop') - List args - - @Parameter(names = ['-f','-force'], description = 'Delete the repository without taking care of local changes') - boolean force - - @Override - String getPipeline() { args[0] } - - @Override - String getName() { 'drop' } - - @Override - void run() { - new DropImpl(this).run() - } -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/FsCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/FsCmd.groovy deleted file mode 100644 index 49e69c6d05..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/FsCmd.groovy +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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.v1 - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.FsImpl -import nextflow.exception.AbortOperationException - -/** - * CLI `fs` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@CompileStatic -@Parameters(commandDescription = 'Perform basic filesystem operations') -class FsCmd extends AbstractCmd implements UsageAware { - - trait SubCmd { - abstract String getName() - abstract int getArity() - abstract String getDescription() - abstract FsImpl.Command getCommand() - - String usage() { - "Usage: nextflow fs ${name} " + (arity==1 ? "" : "source_file target_file") - } - } - - private List commands = (List)[ - new CmdCopy(), - new CmdMove(), - new ListImpl(), - new CmdCat(), - new CmdRemove() - ] - - @Parameter(hidden = true) - List args = [] - - @Override - String getName() { 'fs' } - - @Override - void run() { - if( !args ) { - usage() - return - } - - final cmd = commands.find { it.name == args[0] } - if( !cmd ) { - def matches = commands.collect{ it.name }.closest(args[0]) - def msg = "Unknown fs sub-command: ${args[0]}" - if( matches ) - msg += " -- Did you mean one of these?\n" + matches.collect { " $it"}.join('\n') - throw new AbortOperationException(msg) - } - - if( args.size() - 1 != cmd.getArity() ) - throw new AbortOperationException(cmd.usage()) - - new FsImpl().run(cmd.getCommand(), args.drop(1)) - } - - /** - * Print the command usage help - */ - void usage() { - usage(args) - } - - /** - * Print the command usage help - * - * @param args The arguments as entered by the user - */ - void usage(List args) { - - def result = [] - if( !args ) { - result << 'Usage: nextflow fs [args]' - result << '' - result << 'Commands:' - commands.each { - result << " ${it.name}\t${it.description}" - } - result << '' - println result.join('\n').toString() - } - else { - def sub = commands.find { it.name == args[0] } - if( sub ) - println sub.usage() - else { - throw new AbortOperationException("Unknown fs sub-command: ${args[0]}") - } - } - - } - - class CmdCopy implements SubCmd { - @Override String getName() { 'cp' } - @Override int getArity() { 2 } - @Override String getDescription() { 'Copy a file' } - @Override FsImpl.Command getCommand() { FsImpl.Command.COPY } - } - - class CmdMove implements SubCmd { - @Override String getName() { 'mv' } - @Override int getArity() { 2 } - @Override String getDescription() { 'Move a file' } - @Override FsImpl.Command getCommand() { FsImpl.Command.MOVE } - } - - class ListImpl implements SubCmd { - @Override String getName() { 'ls' } - @Override int getArity() { 1 } - @Override String getDescription() { 'List the contents of a folder' } - @Override FsImpl.Command getCommand() { FsImpl.Command.LIST } - } - - class CmdCat implements SubCmd { - @Override String getName() { 'cat' } - @Override int getArity() { 1 } - @Override String getDescription() { 'Print a file to stdout' } - @Override FsImpl.Command getCommand() { FsImpl.Command.CAT } - } - - class CmdRemove implements SubCmd { - @Override String getName() { 'rm' } - @Override int getArity() { 1 } - @Override String getDescription() { 'Remove a file' } - @Override FsImpl.Command getCommand() { FsImpl.Command.REMOVE } - } - -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/InfoCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/InfoCmd.groovy deleted file mode 100644 index f979009143..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/InfoCmd.groovy +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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.v1 - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.InfoImpl - -/** - * CLI `info` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@CompileStatic -@Parameters(commandDescription = 'Print project and system runtime information') -class InfoCmd extends AbstractCmd implements InfoImpl.Options { - - @Parameter(description = 'project name') - List args = [] - - @Parameter(names = ['-d'], arity = 0, description = 'Show detailed information') - boolean detailed - - @Parameter(names = ['-dd'], arity = 0, hidden = true) - boolean moreDetailed - - @Parameter(names = ['-o','-output-format'], description = 'Output format, either: text (default), json, yaml') - String format - - @Parameter(names = ['-u','-check-updates'], description = 'Check for remote updates') - boolean checkForUpdates - - @Override - String getPipeline() { - args.size() > 0 ? args[0] : null - } - - @Override - String getName() { 'info' } - - @Override - void run() { - new InfoImpl(this).run() - } - -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/ListCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/ListCmd.groovy deleted file mode 100644 index 71f82a597a..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/ListCmd.groovy +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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.v1 - -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.ListImpl - -/** - * CLI `list` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@CompileStatic -@Parameters(commandDescription = 'List all downloaded projects') -class ListCmd extends AbstractCmd implements ListImpl.Options { - - @Override - String getName() { 'list' } - - @Override - void run() { - new ListImpl(this).run() - } - -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/LogCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/LogCmd.groovy deleted file mode 100644 index 2e00168170..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/LogCmd.groovy +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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.v1 - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.LogImpl - -/** - * CLI `log` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@CompileStatic -@Parameters(commandDescription = 'Print executions log and runtime info') -class LogCmd extends AbstractCmd implements LogImpl.Options { - - @Parameter(names = ['-after'], description = 'Show log entries for runs executed after the specified one') - String after - - @Parameter(names = ['-before'], description = 'Show log entries for runs executed before the specified one') - String before - - @Parameter(names = ['-but'], description = 'Show log entries of all runs except the specified one') - String but - - @Parameter(names = ['-f','-fields'], description = 'Comma separated list of fields to include in the printed log -- Use the `-l` option to show the list of available fields') - String fields - - @Parameter(names = ['-F','-filter'], description = "Filter log entries by a custom expression e.g. process =~ /foo.*/ && status == 'COMPLETED'") - String filterStr - - @Parameter(names = ['-l','-list-fields'], arity = 0, description = 'Show all available fields') - boolean listFields - - @Parameter(names = ['-q','-quiet'], arity = 0, description = 'Show only run names') - boolean quiet - - @Parameter(names = ['-s','-separator'], description = 'Character used to separate column values') - String separator = '\\t' - - @Parameter(names = ['-t','-template'], description = 'Text template used to print each record in the log ') - String templateStr - - @Parameter(description = 'Session IDs or run names') - List args = [] - - @Override - String getName() { 'log' } - - @Override - void run() { - new LogImpl(this).run() - } - -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/NodeCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/NodeCmd.groovy deleted file mode 100644 index 4a37c591a9..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/NodeCmd.groovy +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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.v1 - -import com.beust.jcommander.DynamicParameter -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.ILauncherOptions -import nextflow.cli.NodeImpl - -/** - * CLI `node` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@CompileStatic -@Parameters(commandDescription = 'Launch Nextflow in deamon mode') -class NodeCmd extends AbstractCmd implements NodeImpl.Options { - - @Parameter(names = ['-bg'], arity = 0, description = 'Start the cluster node daemon in background') - void setBackground(boolean value) { - launcher.options.background = value - } - - @DynamicParameter(names = ['-cluster.'], description = 'Define cluster config options') - Map clusterOptions = [:] - - @Parameter(description = 'Daemon name or class') - List args = [] - - @Override - String getProvider() { - args.size() ? args[0] : null - } - - @Override - ILauncherOptions getLauncherOptions() { - launcher.options - } - - @Override - String getName() { 'node' } - - @Override - void run() { - new NodeImpl(this).run() - } - -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/PluginCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/PluginCmd.groovy deleted file mode 100644 index c3a0ea41f5..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/PluginCmd.groovy +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2013-2023, 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.v1 - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.ILauncherOptions -import nextflow.cli.PluginImpl -import nextflow.exception.AbortOperationException -import static nextflow.cli.PluginExecAware.CMD_SEP - -/** - * CLI `plugin` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@CompileStatic -@Parameters(commandDescription = 'Manage plugins and execute custom plugin commands') -class PluginCmd extends AbstractCmd { - - @Parameter(hidden = true) - List args = [] - - @Override - String getName() { 'plugin' } - - @Override - void run() { - if( !args ) - throw new AbortOperationException("Missing plugin command - usage: nextflow plugin install ") - - // plugin install command - if( args[0] == 'install' ) { - if( args.size()!=2 ) - throw new AbortOperationException("Missing plugin install target - usage: nextflow plugin install ") - PluginImpl.install(args[1].tokenize(',')) - } - - // plugin run command - else if( args[0].contains(CMD_SEP) ) { - PluginImpl.exec(args.pop(), args, launcher.options) - } - - else { - throw new AbortOperationException("Invalid plugin command: ${args[0]}") - } - } - -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/PullCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/PullCmd.groovy deleted file mode 100644 index e9f5037a70..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/PullCmd.groovy +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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.v1 - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.PullImpl - -/** - * CLI `pull` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@CompileStatic -@Parameters(commandDescription = 'Download or update a project') -class PullCmd extends AbstractCmd implements PullImpl.Options, HubOptions { - - @Parameter(arity = 1, description = 'project name or repository url to pull') - List args - - @Parameter(names = ['-all'], arity = 0, description = 'Update all downloaded projects') - boolean all - - @Parameter(names = ['-r','-revision'], description = 'Revision of the project to run (either a git branch, tag or commit SHA number)') - String revision - - @Parameter(names=['-d','-deep'], description = 'Create a shallow clone of the specified depth') - Integer deep - - @Override - String getPipeline() { args[0] } - - @Override - String getName() { 'pull' } - - @Override - void run() { - new PullImpl(this).run() - } - -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/RunCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/RunCmd.groovy deleted file mode 100644 index 6b125e6dea..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/RunCmd.groovy +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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.v1 - -import com.beust.jcommander.DynamicParameter -import com.beust.jcommander.IStringConverter -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.ILauncherOptions -import nextflow.cli.RunImpl -import nextflow.util.Duration - -/** - * CLI `run` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@CompileStatic -@Parameters(commandDescription = 'Execute a pipeline project') -class RunCmd extends AbstractCmd implements RunImpl.Options, HubOptions { - - static class DurationConverter implements IStringConverter { - @Override - Long convert(String value) { - if( !value ) throw new IllegalArgumentException() - if( value.isLong() ) { return value.toLong() } - return Duration.of(value).toMillis() - } - } - - @Parameter(description = 'Project name or repository url') - List args = [] - - @Parameter(names = ['-ansi'], hidden = true, arity = 0) - void setAnsi(boolean value) { - launcher.options.ansiLog = value - } - - @Parameter(names = ['-ansi-log'], arity = 1, description = 'Enable/disable ANSI console logging') - void setAnsiLog(boolean value) { - launcher.options.ansiLog = value - } - - @Parameter(names = ['-bg'], arity = 0, hidden = true) - void setBackground(boolean value) { - launcher.options.background = value - } - - @Parameter(names = ['-bucket-dir'], description = 'Remote bucket where intermediate result files are stored') - String bucketDir - - @Parameter(names = ['-cache'], arity = 1, description = 'Enable/disable processes caching') - Boolean cacheable - - @DynamicParameter(names = ['-cluster.'], description = 'Set cluster options', hidden = true ) - Map clusterOptions = [:] - - @Parameter(names = ['-c','-config'], hidden = true ) - List runConfig - - @Parameter(names = ['-disable-jobs-cancellation'], description = 'Prevent the cancellation of child jobs on execution termination') - Boolean disableJobsCancellation - - @Parameter(names = ['-dsl1'], description = 'Execute the workflow using DSL1 syntax') - boolean dsl1 - - @Parameter(names = ['-dsl2'], description = 'Execute the workflow using DSL2 syntax') - boolean dsl2 - - @Parameter(names = ['-dump-channels'], description = 'Dump channels for debugging purpose') - String dumpChannels - - @Parameter(names = ['-dump-hashes'], description = 'Dump task hash keys for debugging purpose') - boolean dumpHashes - - @Parameter(names = ['-entry'], arity = 1, description = 'Entry workflow name to be executed') - String entryName - - @DynamicParameter(names = ['-e.','-env.'], description = 'Add the specified variable to execution environment') - Map env = [:] - - @DynamicParameter(names = ['-executor.'], description = 'Set executor options', hidden = true ) - Map executorOptions = [:] - - @Parameter(names = ['-E'], description = 'Exports all current system environment') - boolean exportSysEnv - - @Parameter(names = ['-latest'], description = 'Pull latest changes before run') - boolean latest - - @Parameter(names = ['-lib'], description = 'Library extension path') - String libPath - - @Parameter(names = ['-main-script'], description = 'The script file to be executed when launching a project directory or repository' ) - String mainScript - - @Parameter(names = ['-name'], description = 'Assign a mnemonic name to the a pipeline run') - String runName - - @Parameter(names = ['-offline'], description = 'Do not check for remote project updates') - boolean offline - - @Parameter(names = ['-params-file'], description = 'Load script parameters from a JSON/YAML file') - String paramsFile - - @Parameter(names = ['-plugins'], description = 'Specify the plugins to be applied for this run e.g. nf-amazon,nf-tower') - String plugins - - @Parameter(names = ['-pi','-poll-interval'], description = 'Executor poll interval (duration string ending with ms|s|m)', converter = DurationConverter, hidden = true) - long pollInterval - - @Parameter(names = ['-ps','-pool-size'], description = 'Number of threads in the execution pool', hidden = true) - Integer poolSize - - @Parameter(names = ['-preview'], description = "Run the workflow script skipping the execution of all processes") - boolean preview - - @DynamicParameter(names = ['-process.'], description = 'Set process options' ) - Map processOptions = [:] - - @Parameter(names = ['-profile'], description = 'Choose a configuration profile') - String profile - - @Parameter(names = ['-qs','-queue-size'], description = 'Max number of processes that can be executed in parallel by each executor') - Integer queueSize - - @Parameter(names = ['-resume'], description = 'Execute the script using the cached results, useful to continue executions that was stopped by an error') - String resume - - @Parameter(names = ['-r','-revision'], description = 'Revision of the project to run (either a git branch, tag or commit SHA number)') - String revision - - @Parameter(names=['-d','-deep'], description = 'Create a shallow clone of the specified depth') - Integer deep - - @Parameter(names = ['-stdin'], hidden = true) - boolean stdin - - @Parameter(names = ['-stub-run','-stub'], description = 'Execute the workflow replacing process scripts with command stubs') - boolean stubRun - - @Parameter(names = ['-test'], description = 'Test a script function with the name specified') - String test - - @Parameter(names = ['-with-apptainer'], description = 'Enable process execution in a Apptainer container') - String withApptainer - - @Parameter(names = ['-with-charliecloud'], description = 'Enable process execution in a Charliecloud container runtime') - String withCharliecloud - - @Parameter(names = ['-with-conda'], description = 'Use the specified Conda environment package or file (must end with .yml|.yaml suffix)') - String withConda - - @Parameter(names = ['-without-conda'], description = 'Disable the use of Conda environments') - Boolean withoutConda - - @Parameter(names = ['-with-dag'], description = 'Create pipeline DAG file') - String withDag - - @Parameter(names = ['-with-docker'], description = 'Enable process execution in a Docker container') - String withDocker - - @Parameter(names = ['-without-docker'], arity = 0, description = 'Disable process execution with Docker') - boolean withoutDocker - - @Parameter(names = ['-with-fusion'], hidden = true) - String withFusion - - @Parameter(names = ['-with-mpi'], hidden = true) - boolean withMpi - - @Parameter(names = ['-N','-with-notification'], description = 'Send a notification email on workflow completion to the specified recipients') - String withNotification - - @Parameter(names = ['-with-podman'], description = 'Enable process execution in a Podman container') - String withPodman - - @Parameter(names = ['-without-podman'], description = 'Disable process execution in a Podman container') - boolean withoutPodman - - @Parameter(names = ['-with-report'], description = 'Create processes execution html report') - String withReport - - @Parameter(names = ['-with-singularity'], description = 'Enable process execution in a Singularity container') - String withSingularity - - @Parameter(names = ['-with-spack'], description = 'Use the specified Spack environment package or file (must end with .yaml suffix)') - String withSpack - - @Parameter(names = ['-without-spack'], description = 'Disable the use of Spack environments') - Boolean withoutSpack - - @Parameter(names = ['-with-timeline'], description = 'Create processes execution timeline file') - String withTimeline - - @Parameter(names = ['-with-tower'], description = 'Monitor workflow execution with Seqera Tower service') - String withTower - - @Parameter(names = ['-with-trace'], description = 'Create processes execution tracing file') - String withTrace - - @Parameter(names = ['-with-wave'], hidden = true) - String withWave - - @Parameter(names = ['-with-weblog'], description = 'Send workflow status messages via HTTP to target URL') - String withWebLog - - @Parameter(names = ['-w', '-work-dir'], description = 'Directory where intermediate result files are stored') - String workDir - - @DynamicParameter(names = ['--'], description = 'Pipeline parameters', hidden = true) - Map params = [:] - - @Override - String getPipeline() { - stdin ? '-' : args[0] - } - - @Override - List getArgs() { - args.size() > 1 ? args[1..-1] : [] - } - - @Override - String getLauncherCliString() { - launcher.cliString - } - - @Override - ILauncherOptions getLauncherOptions() { - launcher.options - } - - @Override - String getName() { 'run' } - - @Override - void run() { - new RunImpl(this).run() - } - -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/SecretsCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/SecretsCmd.groovy deleted file mode 100644 index cbeb41da4a..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/SecretsCmd.groovy +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright 2020-2022, 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.v1 - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import groovy.util.logging.Slf4j -import nextflow.cli.SecretsImpl -import nextflow.exception.AbortOperationException - -/** - * CLI `secrets` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@Slf4j -@CompileStatic -@Parameters(commandDescription = 'Manage pipeline secrets (preview)') -class SecretsCmd extends AbstractCmd implements UsageAware { - - interface SubCmd { - String getName() - void apply(List args) - void usage(List args) - } - - private List commands = (List)[ - new GetCmd(), - new SetCmd(), - new ListCmd(), - new DeleteCmd() - ] - - @Parameter(hidden = true) - List args = [] - - @Override - String getName() { 'secrets' } - - @Override - void run() { - if( !args ) { - usage() - return - } - - final cmd = commands.find { it.name == args[0] } - if( !cmd ) { - def matches = commands.collect{ it.name }.closest(args[0]) - def msg = "Unknown secrets sub-command: ${args[0]}" - if( matches ) - msg += " -- Did you mean one of these?\n" + matches.collect { " $it"}.join('\n') - throw new AbortOperationException(msg) - } - - cmd.apply(args.drop(1)) - } - - /** - * Print the command usage help - */ - @Override - void usage() { - usage(args) - } - - /** - * Print the command usage help - * - * @param args The arguments as entered by the user - */ - @Override - void usage(List args) { - - List result = [] - if( !args ) { - result << this.getClass().getAnnotation(Parameters).commandDescription() - result << 'Usage: nextflow secrets [options]' - result << '' - result << 'Commands:' - commands.collect{ it.name }.sort().each { result << " $it".toString() } - result << '' - } - else { - def sub = commands.find { it.name == args[0] } - if( sub ) - sub.usage(result) - else { - throw new AbortOperationException("Unknown secrets sub-command: ${args[0]}") - } - } - - println result.join('\n').toString() - } - - private void addOption(String fieldName, List args) { - def annot = this.class.getDeclaredField(fieldName)?.getAnnotation(Parameter) - if( annot ) { - args << ' ' + annot.names().join(', ') - args << ' ' + annot.description() - } - else { - log.debug "Unknown help field: $fieldName" - } - } - - @Deprecated - class PutCmd extends SetCmd { - @Override - String getName() { 'put' } - - void apply(List args) { - log.warn "Put command is deprecated - use 'set' instead'" - super.apply(args) - } - } - - class SetCmd implements SubCmd { - @Override - String getName() { 'set' } - - @Override - void apply(List args) { - if( args.size() < 1 ) - throw new AbortOperationException("Missing secret name") - if( args.size() < 2 ) - throw new AbortOperationException("Missing secret value") - - new SecretsImpl().run(SecretsImpl.Command.SET, args) - } - - @Override - void usage(List args) { - args << 'Set a key-pair in the secrets store' - args << "Usage: nextflow secrets $name ".toString() - args << '' - args << '' - } - } - - class GetCmd implements SubCmd { - @Override - String getName() { 'get' } - - @Override - void apply(List args) { - if( args.size() != 1 ) - throw new AbortOperationException("Wrong number of arguments") - - if( !args[0] ) - throw new AbortOperationException("Missing secret name") - - new SecretsImpl().run(SecretsImpl.Command.GET, args) - } - - @Override - void usage(List args) { - args << 'Get a secret value with the name' - args << "Usage: nextflow secrets $name ".toString() - args << '' - } - } - - class ListCmd implements SubCmd { - @Override - String getName() { 'list' } - - @Override - void apply(List args) { - if( args.size() > 0 ) - throw new AbortOperationException("Wrong number of arguments") - - new SecretsImpl().run(SecretsImpl.Command.LIST, args) - } - - @Override - void usage(List args) { - args << 'List all names in the secrets store' - args << "Usage: nextflow secrets $name".toString() - args << '' - } - } - - class DeleteCmd implements SubCmd { - @Override - String getName() { 'delete' } - - @Override - void apply(List args) { - if( args.size() != 1 ) - throw new AbortOperationException("Wrong number of arguments") - - if( !args[0] ) - throw new AbortOperationException("Missing secret name") - - new SecretsImpl().run(SecretsImpl.Command.DELETE, args) - } - - @Override - void usage(List args) { - args << 'Delete an entry from the secrets store' - args << "Usage: nextflow secrets $name".toString() - args << '' - addOption('secretName', args) - args << '' - } - } -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v1/ViewCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v1/ViewCmd.groovy deleted file mode 100644 index 14841a3713..0000000000 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v1/ViewCmd.groovy +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2020-2022, Seqera Labs - * Copyright 2013-2019, Centre for Genomic Regulation (CRG) - * - * 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.v1 - -import com.beust.jcommander.Parameter -import com.beust.jcommander.Parameters -import groovy.transform.CompileStatic -import nextflow.cli.ViewImpl - -/** - * CLI `view` sub-command (v1) - * - * @author Paolo Di Tommaso - */ -@CompileStatic -@Parameters(commandDescription = 'View project script file(s)') -class ViewCmd extends AbstractCmd implements ViewImpl.Options { - - @Override - String getName() { 'view' } - - @Parameter(required = true, description = 'project name') - List args = [] - - @Parameter(names = ['-l','-all'], arity = 0, description = 'List repository content') - boolean all - - @Parameter(names = ['-q','-quiet'], arity = 0, description = 'Hide header line') - boolean quiet - - @Override - String getPipeline() { - args.size() > 0 ? args[0] : null - } - - @Override - void run() { - new ViewImpl(this).run() - } -} diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/CleanCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/CleanCmd.groovy index 74a5a4515d..616616054b 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/CleanCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/CleanCmd.groovy @@ -17,7 +17,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic -import nextflow.cli.CleanImpl +import nextflow.cli.CmdClean import nextflow.cli.ILauncherOptions import picocli.CommandLine.Command import picocli.CommandLine.Option @@ -34,7 +34,7 @@ import picocli.CommandLine.ParentCommand name = 'clean', description = 'Clean up project cache and work directories' ) -class CleanCmd extends AbstractCmd implements CleanImpl.Options { +class CleanCmd extends AbstractCmd implements CmdClean.Options { @ParentCommand private Launcher launcher @@ -70,7 +70,7 @@ class CleanCmd extends AbstractCmd implements CleanImpl.Options { @Override void run() { - new CleanImpl(this).run() + new CmdClean(this).run() } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/CloneCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/CloneCmd.groovy index cb4276dd16..2e2e38b639 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/CloneCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/CloneCmd.groovy @@ -17,7 +17,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic -import nextflow.cli.CloneImpl +import nextflow.cli.CmdClone import picocli.CommandLine.Command import picocli.CommandLine.Option import picocli.CommandLine.Parameters @@ -32,7 +32,7 @@ import picocli.CommandLine.Parameters name = 'clone', description = 'Clone a project into a folder' ) -class CloneCmd extends AbstractCmd implements CloneImpl.Options, HubOptions { +class CloneCmd extends AbstractCmd implements CmdClone.Options, HubOptions { @Parameters(index = '0', description = 'name of the project to clone') String pipeline @@ -48,6 +48,6 @@ class CloneCmd extends AbstractCmd implements CloneImpl.Options, HubOptions { @Override void run() { - new CloneImpl(this).run() + new CmdClone(this).run() } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/ConfigCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/ConfigCmd.groovy index 2614281b8b..68ebbc572b 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/ConfigCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/ConfigCmd.groovy @@ -17,7 +17,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic -import nextflow.cli.ConfigImpl +import nextflow.cli.CmdConfig import nextflow.cli.ILauncherOptions import picocli.CommandLine.Command import picocli.CommandLine.Option @@ -34,7 +34,7 @@ import picocli.CommandLine.ParentCommand name = 'config', description = 'Print a project configuration' ) -class ConfigCmd extends AbstractCmd implements ConfigImpl.Options { +class ConfigCmd extends AbstractCmd implements CmdConfig.Options { @ParentCommand private Launcher launcher @@ -64,7 +64,7 @@ class ConfigCmd extends AbstractCmd implements ConfigImpl.Options { @Override void run() { - new ConfigImpl(this).run() + new CmdConfig(this).run() } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/ConsoleCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/ConsoleCmd.groovy index 8003f99c2e..7498951e8f 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/ConsoleCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/ConsoleCmd.groovy @@ -17,7 +17,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic -import nextflow.cli.ConsoleImpl +import nextflow.cli.CmdConsole import picocli.CommandLine.Command import picocli.CommandLine.Parameters @@ -31,13 +31,13 @@ import picocli.CommandLine.Parameters name = 'console', description = 'Launch Nextflow interactive console' ) -class ConsoleCmd extends AbstractCmd implements ConsoleImpl.Options { +class ConsoleCmd extends AbstractCmd implements CmdConsole.Options { @Parameters(arity = '0..1', description = 'script filename') String script @Override void run() { - new ConsoleImpl(this).run() + new CmdConsole(this).run() } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/DropCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/DropCmd.groovy index 8cc253aeba..ff7034f978 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/DropCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/DropCmd.groovy @@ -17,7 +17,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic -import nextflow.cli.DropImpl +import nextflow.cli.CmdDrop import picocli.CommandLine.Command import picocli.CommandLine.Option import picocli.CommandLine.Parameters @@ -32,7 +32,7 @@ import picocli.CommandLine.Parameters name = 'drop', description = 'Delete the local copy of a project' ) -class DropCmd extends AbstractCmd implements DropImpl.Options { +class DropCmd extends AbstractCmd implements CmdDrop.Options { @Parameters(description = 'name of the project to drop') String pipeline @@ -42,6 +42,6 @@ class DropCmd extends AbstractCmd implements DropImpl.Options { @Override void run() { - new DropImpl(this).run() + new CmdDrop(this).run() } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/FsCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/FsCmd.groovy index 99af7e6ec7..ad4393ca77 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/FsCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/FsCmd.groovy @@ -17,7 +17,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic -import nextflow.cli.FsImpl +import nextflow.cli.CmdFs import picocli.CommandLine.Command import picocli.CommandLine.Parameters @@ -37,32 +37,32 @@ class FsCmd extends AbstractCmd { void copy( @Parameters(paramLabel = '') String source, @Parameters(paramLabel = '') String target) { - new FsImpl().run(FsImpl.Command.COPY, [ source, target ]) + new CmdFs().run(CmdFs.Command.COPY, [ source, target ]) } @Command(description = 'Move a file') void move( @Parameters(paramLabel = '') String source, @Parameters(paramLabel = '') String target) { - new FsImpl().run(FsImpl.Command.MOVE, [ source, target ]) + new CmdFs().run(CmdFs.Command.MOVE, [ source, target ]) } @Command(description = 'List the contents of a folder') void list( @Parameters(paramLabel = '') String source) { - new FsImpl().run(FsImpl.Command.LIST, [ source ]) + new CmdFs().run(CmdFs.Command.LIST, [ source ]) } @Command(description = 'Print a file to stdout') void cat( @Parameters(paramLabel = '') String source) { - new FsImpl().run(FsImpl.Command.CAT, [ source ]) + new CmdFs().run(CmdFs.Command.CAT, [ source ]) } @Command(description = 'Remove a file') void remove( @Parameters(paramLabel = '') String source) { - new FsImpl().run(FsImpl.Command.REMOVE, [ source ]) + new CmdFs().run(CmdFs.Command.REMOVE, [ source ]) } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/InfoCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/InfoCmd.groovy index 182b803b0e..14797c0903 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/InfoCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/InfoCmd.groovy @@ -17,7 +17,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic -import nextflow.cli.InfoImpl +import nextflow.cli.CmdInfo import picocli.CommandLine.Command import picocli.CommandLine.Option import picocli.CommandLine.Parameters @@ -32,7 +32,7 @@ import picocli.CommandLine.Parameters name = 'info', description = 'Print project and system runtime information' ) -class InfoCmd extends AbstractCmd implements InfoImpl.Options { +class InfoCmd extends AbstractCmd implements CmdInfo.Options { @Parameters(arity = '0..1', description = 'project name') String pipeline @@ -51,7 +51,7 @@ class InfoCmd extends AbstractCmd implements InfoImpl.Options { @Override void run() { - new InfoImpl(this).run() + new CmdInfo(this).run() } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/Launcher.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/Launcher.groovy index 840393ccd5..a495c153dc 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/Launcher.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/Launcher.groovy @@ -64,7 +64,7 @@ import picocli.CommandLine.ParseResult PluginCmd.class, PullCmd.class, RunCmd.class, - SelfUpdateCmd.class, + CmdSelfUpdate.class, ViewCmd.class ] ) diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/ListCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/ListCmd.groovy index 8d1047e633..4d98554739 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/ListCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/ListCmd.groovy @@ -17,7 +17,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic -import nextflow.cli.ListImpl +import nextflow.cli.CmdList import picocli.CommandLine.Command /** @@ -30,11 +30,11 @@ import picocli.CommandLine.Command name = 'list', description = 'List all downloaded projects' ) -class ListCmd extends AbstractCmd implements ListImpl.Options { +class ListCmd extends AbstractCmd implements CmdList.Options { @Override void run() { - new ListImpl(this).run() + new CmdList(this).run() } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/LogCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/LogCmd.groovy index 25a7abb55e..2df7c693ad 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/LogCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/LogCmd.groovy @@ -17,7 +17,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic -import nextflow.cli.LogImpl +import nextflow.cli.CmdLog import picocli.CommandLine.Command import picocli.CommandLine.Option import picocli.CommandLine.Parameters @@ -32,7 +32,7 @@ import picocli.CommandLine.Parameters name = 'log', description = 'Print executions log and runtime info' ) -class LogCmd extends AbstractCmd implements LogImpl.Options { +class LogCmd extends AbstractCmd implements CmdLog.Options { @Option(names = ['--after'], paramLabel = '|', description = 'Show log entries for runs executed after the specified one') String after @@ -66,7 +66,7 @@ class LogCmd extends AbstractCmd implements LogImpl.Options { @Override void run() { - new LogImpl(this).run() + new CmdLog(this).run() } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/NodeCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/NodeCmd.groovy index d97ac9df2a..08c503d5e5 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/NodeCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/NodeCmd.groovy @@ -18,7 +18,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic import nextflow.cli.ILauncherOptions -import nextflow.cli.NodeImpl +import nextflow.cli.CmdNode import picocli.CommandLine.Command import picocli.CommandLine.Option import picocli.CommandLine.Parameters @@ -34,7 +34,7 @@ import picocli.CommandLine.ParentCommand name = 'node', description = 'Launch Nextflow in deamon mode' ) -class NodeCmd extends AbstractCmd implements NodeImpl.Options { +class NodeCmd extends AbstractCmd implements CmdNode.Options { @ParentCommand private Launcher launcher @@ -57,7 +57,7 @@ class NodeCmd extends AbstractCmd implements NodeImpl.Options { @Override void run() { - new NodeImpl(this).run() + new CmdNode(this).run() } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/PluginCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/PluginCmd.groovy index 769698de1c..de380ea9bb 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/PluginCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/PluginCmd.groovy @@ -19,7 +19,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic import nextflow.cli.ILauncherOptions -import nextflow.cli.PluginImpl +import nextflow.cli.CmdPlugin import nextflow.exception.AbortOperationException import picocli.CommandLine.Command import picocli.CommandLine.Parameters @@ -53,12 +53,12 @@ class PluginCmd extends AbstractCmd { if( command == 'install' ) { if( args.size()!=1 ) throw new AbortOperationException("Missing plugin install target - usage: nextflow plugin install ") - PluginImpl.install(args[0].tokenize(',')) + CmdPlugin.install(args[0].tokenize(',')) } // plugin run command else if( command.contains(CMD_SEP) ) { - PluginImpl.exec(command, args, launcher.options) + CmdPlugin.exec(command, args, launcher.options) } else { diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/PullCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/PullCmd.groovy index 79a8ea9e09..14c72294b9 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/PullCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/PullCmd.groovy @@ -17,7 +17,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic -import nextflow.cli.PullImpl +import nextflow.cli.CmdPull import picocli.CommandLine.Command import picocli.CommandLine.Option import picocli.CommandLine.Parameters @@ -32,7 +32,7 @@ import picocli.CommandLine.Parameters name = 'pull', description = 'Download or update a project' ) -class PullCmd extends AbstractCmd implements PullImpl.Options, HubOptions { +class PullCmd extends AbstractCmd implements CmdPull.Options, HubOptions { @Parameters(description = 'project name or repository url to pull') String pipeline @@ -48,7 +48,7 @@ class PullCmd extends AbstractCmd implements PullImpl.Options, HubOptions { @Override void run() { - new PullImpl(this).run() + new CmdPull(this).run() } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/RunCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/RunCmd.groovy index 6dc1763ae9..3777561bdd 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/RunCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/RunCmd.groovy @@ -19,7 +19,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic import groovy.util.logging.Slf4j import nextflow.cli.ILauncherOptions -import nextflow.cli.RunImpl +import nextflow.cli.CmdRun import nextflow.util.Duration import picocli.CommandLine.Command import picocli.CommandLine.ITypeConverter @@ -38,7 +38,7 @@ import picocli.CommandLine.ParentCommand name = 'run', description = 'Execute a pipeline' ) -class RunCmd extends AbstractCmd implements RunImpl.Options, HubOptions { +class RunCmd extends AbstractCmd implements CmdRun.Options, HubOptions { static class DurationConverter implements ITypeConverter { @Override @@ -323,7 +323,7 @@ class RunCmd extends AbstractCmd implements RunImpl.Options, HubOptions { @Override void run() { - new RunImpl(this).run() + new CmdRun(this).run() } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/SecretsCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/SecretsCmd.groovy index d2fab62cae..e5fe1b6c9b 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/SecretsCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/SecretsCmd.groovy @@ -18,7 +18,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic -import nextflow.cli.SecretsImpl +import nextflow.cli.CmdSecrets import picocli.CommandLine.Command import picocli.CommandLine.Parameters @@ -37,25 +37,25 @@ class SecretsCmd extends AbstractCmd { @Command(description = 'Set a key-pair in the secrets store') void get( @Parameters(paramLabel = '') String name) { - new SecretsImpl().run(SecretsImpl.Command.GET, [ name ]) + new CmdSecrets().run(CmdSecrets.Command.GET, [ name ]) } @Command(description = 'Get a secret value with the name') void set( @Parameters(paramLabel = '') String name, @Parameters(paramLabel = '') String value) { - new SecretsImpl().run(SecretsImpl.Command.SET, [ name, value ]) + new CmdSecrets().run(CmdSecrets.Command.SET, [ name, value ]) } @Command(description = 'List all names in the secrets store') void list() { - new SecretsImpl().run(SecretsImpl.Command.LIST, []) + new CmdSecrets().run(CmdSecrets.Command.LIST, []) } @Command(description = 'Delete an entry from the secrets store') void delete( @Parameters(paramLabel = '') String name) { - new SecretsImpl().run(SecretsImpl.Command.DELETE, [ name ]) + new CmdSecrets().run(CmdSecrets.Command.DELETE, [ name ]) } } diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/SelfUpdateCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/SelfUpdateCmd.groovy index 0733b26cc9..0253c04367 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/SelfUpdateCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/SelfUpdateCmd.groovy @@ -27,7 +27,7 @@ import picocli.CommandLine.Command name = 'self-update', description = 'Update nextflow runtime to the latest available version' ) -class SelfUpdateCmd extends AbstractCmd { +class CmdSelfUpdate extends AbstractCmd { @Override void run() { // actually it's doing nothing, the update process is managed by the external launcher script diff --git a/modules/nextflow/src/main/groovy/nextflow/cli/v2/ViewCmd.groovy b/modules/nextflow/src/main/groovy/nextflow/cli/v2/ViewCmd.groovy index bed01cc71b..57b2a0fd7c 100644 --- a/modules/nextflow/src/main/groovy/nextflow/cli/v2/ViewCmd.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/cli/v2/ViewCmd.groovy @@ -17,7 +17,7 @@ package nextflow.cli.v2 import groovy.transform.CompileStatic -import nextflow.cli.ViewImpl +import nextflow.cli.CmdView import picocli.CommandLine.Command import picocli.CommandLine.Option import picocli.CommandLine.Parameters @@ -32,7 +32,7 @@ import picocli.CommandLine.Parameters name = 'view', description = 'View project script file(s)' ) -class ViewCmd extends AbstractCmd implements ViewImpl.Options { +class ViewCmd extends AbstractCmd implements CmdView.Options { @Parameters(description = 'project name') String pipeline @@ -45,6 +45,6 @@ class ViewCmd extends AbstractCmd implements ViewImpl.Options { @Override void run() { - new ViewImpl(this).run() + new CmdView(this).run() } } diff --git a/modules/nextflow/src/main/groovy/nextflow/config/ConfigBuilder.groovy b/modules/nextflow/src/main/groovy/nextflow/config/ConfigBuilder.groovy index 41b9a4390f..c3cce3de69 100644 --- a/modules/nextflow/src/main/groovy/nextflow/config/ConfigBuilder.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/config/ConfigBuilder.groovy @@ -26,10 +26,10 @@ import groovy.transform.PackageScope import groovy.util.logging.Slf4j import nextflow.Const import nextflow.NF -import nextflow.cli.ConfigImpl +import nextflow.cli.CmdConfig import nextflow.cli.ILauncherOptions -import nextflow.cli.NodeImpl -import nextflow.cli.RunImpl +import nextflow.cli.CmdNode +import nextflow.cli.CmdRun import nextflow.exception.AbortOperationException import nextflow.exception.ConfigParseException import nextflow.secret.SecretHolder @@ -53,9 +53,9 @@ class ConfigBuilder { ILauncherOptions options - RunImpl cmdRun + CmdRun cmdRun - NodeImpl cmdNode + CmdNode cmdNode Path baseDir @@ -105,7 +105,7 @@ class ConfigBuilder { return this } - ConfigBuilder setRunOptions( RunImpl cmdRun ) { + ConfigBuilder setRunOptions( CmdRun cmdRun ) { this.cmdRun = cmdRun setProfile(cmdRun.profile) return this @@ -126,12 +126,12 @@ class ConfigBuilder { return this } - ConfigBuilder setNodeOptions( NodeImpl node ) { + ConfigBuilder setNodeOptions( CmdNode node ) { this.cmdNode = node return this } - ConfigBuilder setCmdConfig( ConfigImpl cmdConfig ) { + ConfigBuilder setCmdConfig( CmdConfig cmdConfig ) { showAllProfiles = cmdConfig.showAllProfiles setProfile(cmdConfig.profile) return this @@ -527,7 +527,7 @@ class ConfigBuilder { } @PackageScope - void configRunOptions(ConfigObject config, Map env, RunImpl cmdRun) { + void configRunOptions(ConfigObject config, Map env, CmdRun cmdRun) { // -- set config options if( cmdRun.cacheable != null ) @@ -892,7 +892,7 @@ class ConfigBuilder { } } - static String resolveConfig(Path baseDir, RunImpl cmdRun) { + static String resolveConfig(Path baseDir, CmdRun cmdRun) { final config = new ConfigBuilder() .setShowClosures(true) diff --git a/modules/nextflow/src/main/groovy/nextflow/k8s/K8sDriverLauncher.groovy b/modules/nextflow/src/main/groovy/nextflow/k8s/K8sDriverLauncher.groovy index 086a22fc3a..b63baac829 100644 --- a/modules/nextflow/src/main/groovy/nextflow/k8s/K8sDriverLauncher.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/k8s/K8sDriverLauncher.groovy @@ -25,9 +25,9 @@ import com.beust.jcommander.DynamicParameter import com.beust.jcommander.Parameter import com.google.common.hash.Hashing import groovy.util.logging.Slf4j -import nextflow.cli.RunImpl -import nextflow.cli.v1.KubeRunCmd -import nextflow.cli.v1.RunCmd +import nextflow.cli.CmdRun +import nextflow.cli.CmdKubeRun +import nextflow.cli.CmdRun import nextflow.config.ConfigBuilder import nextflow.exception.AbortOperationException import nextflow.file.FileHelper @@ -89,7 +89,7 @@ class K8sDriverLauncher { /** * Command run options */ - private KubeRunCmd cmd + private CmdKubeRun cmd /** * Kubernetes client @@ -266,7 +266,7 @@ class K8sDriverLauncher { .setShowClosures(true) .setLauncherOptions(cmd.launcher.options) .setProfile(cmd.profile) - .setRunOptions(new RunImpl(cmd)) + .setRunOptions(new CmdRun(cmd)) if( !interactive && !pipelineName.startsWith('/') && !cmd.remoteProfile && !cmd.runRemoteConfig ) { // -- check and parse project remote config @@ -384,9 +384,9 @@ class K8sDriverLauncher { } - private Field getField(RunCmd cmd, String name) { + private Field getField(CmdRun.V1 cmd, String name) { def clazz = cmd.class - while( clazz != RunCmd ) { + while( clazz != CmdRun.V1 ) { clazz = cmd.class.getSuperclass() } clazz.getDeclaredField(name) diff --git a/modules/nextflow/src/main/groovy/nextflow/processor/TaskProcessor.groovy b/modules/nextflow/src/main/groovy/nextflow/processor/TaskProcessor.groovy index 9dbab10c3f..38cac391c9 100644 --- a/modules/nextflow/src/main/groovy/nextflow/processor/TaskProcessor.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/processor/TaskProcessor.groovy @@ -484,7 +484,7 @@ class TaskProcessor { /** * The thread pool used by GPars. The thread pool to be used is set in the static - * initializer of {@link nextflow.cli.RunImpl} class. See also {@link nextflow.util.CustomPoolFactory} + * initializer of {@link nextflow.cli.CmdRun} class. See also {@link nextflow.util.CustomPoolFactory} */ final PGroup group = Dataflow.retrieveCurrentDFPGroup() diff --git a/modules/nextflow/src/main/groovy/nextflow/util/SpuriousDeps.groovy b/modules/nextflow/src/main/groovy/nextflow/util/SpuriousDeps.groovy index 246d7e3661..6ffa7a2381 100644 --- a/modules/nextflow/src/main/groovy/nextflow/util/SpuriousDeps.groovy +++ b/modules/nextflow/src/main/groovy/nextflow/util/SpuriousDeps.groovy @@ -19,7 +19,7 @@ package nextflow.util import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import nextflow.cli.v1.AbstractCmd +import nextflow.cli.CmdBase /** * This class is used to resolve at runtime some spurious dependencies * with optional modules @@ -31,10 +31,10 @@ import nextflow.cli.v1.AbstractCmd @CompileStatic class SpuriousDeps { - static AbstractCmd cmdCloud() { + static CmdBase cmdCloud() { try { final clazz = Class.forName('nextflow.cli.CmdCloud') - return (AbstractCmd)clazz.newInstance() + return (CmdBase)clazz.newInstance() } catch (ClassNotFoundException e) { return null diff --git a/nextflow b/nextflow index 9f8b21a936..fcf9adcfb7 100755 --- a/nextflow +++ b/nextflow @@ -22,7 +22,7 @@ NXF_PROT=${NXF_PROT:-'https'} NXF_BASE=${NXF_BASE:-$NXF_PROT://www.nextflow.io/releases} NXF_TEMP=${NXF_TEMP:-$TMPDIR} NXF_DIST=${NXF_DIST:-$NXF_HOME/framework} -NXF_CLI="$0 $@" +NXF_CLI=${NXF_CLI:-"$0 $@"} NXF_CLI_OPTS=${NXF_CLI_OPTS:-} export NXF_CLI @@ -399,7 +399,7 @@ else [[ $? -ne 0 ]] && echo_red 'Unable to initialize nextflow environment' && exit 1 # use v2 launcher if specified - [[ "$NXF_CLI_V2" == 'true' && "${cli[-1]}" == "\"nextflow.cli.v1.Launcher\"" ]] && cli[-1]="\"nextflow.cli.v2.Launcher\"" + [[ "$NXF_CLI_V2" == 'true' && "${cli[-1]}" == "\"nextflow.cli.Launcher\"" ]] && cli[-1]="\"nextflow.cli.v2.Launcher\"" # first string between double quotes is the full path to java, also blank spaces are included # remainder string are arguments diff --git a/nf b/nf index 0d7d02694b..b64a9a4c35 100755 --- a/nf +++ b/nf @@ -14,4 +14,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -NXF_CLI_V2="true" nextflow "$@" +NXF_CLI="$0 $@" NXF_CLI_V2="true" nextflow "$@" diff --git a/packing.gradle b/packing.gradle index ce28e2cb5f..e35a403b60 100644 --- a/packing.gradle +++ b/packing.gradle @@ -31,7 +31,7 @@ dependencies { } -ext.mainClassName = 'nextflow.cli.v1.Launcher' +ext.mainClassName = 'nextflow.cli.Launcher' ext.homeDir = System.properties['user.home'] ext.nextflowDir = "$homeDir/.nextflow/framework/$version" ext.releaseDir = "$buildDir/releases" diff --git a/plugins/nf-console/src/main/nextflow/ui/console/ConsoleRunner.groovy b/plugins/nf-console/src/main/nextflow/ui/console/ConsoleRunner.groovy index 456eade873..c21eee8e3d 100644 --- a/plugins/nf-console/src/main/nextflow/ui/console/ConsoleRunner.groovy +++ b/plugins/nf-console/src/main/nextflow/ui/console/ConsoleRunner.groovy @@ -18,14 +18,14 @@ package nextflow.ui.console import javax.swing.UIManager import groovy.util.logging.Slf4j -import nextflow.cli.v1.LauncherOptions +import nextflow.cli.LauncherOptions import nextflow.util.LoggerHelper import org.codehaus.groovy.runtime.StackTraceUtils /** * Implement the {@link ConsoleExtension} to launch the NF console app. * - * See {@link nextflow.cli.ConsoleImpl#run()} + * See {@link nextflow.cli.CmdConsole#run()} * * @author Paolo Di Tommaso */ diff --git a/plugins/nf-console/src/main/nextflow/ui/console/Nextflow.groovy b/plugins/nf-console/src/main/nextflow/ui/console/Nextflow.groovy index 747c246199..f53e7b01a2 100644 --- a/plugins/nf-console/src/main/nextflow/ui/console/Nextflow.groovy +++ b/plugins/nf-console/src/main/nextflow/ui/console/Nextflow.groovy @@ -27,9 +27,9 @@ import groovy.console.ui.OutputTransforms import groovy.util.logging.Slf4j import nextflow.NextflowMeta import nextflow.Session -import nextflow.cli.v1.LauncherOptions -import nextflow.cli.InfoImpl -import nextflow.cli.RunImpl +import nextflow.cli.LauncherOptions +import nextflow.cli.CmdInfo +import nextflow.cli.CmdRun import nextflow.config.ConfigBuilder import nextflow.script.ScriptBinding import nextflow.script.ScriptFile @@ -85,7 +85,7 @@ class Nextflow extends Console { return new ConfigBuilder() .setLauncherOptions( new LauncherOptions() ) .setBaseDir(base) - .setRunOptions( new RunImpl() ) + .setRunOptions( new CmdRun() ) .build() } @@ -171,7 +171,7 @@ class Nextflow extends Console { */ void showAbout(EventObject evt = null) { def pane = swing.optionPane() - pane.setMessage('REPL Console for evaluating Nextflow scripts\n\n' + InfoImpl.getInfo(0)) + pane.setMessage('REPL Console for evaluating Nextflow scripts\n\n' + CmdInfo.getInfo(0)) def dialog = pane.createDialog(frame, 'About ' + TITLE) dialog.show() }