Xamarin SutdioでNuGetパッケージを簡単に作る
NuGetパッケージは依存関係を自動(?)で解消してくれたりリポジトリを検索してインストールしたりで利用する分には簡単(??)なのですが、いざ作成しようとすると.nuspecを編集したりコマンド叩かなきゃいけなかったりで結構めんどくさいです。
なので簡単にNuGetパッケージを作成するXamarin Studio Addinを作成しました。
なお簡単っていっても個人運用向けで、ちゃんと公開する場合はしっかり.nuspecを編集しないといけないので結局面倒くさいです。
使い方
一番簡単な使い方。
1
からdllをダウンロードして
/Applications/Xamarin Studio.app/Contents/Resources/lib/monodevelop/AddIns
とかに入れる。
2 Xamarin Studio起動してプロジェクト開く。
3 ソリューションダブルクリックしてDescriptionに適当な文字を入れる。(ビルドしてなかったらビルドする)
4 MainMenu→Edit→Make Nuspecで.nuspecファイル作成
5 MainMenu→Edit→Make PackageでNuGetパッケージ作成
もっと詳しく
一応、上記のやり方でパッケージは作れるのですが大抵残念仕様です。なのでしっかり.nuspecを編集します。
ソリューションに追加された.nuspecファイルを見てみましょう。
<?xml version="1.0" encoding="utf-8"?> <package> <metadata> <id>$id$</id> <version>$version$</version> <authors>$author$</authors> <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl> <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl> <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl> <requireLicenseAcceptance>false</requireLicenseAcceptance> <description>$description$</description> <releaseNotes>Summary of changes made in this release of the package.</releaseNotes> <copyright>$copyright$</copyright> <tags>Tag1 Tag2</tags> <dependencies> <dependency id="Xamarin.Forms" version="2.3.1.114" /> <dependency id="Xamarin.Android.Support.Animated.Vector.Drawable" version="23.3.0" /> <dependency id="Xamarin.Android.Support.Design" version="23.3.0" /> <dependency id="Xamarin.Android.Support.v4" version="23.3.0" /> <dependency id="Xamarin.Android.Support.v7.AppCompat" version="23.3.0" /> <dependency id="Xamarin.Android.Support.v7.CardView" version="23.3.0" /> <dependency id="Xamarin.Android.Support.v7.MediaRouter" version="23.3.0" /> <dependency id="Xamarin.Android.Support.v7.RecyclerView" version="23.3.0" /> <dependency id="Xamarin.Android.Support.Vector.Drawable" version="23.3.0" /> </dependencies> </metadata> <files> <file src="../Sample/bin/$Configuration$/Sample.dll" target="lib/" /> <file src="../Sample.iOS/bin/$Configuration$/Sample.iOS.dll" target="lib/" /> <file src="../Sample.Android/bin/$Configuration$/Sample.Android.dll" target="lib/" /> </files> </package>
Xamarin Studioで開くとシンタックスハイライトが全く効かないのでつらいですが見てみると$id$とか$$で囲われたのがあると思います。
これはMake Package
を実行すると対応した値に変換されます。
以下がその対応表になります。
From | To | Description |
---|---|---|
$id$ | solution.Name | ソリューションの名前 |
$title$ | solution.Name | ソリューションの名前 |
$version$ | solution.Version | ソリューションの名前 |
$author$ | solution.AuthorInformation.Name | ソリューションの製作者情報の名前 |
$description$ | solution.Description | ソリューションの詳細 |
$copyright$ | solution.AuthorInformation.Copyright | ソリューションの製作者情報のコピーライト |
$Configuration$ | IdeApp.Workspace.ActiveConfigurationId | 現在のコンフィグ(DebugとかReleaseとか) |
ただし、$hoge$はdependenciesでは使えません。そこで使うことを想定してないので書くととても残念な事になります。
また、dependencyがいっぱいありますがこれは各プロジェクトのpackages.configの中身をそのまま持ってきた感じになります。
こんな感じ↓
private static IEnumerable<XElement> GetDependencies() => ProjectService.CurrentSolution.GetAllProjects() .Where(x => File.Exists(x.BaseDirectory.Combine("packages.config"))) .SelectMany(x => XElement.Load(x.BaseDirectory.Combine("packages.config")).Elements("package")) .Select(x => new XElement("dependency", new XAttribute("id", x.Attribute("id").Value), new XAttribute("version", x.Attribute("version").Value))) .Distinct(x => x.Attribute("id")?.Value);
また、filesも同じくプロジェクトをごそっと持ってきた感じになります。 こんな感じ↓
private static IEnumerable<XElement> GetFiles() => ProjectService.CurrentSolution.GetAllProjects() .Select(x => new XElement("file", new XAttribute("src", Path.Combine("..", x.GetOutputFileName(IdeApp.Workspace.ActiveConfiguration) .ToRelative(ProjectService.CurrentSolution.BaseDirectory)).Replace( IdeApp.Workspace.ActiveConfigurationId, "$Configuration$")), new XAttribute("target", "lib/")));
テストプロジェクトがあった場合はfilesに含まれてしまったり、全部lib/なので全プラットフォーム対象になってしまったりなのでfileは要編集です。
そしてそれぞれよしなに編集した.nuspecファイルがこちらになります。
<?xml version="1.0" encoding="utf-8"?> <package> <metadata> <id>$id$</id> <version>$version$</version> <authors>$author$</authors> <licenseUrl>https://opensource.org/licenses/MIT</licenseUrl> <projectUrl>https://github.com/crocus7724</projectUrl> <requireLicenseAcceptance>false</requireLicenseAcceptance> <description>$description$</description> <releaseNotes>First Release.</releaseNotes> <copyright>$copyright$</copyright> <tags>Xamarin, Xamarin.Forms</tags> <dependencies> <dependency id="Xamarin.Forms" version="2.3.1.114" /> </dependencies> </metadata> <files> <file src="../Sample/bin/$Configuration$/Sample.dll" target="lib/portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10" /> <file src="../Sample.iOS/bin/$Configuration$/Sample.iOS.dll" target="lib/Xamarin.iOS10" /> <file src="../Sample.Android/bin/$Configuration$/Sample.Android.dll" target="lib/MonoAndroid10" /> </files> </package>
.nuspecファイルを編集した場合は⌘+Sで保存してください。残念ながらオートセーブは未実装です。
また、一応申し訳程度の設定があります。
適当英語で申し訳ないのですが、
- 出力先ディレクトリ(Defaultだと.slnと同じ階層とか)
- Releaseビルドを使うか($Configuration$が常時Releaseになります
Debugって直接書いてたら意味ないオプション) Make Package
前にビルドするか- 作ったパッケージを
nuget push
するか
を設定できます。
ただ、Auto Publishをする場合は事前にTerminalでnuget setapikey <key> -source <url>
をする必要があります。
今回はローカルのサーバーにDockerでNuGet ServerをApiKey=nuget
、Publish URL=http://192.168.1.11:5001
で立ててそれを使ってみました。
この場合のAPIキーの設定はこんな感じ。
nuget setapikey nuget -source http://192.168.1.11:5001
それではMake Package
をしてみましょう。
上記のようにエラーっぽいメッセージがなければ成功です。 あとはNuGetのSourcesにURLを足して
NuGetパッケージマネージャーを見てみると
追加するとちゃんとクラスも表示されているので大成功です!(もっと特徴的な名前にすればよかった)
最後に
実はこれソースコードを見ればわかるのですが裏で結構がちゃがちゃやってます(だいたいnugetのせい)。
なので結構バギーです。もしよろしければ使ってみて動かなかった場合は@crocus7724までお知らせください。