0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

`flutter create`で生成されるいらないコメントを消すツールを作った

Last updated at Posted at 2023-10-26

こんにちは!

今回はFlutterプロジェクト生成時によく使うflutter createコマンドについて、勝手に生成されるTips系のコメントを消した状態で実行する拡張機能のようなものを作成したので、ご紹介します。

▼ GitHubでプログラムと実行ファイルは公開しているため、忙しい方はそちらをご覧ください!

記事中に所々「邪魔」「不要」という言葉を使用していますが、
決してデフォルトのflutter createの仕様を貶すために作ったわけではありません。

0.0 まずFlutterとは

Flutter は クロスプラットフォームのオープンソースなフレームワークで、基本的に単一コードで複数プラットフォーム対応可能なアプリケーションを作成できます。

言語として Dart というものを用い、JavaScriptやTypeScriptに似た構造で書くことができます。

従来であれば、Androidアプリの開発にはJava・Kotlin・C#、iOSであればSwift・Objective-Cあたりを使うのが主流ですが、 Flutterを使えば1つのコードでAndroid/iOS対応の画面、アプリを実装できます

また、ボタンやアイコンといった基本的なデザインはもちろん、位置情報取得やBluetooth通信といったネイティブAPIに関するパッケージも用意されており、それぞれに対応するドキュメントもしっかり書かれているため、作りたいものをうまいこと実現するのに向いていると思います。

0.1 flutter createコマンドとは

Flutterプロジェクトの 雛型を自動生成 してくれるコマンドです。
flutter create project_nameで、任意の名前のプロジェクトを生成してくれます。

image.png

ためしにflutter create hogeとしてみました。
libフォルダの中にあるmain.dartというファイルを編集してビルドするだけで、自動的にクロスコンパイルしてくれます。
コマンドひとつでこれだけしっかりした雛型を作ってくれるあたり、かなり便利です。

1.1 flutter createの不便な点

ここからが本題です。

先ほどの便利なflutter createコマンドですが、これで生成されたmain.dartpubspec.yamlファイルを見てみます。長いので一部のみ抜粋します。

main.dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // This is the theme of your application.
        //
        // TRY THIS: Try running your application with "flutter run". You'll see
        // the application has a blue toolbar. Then, without quitting the app,
        // try changing the seedColor in the colorScheme below to Colors.green
        // and then invoke "hot reload" (save your changes or press the "hot
        // reload" button in a Flutter-supported IDE, or press "r" if you used
        // the command line to start the app).
        //
        // Notice that the counter didn't reset back to zero; the application
        // state is not lost during the reload. To reset the state, use hot
        // restart instead.
        //
        // This works for code too, not just values: Most code changes can be
        // tested with just a hot reload.
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}
pubspec.yaml
name: hoge
description: A new Flutter project.
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1

environment:
  sdk: '>=3.0.5 <4.0.0'

# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
  flutter:
    sdk: flutter

これ、コード上にコメントアウトを活用してTipsを書いてくれているようですが、さすがにこの量は少し邪魔だと感じてしまいます。

ということで、flutter createコマンドの欠点は 「不要なコメントが自動生成される」 で決定です!
他はめちゃくちゃ素晴らしいものだと思います。

1.2 環境

使用した環境は次の通りです。

デバイス

  • OS: Windows 10 Pro

Flutter環境

Flutter 3.10.5 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 796c8ef792 (4 months ago) • 2023-06-13 15:51:02 -0700
Engine • revision 45f6e00911
Tools • Dart 3.0.5 • DevTools 2.23.1

1.3 <実装編>

「不要なコメントが自動生成されるのなら自動削除すれば良い」ということで、Rust で以下を実装していきます。

だいたいの流れはこのような感じです。

  • プロセスの実行とファイルシステム操作に必要なライブラリをインポート
  • コマンドライン引数からプロジェクト名を取得
  • flutterコマンドを実行するためのコマンドを生成
  • 指定されたファイルの内容を読み込み
  • コメント行を削除
    • 各行を処理し、//#で始まる行をフィルタリング
    • フィルタリングされた行を改行で結合し、元のファイルに書き込み

実装したコードがこちらです。

use std::process::Command;
use std::fs;

