Luxeritasバージョンアップに伴うパッチ作成方法

Contents

なぜそんな説明をするのか?

そろそろLuxeritasからの移行を考えているからです。公開した以上どこかでメンテナンスをやめるなら、引き継ぎ可能な状態にしようという意味合いです。

どうして移行したいのか?

改変パッチの配布が面倒だからです。配布物に含まれるコードはGPLなのにminifyしたソースしか含んでいなかったり、各ファイルのライセンスが明確ではありません。通常GPLならminifyする前のソースを要求し、そのソースは再配布も堂々とできるのですが、これだけしっかり配布している中それらソースをどこにも置いていません。サイトを読む限りGPLについても独自の見解をお持ちのようで、弁護士を頼んで云々とあり、正直あんまり関わりたくありません。

本来であればパッチ配布などという形態にしなくても、gitリポジトリごとどこかに置いてもらえば、こちらもフォークして修正して公開できるわけです。あとはプルリクエスト出したりと健全な活動で取り込まれれば私の作業はなくなるし、リジェクトされても他の人がフォークしたものに取り込むのは容易なわけで、いずれにしても私の作業はかなり楽になります。極めつけが先のminifyソースなのですが…これは実際の作業で実感してもらうべきですね。

Luxeritasの改変パッチのLuxeritasバージョンアップ追随方法

準備

環境作成

まずはWordPressのデバッグ環境作ります。起動したらそのままサイトを構築します。

Luxeritas 3.15.0.3をインストール

管理画面からインストールします。

ローカルgitリポジトリを作成

$ cd wordpress/wp-content/themes/luxeritas
$ sudo chown -R $USER:$(id -gn) .
$ git init
$ git add .
$ git commit -m 'initial commit'
$ sudo chown -R www-data:www-data .

Luxeritasテーマを有効にする

有効にしたらどこでもいいのでサイトを表示する

branchを切ってファイル名を入れることができるパッチを当ててcommitする

$ sudo chown -R $USER:$(id -gn) .
$ git clean -df . # キャッシュファイルを削除
$ git branch luxeritas-3.15.0.3_plus_filename
$ git checkout luxeritas-3.15.0.3_plus_filename
$ gzip -dc (パッチ格納フォルダ)/luxeritas-3.15.0.3_plus_filename.patch.gz | patch -p1
$ git add .
$ git commit -m 'パッチ完成'
$ sudo chown -R www-data:www-data .

ファイル名が入れられるか実際にテストする

masterに戻して新しいbranchを切って言語を追加するパッチを当ててcommitする

$ sudo chown -R $USER:$(id -gn) .
$ git clean -df . # キャッシュファイルを削除
$ git checkout master
$ git branch luxeritas-3.15.0.3_plus_extra_languages_01
$ git checkout luxeritas-3.15.0.3_plus_extra_languages_01
$ gzip -dc (パッチ格納フォルダ)/luxeritas-3.15.0.3_plus_extra_languages_01.patch.gz | patch -p1
$ git add .
$ git commit -m 'パッチ完成'
$ sudo chown -R www-data:www-data .

言語が追加されているか実際にテストする

masterに戻す

$ sudo chown -R $USER:$(id -gn) .
$ git clean -df . # キャッシュファイルを削除
$ git checkout master
$ sudo chown -R www-data:www-data .

ちなみにこの状態で、各パッチと同じ効果を持つパッチファイルは以下のように作成できます。

$ git diff master luxeritas-3.15.0.3_plus_filename | gzip >luxeritas-3.15.0.3_plus_filename.remake.patch.gz
$ git diff master luxeritas-3.15.0.3_plus_extra_languages_01 | gzip >luxeritas-3.15.0.3_plus_extra_languages_01.remake.patch.gz

minifyされたファイルに変更があるバージョンアップに追従する

3.15.0.3→3.16.0のバージョンアップが該当します。masterブランチなのでそのまま3.16.0にバージョンアップします。

Luxeritas 3.16.0をインストール

今回は余計なファイルを作らないようにコマンドを叩いてインストールします。

$ sudo chown -R $USER:$(id -gn) .
$ git clean -df . # キャッシュファイルを削除
$ rm -r *
$ cd ..;unzip (Luxeritas格納フォルダ)/luxeritas-3.16.0.zip;cd luxeritas
$ git add .
$ git commit -m 'update 3.16.0'
$ sudo chown -R www-data:www-data .

