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.startup;
020
021import java.nio.file.Path;
022import java.util.Optional;
023import java.util.logging.Logger;
024import org.jdrupes.builder.api.FileResource;
025import org.jdrupes.builder.api.FileTree;
026import static org.jdrupes.builder.api.Intend.*;
027import org.jdrupes.builder.api.Masked;
028import org.jdrupes.builder.api.ResourceType;
029import org.jdrupes.builder.core.AbstractProject;
030import org.jdrupes.builder.core.ResourceCollector;
031import org.jdrupes.builder.java.ClasspathScanner;
032import org.jdrupes.builder.java.JavaCompiler;
033import static org.jdrupes.builder.java.JavaTypes.*;
034
035/// The JDrupes Builder project for compiling the user's JDrupes Builder
036/// project.
037///
038public class BootstrapBuild extends AbstractProject implements Masked {
039
040    /* default */ static final String BUILD_EXTENSIONS = "buildExtensions";
041    /* default */ static final String EXTENSIONS_SNAPSHOT_REPO
042        = "extensionsSnapshotRepository";
043
044    /// The log.
045    protected final Logger log = Logger.getLogger(getClass().getName());
046
047    /// Instantiates a new bootstrap project.
048    ///
049    @SuppressWarnings("PMD.ConstructorCallsOverridableMethod")
050    public BootstrapBuild() {
051        super(parent(BootstrapRoot.class), jdbldDirectory());
052
053        // Add this (the builder) to the class path. (Build extensions
054        // will be added by the bootstrap launcher, because we don't have
055        // access to the properties file here.)
056        var jcp = Path.of(System.getProperty("java.class.path"))
057            .toAbsolutePath().toString();
058        log.fine(() -> "Using java.class.path " + jcp
059            + " as base for builder project compilation");
060        dependency(Consume, new ClasspathScanner(this, jcp));
061
062        // Collect directories with "build configuration", derive source
063        // trees and use as java sources.
064        var bldrDirs
065            = newResource(new ResourceType<FileTree<FileResource>>() {},
066                Path.of("").toAbsolutePath(),
067                "**/" + context().jdbldDirectory().toString())
068                    .withDirectories();
069        addExcludes(bldrDirs);
070        var srcTrees = bldrDirs.stream()
071            .map(r -> newResource(JavaSourceTreeType, r.path().resolve("src"),
072                "**/*.java"));
073        generator(JavaCompiler::new).addSources(srcTrees);
074
075        // Add resources
076        var resourceTrees = bldrDirs.stream()
077            .map(r -> newResource(JavaResourceTreeType,
078                r.path().resolve("resources"), "**/*"));
079        generator(new ResourceCollector<>(this, JavaResourceTreeType)
080            .add(resourceTrees));
081    }
082
083    private void addExcludes(FileTree<FileResource> bldrDirs) {
084        for (var dir : Optional.ofNullable(context().commandLine()
085            .getOptionValues("B-x")).orElse(new String[0])) {
086            bldrDirs.exclude(dir);
087        }
088    }
089
090}