さくらのレンタルサーバにgit-ftp

git-ftpについて簡単な説明

git-ftpは、gitのサブコマンドとして作られたFTPクライアントです。

git-ftpではサーバー側に .git-ftp.log ファイルを設置し、その中に現在サーバー上にアップされているコミットIDを保存しています。
それによりコミットIDでサーバーとリポジトリの差分が比較可能となり、必要なファイルのみアップされる仕組みになっています。

git-ftp でファイルをアップロード

git-ftpを使用する場合、初回アップロードは基本的に init サブコマンドを使用します。

git ftp init -u <ユーザー名> -p <パスワード> --force --syncroot public ftp://<ホスト名><アップ先のパス>

init コマンドによって、 .git-ftp.log ファイルの生成と、ファイルのアップロードが行われます。
この際、既に同名ファイルが存在する場合は上書き保存されてしまうため、アップ先のパスが正しいか不安という場合は catchup サブコマンドを使いましょう。

git ftp catchup -u <ユーザー名> -p <パスワード> ftp://<ホスト名><アップ先のパス>

catchup サブコマンドでは .git-ftp.log ファイルの生成のみ行われます。
意図したパスに .git-ftp.log が生成されていることが確認できたのち、一度 .git-ftp.log を削除し、再度 init サブコマンドを実行すれば確実です。(.git-ftp.log を削除しない場合、サーバーとリポジトリのコミットIDが同じになるためリポジトリ側で改めてコミットする必要がある)

さくらのレンタルサーバに git-ftp でアップロード

アップロード先がさくらのレンタルサーバの場合でもgit-ftpを使用できます。

国外IPアドレスフィルタ

まず、git-ftpに直接関係しませんが、さくらのレンタルサーバには国外IPアドレスフィルタという機能が存在します。

GitHub Actionsなどの自動デプロイでgit-ftpを使用する場合はこちらの設定を変更する必要があるでしょう。

ホワイトリストで許可するIPアドレスを指定する方法があるみたいですが、ざっと調べた感じだとGitHub Actionsの場合はIPアドレスが頻繁に変わるようなので無効にするしかないかもしれません。

オプションの設定

git ftp init -u <ユーザー名> -p <パスワード> --force --syncroot <ローカル側のパス> ftp://<ホスト名><アップ先のパス>
<ユーザー名>FTPユーザー
<パスワード>FTPパスワード
<ローカル側のパス>リポジトリ内のアップロードするファイルのパス(dist など)
<ホスト名>FTPホスト名(おそらく、<ユーザー名>.sakura.ne.jp)
<アップ先のパス>ユーザー用のディレクトリからのパス(/wwwなど)

基本的に難しい設定はありませんが、アップ先のパスだけちょっと引っかかるかもしれません。

GUIのFTPクライアントで接続すると /home/ユーザー名/www/ に接続されるようですが、git-ftpで設定するアップロード先のパスには /home/ユーザー名 は必要ないので注意が必要です。

また、--force を使って対話的な質問を無効にしています。こちらも自動デプロイからgit-ftpを使う場合は設定しておいたほうがよいでしょう。

初回以降のアップロード

初回以降のアップロードには push サブコマンドを使用します。

git ftp push -u <ユーザー名> -p <パスワード> --force --syncroot <ローカル側のパス> ftp://<ホスト名><アップ先のパス>

オプションは init と全く同じなので迷うことはないかと思います。

いまいちよくわからないfigure要素の使い方

HTML5から追加された <figure> 要素について、調べてもいまいちよくわからないのでまとめてみました。
結論から言っていまだにいまいちしっくりきてません。

とりあえず HTML Living Standard と MDN を参考にしています。
https://html.spec.whatwg.org/multipage/grouping-content.html#the-figure-element
https://developer.mozilla.org/ja/docs/Web/HTML/Element/figure

figure 要素とは

HTML Living Standard では以下の特徴を持つものを <figure> 要素として定義しています。

  • 要素内のコンテツに対して、必要に応じてキャプションを持つことができる
  • 自己完結型
  • ドキュメントのメインフローから単一のユニットとして参照される

まずはここから見ていきましょう。

必要に応じてキャプションを持つことができる

キャプションとは説明文とか凡例とかのことを指します。

教科書とかでよくある、写真とか表の下についてるやつですね。

キャプションは <figcaption> 要素で記述します。

<figure>
  <img src="川の画像.jpg" alt="すごく流れの速い川">
  <figcaption>図1:すごく流れの速い川</figcaption>