簡単な動作確認

luxeritas-3.16.0_plus_filenameブランチの作成

$ sudo chown -R $USER:$(id -gn) .
$ git clean -df . # キャッシュファイルを削除
$ git branch luxeritas-3.16.0_plus_filename
$ git checkout luxeritas-3.16.0_plus_filename

luxeritas-3.15.0.3_plus_filenameブランチのマージ→失敗

$ git merge luxeritas-3.15.0.3_plus_filename
Auto-merging languages/admin/luxeritas-ja-luxe-blocks.json
Auto-merging js/luxe-blocks.js
CONFLICT (content): Merge conflict in js/luxe-blocks.js
Automatic merge failed; fix conflicts and then commit the result.
$

このjs/luxe-blocks.jsがminifyされたファイルで、内容を部分引用すると、こんな感じのファイルになっています。

/*! Luxeritas WordPress Theme - free/libre wordpress platform
 *
 * @copyright Copyright (C) 2015 Thought is free.
 * @link https://thk.kanzae.net/
 * @license http://www.gnu.org/licenses/gpl-2.0.html GPL v2 or later
 * @author LunaNuko
 */
/*!
  Copyright (c) 2017 Jed Watson.
  Licensed under the MIT License (MIT), see
  http://jedwatson.github.io/classnames
*/!function(o){"use strict";var n={};function i(e){if(n[e])return n[e].exports;var t=n[e]={i:e,l:!1,exports:{}};return o[e].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.m=o,i.c=n,i.d=function(e,t,o){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esMod",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esMod)return t;var o=Object.create(null);if(i.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)i.d(o,n,function(e){r...

ライセンスの記述用コメントが12行あるのですが(GPLなのにminifyだけかいーと思いつつ)、12行目の末尾にはminifyされた長い1行コードがくっついています。つまり全体で1行しかないソースコードなのです。パッチを元にした差分は行単位に抽出されるので、1行がこれだけ長いと、もう差分としての意味をなしません。まずはコンフリクトしてしまったマージの途中経過は破棄しておきます。

$ git reset --hard

ではザックリどうするのか説明すると、まずはminifyされたコードをとりあえず読める形にフォーマットします。その上で最初に書いた差分コードを人力で適用するのです。適用したら今度は自分で再度minifyします。では実際にやってみます。

luxeritas-3.15.0.3_plus_filenameブランチのコミットの分割

最初に行うのは元となるブランチでの分割です。まずは別の名前のブランチを作って、minifyされたコードのコミットとそれ以外のコードのコミットに分けます。

$ git checkout luxeritas-3.15.0.3_plus_filename
$ git branch luxeritas-3.15.0.3_plus_filename.1
$ git checkout luxeritas-3.15.0.3_plus_filename.1
$ git reset HEAD~
$ git add js/luxe-blocks.js
$ git commit -m 'minified patch'
$ git add .
$ git commit -m 'not minified patch'

次にさらに別のブランチを作って、変更前のminifyされたコードを読める形にフォーマットにしただけのコミットを作ります(nodejsが必要です)。

$ git branch luxeritas-3.15.0.3_plus_filename.2
$ git checkout luxeritas-3.15.0.3_plus_filename.2
$ git reset --hard HEAD~
$ git branch luxeritas-3.15.0.3_plus_filename.3
$ git reset --hard HEAD~
$ npx js-beautify -s 2 js/luxe-blocks.js >js/luxe-blocks.js.new
$ mv js/luxe-blocks.js.new js/luxe-blocks.js
$ git add .
$ git commit -m 'npx js-beautify -s 2 js/luxe-blocks.js'
$ git checkout luxeritas-3.15.0.3_plus_filename.3
$ npx js-beautify -s 2 js/luxe-blocks.js >js/luxe-blocks.js.new
$ mv js/luxe-blocks.js.new js/luxe-blocks.js
$ git add .
$ git commit -m 'npx js-beautify -s 2 js/luxe-blocks.js'

作成してできた2つのブランチの差分が実際に私が編集した中身です。

$ git diff luxeritas-3.15.0.3_plus_filename.2 luxeritas-3.15.0.3_plus_filename.3
diff --git a/js/luxe-blocks.js b/js/luxe-blocks.js
index ee7b1cb..3ed89d7 100644
--- a/js/luxe-blocks.js
+++ b/js/luxe-blocks.js
@@ -4460,6 +4460,10 @@ function() {
       language: {
         type: "string",
         default: ""
+      },
+      filename: {
+        type: "string",
+        default: ""
       }
     },
     supports: {
@@ -4503,6 +4507,7 @@ function() {
     },
     edit: function(e) {
       var t = e.attributes,
+        t0 = t,
         o = e.setAttributes,
         n = e.className,
         i = t.content,
@@ -4524,7 +4529,17 @@ function() {
         options: l,
         onChange: function(e) {
           return o({
-            language: e
+            language: e,
+            filename: t0.filename
+          })
+        }
+      })), t.push(a(s.TextControl, {
+        label: c("File Name", "luxeritas"),
+        value: t0.filename,
+        onChange: function(e) {
+          return o({
+            language: r,
+            filename: e
           })
         }
       })), e = a("p", null, c("* The theme can be changed from the CSS tab of Luxeritas menu.", "luxeritas")), [a(u.InspectorControls, {
@@ -4546,13 +4561,24 @@ function() {
     },
     save: function(e) {
       var t = e.attributes,
+        t0 = t,
         e = t.content,
         t = t.language.replace("highlight_", "");
-      return "" != t ? a("pre", {
-        className: "line-numbers language-" + t
-      }, a("code", {
-        className: "language-" + t
-      }, e)) : a("pre", null, a("code", null, e))
+      var obj;
+      if ("" != t) {
+        var pre = {
+          className: "line-numbers language-" + t
+        };
+        if (t0.filename) {
+          pre["data-label"] = t0.filename
+        }
+        obj = a("pre", pre, a("code", {
+          className: "language-" + t
+        }, e))
+      } else {
+        obj = a("pre", null, a("code", null, e))
+      }
+      return obj
     }
   })
 }(),
$ 

minifyされた場合、必ずしも変更の前後でこのような差分が取れるとは限りませんが、小規模な場合は運が良ければこのように復元可能です(luxeritas本体の場合は、変更量が多すぎ、変数名などが変わってしまい、途中から未変更の部分が差分になり、現実的に復元不可能になります)。復元出来たので、この差分のコミットを作ります。

$ git checkout luxeritas-3.15.0.3_plus_filename.2
$ git branch temp
$ git reset --hard luxeritas-3.15.0.3_plus_filename.3
$ git reset --soft temp
$ git branch --delete temp
$ git commit -m 'minifiedされたソースの修正'

後は再度minifyしておきます。

$ npx -p uglify-js uglifyjs js/luxe-blocks.js >js/luxe-blocks.js.new
$ mv js/luxe-blocks.js.new js/luxe-blocks.js
$ (git show HEAD:js/luxe-blocks.js | head -12;cat js/luxe-blocks.js) >js/luxe-blocks.js.new # ライセンス部分を残す
$ mv js/luxe-blocks.js.new js/luxe-blocks.js
$ git add .
$ git commit -m 'npx -p uglify-js uglifyjs js/luxe-blocks.js'

これでminifyされたファイルの差分を、beautifyする差分と実際の差分とminifyする差分に分割出来ました。後はminifyされていなかった差分を追加するだけです。

$ git cherry-pick luxeritas-3.15.0.3_plus_filename.1

これで、luxeritas-3.15.0.3_plus_filenameを人間が分かる差分に分割できました。分割前の差分とdiffを取って確認します。

$ git diff luxeritas-3.15.0.3_plus_filename  luxeritas-3.15.0.3_plus_filename.2
$ 

差分はありません。では.2のブランチを本物にします。

$ git branch --delete --force luxeritas-3.15.0.3_plus_filename luxeritas-3.15.0.3_plus_filename.1 luxeritas-3.15.0.3_plus_filename.3
$ git branch -m luxeritas-3.15.0.3_plus_filename.2 luxeritas-3.15.0.3_plus_filename
$ git log
commit e905bbbb791e5cdb96de498a80ad917e0df83b3c (HEAD -> luxeritas-3.15.0.3_plus_filename)
Author: Your Name <you@example.com>
Date:   Wed May 26 21:07:15 2021 +0900

    not minified patch

commit e2d55084a441f41106f1ed05426aa6c6cdc6c50e
Author: Your Name <you@example.com>
Date:   Wed May 26 22:55:39 2021 +0900

    npx -p uglify-js uglifyjs js/luxe-blocks.js

commit 7d8976ae390a81f672d2660e1082de56eb380cef
Author: Your Name <you@example.com>
Date:   Wed May 26 22:53:51 2021 +0900

    minifiedされたソースの修正

commit 12b625799cee68f4f793fbbc45fc9b3fc2da54c3
Author: Your Name <you@example.com>
Date:   Wed May 26 22:38:25 2021 +0900

    npx js-beautify -s 2 js/luxe-blocks.js

commit 90fe59f25fad19c09af833bec3bc16ffcc22dd5f
Author: Your Name <you@example.com>
Date:   Wed May 26 12:48:55 2021 +0900

    初期コミット
$ 

分割完了です。

luxeritas-3.16.0_plus_filenameへの手動マージ

ではサクッとluxeritas-3.16.0_plus_filenameに移動し、beautifyします。

$ git checkout luxeritas-3.16.0_plus_filename
$ npx js-beautify -s 2 js/luxe-blocks.js >js/luxe-blocks.js.new
$ mv js/luxe-blocks.js.new js/luxe-blocks.js
$ git add .
$ git commit -m 'npx js-beautify -s 2 js/luxe-blocks.js'

試しにチェリーピック

$ git cherry-pick luxeritas-3.15.0.3_plus_filename~2
Auto-merging js/luxe-blocks.js
CONFLICT (content): Merge conflict in js/luxe-blocks.js
error: 7d8976aを適用できませんでした... minifiedされたソースの修正
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
$ 

案の定失敗したのでもとに戻して…

$ git reset --hard

手動で差分を反映した結果がコレ。

$ git diff
diff --git a/js/luxe-blocks.js b/js/luxe-blocks.js
index 4168294..de9ae2c 100644
--- a/js/luxe-blocks.js
+++ b/js/luxe-blocks.js
@@ -4465,6 +4465,10 @@ function() {
       linenumber: {
         type: "boolean",
         default: !0
+      },
+      filename: {
+        type: "string",
+        default: ""
       }
     },
     supports: {
@@ -4508,6 +4512,7 @@ function() {
     },
     edit: function(e) {
       var t = e.attributes,
+        t0 = t,
         o = e.setAttributes,
         n = e.className,
         i = t.content,
@@ -4530,7 +4535,17 @@ function() {
         options: a,
         onChange: function(e) {
           return o({
-            language: e
+            language: e,
+            filename: t0.filename
+          })
+        }
+      })), t.push(c(u.TextControl, {
+        label: s("File Name", "luxeritas"),
+        value: t0.filename,
+        onChange: function(e) {
+          return o({
+            language: r,
+            filename: e
           })
         }
       })), e = c("p", {
@@ -4569,16 +4584,27 @@ function() {
     },
     save: function(e) {
       var t = e.attributes,
+        t0 = t,
         o = t.content,
         e = t.linenumber,
         t = t.language.replace("highlight_", "");
-      return "" != t ? c("pre", !0 === e ? {
-        className: "line-numbers language-" + t
-      } : {
-        className: "language-" + t
-      }, c("code", {
-        className: "language-" + t
-      }, o)) : c("pre", null, c("code", null, o))
+      var obj;
+      if ("" != t) {
+        var pre = !0 === e ? {
+          className: "line-numbers language-" + t,
+        } : {
+          className: "language-" + t
+        };
+        if (t0.filename) {
+          pre["data-label"] = t0.filename;
+        }
+        obj = c("pre", pre, c("code", {
+          className: "language-" + t
+        }, o));
+      } else {
+        obj = c("pre", null, c("code", null, o));
+      }
+      return obj;
     }
   })
 }(),
$

見た目あんまり変わってないように見えますが、行番号の表示/非表示が切り替えられるようになっていたので、そこに影響しない修正に変更しています。

峠は超えたので、気を取り直してコミットして、後は機械的な修正を適用します。

$ git add .
$ git commit -m 'minifiedされたソースの修正'
$ npx -p uglify-js uglifyjs js/luxe-blocks.js >js/luxe-blocks.js.new
$ mv js/luxe-blocks.js.new js/luxe-blocks.js
$ git add .
$ git commit -m 'npx -p uglify-js uglifyjs js/luxe-blocks.js'
$ git cherry-pick luxeritas-3.15.0.3_plus_filename
$ sudo chown -R www-data:www-data .

ファイル名が入れられるか実際にテストする

masterに戻す

$ sudo chown -R $USER:$(id -gn) .
$ git clean -df . # キャッシュファイルを削除
$ git checkout master
$ sudo chown -R www-data:www-data .

luxeritas-3.16.0_plus_extra_languages_01ブランチの作成

$ sudo chown -R $USER:$(id -gn) .
$ git clean -df . # キャッシュファイルを削除
$ git branch luxeritas-3.16.0_plus_extra_languages_01
$ git checkout luxeritas-3.16.0_plus_extra_languages_01

luxeritas-3.16.0_plus_extra_languages_01ブランチのマージ

$ git merge luxeritas-3.15.0.3_plus_extra_languages_01
$ sudo chown -R www-data:www-data .

成功します!

言語が追加されているか実際にテストする

masterに戻してパッチファイルの作成

$ sudo chown -R $USER:$(id -gn) .
$ git clean -df . # キャッシュファイルを削除
$ git checkout master
$ sudo chown -R www-data:www-data .
$ git diff master luxeritas-3.16.0_plus_filename | gzip >luxeritas-3.16.0_plus_filename.remake.patch.gz
$ git diff master luxeritas-3.16.0_plus_extra_languages_01 | gzip >luxeritas-3.16.0_plus_extra_languages_01.remake.patch.gz

minifyされたファイルに変更がないバージョンアップに追従する

続けてminifyがないケースを実施します。

Luxeritas 3.17.0.1をインストール

$ sudo chown -R $USER:$(id -gn) .
$ git clean -df . # キャッシュファイルを削除
$ rm -r *
$ cd ..;unzip (Luxeritas格納フォルダ)/luxeritas-3.17.0.1.zip;cd luxeritas
$ git add .
$ git commit -m 'update 3.17.0.1'
$ sudo chown -R www-data:www-data .

簡単な動作確認

luxeritas-3.17.0.1_plus_filenameブランチの作成

$ sudo chown -R $USER:$(id -gn) .
$ git clean -df . # キャッシュファイルを削除
$ git branch luxeritas-3.17.0.1_plus_filename
$ git checkout luxeritas-3.17.0.1_plus_filename

luxeritas-3.16.0_plus_filenameブランチのマージ

$ git merge luxeritas-3.16.0_plus_filename
$ sudo chown -R www-data:www-data .

minifiedファイルもなく競合もないのであっさり成功します。

ファイル名が入れられるか実際にテストする

masterに戻す

$ sudo chown -R $USER:$(id -gn) .
$ git clean -df . # キャッシュファイルを削除
$ git checkout master
$ sudo chown -R www-data:www-data .

luxeritas-3.17.0.1_plus_extra_languages_01ブランチの作成

$ sudo chown -R $USER:$(id -gn) .
$ git clean -df . # キャッシュファイルを削除
$ git branch luxeritas-3.17.0.1_plus_extra_languages_01
$ git checkout luxeritas-3.17.0.1_plus_extra_languages_01

luxeritas-3.16.0_plus_extra_languages_01ブランチのマージ

$ git merge luxeritas-3.16.0_plus_extra_languages_01
$ sudo chown -R www-data:www-data .

成功します!

言語が追加されているか実際にテストする

masterに戻してパッチファイルの作成

$ sudo chown -R $USER:$(id -gn) .
$ git clean -df . # キャッシュファイルを削除
$ git checkout master
$ sudo chown -R www-data:www-data .
$ git diff master luxeritas-3.17.0.1_plus_filename | gzip >luxeritas-3.17.0.1_plus_filename.remake.patch.gz
$ git diff master luxeritas-3.17.0.1_plus_extra_languages_01 | gzip >luxeritas-3.17.0.1_plus_extra_languages_01.remake.patch.gz

まとめ

これでパッチのバージョンアップ追従方法の解説も完了しました。Luxeritasもお世話にはなっていますが、どこにもこだわりがあるわけではなく、パッチがあるのも機能が足りないからだし、ほんと理不尽な労力だと思います。現状CoCoonが輝いて見えてます。いや眩しすぎて直視できない!