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