package eu.m724.blog; import eu.m724.blog.data.Feed; import eu.m724.blog.data.Post; import eu.m724.blog.data.Site; import org.apache.commons.cli.*; import org.apache.commons.io.file.PathUtils; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.lib.RepositoryBuilder; import java.io.IOException; import java.nio.file.FileAlreadyExistsException; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Comparator; import java.util.stream.Collectors; public class Main { public static void main(String[] args) throws IOException { System.out.println("Hello world!"); var options = new Options() .addOption("h", "help", false, "Show help") .addOption("f", "force", false, "Overwrite current build") .addOption("dir", "working-dir", true, "Working directory. Default: current directory") .addOption("t", "template-dir", true, "Template directory. Default: working directory/template") .addOption("o", "output-dir", true, "Output directory. Default: working directory/generated_out") .addOption("s", "server", false, "Run webserver. Default: no"); CommandLine commandLine; try { commandLine = new DefaultParser().parse(options, args); if (commandLine.hasOption("help")) throw new ParseException("Showing help"); } catch (ParseException e) { System.out.println(e.getMessage()); new HelpFormatter().printHelp("blog-software-java", options); System.exit(1); return; } var workingDirectory = Path.of(commandLine.getOptionValue("working-dir", ".")); var templateDirectory = Path.of(commandLine.getOptionValue("output-dir", workingDirectory.resolve("template").toString())); var outputDirectory = Path.of(commandLine.getOptionValue("output-dir", workingDirectory.resolve("generated_out").toString())); var force = commandLine.hasOption("force"); var server = commandLine.hasOption("server"); var openBrowser = true; // var start = System.nanoTime(); var repository = new RepositoryBuilder() .setGitDir(workingDirectory.resolve(".git").toFile()) .build(); var git = new Git(repository); // if (outputDirectory.toFile().exists()) { if (force) { PathUtils.deleteDirectory(outputDirectory); } else { throw new FileAlreadyExistsException(outputDirectory.toString(), null, "Output directory already exists"); } } var site = Site.fromConfig(git); var template = new TemplateRenderer(templateDirectory); Files.createDirectory(outputDirectory); copyIfExists(workingDirectory.resolve("assets"), outputDirectory.resolve("assets")); copyIfExists(templateDirectory.resolve("static"), outputDirectory.resolve("static")); Files.createDirectory(outputDirectory.resolve("post")); var postDirectory = workingDirectory.resolve("posts"); var posts = new ArrayList(); try (var stream = Files.walk(postDirectory)) { for (var path : stream.collect(Collectors.toSet())) { if (!Files.isRegularFile(path)) continue; // directory is created below if (!path.toString().endsWith(".html")) { System.out.println("Post " + path.getFileName() + ": unsupported file type"); continue; } path = postDirectory.relativize(path); var post = Post.fromFile(git, path); var render = template.renderPost(site, post); var outFile = outputDirectory.resolve("post").resolve(path); try { Files.createDirectory(outFile.getParent()); } catch (FileAlreadyExistsException ignored) { } Files.writeString(outFile, render); posts.add(post); } } posts.sort(Comparator.comparing(Post::createdAt).reversed()); Files.writeString(outputDirectory.resolve("index.html"), template.renderIndex(site, posts)); Files.writeString(outputDirectory.resolve("posts.rss"), Feed.generateRss(site, posts)); var end = System.nanoTime(); System.out.printf("Exported to %s (%.2f ms)\n", outputDirectory, (end - start) / 1000000.0); if (server) { var listenAddress = new Server(outputDirectory).start(); if (openBrowser) { try { var process = Runtime.getRuntime().exec(new String[] { "xdg-open", "http://" + listenAddress.getHostString() + ":" + listenAddress.getPort() }); var code = process.waitFor(); if (code != 0) { throw new Exception("Exit code " + code); } System.out.println("Opened browser"); } catch (Exception e) { System.out.println("Failed to open browser: " + e); } } } } private static boolean copyTree(Path srcDir, Path destDir) throws IOException { if (!Files.isDirectory(srcDir)) { return false; } try (var walk = Files.walk(srcDir)) { for (var src : walk.collect(Collectors.toSet())) { var rel = srcDir.relativize(src); var dest = destDir.resolve(rel); if (Files.isRegularFile(src)) { var parent = dest.getParent(); if (!Files.isDirectory(parent)) { Files.createDirectories(parent); } Files.copy(src, dest); } } } return true; } private static void copyIfExists(Path srcDir, Path destDir) throws IOException { System.out.print(srcDir); if (copyTree(srcDir, destDir)) { System.out.println(" copied"); } else { System.out.println(" doesn't exist, not copying"); } } }