WindowsでHexo+GitHub Pagesでデプロイまで実行できなかった話
ブログ向けの静的ジェネレータを探していたらHexoがよさそうだったのでまずはインストールして使ってみることにしました。
Hexoはnode.js製なのでnpmが必要なのでそこからのWindows版インストール手順をまとめてみました。
が、結論から言うとHexoでサイト作成はうまくいきましたが、GitHub Pagesへデプロイはできませんでした。
Windows環境でうまく言った方アドバイスをいただけると助かります。
目次
- 構築環境
- node.jsのダウンロードとインストール
- hexoをインストール
- サンプルブログを作ってみる
- Github pagesの設定
- パッケージのインストール
- configにgithubを設定
- github pagesにdeploy
- トラブルシューティング
構築環境
OS: Windows10
node: v8.11.3
node.jsのダウンロードとインストール
node.jsの公式サイトからWindows64bit版のnode.jsをダウンロードしてください。
https://nodejs.org/ja/
ダウンロードしたexeをクリックしてインストールをします。インストールが完了したらコマンドプロンプトを起動して以下コマンドを実行してください。
> node -v v8.11.3 >npm -v 5.6.0
hexoをインストール
npmでhexoをインストールします。
> npm install -g hexo
途中で以下のようなWarnが出ますが特に問題ない模様。
npm WARN deprecated titlecase@1.1.2: no longer maintained ・・・省略・・・ npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules\hexo\node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})
インストールが完了したら以下コマンドを実行してください。
> hexo -v hexo-cli: 1.1.0 os: Windows_NT 10.0.17134 win32 x64 http_parser: 2.8.0 node: 8.11.3 v8: 6.2.414.54 uv: 1.19.1 zlib: 1.2.11 ares: 1.10.1-DEV modules: 57 nghttp2: 1.32.0 napi: 3 openssl: 1.0.2o icu: 60.1 unicode: 10.0 cldr: 32.0 tz: 2017c
サンプルブログを作ってみる
以下コマンドを実行してmyblogというブログのひな型を作成します。
ちなみに実行したディレクトリにmyblogディレクトリを作成するので、実行前に任意の場所にcdで移動しておいてください。
>hexo init myblog INFO Cloning hexo-starter to ~\Desktop\サイト\hexo\myblog Cloning into 'myblog'... remote: Counting objects: 65, done. remote: Total 65 (delta 0), reused 0 (delta 0), pack-reused 65 Unpacking objects: 100% (65/65), done. Checking connectivity... done. Submodule 'themes/landscape' (https://github.com/hexojs/hexo-theme-landscape.git) registered for path 'themes/landscape' Cloning into '/myblog/themes/landscape'... Submodule path 'themes/landscape': checked out '73a23c51f8487cfcd7c6deec96ccc7543960d350' [32mINFO [39m Install dependencies npm WARN deprecated titlecase@1.1.2: no longer maintained > nunjucks@3.1.3 postinstall myblog\node_modules\nunjucks > node postinstall-build.js src npm WARN rollback Rolling back node-pre-gyp@0.10.0 failed (this is probably harmless): EPERM: operation not permitted, scandir 'myblog\node_modules\fsevents\node_modules' npm notice created a lockfile as package-lock.json. You should commit this file. npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.4 (node_modules\fsevents): npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.4: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"}) added 400 packages in 18.869s INFO Start blogging with Hexo!
すると以下のような構成のディレクトリが作成されます。
myblog ├node_modules ├scaffolds ├source ├themes ├.gitgnore ├_config.yml ├package.json └package-lock.json
サーバを起動する。
>hexo server INFO Start processing INFO Hexo is running at http://localhost:4000/. Press Ctrl+C to stop.
ブラウザを開いて以下にアクセスをしてみてください。
http://localhost:4000/
このような画面が表示されればOKです。
Github pagesの設定
Githubにログインし、タブメニュの[Settings]を開き"GitHub Pages"の以下を設定して[Save]を押す。
Source: master branch
すると"Your site is ready to be published at "の後ろに公開されるページのURLが記載されているのでコピーしておきます。
パッケージのインストール
Hexoはバージョン3からデプロイ機能が本体から切り離されたので以下パッケージをインストールします。
npm install hexo-deployer-git --save
configにgithubを設定
hexoの_config.ymlを以下のように編集します。
repoは自分のGitリポジトリによって適宜修正すること。
# URL ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' url: http://yoursite.com root: / permalink: :year/:month/:day/:title/ permalink_defaults: ・・・省略・・・ # Deployment ## Docs: https://hexo.io/docs/deployment.html deploy: type: ↓ # URL ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' url: https://【アカウント名】.github.io/【リポジトリ名】/ root: 【リポジトリ名】 permalink: :year/:month/:day/:title/ permalink_defaults: ・・・省略・・・ # Deployment ## Docs: https://hexo.io/docs/deployment.html deploy: type: github repo: 【Git リポジトリURL】 branch: master
トラブルシューティング
deployコマンド実行時に/dev/ttyにデバイスとアドレスが見つからない
【手順】
以下をコマンドを実行する
>hexo deploy -g
【ログ】
標準出力で以下が表示される。
Fatal: HttpRequestException encountered. bash: /dev/tty: No such device or address error: failed to execute prompt script (exit code 1) fatal: could not read Username for 'https://github.com': Invalid argument FATAL Something's wrong. Maybe you can find the solution here: http://hexo.io/docs/troubleshooting.html Error: Fatal: HttpRequestException encountered. bash: /dev/tty: No such device or address error: failed to execute prompt script (exit code 1) fatal: could not read Username for 'https://github.com': Invalid argument at ChildProcess.<anonymous> (myblog\node_modules\hexo-util\lib\spawn.js:37:17) at emitTwo (events.js:126:13) at ChildProcess.emit (events.js:214:7) at ChildProcess.cp.emit (hexo\myblog\node_modules\cross-spawn\lib\enoent.js:40:29) at maybeClose (internal/child_process.js:925:16) at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
【原因】
Windows環境のため/dev/ttyなんてディレクトリは存在しない。
【対処方法】
repoに"http"ではなく"ssh"接続のURLを設定したが解消されず。
ホストキーの認証に失敗
【手順】
以下をコマンドを実行する
>hexo deploy -g
【ログ】
標準出力で以下が表示される。
nothing to commit, working directory clean Host key verification failed. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. FATAL Something's wrong. Maybe you can find the solution here: http://hexo.io/docs/troubleshooting.html Error: Host key verification failed. fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. at ChildProcess.<anonymous> (myblog\node_modules\hexo-util\lib\spawn.js:37:17) at emitTwo (events.js:126:13) at ChildProcess.emit (events.js:214:7) at ChildProcess.cp.emit (myblog\node_modules\cross-spawn\lib\enoent.js:40:29) at maybeClose (internal/child_process.js:925:16) at Socket.stream.socket.on (internal/child_process.js:346:11) at emitOne (events.js:116:13) at Socket.emit (events.js:211:7) at Pipe._handle.close [as _onclose] (net.js:557:12)
【原因】
Gitに登録されている秘密鍵の設定がおかしいため認証に失敗している。
【対処方法】
不明。
Git Bashの場合、Windowsユーザの配下にある.sshディレクトリに公開鍵と秘密鍵を設定してみましたが、改善されず。
Netbeans+PHPUnit+Mockeryで単体テスト環境を構築
NetbeansにPHPUnit+Mockeryを入れて単体テストを動作させる記事がなかったのでメモ程度で作成。
目次
composerでPHPUnit+Mockeryをインストール
適当なプロジェクトで右クリック→[composer]→[初期化]を実行すると、composer.jsonが作成される。
その後、プロジェクトで右クリック→[composer]→[依存性の追加]を押すと、パッケージのウィンドウが表示される。
「トークン」欄に"phpunit"と入力してEnterを押すとパッケージ検索が開始されます。
しばらく待つと検索結果に"phpunit/phpunit"が出てくるので選択すると、今度はバージョン検索が走ります。
使用可能なバージョンから"7.1.5"を選択し[必須(dev)]を押してインストールを開始してください。
同様の手順で"mockery/mockery"の"1.1.0"をインストールします。
netbeansにphpunitの設定
プロジェクトを右クリック→[構成を設定]→[カスタマイズ]を選択します。
プロジェクトプロパティ画面が開き、左メニュの[テスト]を選択し[フォルダの追加]を押し、新規フォルダ"tests"を作成して[開く]で追加します。
同画面の下部にある"テスト・プロバイダ"より"PHPUnit"を選択して[OK]を押します。
サンプルソースと単体テストを用意する。
TemperatureとTemperatureTestを作成します。
TemperatureTestはテストフォルダに作成してください。
ちなみに本ソースは以下公式サイトを日本語化したサイトのものを引用しています。
Mockery 0.8.0 日本語ドキュメント
Temperatureのソース
<?php class Temperature { public function __construct($service) { $this->_service = $service; } public function average() { $total = 0; for ($i=0;$i<3;$i++) { $total += $this->_service->readTemp(); } return $total/3; } }
TemperatureTestのソース
<?php require_once "../Temperature.php"; require __DIR__ . '/../vendor/autoload.php'; use \Mockery as m; class TemperatureTest extends PHPUnit_Framework_TestCase { public function tearDown() { m::close(); } public function testAverage() { $service = m::mock('service'); $service->shouldReceive('readTemp')->times(3)->andReturn(10, 12, 14); $temperature = new Temperature($service); $this->assertEquals(12, $temperature->average()); } }
今回少しハマったのがrequireの部分。公式サイトではこの2行がなくてコピーしただけでは"PHP fatal error"が出力され動きませんでした。
公式サイトを読み進めていくと、実は以下に書いてあります。
Composerをご利用でしたら、Composerが生成したオートローダーファイルをシンプルにincludeするだけですみます。
require __DIR__ . '/../vendor/autoload.php'; // vendorディレクトリがひとつ上の階層であると仮定
初めて動かすときはコピペでやる人が多いと思うのでサンプルソースにはrequireも書いてほしいですね。
↑のrequireとテスト対象のソースをrequireすれば単体テスト動きました。
Windows10にRubyをインストールする手順
Javaが有償化するので他の言語を学ぼうと思いたり、PythonかRuby、Goどれがいいかなと調べてみたらRuby on Railsというフレームワークが便利そうなのでひとまずRubyをインストールしてみました。(Ruby on Railsはまた別途)
というわけで今日はRubyをWindows10にインストールしてみます。
Rubyをインストール
まずは以下からRuby+Devkit 2.5.1-1 (x64) をダウンロードします。
https://rubyinstaller.org/downloads/
"I accept the Licence"を選択して"Next"を押します。
"Use UTF-8 as default external encording."にチェックを入れて"Install"を押します。
他はそのままでOKです。
そのまま"Next"を押します。
インストール中です。完了するまで待ちます。
そのまま"Finish"を押します。
以下のような画面が立ち上がるのでそのままEnterキーを押して続行します。
そのままEnterキーを押して終了します。
Windowsの検索から"Intaractive Ruby"を起動すると以下のような画面が立ち上がります。
またコマンドプロンプトで実行するためにはWindowsの環境変数を編集を起動して、ユーザ環境変数の”Path”にRubyがインストールされたディレクトリを設定します。(今回は”C:\Ruby25-x64\bin”)
その後、コマンドプロンプトを起動して"ruby -v"を実行して動作確認してみましょう。
バージョンが表示されれば問題ありません。
以上でRubyのインストールは完了です。
WindowsにOpenJDKをインストールする手順
2018年9月のJava11からOracleJDKが有償化され、今後は有償プランか、OpenJDKへ移行になると思います。
個人利用する方はOpenJDK一択になるため、今回Windowsのインストールを試してみました。
OpenJDK(RedHat)のダウンロード
以下RedHatからOpenJDK(Windows Installer)をダウロードしてください。
OpenJDK Download | Red Hat Developers
ダウンロードのためにはRedHatアカウントが必要です。
OpenJDK(RedHat)のインストール
OpenJDKのインストールはJavaFXが必要な場合、インストール時にチェックしてください。
あとは環境変数のPathにOpenJDKのjava.exeが存在するディレクトリを指定すれば動きます。
ただし、OracleJDK8以降が事前にインストールされていた場合、環境変数のJAVA_HOMEやPathを設定するだけではないので口述します。
環境変数の設定
Windows検索欄に"システムの詳細設定の表示"と入力→「環境変数」を押す。
OracleJDK8以前と以降で参照する環境変数が異なります。
OracleJDK8以前:JAVA_HOMEにパスを設定
OracleJDK8以降:システム環境変数の"Path"の"C:\ProgramData\Oracle\Java\javapath"
それぞれ以下のように対策します。
OracleJDK8以前:JAVA_HOMEのパスを変更
OracleJDK8以降:システム環境変数の"Path"の"C:\ProgramData\Oracle\Java\javapath"の優先度を下げ、それより上にOpenJDKのディレクトリを設定する。
右側の「下へ」を押して"C:\ProgramData\Oracle\Java\javapath"の優先度を下げてください。
またOpenJDKのディレクトリを直接入力せず、「%JAVA_HOME%\bin」を入れてJAVA_HOMEにJDKのディレクトリを入れると、今までと同様に運用できる。
Grailsで起動時のポート番号を変更
Grailsでrun-appを実行するとデフォルトではポート番号:8080で起動します。
このポート番号を変更する方法がいくつかあったので整理してみました。
grails> run-app ・・・中略・・・ Grails application running at http://localhost:9090 in environment: development
目次
■application.ymlに記述
application.ymlの冒頭に以下を追加する。
--- server: port: 9090
■起動コマンド実行時にオプションで指定
起動コマンド実行時にportオプションで番号を指定する。
>grails run-app -port 8090
■環境変数で指定
環境変数GRAILS_OPTSに"-Dserver.port"に指定する。
Windows10のpowershellを使ってる場合、set-itemで環境変数に設定できる。
>set-item env:GRAILS_OPTS -value "-Dserver.port=8100" >get-item env:GRAILS_OPTS Name Value ---- ----- GRAILS_OPTS -Dserver.port=8100
IntelliJ IDEAでPlantUMLプラグインをインストールしてリアルタイムにUMLをプレビュー表示する
UMLツールの代表だったastahが有料になってしまったため代替を探していたら、PlantUMLという無料UMLツールを見つけたので紹介します。
PlantUMLを使うことによって以下のようなメリットがあります。
メリット:
目次
PlantUMLプラグインのインストール
IntelliJ IDEAを起動してメニュより「File」→「Settings」→「Plugins」の画面の下部にある「Browse repositories...」を押下します。そこで開いた画面上部の検索ボックスに"PlantUML"と入力すると、"PlantUML integration"というプラグインが出てくるので「install」を押してインストールしましょう。
インストールが完了したら、IntelliJ IDEAを再起動して有効化します。
Graphvizをダウンロード
図の表示にはGraphvizを使用します。以下からサイトにアクセスしてstable版(msiまたはzip)をダウンロードしてきます。
http://www.graphviz.org/download/
ダウンロードしたら解凍して"C:\Program Files (x86)\graphviz-2.38\"のように配置します。
IntelliJ IDEAでGraphvizの設定
メニュより「File」→「Settings」→「Other Settings」を選択すると画面に"PlantUML"のリンクがあるのでクリックします。
「Graphviz dot executable」の入力欄に先ほど配置したgraphviz配下にあるdot.exeのパスを入力します。
例:C:\Program Files (x86)\graphviz-2.38\release\bin\dot.exe
UMLの作成
適当なプロジェクト上で右クリックして「UML xxxx」を選択して作成します。今回はUML Classでファイル名はSampleClassで決定にします。
するとSample.pumlというファイルが作成され、デフォルトで以下が記述されており、右側に図が表示されます。
@startuml Alice -> Bob: Authentication Request Bob --> Alice: Authentication Response Alice -> Bob: Another authentication Request Alice <-- Bob: another authentication Response @enduml
参考サイト
記述方法は以下サイトが分かりやすいです。
http://translate.plantuml.com/ja
PlantUML - クラス図 | プログラマーズ雑記帳
PlantUML - シーケンス図 | プログラマーズ雑記帳
CodeceptionのRESTでsetCookieを実行したい
CodeceptionのRESTでsetCookieをしようとするとsetCookieがないというエラーがでる。こんな感じ。
[RuntimeException] Call to undefined method ApiTester::setCookie
よくよく公式サイトを調べてみると、確かにRESTはsetCookieメソッドが存在しない。
REST - Codeception - Documentation
でもRESTでCookieを設定するテストがあるため、どうにかできないか悩んでアレコレやっていたらHelperに自作メソッドを作るしかない!という感じになりました。
が、、、、これも日本語のサイトでドンピシャな内容が全然ないため、すっごい悩んでたら今さっきやっと解決したので載せておきます。
目次
RESTでsetCookieを呼び出す方法
前提
プロジェクト名: api
yamlにHelperを記述
yamlファイルに以下のようににHelperを記述する。(プロジェクト生成時にデフォルトで記載されている)
このHeplerにsetCookieメソッドを作成する。
$ vim tests/api.suite.yml actor: ApiTester modules: enabled: - REST: url: http://localhost/ depends: PhpBrowser part: Json - \Helper\Api
setCookieメソッドを作成
setCookieメソッドも1から作る必要はありません。getModule()を使えば他モジュールのメソッドを呼び出すことができるようになります。あとはPhpBrowserのものを同じメソッド名でラッパーするだけです。
$ vim tests/support/Helper/Api.php <?php namespace Helper; // here you can define custom actions // all public methods declared in helper class will be available in $I class Api extends \Codeception\Module { function setCookie($name, $value) { $this->getModule('PhpBrowser')->setCookie($name, $value); } }
クッキーをセットしてGET送信
今回実行する受け入れテストは以下のようなもの。
$ vim tests/api/SampleTestCept.php <?php $I = new ApiTester($scenario); $I->wantTo('perform actions and see result'); $I->setCookie('sessionid', 'el4ukv0kqbvoirg7nkp4dncpk3'); $I->sendGET('/'); $I->seeResponseCodeIs(200);
debugモードで実行してリクエストの中身を確認してみます。
$ php codecept run api --debug ・・・中略・・・ SampleTestCept: Perform actions and see result Signature: SampleTestCept Test: tests/api/SampleTestCept.php Scenario -- I set cookie "sessionid","el4ukv0kqbvoirg7nkp4dncpk3" [Cookie Jar] ["sessionid=el4ukv0kqbvoirg7nkp4dncpk3; path=/; httponly"] I send get "/" ・・・中略・・・
念のためnginxのログも事前にログフォーマットで"sessionid"のCookieを表示するように設定しておき、ちゃんと受信できているか確認してみます。
nginxのコンフィグ設定はこんな感じ。
$ sudo vim /etc/nginx/nginx.conf http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" "$cookie_sessionid"'; access_log /var/log/nginx/access.log main;
ログを確認結果。
$ sudo tail /var/log/nginx/access.log 127.0.0.1 - - [14/Feb/2018:16:37:44 +0000] "GET // HTTP/1.1" 200 3770 "-" "Symfony BrowserKit" "-" "el4ukv0kqbvoirg7nkp4dncpk3"