All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jbuild.api.JbTask Maven / Gradle / Ivy

The newest version!
package jbuild.api;

import jbuild.api.change.ChangeSet;

import java.io.IOException;
import java.util.List;

/**
 * A jb build task.
 * 

*

Implementation requirements

* Implementations must be annotated with {@link JbTaskInfo}. * If a task declares that it returns any {@link JbTask#outputs()}, then it must produce those outputs. * A task should not read any files except those declared in {@link JbTask#inputs()}, * or start any Threads which do not complete before the task's run method returns. *

*

Instantiation and run rules

* A task is instantiated if it's invoked directly or indirectly (via task transitive dependencies), * or when jb must report task metadata (inputs/outputs), for example, when the user invokes jb with the * {@code -s -l debug} flags. * A task will not be instantiated more than once per build. A task may or may not be executed after being instantiated. * When the task is executed, it is only executed once, and only one of the {@code run} methods is invoked * (on incremental builds, the {@link JbTask#run(ChangeSet, String...)} method is called, otherwise * {@link JbTask#run(String...)} is invoked). *

* Notice that tasks do not need to support incremental builds. Only implement {@link JbTask#run(ChangeSet, String...)} * if you can support incremental execution (the default implementation delegates to {@link JbTask#run(String...)}). *

*

Task Configuration

* If a task implementation provides a default constructor, then {@code jb} will call that as * long as no configuration is provided for the task. *

* Configurable task implementations may take arguments in its constructors, so {@code jb} * will try to match the configuration provided for the task with the arguments of the best matching constructor. *

* Each provided configuration parameter must match an argument of one of the constructors by name and type. *

* To find configuration for the task in the {@code jb} configuration, a top-level property * with the same name as the task is searched for. *

* The following types may be used by an argument of a task constructor: *

    *
  • {@link JBuildLogger} (provided by {@code jb})
  • *
  • {@link jbuild.api.config.JbConfig} (provided by {@code jb})
  • *
  • {@link String} (may be null)
  • *
  • {@code int}
  • *
  • {@code float}
  • *
  • {@code boolean}
  • *
  • {@code List} (may be null)
  • *
  • {@code String[]} (may be null)
  • *
* For example, if the task is called {@code example-task}, * then the configuration for the task may look like this in the {@code jb} configuration file: *
 * 
 * example-task:
 *     quiet: false
 * 
 * 
* This would match a task constructor that looks as follows: *
 * 
 * {@code public ExampleTask(boolean quiet)}
 * 
 * 

How jb chooses a constructor to call

* Which constructor is chosen depends on the data provided by the task configuration. * The more arguments a constructor takes, the higher its priority. * If the provided parameters are not enough to call any constructors, jb will attempt to use the * constructor with the fewest parameters, passing {@code null} to the missing arguments. *

Receiving jb's own configuration

* A task data may receive {@code jb}'s own configuration by using a constructor parameter with * the {@link jbuild.api.config.JbConfig} type. *

* For example: *

 * 
 * {@code
 * ExampleTask(JbConfig jbConfig) {}}
 * 
 * 
* Notice that jb configuration will not include custom task's configurations. */ public interface JbTask { /** * Internal method, returns the summary of this task based on the other methods of this class. *

* Do not implement this method. * * @return the summary of this task. */ default List getSummary() { return List.of(inputs(), outputs(), dependsOn(), dependents()); } /** * Get the task inputs. *

* Inputs may be file entities paths or simple patterns. Paths ending with a * {@code /} are directories. Patterns may be of the simple form {@code *.txt} * to match files by extension on a particular directory, or * {@code **/some-dir/*.txt} to also include files in subdirectories. * * @return input paths and patterns */ default List inputs() { return List.of(); } /** * Get the task outputs. *

* Outputs may be file entities paths or simple patterns. Paths ending with a * {@code /} are directories. Patterns may be of the simple form {@code *.txt} * to match files by extension on a particular directory, or * {@code **/some-dir/*.txt} to also include files in subdirectories. * * @return output paths and patterns */ default List outputs() { return List.of(); } /** * @return tasks this task depends on. */ default List dependsOn() { return List.of(); } /** * @return tasks that should depend on this task. */ default List dependents() { return List.of(); } /** * Run this task. *

* If this task returns any {@link JbTask#inputs()} or {@link JbTask#outputs()}, * then it will only be invoked in case any of those changed since the last invocation. * The detected changes are provided via the {@code changeSet} argument. *

* The task must produce the outputs it declared, otherwise {@code jb} will assume that * the task has failed. *

* To signal an error without causing jb to print the full stack-trace, throw * either {@link IOException} or {@link JBuildException}. Any other * {@link Throwable} is considered a programmer error and will result in the * stack-trace being printed. *

* This method is only invoked on incremental builds. The initial build, or builds with the * cache disabled, will invoke {@link JbTask#run(String...)} instead. * * @param changeSet the changes since the last invocation of this task * @param args command-line arguments provided by the user * @throws IOException if an IO errors occur * @implNote the default implementation just delegates to {@link JbTask#run(String...)}, so if you * do not need to support incremental builds, implement only that method. */ default void run(ChangeSet changeSet, String... args) throws IOException { run(args); } /** * Run this task. *

* If this task returns any {@link JbTask#inputs()} or {@link JbTask#outputs()}, * then it will only be invoked in case any of those changed. *

* The task must produce the outputs it declared, otherwise {@code jb} will assume that * the task has failed. *

* To signal an error without causing jb to print the full stack-trace, throw * either {@link IOException} or {@link JBuildException}. Any other * {@link Throwable} is considered a programmer error and will result in the * stack-trace being printed. * * @param args command-line arguments provided by the user * @throws IOException if an IO errors occur */ void run(String... args) throws IOException; }