tech.guitarrapc.cóm

Technical updates

PowerShellっぽく陸上自衛隊のイラク派遣日報をまとめてダウンロードしてみる

面白い記事があったので、私もやってみます。

blog.daruyanagi.jp

毎度毎度、PowerShellっぽさとは何かなぁ思うのですが、PowerShell実践ガイドブックでもWebサイトのステータス監視などを書いたので、良い題材な気がします。

目次

C# だとどう書くのか

C#ならAngleSharpを使って次のようなコードでダウンロード処理を行うことができます。 私の自宅では、60Mbpsを維持して5分でおわりました。

gist.github.com

PowerShellだとどうなるでしょうか。

元記事の処理

元記事では次のように書いています。

$source = "https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html"
$folder = "C:\Users\Hideto\pdf"

$result = Invoke-WebRequest $source -UseBasicParsing
$urls = $result.Links.href | Get-Unique |  where { $_ -match ".pdf" }

foreach ($url in $urls)
{
    $file = ($url  -split "/")[-1]
    Invoke-WebRequest -Uri $url -OutFile (Join-Path $folder $file)
}

PowerShell 6.0で、ここから何処まで手早く書きつつ、素早く処理できるか考えてみましょう。

必要な処理を抜き出す

必要な処理は、次の4つとわかります。

  • サイトの構造からリンクURLを抜き出す
  • PDFのパスのみを取得する
  • 重複があればはじく
  • ダウンロードする

インライン処理

URLや、パスに関しては、処理を括弧でくくることでインライン処理しつつプロパティにアクセスできます。 変数に保持したいかどうか次第ですが、書き捨てでコンソールで書くならこんなのでもいいでしょう。

(Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href

パイプラインとメソッド形式の選択

さて、PDFに絞る方法ですが、パイプラインの入力をStringクラスのEndsWithメソッドで絞るのが楽でしょう。

(Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href | 
Where {$_.EndsWith(".pdf")}

コレクション入力を都度処理するときは、パイプラインで書くのも楽ですがメソッド形式で書くという選択もあります。 メソッド形式については過去の記事をどうぞ。

tech.guitarrapc.com

PowerShell実践ガイドブックでは書かなかったのですが、.ForEach().Where() メソッドは、foreach構文同様にコレクションを処理する時に一度メモリにため込むため、パイプラインよりも高速に動作します。ただしメモリに保持するということは、膨大な大きさのコレクションではメモリを大量に使うため対象のサイズに注意が必要です。

(Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href.Where({$_.EndsWith(".pdf")})

なお、一行が長くなって改行したい場合は、.で改行します。.WhereではなくWhereとなるので気を付けましょう。

(Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href.
Where({$_.EndsWith(".pdf")})

あるいは{(で改行するのもいいでしょう。

(Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href.Where({
$_.EndsWith(".pdf")})

メソッド形式で数をフィルタ (Select-Object -First 1 に相当する処理は、Whereメソッドで指定します。

(Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href.
Where({$_.EndsWith(".pdf")}, "First", 1)

こういう処理を書いている時は、1個だけ試したい、というのはあるあるですからね。

一意に絞る

URLの数を見てみると、1220個ありますが、PDFを末尾に持つURLで絞ると870個です。 しかし、ここには重複したURLが含まれているため、一意(ユニーク)なURLに絞りましょう。 PDFのURLは順不同に並んでいるため、Get-UniqueではなくSort-Object -Uniqueをする必要があります。

(Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href | 
Where {$_.EndsWith(".pdf")} | 
Sort-Object -Unique

これで、435個に絞られました。

URLからファイル名を取る

元記事では、$file = ($url -split "/")[-1]と書いており/で分割してできた配列の最後*1をとっています。 PowerShellらしいといえばらしいのですが、Split-Pathを使うと配列を意識せず/の最後をとれます。

Split-Path PDFのURLパス -Leaf

PDFファイルのURL、ファイル名まで取れたのを確認してみましょう。 1つだけ試すならこれで。

(Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href.
Where({$_.EndsWith(".pdf")}, "First", 1).
ForEach({Split-Path $_ -Leaf})

パイプラインならこうです。

(Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href | 
Where {$_.EndsWith(".pdf") | 
Select-Object -First 1 | 
ForEach {Split-Path $_ -Leaf}

ダウンロードする

1つだけダウンロードするならこうです。

(Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href.
Where({$_.EndsWith(".pdf")}, "First", 1).
ForEach({Invoke-WebRequest -Uri $_ -OutFile (Split-Path $_ -Leaf)})

全てなら、一意に絞りましょう。

((Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href.
Where({$_.EndsWith(".pdf")}) | 
Sort-Object -Unique).
ForEach({Invoke-WebRequest -Uri $_ -OutFile (Split-Path $_ -Leaf)})

パイプラインでも、同様に書けます。

(Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href | 
Where {$_.EndsWith(".pdf")} | 
Sort-Object -Unique | 
ForEach {Invoke-WebRequest -Uri $_ -OutFile (Split-Path $_ -Leaf)}

また、パイプラインの場合は-PipelineVariable を使ってメソッドよりも柔軟に書くことができます。 -PipelineVariableは、自動変数を一度変数に受けて明示的な変数に割り当てることを不要にするので非常に便利です。

(Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href | 
Where {$_.EndsWith(".pdf")} | 
Sort-Object -Unique -PipelineVariable pdf | 
ForEach{Invoke-WebRequest -Uri $pdf -OutFile (Split-Path $_ -Leaf)}

もちろんこれでダウンロードできるのですが、1つ1つのファイルをダウンロードしたら次に行く同期処理です。 そのため、ダウンロードに時間がかかり435ファイルで6分かかります。

次にこれを高速化してみましょう。

非同期ダウンロードで高速化する

PowerShellの非同期技法は、大きく2つです。 Job機能を使うか、.NETの非同期構文です。

Jobを使った非同期処理

PowerShellらしさ、となるとJob機能ですがオーバーヘッドが大きい処理のため、必ずしも適切ではないケースがあります。今回のような「膨大な数」がまさにそのケースで、こういったときには.NETランタイムを使うと非同期処理がしやすいです。

Jobに変数を渡す時は、スクリプトブロックにparam句を使って -ArgumentList パラメーターを使って渡しますが、実行すると全くダウンロードされないことが分かるでしょう。 これがJobの問題点で、ダウンロードのような処理を大量のジョブでリソース割り当てを行うと大概うまくいきません。 ただの分散処理なら問題ないのですが、ダウンロードは陥りやすいでしょう。

$jobs = (Invoke-WebRequest -Uri https://www.asahi.com/articles/ASL4J669JL4JUEHF016.html).Links.href | 
Where {$_.EndsWith(".pdf")} | 
Sort-Object -Unique | 
ForEach{Start-Job{param($x,$file,$path) cd $path; Invoke-WebRequest -Uri $x -OutFile $file} -ArgumentList $_,(Split-Path $_ -Leaf),$pwd}
Receive-Job $jobs -Wait

Taskを使った非同期処理

.NETのTaskを使ってみましょう。HttpClient経由でダウンロードします。 先ほどのC#の処理からダウンロード部分を抜き出してヒア文字列としたら、Add-Typeでクラスをコンパイル/読み込みします。 あとは、uri一覧をPowerShellで取得してダウンロードを呼び出すだけです。

おおよそC#と同程度の時間で終わります。

gist.github.com

C#側にダウンロード、非同期ロジックを任せることができるので、PowerShellのコードがシンプルなことがわかります。

まとめ

たぶんPowerShellっぽさは、「型を必要になるまで意識せずに」、「適当にコマンドつなげたら書ける」の2点だと思います。 なので、同期処理の場合はワンライナーにしましたし、するのは違和感ないと思います。 一方で、Jobが入った瞬間難しい見た目ですね。.NETランタイム使うのも、唐突に新しい考えが入った印象が強いと思います。 自分が書きやすく、未来の自分が読むのも困らないように書くにはコツがあります。

  • コマンドレットのエイリアスはあまり使わない(Whereや%のような頻出以外は、なるべくフルで)
  • パラメーターを必ず用いる
  • パスやディレクトリを直接触らない

あとは、シェルっぽいやり方として

  • 変数にすることでDRYができるならするが、DRYにならずメンテもしないなら書き捨てる
  • コマンドはパイプラインでつなげていく

見た目が難しくなる = 読み下しが難しくなる要素は、スクリプトブロックなどの「読み手に解釈」を求めるものがあるかもしれません。 渡す順番が処理に影響する、スコープが影響するのは難しいでしょう。

  • スクリプトブロックでparamを使い、-ArgumentListパラメーターで渡す

数が少ないなら同期で十分です。 もし数が多く、非同期で書きたい場合はJobか.NETのTaskを使うといいでしょう。

gist.github.com

参考

PowerShell のStart-Jobに非同期数制御があれば、また話はべつなのですが.... 自宅の回線がネックになってるので、余り速度が速くなりませんでしたが900Mbpsとか超えている環境では顕著に変わるでしょう。

コマンドの長さと、Invoke-WebRequest がパイプラインからの入力を受け付けないのがネックで長いですね。

*1:PowerShellは配列の最後の要素に-1でアクセスできます

『PowerShell実践ガイドブック』の先行レビューアーを募集します!

刊行される「PowerShell実践ガイドブック」(通称:貝殻本)ですが、編集さんにかけあったところ先行レビューという形で書籍をプレゼントできることになりました!

tech.guitarrapc.com

マイナビBOOKSのPC書籍編集部ブログで、応募フォームが用意されています!

book.mynavi.jp

レビュワー募集終了のお知らせ

締め切りを迎えて、抽選により5名様にレビュワーの連絡と書籍が発送されました。 レビューされるのを心待ちにしています!

お願い

当選された方は、アマゾンやブログ(はてな、note、medium、など場所は問いません)でのレビュー+TwitterなどのSNSでの告知をお願いします。 書籍到着から2週間以内にレビューを公開しご連絡ください、拡散します!

「意気込み」とは、ですが、読みたいんだーと思っていただけるの本当にうれしいです。 その読みたい理由とか教えていただけると嬉しいなぁと思います。

以下、応募サイトの抜粋です!

募集内容

発売に先立って『PowerShell実践ガイドブック』をプレゼントします。当選された方は、レビューをお願いします。Amazon.co.jpのレビューやブログ(はてな、note、mediumなどなど、場所は問いません)でのレビュー+TwitterなどのSNSでの告知をお願いします。 書籍到着から2週間以内にレビューを公開し、ご連絡ください。マイナビブックスや著者などが拡散します。

募集人数

5名

募集締切

2018年5月21日 23:59

応募方法

こちらの申し込みフォームから ・名前(ハンドル) ・メールアドレス ・意気込み ・レビュー場所(の予定) を記入して、ご応募ください。 「意気込み」欄には、PowerShellをどのように使っているか、あるいは、これから学びたいと思っている理由など、本書を読みたい!という(熱い)気持ちを自由にお書きください。

当選発表

当選者にはマイナビ出版からメールをお送りします。送付先をお知らせいただければ、書籍を発送いたします。

お問い合わせ

本件についてのお問い合わせは、books-hen3[at]mynavi.jp宛てにお送りください。 ※上記の[at]のところは@に変更してお送りください。

ご応募をお待ちしています!

「PowerShell実践ガイドブック」という本を書きました!

このたび、PowerShell実践ガイドブックという本を執筆・刊行する運びとなりました。

本日から予約開始、2018/5/30日に発売です。

※ Amazonの紹介文がおかしいのは修正予定です。 修正されました。

Amazonなどのオンライン書店で予約が始まってます。 Kindle版もありますが、まだAmazonでは発売情報が出ていませんのでお待ちください。 5/22 Kindle版も予約開始しています。

また、マイナビ出版でもPDFを販売しています。

book.mynavi.jp

PowerShell Coreを扱った本は、世界では2017年に発売された6.0リリース前の本のみで、国内でも初めてになります。

こんな人におすすめです

  • ふだんのちょっとしたPC作業を自動化をしてみたい方
  • システム管理者としてPowerShell使っていく、使いこなしたい方
  • 開発者からみてPowerShellをどう使うか気になる方

テーマは、PowerShell Core (PowerShell 6.0) をメインに据えた、PowerShellを実際に使っていくときのガイドとなる本です。 この本は過去の「PowerShellを触り始めた直後の自分」がほしかった本でもあり、今の自分が幅広い利用者を想定して書き出せる限界ギリギリを絞りました。 コードパズルに近いマニアックな内容にならず、プログラマーでないとわからないということがないように気を使っています。

Twitterアンケートでも本当に幅広い方がPowerShellを使っていて嬉しい反面、最新の情報や実践を見据え体系的にまとまった情報を得にくいと感じていました。

私自身がPowerShellを学び始めたときに困ったのが「情報がない」です。 PowerShell 6.0になって、Windowsだけでなく、macOSやLinuxでも動かせるようになりました。 とはいえ、PowerShell 6.0をどうやって導入するのか、何に使えるのか、どうやって動かすのか、スクリプトってなに、関数? 高度な関数?実際に使ってみてハマることは?という、基本的なことすらも分かりにくいと感じていました。 PowerShellに関する記事を数多く書いて来ましたが、「本によるまとまった情報の取り込み力」が必要と考えての一冊です。

本書が、そんな悩みを解決できる一助になれば、幸いです。

Windows PowerShell In Action や Windows PowerShell Cookbook との違い

当初案のタイトルは、PowerShell In Action でした。 まさにテーマが In Action「実際に使う」ということだったので被ってることにしょんぼりすることになるとは思いませんでした。

Windows PowerShell イン アクション も Windows PowerShell クックブックも何度か推薦するぐらい素晴らしい良著で私の大好きな本です。

PowerShell実践ガイドブックは、この2冊と明確に立ち位置が違います。

  • PowerShell Core (現時点の最新である PowerShell 6.0) をメインとした内容になっている
  • 体系的な基本機能も網羅しているが、常に実践を意識した内容になっている
  • 実際にPowerShellを使うにあたっての操作や直面する課題を対象にしている

これまで学んできたことを含めて全ページ書き下ろしているので、お気に入りの一冊に加えていただけると嬉しいです。

章構成と立ち読み

大まかな構成は、まずは触ってみる(1章)→コンソール操作と基本機能(2章)→管理操作(3章)→スクリプティングと自動化(4章)→実践とTips(5章)となっています。

本書の前書き「はじめに」のセクションをテキストで出すことを編集者さんに許可もらったので、ブログで一部を公開します。 「はじめに」の全文はマイナビ出版様より立ち読みとして公開予定もあるそうです。

本書の想定する読者

本書は、これからPowerShellを触ってみたい方、システム管理者、開発者の三者を想定しています。 これから触る方には、日常の中で繰り返し手作業で行っていることを自動化する足がかりになるでしょう。 特に、筆者自身が今までコマンドプロンプトやPowerShellをちょっとだけ起動したことはあったけれども「さらに習得したい」と考えたときに手に取りたかったものとして本書を執筆しました。

システム管理に求められる問題領域は、コンピューターシステムの構成や運用に始まり、ネットワーク、コンピューターセキュリティなど多くのリソースに及びます。さらに、クラウド管理、データベース管理、Webシステム管理などが求められることも少なくありません。開発者としても、多くのビルド、デプロイ、Application Programming Interface(API)を通した各種サービス操作を日常的に行います。

両者に共通するのは、多岐にわたる知識と解決です。限られた時間の中で解決するために、多くの操作を自動化する必要に迫られます。操作自体はシンプルな処理の連続であることが多く、コマンド1つ、あるいはパイプラインでつないで、はたまたスクリプトで自動化されます。

PowerShellは自動化に際して大きな力を発揮します。特に構造化データの取り扱いの容易さが大きな力になるでしょう。経験の有無にかかわらず、繰り返し作業やうんざりする作業をPowerShellを使って自動化したい方にとって本書が力になると考えています。

本書で得られること

本書を通して、PowerShellを使うことに対して「知らない」に起因する心理的なハードルの軽減すること、そして、PowerShellの網羅的な内容を知ることができるように気を配りました。本書は詳細機能の説明を無理に詰め込むことはせず、本書を読み進めることによってPowerShell 6.0の概要の把握から、C#コマンドレットの作成の入り口までの導入を目指しています。

本書は5章に分かれています。各章はテーマを持ち、実践的なTipsを交えつつ紹介しています。

第1章では、起動するのも初めて、これからまさに触ろうと思ったときに知りたかった「何ができるか」を平易に伝えることを念頭に置きました。Visual Studio Codeを使ったPowerShellのデバッグにも触れています。他言語の経験者の方やすでに慣れ親しんでいる方からすると、すでに知っていること、普段から行っていることの繰り返しに近いため、第2章から読み進めてもいいでしょう。

第2章では、PowerShellのコンソール操作に触れつつ、しっかりと基礎を学ぶことを目標に置いています。 PowerShellは、操作することを自動化に結び付けやすいため、多くの方にとってはこのコンソール操作をどうするかが知りたいことだと思います。

第3章では、クロスプラットフォームなシステム管理操作がテーマです。操作ログやリモート操作を始めとして、PowerShellでどのようにシステム管理を行うかを主題にしています。

第4章では、スクリプティングを網羅しつつ、理解できるようにしました。スクリプト、関数、クラス構文を始めとした機能の利用から、実際にモジュールを作って公開することまで、手を動かしながら学べます。

第5章では、さらに一歩進んだPowerShellの利用に触れています。実際にPowerShellを使って気付く悩みがちなこと、より実践的なTipsに踏み込んでいます。

PowerShellは画面がテキストだけということもあり、コマンド操作経験がない方がいきなり触るには難しいと考えています。そこで、第1章は、平易な言葉と例を用いて、可能な限りわかりやすい表現を心がけました。第2章以降は、オブジェクトなどの概念を順に追いかけつつ、手を動かしながら理解していく内容になっています。初めてPowerShellを触る場合でも、C#や.NETランタイムの知識や経験は必要ないように配慮して書きましたが、第2章以降ではそれを知っていることが理解を助けるでしょう。

本書で得られないこと

PowerShellは、管理や自動化といったタスクを達成しようと思ったときに使うであろうツールです。本書が目指すのは、ツールの扱い方であり使い方ではありません。したがって、標準だけでも500を越えるコマンドの1つひとつの説明はしないので、どんなときにどのような管理をするのかというユースケース、Acrive Directoryのアカウントの操作方法などは本書で説明しません。

また、本書をもってプログラマーになることは目的としていません。スクリプト環境としてVisualStudio Code(以降、VS Code)を使って説明しますが、PowerShell ISEやVS Codeの使い方やスニペット、GUIアプリケーションの作成などは触れません。

線引き

「PowerShellは何でもできるわけではない」といってしまうのは簡単です。やりたいことを探していて、要件をまったく満たしておらず使えないということもあります。コマンド1つで実行できて極めて便利なこともあるでしょう。しかし、可能ではあるものの、PowerShellで行うには複雑になってしまって難しいこともあります。

本書では、こういったPowerShellだけでは扱いにくいことをどのように扱うか、あなた自身が学んでいけるようにガイドを示します。

Windows PowerShell と PowerShell Core

2018年現在、PowerShellには、2006年に発表されたWindows PowerShellと2018年に正式版を迎えたPowerShell Coreが存在しています。

PowerShell 6.0は、PowerShell Coreの最新リリースバージョンです。Windows PowerShellのコードを元に.NET Coreをベースとしてさまざまな改善が図られており、Windows PowerShellを置き換えることを視野に開発されています。パフォーマンスや使い勝手の大幅な改善を目的に後方互換性をなくした機能もあり、.NET Frameworkには存在するものの.NET Coreにない機能は削られてもいます。

本書はPowerShell Coreの最新リリースである「PowerShell 6.0」を前提として紹介していますが、Windows PowerShellからみた変更点にも極力触れています。Windows PowerShellについて知識をお持ちの方は、PowerShell Coreでどのように変化したのかにも注目してください。

東プレ REALFORCE TKL S / R2TLS-JP4-BKにメインキーボードを変更した

ここ最近色々と活動していましたが、タイプ量が相当多く、キーボードを自分で持ち込むことがありました。

そこでメインキーボードを REALFORCE 91UDK-G からREALFORCE TKL S / R2TLS-JP4-BK に変えてみたのでレビューを。

目次

これまで使っていたキーボード

アマゾンの購入履歴から2013年4月18日にREALFORCE 91UDK-Gを購入して愛用していたので、ちょうど5年使っていました。

tech.guitarrapc.com

購入ページ | ダイヤテック株式会社

Realforce 91UDK-G テンキーレス・ALL45g

もともとノートPCでの作業との一貫性からテンキーレスに慣れていたので十分満足しています。 会社の静音モデルと比べても何の不自由もなく、カタカタ毎日入力する日々です。

静音モデルのREALFORCE 91UBK-Sが2018年6月生産終了になっており、REALFORCE 91UDK-Gがリストにないのでそろそろ世代が変わった感があります。

第二世代REALFORCE

長年使っていると安定していて心地いい反面で、新製品がなく物足りなさを覚えます。 特に、テンキーレスで横幅はいいのですが、縦方向のサイズは邪魔に感じます。 静かにタイピングする方ですが、タイプ音ももっと静かにできるならしたいなぁと感じます。 そんな折に第二世代が発売されると聞いて、自分で買う理由を探していました。*1

www.4gamer.net

ちょうど家でなくても自分のキーボードを持ち込めることがあったのでこれ幸いと購入することにしました。

キーボードの選択

まずは一覧を確認しましょう。

今回の購入条件は次の通りです。

  • テンキーレス
  • 日本語キーボード*2
  • 変荷重は不要
  • 色は黒

この条件に当てはまるのは2つ、REALFORCE TKL S / R2TLS-JP4-BKとREALFORCE TKL SA / R2TLSA-JP3-BKです。

違いはAPCの有無と荷重が45gか30gかのみです。

APC気になるものの、あまり必要と思っていないのと触ってみてあんまり感動しなかったのでなし。 残りは荷重ですが、Realforce 91UDK-Gと同じ45gかなという選択と思いきや、APC要らないという時点でREALFORCE TKL S / R2TLS-JP4-BKで確定です。

荷重に関しては購入後も良かったかわかりません。 私は1日18時間ぐらいタイプするわけですが、寝る理由がタイプが重くて疲れてもう打てないから、というのが1月ほど続いたのでもっと軽いともっとタイプできていい感じな気もします。 軽さは正義に直結しませんが、疲れには直結するので悩ましいです。

購入は早く使いたかったのでAmazon Primeです。 2018年4月16日購入価格が\22,014で、2018年4月28日現在\19,293なので今の方が格段に安いです。なんなの

REALFORCE TKL SA / R2TLSA-JP3-BKが\21,225なのでAPCと荷重30gに価値を感じるか次第でしょう。

感想

明らかにすべてが改善しているので満足しています。 特に気になったのが次のポイントです。

サイズ

横方向のサイズはあまり変わりませんが、無駄に感じていた丸め加工ではなくまっすぐになっているのがうれしいです。

縦方向の余白も大幅に減ってサイズがコンパクトになっています。地味ですがものすごく体感が変わっていて最高にうれしいです。

スペースキーの大型化

長年使っていて困っていないのでどちらでもいいのですが、スペースキーが大きくなると打ちやすくなったと感じます。

静音性

圧倒的に違います。 REALFORCE 91UDK-G とだけでなく、REALFORCE 91UBK-Sと比べても明らかに静かになっています。

打鍵感

以前のREALFORCE 91UDK-G ではカタカタという感じでしたが、スコスコと音以外にもスムーズな打鍵感があります。 個人的にとても打ちやすく、メカニカルだけどメカニカルのタイプにある微妙に苦手な感じがないバランスの良さを感じています。

Fn機能

使いません。普段MacBook も使うのですが、Windowsと共通のキーボード配列にはこだわっていません。 Caps Lock KEY ⇔ Ctrl KEY の入れ替えもしない方なので使わないです。 インジケータの色も普段インジケータすべて消えているのでいらないという。

印字

REALFORCE TKL S / R2TLS-JP4-BKは、レーザー印刷のため、キートップの文字をなでると少し凹凸があるのが分かります。 REALFORCE TKL SA / R2TLSA-JP3-BK やREALFORCE 91UDK-Gは昇華印刷だったので少し変わった感じはします。 気にならないかというと、少し吸い付く感じがあるので意識すると気になります。 が、さすがにそこに意識は向けてないのでこの記事を書いていてわざわざ違いに気を払わないと気づきませんでした。

レーザーは、昇華と違い印字が消えるので消えたタイミングを変える言い訳になりそうです。

安定性

実は裏面のラバーフィートが、REALFORCE 91UDK-Gと全然違います。 REALFORCE TKL S / R2TLS-JP4-BKは、四隅にラバーフィートがあり全くずれません。 REALFORCE 91UDK-Gでは、キーボード下部のみだったためにずれることがありストレスだったのから大きく良くなっています。 キーボードが安定しているのスゴク大事。

まとめ

プログラミングしている以上、タイピングがここまで感じ変わると嬉しいですね。 もし、今キーボードでREALFORCEどうなの?と思っていらっしゃるなら、第二世代REALFORCEを使ってみると感想が変わると思います。 ぜひ試す機会があればオススメです。

このキーボードにしてから、一日20時間まで疲れを感じなくなったのは成果としてあります。 お仕事募集しているので、どこかで話しながらキーボード試したい時は声かけてください!

*1:使えるものがあるうちは余り買い替える衝動がないのです

*2:私はASCII配列でもなんでもokですが、日頃触る機会の多い配列に合わせます

VSTSの YAML Build Preview でビルド

Visual Studio Team Service (以降 VSTS) は、プロジェクト管理、Gitリポジトリ、CI (リリース含む) などソフトウェア開発を支援する結構大掛かりなサービスです。

私自身は CI の環境としては結構好き*1な一方他の機能はちょっと大掛かりと感じます。本記事では言及しませんが、パッケージ管理も便利です。*2

今回は VSTS でずっとほしかった YAML 定義からのビルドパイプラインについてです。ようやくYAML来たので少しは楽できそうです。

YAMLといっても、この VSTS 拡張じゃないので悪しからず。

https://marketplace.visualstudio.com/items?itemName=adamvoss.yamlmarketplace.visualstudio.com

目次

参考資料

ある程度概要をつかみつつ詳細を見通すのには、このあたりを見ておけばいいと思います。英語記事も含めて触ってみた、こんな感じという内容が多いのは利用者の絶対数と、他CIに比べて Yamlでの調整がしにくいのが大きい感じがします。(GUI でのパイプライン構築が強いのもありますが)

kkamegawa.hatenablog.jp

docs.microsoft.com

azure-pipelines-agent/yamlgettingstarted.md at master · microsoft/azure-pipelines-agent · GitHub

概要

従来 VSTS ではWebポータルからGUIでビルドパイプラインを構築していました。このあたりは、CircleCI や Travis、AppVayor に慣れてると不思議な感覚です。

VSTS の YAML Build とは、簡単にいうと Circle CI のような yaml 定義でのビルドパイプライン構築ができるというものです。慣れた手法ですね。なお、ビルドパイプラインだけなので、Push連動などビルドタイミングやオプション設定はできません。

さて、ではGUI での構築はどうなんでしょうか? YAML を使いたいだけの理由があるのでしょうか?私にとっては、ものによる、と思います。ビルドの95%はシンプルなので YAML がベターです。一方でその場でインスタントに組むにはGUIも悪くないでしょう。

今がPreview だからこそ、感覚として他のビルドで慣れた肌感との違いをメモしておきます。

GUI のメリット

  • リポジトリにコミットがいらないので CI ビルドのためにコミットを重ねる必要がないのはあるあるでしょう。*3
  • パイプラインを作っていてある程度複雑になっても意外とやりやすいと感じます
    • yaml ですこし細かいことをしたときに読み解かなくてもパッとみたいことに目線のスコープを絞れるのは GUIの良さでしょう

GUI で困ること

  • GUIで1つずつのパイプラインを組むので、どんな構成なのかをざっと把握するには不便です。全体の普遍的な把握にはだるいです
  • ビルド構成のクローンからの作成が可能ですが、まとめて直したいときには1つずつ直す必要があって容易に刺身タンポポになります
    • ビルド職人さんはほぼ発生しないのですが、刺身タンポポさんが発生しやすいのは由々しき欠点です
  • リポジトリごとに決まったパターンでのビルドを、ビルド構成/デプロイ先の些細な差異で構築したときに面倒さが爆発します
    • ビルドパイプラインは単純を維持するのがいいので、Parallel にパラメータ変更で回すなどは避けるべきです
    • 一方で、似たビルドが多数できても違いを把握するのは大変でしょう

YAML ビルドの利用開始前作業

YAML ビルドを試す前にちょっとだけ準備です。

アカウントをとる

VSTS にアクセスして適当にアカウントをとっておきます。無料です。Hosted Agent でマネージドビルドができるので、まぁあってもいいかなぐらいです。

www.visualstudio.com

YAMLビルドの有効化

まだ YAML Build は Preview 機能なので有効化が必要です。

  • アカウントのアイコンから Preview features を開く

  • ユーザーアカウントではなく 作成した VSTS アカウント全体の設定に切り替えます for this account
  • Build YAML definitions を on に変更

これで準備できました。

YAML でビルドパイプラインを書いてみる

では本筋です。ドキュメントは本家を見ておけば大丈夫だと思います。

azure-pipelines-agent/yamlgettingstarted.md at master · microsoft/azure-pipelines-agent · GitHub

YAML 定義をする前にどんな定義なのか見る

適当にビルドをWebポータルからポチポチ組むと YAML でどう定義するのか見られます。便利。

View YAML からYAML をプレビューしてみました。

なるほどいい感じです。

gist.github.com

リポジトリに YAML 定義を置いてみる

ではプレビューした YAML使ってビルドプイプラインを定義してみましょう。コピペです。

github.com

ビルドパイプラインをYAMLで作る

書いたYAML からビルドパイプラインを作ります。

VSTS で作業しましょう。

YAML によるビルド定義を作る

VSTS の Build and Release > Build からビルドを新規作成します。

新規ビルドジョブを作ってみると YAML が選択できるようになっています。

Agent Queue の選択

適当に名前を付けたら、Agent Queue を選択します。2018/1/24 現在は、YAML ビルドは マネージドビルドであるのみサポートされています。

  • Hosted VS 2017
  • Hosted Linux Preview
  • Hosted macOS Preview

https://docs.microsoft.com/en-us/vsts/build-release/actions/build-yaml

今回は C# プロジェクトなので Hosted VS2017 を選択します。

YAML パスの指定

YAML ビルドは、Git ソースパスとして Github か VSTS がサポートされています。YAML はリポジトリ内の任意のパスを指定できます。ルートが一番楽で、.vsts-ci.yml がドキュメントで記述されている名前ですが他でもok です。

今回は、v2 フォルダ配下に置いたので、v2/.vsts-ci.yml と指定します。

ビルドリポジトリの指定

Get Source からビルドリポジトリを指定します。Github からぽちっと。

Submodule など チェックアウトオプションの指定

YAML 定義の リポジトリのチェックアウト指定には制約があります。

https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted-features.md

  • YAML 上では Submodule checkout を指定できない
  • Build Report の有効化が指定できない

しかしこれらは、UI上でリポジトリのチェックアウトとしては有効化がかのうなので必要に応じてUIで有効化すればいいでしょう。

環境変数の設定

YAML 内部でも Variables は定義可能です。が、ビルドによって変わるものやシークレットは当然入れなくないでしょう。

https://github.com/Microsoft/vsts-agent/blob/master/docs/preview/yamlgettingstarted-phase.md#variables

CircleCI でもそうですが、シークレットな情報は環境変数に鍵付きマスクで設定しておけます。

ビルド実行

ビルド設定ができたらこれでおしまいです。Save & Queue でビルド開始してみましょう。

なお、YAML の定義がおかしい場合、Queue 実行時にわかります。ちょっとタイミング遅いですね。

問題なく YAML が解釈できればビルドが開始するでしょう。

ビルド画面

ビルド画面はリアルタイムでビルド状況が表示されます。ここで YAML のパイプラインがわかります。ビルドUIでわからないのがやはり嫌ですね。

うまく変数も解釈され、ビルドが成功しました。

まとめ

Hosted Agent でしか動かないのが苦しいですが、おおよそ機能は満たしていていい感じです。

VSTS をこれからちょっと使ってみる、iOS ビルドで触ってみる (Hosted Agent on macOS) 場合にはYAML定義が慣れ親しんでいることが多いのでいいと思います。他のビルドサービスより癖が強く YAML 定義のハードルが高いのでなんとかしてほしいですね。

現状の利用シーン

エージェントが弱いのでほどほどの開始から、という印象ですが Private Agent がきたらすぐにでも使えそうですね。

  • Recommend: Your Project is Simple enough includes pipeline count and parameters
  • Recommend: Your Project is referencing variables with many pipelines. yaml offers easy view checking
  • Accept: yaml <-> pipeline conversion is not available
  • Accept: Private Agent is not available

VSTS yaml ビルドのここが苦しい

  • Checkout options: Tag sources, Report build status, Checkout submodules
  • Hosted Agent のみ対応
    • Private Agent対応していないので強いのがほしいときに非力
    • Hosted Agent がかなり非力で大きなリポジトリのビルドが現実的な時間でできないので致命傷になりかねない
  • パラメータなに使えるかとか初見殺し
    • ぽちぽち作成 -> yaml 生成しないとむりぽ
    • Circle CI とかだとコマンド実行しか露出させないのに対してパイプラインのカスタム要素で構築していく VSTS スタイルだときっつい
    • Store のパイプラインのところとかで、パラメータ提供してくれないときつそう
  • yaml定義はパイプラインには出ない
    • パイプラインの途中だけ無効とかが当然できない
    • パイプラインの内容を yaml 翻訳はできても yaml -> パイプライン翻訳ができてないので制約としは自然
  • yaml -> ふつうのパイプライン、ふつうのパイプライン -> yaml の変換ができない
    • 新しく作るしかない...

ここは嬉しい

  • dotnet みたいにグループ定義になっている場合にParameters として変数見えてるので設定しやすい
  • ビルドステップが単純なら各ブランチビルド定義が楽ちん
  • 変数が定義しやすいのは相当楽。見通しいい
  • UIぽちぽちから yaml 出力できるので定義が楽にテンプレート組める
    • ただし、これがただしいとは限らない
    • 変数が抜けていたりする

*1:Windows な Managed CI Service は VSTS か AppVeyorぐらい

*2:Git リポジトリを Github 以外で管理するメリットがかなり薄いのもあり微妙

*3:ブランチ切って履歴から抹消という手もありますが、そこはチームにお任せで