</figure>

たしかに、キャプションを持つことができる要素というのは今まで <table> しかありませんでした。
あれ、キャプション使うのって表だけじゃなくね? と気づいた結果生まれたのが <figure> 要素なのだと思われます。

自己完結型

自己完結型、というとなんかスタンドの説明みたいですが、自己完結型とはどういう意味でしょうか?
HTML Living Standard の例によると、

段落内の文は自己完結型であるが、文の一部分は自己完結型でない

とのことです。

少し意外ですが、段落だけでなく、その中の1文だけ抜き取った場合でも自己完結型というようです。

まずはここから見ていきましょう。

こんな感じで適当に1文抜き取った場合も自己完結型になるみたいですね。

何も完結していないように見えますが、この場合は「まずはここから見ていきましょう。」という文章を引用して使っていて、前後の文章も成り立っているので自己完結型と言えるようです。
「まずはここから見ていきましょう。」自体の文の意味は関係なく、前後から独立(文の途中じゃない)していることが重要ということでしょうか。

ここらへん、英語のニュアンスとかも関わってきそうで、書いてて正直自信ないです。

ドキュメントのメインフローから単一のユニットとして参照される

横文字が多くてわかりづらいですが、要は本文から参照されるということでしょう。図1のような川で遊ぶのはやめましょう。

みたいな感じですね。

ちなみにこの参照方法について、HTML Living Standard では「上図のような」という相対参照より「図1のような」といった絶対参照を使うことを推奨しています。
理由として、<figure> 要素の特徴に「ページのどこに置いても問題ないし、なんなら別ページに置いても問題ない」というものがあり、「上図のような」という参照の仕方だと場所が限定されてしまうからです。

figure 要素の対象となるもの

イラスト、図、写真、コードスニペットなどが挙げられています。

おそらく、これら以外にも色々なものに使用可能だと思います。
重要なのは、本文から参照されていて、かつ独立したものかどうか、でしょうね。

figure 要素を使うべきかどうか、僕の判断でリスト化してみました。

  • 本文に関わるデータのグラフ → figure要素
  • 説明用のコードスニペット → figure要素
  • メインビジュアルの画像 → figure要素 ではない
  • 引用文 → blockquote要素
  • キャプション付きの引用文 → blockquote要素をfigure要素で囲う(自信ない)
  • ブログ記事のアイキャッチ画像 → figure要素 ではない

アイキャッチ画像はちょっとよく分からんな…
本文から参照するほどの重要な情報が載ってるならfigure要素なのかな。
表紙みたいなものなのでfigure要素ではないと判断しましたが、あなたはどう思いますか?(雑なフリ)

まとめ

こんな感じで一通りfigure要素の定義はみましたが、「完全に理解した!」とは正直言えませんね。
僕としては教科書に出てくるキャプション付きの写真をイメージしてるんですが、そんな解釈でいいのでしょうか?

調べた感じfigure要素自体はGoogleの検索順位には影響しないようなので、迷ったら使わないって選択肢でもいい気がしますけどね。
完全に逃げの姿勢です。
すみません。

font-family で游ゴシックを設定する

font-family で游ゴシックを設定しても Windows の Chrome で見るとかすれて見える問題の対処。

@font-face {
  font-family: 'My Yu Gothic';
  font-weight: normal;
  src: local('Yu Gothic Medium');
}

@font-face {
  font-family: 'My Yu Gothic';
  font-weight: bold;
  src: local('Yu Gothic Bold');
}

body {
  font-family: 'YuGothic'         /* Mac */
             , 'My Yu Gothic'     /* Win Chrome以外 */
             , 'Yu Gothic Medium' /* Win Chrome */
             , sans-serif;
}

body * {
  font-family: inherit;
}

.bold {
  font-weight: bold;
}

Windows の Chrome だと @font-face を使っても src: local('Yu Gothic Bold'); のような太さによる細かい指定が無視されてしまうみたいですが、

  • Chrome では Yu Gothic Medium を太字にしてもそれほど見づらくならない
  • @font-face は Chrome 以外なら Medium や Bold が使える

ということを踏まえて、考えてみました。

游ゴシックフォントデモ

全称セレクタは Safari 用に入れてます。

Ubuntu 18.04 (Bionic Beaver) に MySQL をインストールする

aptmysql-server をインストールします。

$ sudo apt update
$ sudo apt install mysql-server

インストールが終わると自動的に MySQL サーバーが起動するようです。

