001package com.streamconverter.sloc;
002
003import com.streamconverter.StreamConverter;
004import com.streamconverter.sloc.command.JacocoXmlToModuleSlocCommand;
005import com.streamconverter.sloc.command.ModuleXmlConcatCommand;
006import com.streamconverter.sloc.command.SlocAggregateCommand;
007import com.streamconverter.sloc.command.SlocReportFormatCommand;
008import java.io.ByteArrayInputStream;
009import java.io.IOException;
010import java.io.OutputStream;
011import java.nio.charset.StandardCharsets;
012import java.nio.file.Path;
013import java.util.Arrays;
014import java.util.List;
015
016/**
017 * 全モジュールの JaCoCo XML レポートから SLOC(実ステップ数)を集計するツール。
018 *
019 * <p>モジュール名リストを起点に4コマンドのパイプラインで処理する:
020 *
021 * <ol>
022 *   <li>{@link ModuleXmlConcatCommand} — モジュール名→XML連結ストリーム
023 *   <li>{@link JacocoXmlToModuleSlocCommand} — XML→ModuleSloc オブジェクト
024 *   <li>{@link SlocAggregateCommand} — 集約・合計行追加
025 *   <li>{@link SlocReportFormatCommand} — 整形出力
026 * </ol>
027 *
028 * <p><strong>使用方法:</strong>
029 *
030 * <pre>
031 * ./gradlew :streamconverter-tools:slocCount
032 * </pre>
033 *
034 * <p>モジュール名は Gradle タスクから引数として渡される。直接実行する場合は引数にモジュール名を列挙する:
035 *
036 * <pre>
037 * java SlocCounter streamconverter-core streamconverter-db ...
038 * </pre>
039 */
040public class SlocCounter {
041
042  /**
043   * 指定されたモジュールの SLOC を集計し、結果を出力する。
044   *
045   * @param projectRoot プロジェクトルートディレクトリ
046   * @param modules 集計対象のモジュール名リスト
047   * @param output 集計結果の出力先
048   * @throws IOException レポートの読み込みまたは出力に失敗した場合
049   */
050  public void run(Path projectRoot, List<String> modules, OutputStream output) throws IOException {
051    byte[] moduleList = String.join("\n", modules).getBytes(StandardCharsets.UTF_8);
052    StreamConverter.create(
053            new ModuleXmlConcatCommand(projectRoot),
054            new JacocoXmlToModuleSlocCommand(),
055            new SlocAggregateCommand(),
056            new SlocReportFormatCommand())
057        .run(new ByteArrayInputStream(moduleList), output);
058  }
059
060  /** CLI エントリポイント。引数にモジュール名を列挙する。プロジェクトルートはカレントディレクトリを使用する。 */
061  public static void main(String[] args) throws IOException {
062    new SlocCounter().run(Path.of("."), Arrays.asList(args), System.out);
063  }
064}