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 patterns. A 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 patterns the patterns
057    /// @return the stream
058    ///
059    default Stream<Project> projects(String... patterns) {
060        return projects(patterns, new String[0]);
061    }
062
063    /// Return the projects matching the patterns but not matching any
064    /// of the pattern in the `without` parameter. A pattern is a glob
065    /// pattern applied to the project's directory. `""`matches the root
066    /// project. `"*"` matches the root project and all immediate
067    /// sub project. `"**"` matches all projects.
068    ///
069    /// @param patterns the patterns
070    /// @param without patterns to exclude
071    /// @return the stream
072    ///
073    @SuppressWarnings("PMD.UseVarargs")
074    Stream<Project> projects(String[] patterns, String[] without);
075
076    /// Define an alias for requesting one or more specific resources.
077    ///
078    /// @param name the name
079    /// @return the root project
080    ///
081    default CommandBuilder commandAlias(String name) {
082        throw new UnsupportedOperationException();
083    }
084
085    /// Close the project. The re-declaration of this method removes
086    /// the [IOException], which is never thrown.
087    ///
088    @Override
089    void close();
090
091    /// A builder for command aliases.
092    interface CommandBuilder {
093
094        /// Apply the request(s) to the projects selected by the given
095        /// patterns instead of the root project.
096        ///
097        /// @param patterns the patterns
098        /// @return the command builder
099        ///
100        CommandBuilder projects(String... patterns);
101
102        /// Do not apply the request(s) to the projects selected by the
103        /// given patterns.
104        ///
105        /// @param patterns the patterns
106        /// @return the command builder
107        ///
108        CommandBuilder without(String... patterns);
109
110        /// Apply the request(s) to the root project or the selected
111        /// projects. The results from the request are written to the
112        /// standard output.
113        /// 
114        /// To simplify the command alias definition, this method
115        /// replaces a request with no intents (i.e. with
116        /// [ResourceRequest#uses()] being empty) with a request that
117        /// uses all intents.
118        ///
119        /// @param requests the requests
120        /// @return the root project
121        ///
122        RootProject resources(ResourceRequest<?>... requests);
123    }
124}