fn main() {
    let project_name = std::env::args().nth(1).expect("Please provide a project name.");

    let output = Command::new("flutter.bat")
        .arg("create")
        .arg(&project_name)
        .output()
        .expect("Failed to create Flutter project");

    if !output.status.success() {
        panic!("Failed to create Flutter project");
    }

    remove_comments(&format!("{}/lib/main.dart", project_name));
    remove_comments(&format!("{}/pubspec.yaml", project_name));
}

fn remove_comments(file_path: &str) {
    let contents = fs::read_to_string(&file_path).expect("Failed to read file.");

    let filtered: Vec<&str> = contents.lines()
        .filter(|line| !line.trim_start().starts_with("//") && !line.trim_start().starts_with("#"))
        .collect();

    fs::write(&file_path, filtered.join("\n")).expect("Failed to write file.");
}

1.4 <解説編>

部分ごとに解説していきます。

1.4.1 プロセスの実行とファイルシステム操作をインポート

今回は、プロセスの実行(Command)ファイルシステム操作(fs) をインポートしています。

use std::process::Command;
use std::fs;

1.4.2 コマンドライン引数からプロジェクト名を取得

プロジェクト名はプログラムを実行する際に指定する必要があります。

let project_name = std::env::args().nth(1).expect("Please provide a project name.");

1.4.3 flutterコマンドを実行するためのコマンドを生成

Command::new("flutter.bat")は、「"flutter.bat" というコマンドを実行するためのコマンド」を生成しています。ややこしい日本語ですみません。.arg("create").arg(&project_name)は、コマンドに引数を追加し、指定されたプロジェクト名でFlutterプロジェクトを作成します。作成したプロジェクトの実行結果 (成功 or 失敗) は output変数に格納されます。

let output = Command::new("flutter.bat")
    .arg("create")
    .arg(&project_name)
    .output()
    .expect("Failed to create Flutter project");

また、プロジェクトの作成が成功しなかった場合、エラーメッセージを表示して終了します。

if !output.status.success() {
    panic!("Failed to create Flutter project");
}

1.4.4 任意のファイルからコメント行を削除

remove_comments関数が呼び出され、main.dartおよびpubspec.yamlファイルからコメント行を削除します。また、format!マクロは、ファイルのパスを構築するために使用されます。

remove_comments(&format!("{}/lib/main.dart", project_name));
remove_comments(&format("{}/pubspec.yaml", project_name));

1.4.5 指定されたファイルの内容を読み込み

指定されたファイルの内容を読み込みます。ファイルが存在しない場合や読み込みに失敗した場合、エラーメッセージを表示して終了します。

let contents = fs::read_to_string(&file_path).expect("Failed to read file.");

1.4.6 コメント行を削除

ファイルの内容からコメント行を削除するために、各行を処理し、//#で始まる行をフィルタリングします。

let filtered: Vec<&str> = contents.lines()
    .filter(|line| !line.trim_start().starts_with("//") && !line.trim_start().starts_with("#"))
    .collect();

1.4.7 ファイルへの書き込み

フィルタリングされた行を改行で結合し、元のファイルに書き込みます。書き込みに失敗した場合、エラーメッセージを表示して終了します。

fs::write(&file_path, filtered.join("\n")).expect("Failed to write file.");

2.1 使い方

GitHubにも書いてありますが、以下の手順で使用することが可能です。
また、僕のデバイスがWindowsなのもあり、現時点(2023/10/26)では.exe形式の実行ファイルしか作れていません。

  1. flutter_cleaner.exeをコピーまたはダウンロードします。
  2. このプログラム (flutter_cleaner) は flutterコマンドを呼び出すため、Flutterを実行するPCにFlutterがインストールされており、PATHに適切に追加されていることを確認してください。
  3. PC上で実行可能ファイルを実行します。Windowsでは、実行時に現在のディレクトリ内のファイルを明示的に指定する必要があります。
    例: .\flutter_cleaner.exe your_project_name

PC、ファイアウォール、またはウイルス対策ソフトウェアのセキュリティ設定によっては、実行可能ファイルがブロックされる場合があります。

まとめ

今回は、不要なコメント行を自動的に削除することで、flutter createコマンドをより効率的に利用できるツールを開発・解説しました。このツールを使用することで、不要なコメントの手動削除をする必要がなくなり、イライラすることなく、よりスムーズな開発ができたら本望です。

※ 決してデフォルトのflutter createの仕様を貶すために作ったわけではありません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?