001/*
002 * JDrupes Builder
003 * Copyright (C) 2026 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.startup;
020
021import java.nio.file.Path;
022import java.util.stream.Stream;
023import org.jdrupes.builder.api.Launcher;
024import org.jdrupes.builder.api.Project;
025import org.jdrupes.builder.api.Resource;
026import org.jdrupes.builder.api.ResourceRequest;
027import static org.jdrupes.builder.api.ResourceType.CleanlinessType;
028import org.jdrupes.builder.core.ScopedValueContext;
029
030/// An implementation of a [Launcher] that launches a build configuration.
031/// It expects that the JDrupes Builder project has already been compiled
032/// and its classes are available on the classpath. It can be used to
033/// launch a build configuration from a unit test where the context is
034/// already is bound.
035///
036@SuppressWarnings("PMD.TestClassWithoutTestCases")
037public class TestLauncher extends BuildProjectLauncher {
038
039    /// Initializes a new test launcher.
040    ///
041    /// @param classloader the classloader
042    /// @param buildRoot the build root
043    /// @param args the args
044    ///
045    @SuppressWarnings("PMD.UseVarargs")
046    public TestLauncher(ClassLoader classloader, Path buildRoot,
047            String[] args) {
048        super(classloader, buildRoot, args);
049    }
050
051    @Override
052    public <T extends Resource> Stream<T> resources(Stream<Project> projects,
053            ResourceRequest<T> request) {
054        var snapshot = ScopedValueContext.snapshot();
055        @SuppressWarnings("PMD.CloseResource")
056        var context = rootProject().context();
057        var result = reportBuildException(() -> projects.parallel()
058            .map(p -> snapshot.where(scopedBuildContext, context)
059                .call(() -> context.resources(p, request)))
060            .flatMap(r -> r).toList().stream());
061        if (request.isFor(CleanlinessType)) {
062            regenerateRootProject();
063        }
064        return result;
065    }
066}