diff --git a/VERSION b/VERSION index ae27bfc..6c3924b 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.0-beta.5 +1.0.0-beta.6 diff --git a/build.gradle b/build.gradle index 0f9851d..57e9d68 100644 --- a/build.gradle +++ b/build.gradle @@ -18,6 +18,7 @@ dependencies { implementation 'com.google.code.gson:gson:2.10.1' implementation 'org.apache.httpcomponents:httpclient:4.5.14' implementation 'org.apache.httpcomponents:httpmime:4.5.14' + implementation 'org.pf4j:pf4j:3.9.0' testImplementation('org.spockframework:spock-core:2.3-groovy-3.0') testImplementation 'org.wiremock:wiremock:3.5.4' diff --git a/src/main/groovy/io/nextflow/gradle/extensions/CommandExtensionPoint.groovy b/src/main/groovy/io/nextflow/gradle/extensions/CommandExtensionPoint.groovy new file mode 100644 index 0000000..5308db9 --- /dev/null +++ b/src/main/groovy/io/nextflow/gradle/extensions/CommandExtensionPoint.groovy @@ -0,0 +1,72 @@ +/* + * Copyright 2013-2024, Seqera Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.nextflow.gradle.extensions + +import org.pf4j.ExtensionPoint + +/** + * Extension point interface for plugins that want to register top-level CLI commands. + * + * Plugins implementing this interface can provide commands that appear as first-class + * citizens in the Nextflow CLI, accessible directly as 'nextflow ' rather than + * through the legacy 'nextflow plugin :' syntax. + * + * Example: + * - Instead of: nextflow plugin nf-wave:get-container + * - Enable: nextflow wave get-container + * + * @author Edmund Miller + */ +interface CommandExtensionPoint extends ExtensionPoint { + + /** + * Get the primary command name that this plugin registers. + * This will be the top-level command name (e.g., "wave", "launch"). + * + * @return The command name that will be available at the top level + */ + String getCommandName() + + /** + * Get the command description for help output. + * This description will appear in the main help listing. + * + * @return A brief description of what this command does + */ + String getCommandDescription() + + /** + * Get the priority for this command extension. + * Higher priority commands will take precedence in case of name conflicts. + * Built-in commands have priority 1000 by default. + * + * @return Priority value (higher = higher priority), defaults to 100 + */ + default int getPriority() { return 100 } + + /** + * Create the actual command instance that will handle execution. + * This method is called when the command needs to be instantiated. + * + * Note: This returns Object to avoid coupling the gradle plugin to Nextflow's CmdBase. + * Implementations should return a nextflow.cli.CmdBase instance. + * + * @return A CmdBase instance that will handle the command execution + */ + Object createCommand() + +} \ No newline at end of file diff --git a/src/main/groovy/io/nextflow/gradle/extensions/Factory.groovy b/src/main/groovy/io/nextflow/gradle/extensions/Factory.groovy new file mode 100644 index 0000000..8d221fd --- /dev/null +++ b/src/main/groovy/io/nextflow/gradle/extensions/Factory.groovy @@ -0,0 +1,36 @@ +/* + * Copyright 2013-2024, Seqera Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package io.nextflow.gradle.extensions + +/** + * An annotation interface for channel factories that the plugin want to expose + * Nextflow will search for all methods annotated with @Factory in the ExtensionPoint and allow to the user imported them + * + * @author : jorge + * + */ +import java.lang.annotation.ElementType +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy +import java.lang.annotation.Target + +@Retention(RetentionPolicy.RUNTIME) +@Target([ElementType.METHOD]) +@interface Factory { + +} \ No newline at end of file diff --git a/src/main/groovy/io/nextflow/gradle/extensions/Function.groovy b/src/main/groovy/io/nextflow/gradle/extensions/Function.groovy new file mode 100644 index 0000000..c8b5917 --- /dev/null +++ b/src/main/groovy/io/nextflow/gradle/extensions/Function.groovy @@ -0,0 +1,36 @@ +/* + * Copyright 2013-2024, Seqera Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package io.nextflow.gradle.extensions + +/** + * An annotation interface for functions that the plugin want to expose + * Nextflow will search for all methods annotated with @Functions in the ExtensionPoint and allow to the user imported them + * + * @author : jorge + * + */ +import java.lang.annotation.ElementType +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy +import java.lang.annotation.Target + +@Retention(RetentionPolicy.RUNTIME) +@Target([ElementType.METHOD]) +@interface Function { + +} \ No newline at end of file diff --git a/src/main/groovy/io/nextflow/gradle/extensions/Operator.groovy b/src/main/groovy/io/nextflow/gradle/extensions/Operator.groovy new file mode 100644 index 0000000..3a68eb5 --- /dev/null +++ b/src/main/groovy/io/nextflow/gradle/extensions/Operator.groovy @@ -0,0 +1,36 @@ +/* + * Copyright 2013-2024, Seqera Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package io.nextflow.gradle.extensions + +/** + * An annotation interface for operators that the plugin want to expose + * Nextflow will search for all methods annotated with @Operators in the ExtensionPoint and allow to the user imported them + * + * @author : jorge + * + */ +import java.lang.annotation.ElementType +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy +import java.lang.annotation.Target + +@Retention(RetentionPolicy.RUNTIME) +@Target([ElementType.METHOD]) +@interface Operator { + +} \ No newline at end of file diff --git a/src/main/groovy/io/nextflow/gradle/extensions/PluginExtensionPoint.groovy b/src/main/groovy/io/nextflow/gradle/extensions/PluginExtensionPoint.groovy new file mode 100644 index 0000000..c191d72 --- /dev/null +++ b/src/main/groovy/io/nextflow/gradle/extensions/PluginExtensionPoint.groovy @@ -0,0 +1,56 @@ +/* + * Copyright 2013-2024, Seqera Labs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package io.nextflow.gradle.extensions + +import groovy.transform.PackageScope +import org.pf4j.ExtensionPoint + +/** + * Define plugin extension points. A plugin can provide extension methods + * to add custom channel factories, channel operators and custom function + * in the including context. + * + * The extending subclass should mark the extension methods with the + * corresponding annotation {@link Factory}, {@link Operator} and {@link Function} + * + * Note: This returns Object for session to avoid coupling the gradle plugin + * to Nextflow's internal Session class. Implementations should expect a + * nextflow.Session instance. + * + * @author Paolo Di Tommaso + */ +abstract class PluginExtensionPoint implements ExtensionPoint { + + private boolean initialised + + synchronized void checkInit(Object session) { + if( !initialised ) { + init(session) + initialised = true + } + } + + /** + * Channel factory initialization. This method is invoked one and only once before + * the before target extension method is called. + * + * @param session The current nextflow Session (passed as Object to avoid coupling) + */ + abstract protected void init(Object session) + +} \ No newline at end of file