Edited at
DartDay 16

Flutterで利用しているOSSライセンス一覧を生成するDart CLIを作ってみた

せっかく作ったのですが、誰にも使われていないのでその紹介をします。

英語で書いた内容を日本語に訳しただけです。

紹介するのは、OSSライセンス一覧を生成するあれです。

Dart部分だけです。ネイティブのツールの併用して使う想定です。

iosでは、Settings.bundleを利用しています。

androidでは、AboutLibrariesを利用しています。

どちらも他の形式でも生成できるようには考えて作っているので、他の形式に対応したプルリクエストを頂けるとありがたいです。

ソースはこちらです。

https://github.com/ko2ic/dart_oss_licenses


インストール

まずは、dartを入れます。

$ brew tap dart-lang/dart

$ brew install dart

以下でインストール完了です。

$ pub global activate dart_oss_licenses


利用方法

プロジェクトのルートで以下のコマンドを叩くだけです。が、プラットフォームごとに準備が必要です。(それぞれ別段を参照してください。)

$ dart-oss-licenses

仕組みは、



  1. pubspec.lock から利用しているPackageを取得


  2. https://pub.dartlang.org からそれぞれのライブラリ情報を取得

  3. それぞれのライブラリのライセンスを取得

  4. それぞれのネイティブに合わせた形で出力

通信処理では、内容をキャッシュしてないので、何度もやると相手のサーバーに負担がかかりますので、気をつけてください。

キャッシュは早いうちに実装したいと思います。


ios


準備

XcodeでSettings.bundleを作る必要があります。

File -> New -> File... -> Select Settings.bundle -> Next -> Create as /ios/Runner/Settings.bundle

Root.plistを以下に書き換えます。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreferenceSpecifiers</key>
<array>
<dict>
<key>Type</key>
<string>PSChildPaneSpecifier</string>
<key>Title</key>
<string>Licenses</string>
<key>File</key>
<string>com.ko2ic.dart-oss-licenses</string>
</dict>
</array>
<key>StringsTable</key>
<string>Root</string>
</dict>
</plist>

en.lproj/Root.stringsja.lproj/Root.strings を書き換えます。

"Licenses" = "Licenses";

コマンドを打つと<Project>/ios/Runner/Settings.bundle/com.ko2ic.dart-oss-licenses.plist にファイルが生成されます。


実装

Androidと同じ遷移にしたいので、iosのアプリ設定画面だけにしないで、アプリからそこへ遷移できるようにしておきます。


AppDelegate.swift

@UIApplicationMain

@objc class AppDelegate: FlutterAppDelegate {
private var _result: FlutterResult?

override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
) -> Bool {
let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
let channel = FlutterMethodChannel(name: "sample/platform",
binaryMessenger: controller)
channel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
switch call.method {
case "toOssLicense":
if let url = URL(string: UIApplication.openSettingsURLString) {
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
UIApplication.shared.openURL(url)
}
}
default:
result(FlutterMethodNotImplemented)
break
}
})
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}


その他、ネイティブで利用されているライセンスも表示したいので、LicensePlistなどで生成したplistを自分でマージする必要があります。


Android

コマンドを打つと /android/app/src/main/res/values/license_strings.xml が生成されます。

すでにファイルがある場合は、 /android/app/src/main/res/values/license_strings.xml.temp が生成されます。

取得できなかったデータは、生成されたlicense_strings.xmlで、TODOの文字列が挿入されています。

それらを自分で設定し直す必要があります。


実装

AboutLibrariesの以下のバージョンを利用します。


android/app/build.gradle

dependencies {

implementation "com.mikepenz:aboutlibraries:6.1.1"

AboutLibrariesを使って、ライセンス一覧表示画面を作ります。


MainActivity.kt

class MainActivity() : FlutterActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
GeneratedPluginRegistrant.registerWith(this)

MethodChannel(
flutterView,
"sample/platform"
).setMethodCallHandler { call: MethodCall, result: MethodChannel.Result ->
when (call.method) {
"toOssLicense" -> {
LibsBuilder()
.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR)
.withActivityTitle("Licenses")
.withLicenseShown(true)
.withLibraries(
<package name>
)
//start the activity
.start(this)
}
}
}
}
}


<package name> のところには、コマンド実行でコンソールで表示されるSucceeded Package Listの部分を入れてください。

$ dart-oss-licenses

・・・
Succeeded Package List:
"web_socket_channel","device_info","redux","sentry","image_picker","cupertino_icons","qr","mime",


Dartの実装

OSSライセンス一覧に遷移したい場所で以下を呼び出します。

  static const platform = const MethodChannel('sample/platform');

Future<void> toOssLicense() {
return platform.invokeMethod('toOssLicense', {});
}


結果

android.gif