@@ -0,0 +1,2308 @@
+import java.io.File;%0Aimport java.lang.module.FindException;%0Aimport java.lang.module.ModuleDescriptor;%0Aimport java.lang.module.ModuleFinder;%0Aimport java.lang.module.ResolutionException;%0Aimport java.nio.file.Path;%0Aimport java.time.Instant;%0Aimport java.time.ZoneId;%0Aimport java.time.format.DateTimeFormatter;%0Aimport java.util.List;%0Aimport java.util.ServiceLoader;%0Aimport java.util.Set;%0Aimport java.util.spi.ToolProvider;%0A%0Aclass Bootstrap %7B%0A  public static void main(String%5B%5D args) %7B%0A    System.out.println(%22Bootstrap Bach%22);%0A%0A    var bootstrap = Path.of(%22.bach/workspace/classes/bootstrap%22);%0A    var pattern = DateTimeFormatter.ofPattern(%22yyyy.MM.dd.HHmm%22).withZone(ZoneId.of(%22UTC%22));%0A    var version = ModuleDescriptor.Version.parse(pattern.format(Instant.now()));%0A%0A    run(%0A        %22javac%22,%0A        %22--module=build,com.github.sormuras.bach%22,%0A        %22--module-source-path=.bach%22 + File.pathSeparator + %22./*/main/java%22,%0A        %22--module-version=%22 + version + %22-BOOTSTRAP%22,%0A        %22-Werror%22,%0A        %22-Xlint%22,%0A        %22-encoding%22,%0A        %22UTF-8%22,%0A        %22-d%22,%0A        bootstrap.toString());%0A%0A    run(tool(ModuleFinder.of(bootstrap), %22build%22));%0A  %7D%0A%0A  static void run(String name, String... args) %7B%0A    run(ToolProvider.findFirst(name).orElseThrow(), args);%0A  %7D%0A%0A  static ToolProvider tool(ModuleFinder finder, String name) %7B%0A    var parent = Bootstrap.class.getClassLoader();%0A    try %7B%0A      var boot = ModuleLayer.boot();%0A      var configuration = boot.configuration().resolveAndBind(finder, ModuleFinder.of(), Set.of());%0A      var controller = ModuleLayer.defineModulesWithOneLoader(configuration, List.of(boot), parent);%0A      var layer = controller.layer();%0A      var serviceLoader = ServiceLoader.load(layer, ToolProvider.class);%0A      return serviceLoader.stream()%0A          .map(ServiceLoader.Provider::get)%0A          .filter(tool -%3E tool.name().equals(name))%0A          .findFirst()%0A          .orElseThrow();%0A    %7D catch (FindException %7C ResolutionException exception) %7B%0A      throw new Error(%22Build program failed!%22, exception);%0A    %7D%0A  %7D%0A%0A  static void run(ToolProvider tool, String... args) %7B%0A    System.out.println(%22%3E%3E %22 + tool.name() + %22 %22 + String.join(%22 %22, args));%0A    var code = tool.run(System.out, System.err, args);%0A    if (code != 0) throw new Error(%22Non-zero exit code: %22 + code);%0A  %7D%0A%7D%0A

Add bootstrap program