Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.maven.api.build.context;

import java.nio.file.Path;
import java.util.Collection;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.annotations.NotThreadSafe;
import org.apache.maven.api.annotations.Nullable;
import org.apache.maven.api.annotations.Provider;

/**
* Provides incremental build support by tracking inputs, outputs and their relationships.
* <p>
* A first use case is a <strong>basic build</strong> where inputs and outputs are identified but without
* any relationship between those. For such cases, the code would look like:
* <pre>
* context.registerInput(path1);
* context.registerInput(path2);
* </pre>
* <p>
* A second use case is an <strong>aggregated build</strong> where multiple inputs contribute to a single
* output. Use {@link #newInputSet()} to create an {@link InputSet} and register inputs that are then
* aggregated into outputs.
*
* @since 4.0.0
*/
@Experimental
@NotThreadSafe
@Provider
public interface BuildContext {

/**
* {@return whether the build needs to process any inputs}
*/
boolean isProcessingRequired();

/**
* Registers and processes the given output file.
*
* @param outputFile the output file path
* @return the processed output resource
*/
@Nonnull
Output processOutput(@Nonnull Path outputFile);

/**
* Creates a new {@link InputSet} which can be used to associate inputs to outputs.
*
* @return a new input set, never {@code null}
*/
@Nonnull
InputSet newInputSet();

/**
* Registers the specified input {@code Path} with this build context.
*
* @param inputFile the input file to register
* @return the metadata representing the input file, never {@code null}
* @throws IllegalArgumentException if {@code inputFile} is not a file or cannot be read
*/
@Nonnull
Metadata<Input> registerInput(@Nonnull Path inputFile);

/**
* Registers inputs identified by {@code basedir} and {@code includes}/{@code excludes} ant
* patterns.
* <p>
* When a file is found under {@code basedir}, it will be registered if it does not match
* {@code excludes} patterns and matches {@code includes} patterns. {@code null} or empty includes
* parameter will match all files. {@code excludes} match takes precedence over {@code includes}:
* if a file matches one of the excludes patterns it will not be registered regardless of includes
* patterns match.
* <p>
* The implementation is not expected to handle changes to {@code basedir}, {@code includes} or
* {@code excludes} incrementally.
*
* @param basedir the base directory to look for inputs, must not be {@code null}
* @param includes patterns of the files to register, may be {@code null}
* @param excludes patterns of the files to ignore, may be {@code null}
* @return the metadata for the registered inputs
* @throws BuildContextException if an I/O error occurs
*/
@Nonnull
Collection<? extends Metadata<Input>> registerInputs(
@Nonnull Path basedir, @Nullable Collection<String> includes, @Nullable Collection<String> excludes);

/**
* Registers inputs identified by {@code basedir} and {@code includes}/{@code excludes} ant
* patterns, then processes inputs that are new or modified since the previous build.
*
* @param basedir the base directory to look for inputs, must not be {@code null}
* @param includes patterns of the files to register, may be {@code null}
* @param excludes patterns of the files to ignore, may be {@code null}
* @return the processed inputs
* @throws BuildContextException if an I/O error occurs
*/
@Nonnull
Collection<? extends Input> registerAndProcessInputs(
@Nonnull Path basedir, @Nullable Collection<String> includes, @Nullable Collection<String> excludes);

/**
* Marks skipped build execution. All inputs, outputs and their associated metadata are carried
* over to the next build as-is. No context modification operations ({@code register*} or
* {@code process}) are permitted after this call.
*/
void markSkipExecution();

/**
* Sets whether the build should continue even if there are build errors.
*
* @param failOnError {@code true} to fail on error, {@code false} to continue
*/
void setFailOnError(boolean failOnError);

/**
* {@return whether the build should fail on error}
*/
boolean getFailOnError();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.maven.api.build.context;

import java.io.Serial;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.services.MavenException;

/**
* Exception thrown when an error occurs during incremental build context operations.
*
* @since 4.0.0
*/
@Experimental
public class BuildContextException extends MavenException {

@Serial
private static final long serialVersionUID = 1L;

public BuildContextException() {}

public BuildContextException(String message) {
super(message);
}

public BuildContextException(String message, Throwable cause) {
super(message, cause);
}

public BuildContextException(Throwable cause) {
super(cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.maven.api.build.context;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import org.apache.maven.api.annotations.Experimental;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
* Optional annotation that customizes how the incremental build implementation handles
* configuration parameters.
* <p>
* This annotation is mandatory on {@link org.apache.maven.api.Project}
* and {@link org.apache.maven.api.Session} attributes to indicate whether
* they should be considered for change detection.
*
* @since 4.0.0
*/
@Experimental
@Retention(RUNTIME)
@Target({FIELD, METHOD, PARAMETER, TYPE})
public @interface Incremental {

/**
* {@return whether to consider (the default) or ignore the annotated configuration parameter}
*/
boolean consider() default true;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.maven.api.build.context;

import java.nio.file.Path;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.annotations.NotThreadSafe;
import org.apache.maven.api.annotations.Provider;

/**
* Represents an input resource in the incremental build context.
* An input can be associated with one or more {@link Output} resources.
*
* @since 4.0.0
*/
@Experimental
@NotThreadSafe
@Provider
public interface Input extends Resource {

/**
* Associates this input with the given output file and returns the output resource.
*
* @param outputFile the path of the output file to associate
* @return the associated output resource
*/
@Nonnull
Output associateOutput(@Nonnull Path outputFile);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.maven.api.build.context;

import java.io.Serializable;
import java.nio.file.Path;
import java.util.Collection;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.annotations.NotThreadSafe;
import org.apache.maven.api.annotations.Nullable;
import org.apache.maven.api.annotations.Provider;

/**
* Represents a set of inputs being aggregated into one or more outputs.
* <p>
* An input set allows registering multiple input files and then aggregating them
* into an output file, with automatic change detection across builds.
*
* @since 4.0.0
*/
@Experimental
@NotThreadSafe
@Provider
public interface InputSet {

/**
* Adds a previously registered input to this set.
*
* @param inputMetadata the input metadata to add
*/
void addInput(@Nonnull Metadata<Input> inputMetadata);

/**
* Registers an input file and adds it to this set.
*
* @param inputFile the input file to register
* @return the metadata for the registered input
*/
@Nonnull
Metadata<Input> registerInput(@Nonnull Path inputFile);

/**
* Registers input files matching the given patterns and adds them to this set.
*
* @param basedir the base directory to scan for inputs
* @param includes patterns of files to include, may be {@code null} to match all
* @param excludes patterns of files to exclude, may be {@code null}
* @return the metadata for all registered inputs
*/
@Nonnull
Collection<? extends Metadata<Input>> registerInputs(
@Nonnull Path basedir, @Nullable Collection<String> includes, @Nullable Collection<String> excludes);

/**
* Aggregates all registered inputs into the given output file.
*
* @param outputFile the output file to write
* @param aggregator a consumer that receives the output and the collection of inputs
* @return {@code true} if the output was written, {@code false} if it was up-to-date
*/
boolean aggregate(@Nonnull Path outputFile, @Nonnull BiConsumer<Output, Collection<Input>> aggregator);

/**
* Performs an indirect metadata aggregation. The metadata for each input file is cached
* across builds, avoiding recomputation when an input has not changed.
*
* @param outputFile the output file to write
* @param stepId a unique identifier for this aggregation step
* @param identity the identity value for the accumulator
* @param mapper extracts metadata from each input
* @param accumulator combines metadata values
* @param writer writes the accumulated result to the output
* @param <T> the metadata type, must be {@link Serializable}
* @return {@code true} if the output was rewritten, {@code false} if it was up-to-date
* @throws BuildContextException if an error occurs
*/
<T extends Serializable> boolean aggregate(
@Nonnull Path outputFile,
@Nonnull String stepId,
@Nonnull T identity,
@Nonnull Function<Input, T> mapper,
@Nonnull BinaryOperator<T> accumulator,
@Nonnull BiConsumer<Output, T> writer);
}
Loading
Loading