Plugman code-reading

14
Plugmancode reading Plugman = ”version": "0.21.1-dev"

description

Study of Plugman, which is installer/uninstaller for Apache Cordova Plugins.

Transcript of Plugman code-reading

Page 1: Plugman code-reading

Plugmancode readingPlugman = ”version": "0.21.1-dev"

Page 2: Plugman code-reading

plugman• Plugman is ..

• A command line tool to install and uninstall plugins for use with Apache Cordova projects.

• https://github.com/apache/cordova-plugman

Page 3: Plugman code-reading

plugman install

plugman install --plugins_dir plugins --plugin com.phonegap.plugins.barcodescanner --platform android --project android/native --www android/js

pluginが保管されている場所

pluginの名前

対象プラットフォーム

android用のプラグインファイル(java, libs )を配置する対象ディレクトリ

plugins/*.js cordova_plugins.js が配置される

ex) platform android

Page 4: Plugman code-reading

files• このあたりを見る

• main.js

• plugman.js

• install.js

• prepare.js

Page 5: Plugman code-reading

main.js• 一番始めに呼ばれる

• cli のオプションの検証

• plugman のconsole eventの設定

• オプションに基づいた plugman の関数の実行

!

• commands は plugman.js 内で定義される

• ここでいう [cmd] は config, install などのコマンドのこと

L81. var result = plugman.commands[cmd](cli_opts);

Page 6: Plugman code-reading

plugman.js• plugman のメイン部分

• plugman.commands の中に実行可能なコマンド列が並ぶ

• 実行される中身は、addPropertyで対応するモジュールをsrcからrequire

!

• 読み込んだ function を plugman objectのプロパティとして登録

L62. addProperty(plugman, 'install', './src/install', true);

Page 7: Plugman code-reading

install.js src/install.js

• install command の中身

• Install flow

• installPlugin -> possiblyFetch -> runInstall -> handleInstall

• installPlugin(platform, project_dir, id, plugins_dir, options)

• platformのチェック

• possiblyFetch(actions, platform, project_dir, id, plugins_dir, options)

• plugin の fetch を行い runInstall に進む

Page 8: Plugman code-reading

install.js / runInstall• Plugin内にあるplugin.xml をパース、plugin名, IDを取得

• pluginがインストールされているかを確認

• 確認対象のファイルは platform 毎に違うので、platforms/*.js を参照する

• plugin がインストールされていなければ続く

• getEngines でplugin.xml に記載されている処理エンジンを取得(記載無しの場合は default-engineを利用)

• util/default-engines.js に記述のあるengine であれば、scriptSrcのパスがセットされる。存在しない場合は以下のルールで追加される。

<engines>    <engine name="cordova" version="1.8.1" />    <engine name="worklight" version="1.0.0" /></engines>

util/default-engines.js [存在する場合] L6. { 'platform':'*', 'scriptSrc': path.join(project_dir,'cordova','version') }, [存在しない場合] { 'name': theName, 'platform': engine.attrib["platform"], 'scriptSrc':path.resolve(plugin_dir, engine.attrib["scriptSrc"]), 'minVersion' : engine.attrib["version"]}

Page 9: Plugman code-reading

install.js / runInstall• 取得した engine のscriptSrcをchild_processで起動 : callEngineScripts

• scriptSrcの中身は version を出力するシェル

• platforms/ios/cordova/version

• 実行可能なversionという名前のシェルがあるをチェックしている

• 取得したバージョンと plugin.xml に書いてあるバージョンを比較して、サポートバージョンかどうかを確認 : checkEngines

Page 10: Plugman code-reading

install.js / runInstall L223 - L333

• plugin.xml 内の preference があれば、コマンド引数(options)に存在するかを確認。なければそこでコマンド終了

• plugin.xml 内の dependency があれば、install済みpluginを確認。無ければ、local, git からpluginを取得してくる (fetch.js)

• 準備完了。handleInstallを呼ぶ handleInstall(actions, plugin_id, plugin_et, platform, project_dir, plugins_dir, install_plugin_dir, filtered_variables, options.www_dir, options.is_top_level);

Page 11: Plugman code-reading

install.js / handleInstall• plugin.xml の platform タグ内を対象に実際にファイルなどを移動させる

!

!

• platforms/*.js から対応するプラットフォームのコマンドを実行準備

var sourceFiles = platformTag.findall('./source-file'), headerFiles = platformTag.findall('./header-file'), resourceFiles = platformTag.findall('./resource-file'), frameworkFiles = platformTag.findall('./framework[@custom="true"]'), libFiles = platformTag.findall('./lib-file'), assets = assets.concat(platformTag.findall('./asset'));

L516. actions.push(actions.createAction(handler[“source-file"].install,

Page 12: Plugman code-reading

install.js / handleInstall• コピー先を決定してファイルを移動させる

!

!

• actions.process(platform, project_dir)

• 失敗したら uninstall が呼ばれる

• 成功すれば install 処理完了

[platforms/android.js] install:function(source_el, plugin_dir, project_dir, plugin_id) { var dest = path.join(source_el.attrib['target-dir'], path.basename(source_el.attrib['src'])); ! common.copyNewFile(plugin_dir, source_el.attrib['src'], project_dir, dest); },

Page 13: Plugman code-reading

prepare.js

• plugin ファイルへの cordova.defineの追加

!

• cordova_plugins.js ファイルの作成

pluginファイルに自動挿入される cordova.define(“com.phonegap.plugins.

L182. scriptContent = 'cordova.define("' + moduleName + '", function(require, exports, module) { ' + scriptContent + '\n});\n';

L217: var final_contents = "cordova.define('cordova/plugin_list', function(require, exports, module) {\n"; L218: final_contents += 'module.exports = ' + JSON.stringify(moduleObjects,null,' ') + ‘;\n'; … L226: fs.writeFileSync(path.join(wwwDir, 'cordova_plugins.js'), final_contents, 'utf-8');

Page 14: Plugman code-reading

End of Slides