不要なソースコード削除ツール「Chiritori」 v1.0.0をリリースしました

未来に不要になるソースコードを宣言しつつ削除するツール Chiritori v1.0.0 をリリースしました。

Chiritori (GitHub) はこちら

しばらく私自身も細々と使っていたのですが、あったらいいなという機能をいくつか追加しましたので、あらためてChiritoriについて説明します。

Chiritoriってなに?

予め削除対象としてタグ付けしておいたコードを削除するツールです。 以下のような利用用途を想定しています。

  • ある時刻が過ぎたら不要になるコードを管理する
  • 機能リリースによって不要になるコードを整理し、不要になったら削除する

以下のような特徴があります。

  • 主にソースコード中のコメントを利用して削除対象をタグ付けするので利用言語を問わない
  • いくつかの削除戦略を持っており、削除対象全体を消したり、コードのブロックを開く(ネストを開く)ことができる

これらの特徴について、以下にいくつかの利用例を示しながら解説します。

ある時刻以降に不要になったコードを削除する

以下のようにコメント機能を利用し、ある時刻以降は不要になるコードであることを宣言します。

<h2>キャンペーン一覧</h2>
<ul>
  <!-- <time-limited to="2024-12-26 00:00:00"> -->
  <li>クリスマスキャンペーン</li>
  <!-- </time-limited> -->
  <li>新年初売りキャンペーン</li>
</ul>

2024/10/26 00:00:00 以降に以下のコマンドを実行します。

$ chiritori -f campaign.html -o campaign-converted.html

以下のような出力を得ることができます。

<h2>キャンペーン一覧</h2>
<ul>
  <li>新年初売りキャンペーン</li>
</ul>

このように、コード上に「ある時刻以降にコードが不要になること」を宣言したうえで、不要になったら削除できます。

ある条件を満たすと不要になるコードを削除する

Feature Toggleでリリースを管理しているコードベースにおいては、しばしばリリース後に不要な条件分岐が発生します。

const feature = await fetchFeatureState("awesome-feature");

if (feature.released) {
  const awesomeFeature = new awesomeFeature();
  awesomeFeature.run();
}

このとき、awasome-feature は既にリリース済で feature.released が常に真であるなら、条件分岐は不要になります。 コードベースをシンプルに保つのであれば、機能リリースを終えたらこれらのコードを整理する必要があります。

将来的に不要になることを、以下のようにソースコード中のコメントで表現します。

/* <removal-marker name="awesome-feature" > */
const feature = await fetchFeatureState("awesome-feature");
/* </removal-marker> */

/* <removal-marker name="awesome-feature" unwrap-block> */
if (feature.released) {
  const awesomeFeature = new awesomeFeature();
  awesomeFeature.run();
}
/* </removal-marker> */

awesome-feature がリリースされたら以下のコマンドを実行します。

$ chiritori --delimiter-start="/* <" --delimiter-end="> */" --removal-marker-target-name="awesome-feature" -f index.ts

--delimiter-start--delimiter-end 引数によってタグのデリミタを変更できるので、基本的には利用言語によらずに利用ができます。

以下の出力を得ることができます。

const awesomeFeature = new awesomeFeature();
awesomeFeature.run();

unwrap-block 属性を付けたタグは、開始タグの直後と終了タグの直前の行を消すことで、コードブロックが取り除かれ、アンラップされます。

Chiritoriはコードを削除した部分に対して簡易なフォーマット処理を施すので、条件分岐が消えたことで不要になったインデントも取り除きます。

どうやって試すといい?

まずはインストールします。Mac OSあるいはLinux (WindowsにおけるWSL環境も含む)をお使いの場合は、Homebrewでインストールできます。

$ brew tap piyoppi/tap
$ brew install chiritori

(GitHub Releasesからバイナリを直接ダウンロードすることもできます。お使いのOSやCPUアーキテクチャに合ったものをダウンロードしてください)

chiritoriのsamples ディレクトリにあるソースコードに対して、samples内のREADMEのとおりのコマンドを実行することで手っ取り早くお試しいただけます。 これを実際にやってみましょう。

samples内のサンプルコードをひとつダウンロードしてみます。

$ curl https://raw.githubusercontent.com/piyoppi/chiritori/refs/heads/main/samples/sample-code.js -o sample.js

この状態で、サンプルコードの中身を見てみます。

$ cat sample.js
// sample

function main() {
  console.log('Hello, World! 1');
  // -- time-limited-code to="2020-12-31 23:59:59" -- //
    console.log('🧹This code will be removed after 2020-12-31T23:59:59.999Z');
  // -- /time-limited-code -- //

  // -- time-limited-code to="2099-12-31 23:59:59" -- //
    console.log('📌This code will be removed after 2099-12-31T23:59:59.999Z');
  // -- /time-limited-code -- //

  // -- time-limited-code to="2020-12-31 23:59:59" -- //
    console.log('🧹This code will be removed after 2020-12-31T23:59:59.999Z');
  // -- /time-limited-code -- //
  console.log('Hello, World! 2');

  // -- removal-marker name="awesome-feature" unwrap-block -- //
  if (isReleased) {
    console.log('📌This code is unconditionally executed after 2020-12-31T23:59:59.999Z');
    const awesomeFeature = new awesomeFeature()
    awesomeFeature.run();
  }
  // -- /removal-marker -- //
}

Chiritoriを実行してみます。不要なコードが取り除かれていることが分かります。また、 unwrap-block 属性をつけたタグについては、ifブロックが取り除かれています。

% cat sample.js | chiritori --delimiter-start="// --" --delimiter-end="-- //" --time-limited-tag-name="time-limited-code" --removal-marker-target-name="awesome-feature"
// sample

function main() {
  console.log('Hello, World! 1');

  // -- time-limited-code to="2099-12-31 23:59:59" -- //
    console.log('📌This code will be removed after 2099-12-31T23:59:59.999Z');
  // -- /time-limited-code -- //

  console.log('📌This code is unconditionally executed after 2020-12-31T23:59:59.999Z');
  const awesomeFeature = new awesomeFeature()
  awesomeFeature.run();

  console.log('Hello, World! 2');
}

今後の予定

前回のバージョン(v0.3.0)以降に追加された機能(unwrap-block属性、removal-markerタグあたり)は特に改善の余地がある可能性があるので、引き続き私自身も利用しながら細かい箇所を調整していくことになると思います。

また、以下のような機能を追加できないか検討中です。

  • 削除対象を一覧で確認できるようにする
  • タグが存在する行だけを削除する削除戦略の追加

まだまだ粗削りのところがあるかもしれませんが、ぜひ利用してみてください。 今後も便利になるような機能を追加したいので、もしコンセプトに共感いただけた場合ば、フィードバックも歓迎します。ではでは〜

このカウンタは @piyoppi/counter-tools を使っています。

クリックすると匿名でいいねできます。