001/*
002 * JDrupes Builder
003 * Copyright (C) 2025 Michael N. Lipp
004 * 
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
017 */
018
019package org.jdrupes.builder.api;
020
021import java.io.IOException;
022import java.util.stream.Stream;
023
024/// Additional methods for the root project. Root projects are always
025/// created with an associated [BuildContext]. This context is closed
026/// when the root project is closed.
027///
028public interface RootProject extends Project, AutoCloseable {
029
030    /// May be overridden by the root project to apply common settings
031    /// to projects of specific types or with specific properties.
032    /// 
033    /// This method must be invoked by any base class for project 
034    /// configuration classes before it returns the control to the
035    /// project configuration class' constructor. The method is never
036    /// invoked by the user.
037    /// 
038    /// This method is provided for convenience. Alternatively, project
039    /// configuration classes can invoke any user defined method at the
040    /// beginning of their constructor. Using this method simply makes
041    /// sure that such an invocation is never forgotten.
042    ///
043    /// @param project the project to prepare
044    /// @throws Exception the exception
045    ///
046    @SuppressWarnings("PMD.SignatureDeclareThrowsException")
047    default void prepareProject(Project project) throws Exception {
048        // Default does nothing
049    }
050
051    /// Return the projects matching the pattern. The pattern is a glob
052    /// pattern applied to the project's directory. `""`matches the root
053    /// project. `"*"` matches the root project and all immediate
054    /// sub project. `"**"` matches all projects.
055    ///
056    /// @param pattern the pattern
057    /// @return the stream
058    ///
059    Stream<Project> projects(String pattern);
060
061    /// Define an alias for requesting one or more specific resources.
062    ///
063    /// @param name the name
064    /// @return the root project
065    ///
066    default CommandBuilder commandAlias(String name) {
067        throw new UnsupportedOperationException();
068    }
069
070    /// Close the project. The re-declaration of this method removes
071    /// the [IOException], which is never thrown.
072    ///
073    @Override
074    void close();
075
076    /// A builder for command aliases.
077    interface CommandBuilder {
078
079        /// Apply the request(s) to the projects selected by the given
080        /// pattern instead of the root project.
081        ///
082        /// @param pattern the pattern
083        /// @return the command builder
084        ///
085        CommandBuilder projects(String pattern);
086
087        /// Apply the request(s) to the root project or the selected
088        /// projects. The results from the request are written to the
089        /// standard output.
090        /// 
091        /// To simplify the command alias definition, this method
092        /// replaces a request with no intents (i.e. with
093        /// [ResourceRequest#uses()] being empty) with a request that
094        /// uses all intents.
095        ///
096        /// @param requests the requests
097        /// @return the root project
098        ///
099        RootProject resources(ResourceRequest<?>... requests);
100    }
101}