diff --git a/build.gradle b/build.gradle index d95ae61d2d..0fe4ba81ba 100644 --- a/build.gradle +++ b/build.gradle @@ -104,6 +104,7 @@ configurations { dnanexus.extendsFrom runtime ignite.extendsFrom runtime console.extendsFrom runtime + webui.extendsFrom runtime gdocLibs.extendsFrom runtime } @@ -158,6 +159,10 @@ dependencies { exclude module: 'nextflow' } + webui(project(':nxf-webui')) { + exclude module: 'nextflow' + } + drmaa(project(':nxf-drmaa')) { exclude module: 'nextflow' } @@ -279,6 +284,7 @@ ext.deployable << project(':nxf-commons') ext.deployable << project(':nxf-ignite') ext.deployable << project(':nxf-console') ext.deployable << project(':nxf-drmaa') +ext.deployable << project(':nxf-webui') protected error(String message) { logger.error message @@ -353,6 +359,13 @@ task packOne(type: Jar) { manifest.attributes('Application-Class' : 'nextflow.ui.console.Nextflow', 'console' ) manifest.attributes('Dependencies': deps, 'console') + /* + * `webui` dependencies + */ + deps = resolveDeps('webui') + manifest.attributes('Application-Class' : 'nextflow.ui.web.Main', 'webui' ) + manifest.attributes('Dependencies': deps, 'webui') + /* * `ignite` dependencies */ @@ -567,10 +580,10 @@ task dnanexus(dependsOn: packDx) { * Save the runtime classpath */ task exportClasspath { - dependsOn configurations.ignite, configurations.console + dependsOn configurations.ignite, configurations.console, configurations.webui def home = System.getProperty('user.home') - def all = configurations.ignite + configurations.console + def all = configurations.ignite + configurations.console + configurations.webui def libs = all.collect { File file -> /* println file.canonicalPath.replace(home, '$HOME'); */ file.canonicalPath; } new File('.launch.classpath').text = libs.join(':') } diff --git a/nextflow b/nextflow index e5325faa90..c3a9092485 100755 --- a/nextflow +++ b/nextflow @@ -151,7 +151,7 @@ export NXF_HOME bg='' declare -a jvmopts=() declare -a args=("$@") -declare -a cli=(clone config drop help history info ls pull run view node console) +declare -a cli=(clone config drop help history info ls pull run view node console webui) cmd='' while [[ $# != 0 ]]; do case $1 in @@ -281,12 +281,15 @@ elif [[ "$NXF_DRMAA" ]]; then exit 1 fi +[[ "$cmd" == "webui" ]] && NXF_MODE='webui' [[ "$cmd" == "console" ]] && NXF_MODE='console' [[ "$cmd" == "node" && ! "$NXF_MODE" ]] && NXF_MODE='ignite' COLUMNS=${COLUMNS:-`tty -s && tput cols 2>/dev/null || true`} JAVA_OPTS="-Dfile.encoding=UTF-8 -noverify -Dcapsule.trampoline -Dcapsule.java.cmd=$JAVA_CMD" if [[ $cmd == console ]]; then bg=1; +if [[ $cmd == webui ]]; then bg=1; +elif [[ $cmd == console ]]; then bg=1; else JAVA_OPTS+=" -Djava.awt.headless=true" fi diff --git a/settings.gradle b/settings.gradle index 00f78d8987..bd650e9102 100644 --- a/settings.gradle +++ b/settings.gradle @@ -24,6 +24,7 @@ include 'nxf-dnanexus' include 'nxf-console' include 'nxf-drmaa' include 'nxf-ignite' +include 'nxf-webui' rootProject.children.each { prj -> prj.projectDir = new File("$rootDir/subprojects/$prj.name") diff --git a/src/main/groovy/nextflow/config/ComposedConfigScript.groovy b/src/main/groovy/nextflow/config/ComposedConfigScript.groovy index 9a382e93cc..cf1d17fa93 100644 --- a/src/main/groovy/nextflow/config/ComposedConfigScript.groovy +++ b/src/main/groovy/nextflow/config/ComposedConfigScript.groovy @@ -109,4 +109,18 @@ abstract class ComposedConfigScript extends Script { this.configStack.pop() } + /** + * Create an workflow input field + */ + def field( value ) { + new InputField((Object)value) + } + + def field( Map opts, value ) { + new InputField(opts,value) + } + + def field( Map opts ) { + new InputField(opts) + } } diff --git a/src/main/groovy/nextflow/config/InputField.groovy b/src/main/groovy/nextflow/config/InputField.groovy new file mode 100644 index 0000000000..d4e18ff477 --- /dev/null +++ b/src/main/groovy/nextflow/config/InputField.groovy @@ -0,0 +1,89 @@ +package nextflow.config + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode + +/** + * Models a workflow input field parameter rendered in workflow webui + * + * @author Paolo Di Tommaso + */ +@EqualsAndHashCode +@CompileStatic +class InputField { + + /** + * The field name + */ + String name + + /** + * Descriptive name + */ + String label + + /** + * Descriptive text + */ + String hint + + /** + * Field type + */ + String type + + + /** + * default value to show when the field is rendered and + * the actual value entered by the user when submit + */ + def value + + /** + * Creates an empty field + */ + InputField() { } + + /** + * Creates a field and set the value attribute + * + * @param value + */ + InputField( def value ) { + this.value = value + } + + /** + * Creates a field and assign the attributes specified as a map object + * + * @param opts + */ + InputField( Map opts ) { + if( opts.containsKey('name') ) + this.name = opts.name + + if( opts.containsKey('label') ) + this.label = opts.label + + if( opts.containsKey('hint')) + this.hint = opts.hint + + if( opts.containsKey('type') ) + this.type = opts.type + + if( opts.containsKey('value') ) + this.value = opts.value + } + + /** + * Creates a field and assigned the attributes specified + * + * @param opts + * @param value + */ + InputField( Map opts, def value ) { + this(opts) + this.value = value + } + +} diff --git a/src/test/groovy/nextflow/config/ComposedConfigSlurperTest.groovy b/src/test/groovy/nextflow/config/ComposedConfigSlurperTest.groovy index 488801a657..5f5d1ad890 100644 --- a/src/test/groovy/nextflow/config/ComposedConfigSlurperTest.groovy +++ b/src/test/groovy/nextflow/config/ComposedConfigSlurperTest.groovy @@ -417,4 +417,25 @@ class ComposedConfigSlurperTest extends Specification { cleanup: folder?.deleteDir() } + + def 'should create a form field parameters' () { + + given: + def text = ''' + params { + alpha = 'one' + beta = field 'two', type: 'file' + gamma = field type: 'text', label: 'Gamma value' + delta = field 'hello' + } + ''' + + when: + def config = new ComposedConfigSlurper().parse(text) + then: + config.params.alpha == 'one' + config.params.beta == new InputField('two', type: 'file') + config.params.gamma == new InputField(type: 'text', label: 'Gamma value') + config.params.delta == new InputField('hello') + } } diff --git a/subprojects/nxf-webui/build.gradle b/subprojects/nxf-webui/build.gradle new file mode 100644 index 0000000000..6a836459f7 --- /dev/null +++ b/subprojects/nxf-webui/build.gradle @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2013-2015, Centre for Genomic Regulation (CRG). + * Copyright (c) 2013-2015, Paolo Di Tommaso and the respective authors. + * + * This file is part of 'Nextflow'. + * + * Nextflow is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Nextflow is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Nextflow. If not, see . + */ +apply plugin: 'groovy' + +sourceSets { + main.java.srcDirs = [] + main.groovy.srcDirs = ['src/main'] + main.resources.srcDirs = ['src/resources'] + test.groovy.srcDirs = ['src/test'] + test.java.srcDirs = [] + test.resources.srcDirs = [] +} + +dependencies { + compile project(':') +} + diff --git a/subprojects/nxf-webui/src/main/nextflow/ui/web/Main.groovy b/subprojects/nxf-webui/src/main/nextflow/ui/web/Main.groovy new file mode 100644 index 0000000000..9b7948b413 --- /dev/null +++ b/subprojects/nxf-webui/src/main/nextflow/ui/web/Main.groovy @@ -0,0 +1,19 @@ +package nextflow.ui.web + +import groovy.transform.CompileStatic + +/** + * Web UI entry point + * + * @author Paolo Di Tommaso + */ +@CompileStatic +class Main { + + static void main(String... args) { + + println "The web UI starts here!" + + } + +}