$ service mysql status
● mysql.service - MySQL Community Server
   Loaded: loaded (/lib/systemd/system/mysql.service; enabled; vendor preset: en
   Active: active (running) since Sun 2019-03-17 07:36:24 UTC; 19s ago
 Main PID: 19007 (mysqld)
    Tasks: 27 (limit: 1152)
   CGroup: /system.slice/mysql.service
           └─19007 /usr/sbin/mysqld --daemonize --pid-file=/run/mysqld/mysqld.pi

ところが root でログインしようとしてもできません。

$ mysql -uroot
ERROR 1698 (28000): Access denied for user 'root'@'localhost'

これは root の認証方法がデフォルトで auth_socket に設定されているためです。
auth_socket についての詳細は https://dev.mysql.com/doc/refman/5.7/en/socket-pluggable-authentication.html で確認できます。

簡単に説明すると、認証方法が auth_socket に設定されている場合は以下のいずれかに一致する時のみログインすることができます。

  • mysql コマンドで指定したユーザ名が、Ubuntu にログイン中のユーザ名と等しい(今回は root
  • mysql.user テーブルにある、 mysql コマンドで指定したユーザ名の行の authentication_string 列の値が Ubuntu にログイン中のユーザ名と等しい

つまり Ubuntu 上で root ユーザになってからログインすればよいということなので、sudo を使ってログインします。

$ sudo mysql
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.25-0ubuntu0.18.04.2 (Ubuntu)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

ログインできました。

mysql.user テーブルを確認すると確かに auth_socket になっています。

mysql> select User, plugin, authentication_string from mysql.user;
+------------------+-----------------------+-------------------------------------------+
| User             | plugin                | authentication_string                     |
+------------------+-----------------------+-------------------------------------------+
| root             | auth_socket           |                                           |
| mysql.session    | mysql_native_password | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| mysql.sys        | mysql_native_password | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| debian-sys-maint | mysql_native_password | *D7714B61633694B96C8A02C2486C20B8ADBEFE53 |
+------------------+-----------------------+-------------------------------------------+
4 rows in set (0.00 sec)

新しく作成したユーザの認証方法はデフォルトで mysql_native_password になるようです。

mysql> CREATE USER newuser IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.00 sec)

mysql> select User, plugin, authentication_string from mysql.user;
+------------------+-----------------------+-------------------------------------------+
| User             | plugin                | authentication_string                     |
+------------------+-----------------------+-------------------------------------------+
| root             | auth_socket           |                                           |
| mysql.session    | mysql_native_password | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| mysql.sys        | mysql_native_password | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| debian-sys-maint | mysql_native_password | *D7714B61633694B96C8A02C2486C20B8ADBEFE53 |
| newuser          | mysql_native_password | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
+------------------+-----------------------+-------------------------------------------+
5 rows in set (0.00 sec)

root の認証方法を変更する

root の 認証方法を auth_socket から変えたい場合は ALTER USER 文を使います。

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
Query OK, 0 rows affected (0.00 sec)

変更できました。

mysql> select User, plugin, authentication_string from mysql.user;
+------------------+-----------------------+-------------------------------------------+
| User             | plugin                | authentication_string                     |
+------------------+-----------------------+-------------------------------------------+
| root             | mysql_native_password | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
| mysql.session    | mysql_native_password | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| mysql.sys        | mysql_native_password | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| debian-sys-maint | mysql_native_password | *D7714B61633694B96C8A02C2486C20B8ADBEFE53 |
| newuser          | mysql_native_password | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
+------------------+-----------------------+-------------------------------------------+
5 rows in set (0.00 sec)

配列から任意の数の組み合わせをすべて求める

配列 [1,2,3,4,5] からいずれか 2 つ(重複なし)を取得する時の例。

(function() {
  var base = [1,2,3,4,5];
  var num = 2;

  var combi = get_combi(base, num);
  console.log(combi);
})();

function get_combi(base, num, ary = [], idx = 0) {
  var result = [];
  for (var i = idx; i <= base.length - num; i++) {
    var newary = ary.concat(base[i]);
    if (num > 1) {
      var r = get_combi(base, num-1, newary, i+1);
      Array.prototype.push.apply(result, r);
    } else {
      result.push(newary);
    }
  }
  return result;
}

簡単にできるかと思ったら意外と難しくて2日間頭を悩ませました。
組み合わせの数が膨大になるとメモリがクラッシュするっぽいので改善の余地ありです。
いやー、再帰は頭が死ぬのであまり使いたくないですね。