Gitを使用してから、コミットメッセージとその他のビットをJSONペイロードとしてサーバーに送信します。
現在私は持っています:
MSG=`git log -n 1 --format=oneline | grep -o ' .\+'`
MSG=を次のように設定します。
Calendar can't go back past today
それから
curl -i -X POST \
-H 'Accept: application/text' \
-H 'Content-type: application/json' \
-d "{'payload': {'message': '$MSG'}}" \
'https://example.com'
私の実際のJSONには、さらに2つのフィールドがあります。
これは正常に機能しますが、もちろん、アポストロフィを含む上記のようなコミットメッセージがある場合、JSONは無効です。
Bashで必要な文字をエスケープするにはどうすればよいですか?私は言語に精通していないので、どこから始めればよいかわかりません。 '
を\'
に置き換えると、少なくとも私が思うに仕事をするでしょう。
OK、どうしたらいいかわかりました。 Bashはこれを期待どおりネイティブにサポートしますが、いつものように、構文は実際にはあまり推測できません!
基本的に${string//substring/replacement}
はイメージを返すので、使用できます
MSG=${MSG//\'/\\\'}
これをする。次の問題は、最初の正規表現がもう機能しないことですが、それは
git log -n 1 --pretty=format:'%s'
結局、私はそれらを逃れる必要さえありませんでした。代わりに、JSONのすべての 'を\ "に交換しました。さて、あなたは毎日何かを学びます。
Pythonを使用:
このソリューションは純粋なbashではありませんが、非侵襲的であり、Unicodeを処理します。
json_escape () {
printf '%s' "$1" | python -c 'import json,sys; print(json.dumps(sys.stdin.read()))'
}
JSONは標準のpythonライブラリの一部であり、長い間使用されているため、これは非常に最小限のpython依存関係です。
またはPHPを使用:
json_escape () {
printf '%s' "$1" | php -r 'echo json_encode(file_get_contents("php://stdin"));'
}
次のように使用:
$ json_escape "ヤホー"
"\u30e4\u30db\u30fc"
データを適切に引用する方法を心配する代わりに、ファイルに保存し、@
オプションでcurl
が許可する--data
コンストラクトを使用するだけです。 git
の出力がJSON値として使用できるように正しくエスケープされるようにするには、手動で作成するのではなく、jq
などのツールを使用してJSONを生成します。
jq -n --arg msg "$(git log -n 1 --format=oneline | grep -o ' .\+')" \
'{payload: { message: $msg }}' > git-tmp.txt
curl -i -X POST \
-H 'Accept: application/text' \
-H 'Content-type: application/json' \
-d @git-tmp.txt \
'https://example.com'
-d @-
;を使用して標準入力から直接読み取ることもできます。読者がgit
から読み取り、curl
でアップロードする正しいペイロードメッセージを生成するパイプラインを構築するための演習として、それを残します。
(ヒント:jq ... | curl ... -d@- 'https://example.com'
)
jq
これを行うことができます。
軽量、無料、Cで書かれたjq
は、 GitHub で15,000個以上の星を使用したコミュニティサポートを幅広く楽しんでいます。個人的には、毎日のワークフローで非常に迅速で便利だと感じています。
jq -aR . <<< '猫に小判'
説明する、
-a
は「ascii出力」を意味します-R
は「生の入力」を意味します.
は「JSONドキュメントのルートを出力する」ことを意味します<<<
は文字列をstdinに渡します(bashのみ?)OPで指定されたコード例を修正するには、jqをパイプ処理します。
MSG=`git log -n 1 --format=oneline | grep -o ' .\+' | jq -aR .`
私はこれに遭遇したときに、JSONを使用して転送するために、Bashで文字をエスケープしようとしていました。実際には、より大きな エスケープする必要がある文字のリスト があることがわかりました。特に、自由形式のテキストを処理しようとしている場合です。
便利だと思った2つのヒントがあります。
${string//substring/replacement}
このスレッドで説明されている構文。結果として私が思いついたBashの置き換えは次のとおりです。
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\\/\\\\} # \
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\//\\\/} # /
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\'/\\\'} # ' (not strictly needed ?)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\"/\\\"} # "
JSON_TOPIC_RAW=${JSON_TOPIC_RAW// /\\t} # \t (tab)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//
/\\\n} # \n (newline)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^M/\\\r} # \r (carriage return)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^L/\\\f} # \f (form feed)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^H/\\\b} # \b (backspace)
この段階では、(明らかに)必要なUnicode文字を正しくエスケープする方法を考え出していません。これを解決したら、答えを更新します。
git log -n 1 --format=oneline | grep -o ' .\+' | jq --Slurp --raw-input
上記の行は私のために機能します。 jq
ツールについては https://github.com/stedolan/jq を参照してください
私はそのようなものを見つけました:
MSG=`echo $MSG | sed "s/'/\\\\\'/g"`
最も簡単な方法は、 jshon 、コマンドラインツールを使用してJSONを解析、読み取り、作成することです。
jshon -s 'Your data goes here.' 2>/dev/null
これは、バックスラッシュ(\
)、二重引用符("
)および制御文字U+0000
からU+001F
:
$ echo -ne "Hello, ????\n\tBye" | \
Perl -pe 's/(\\(\\\\)*)/$1$1/g; s/(?!\\)(["\x00-\x1f])/sprintf("\\u%04x",ord($1))/eg;'
Hello, ????\u000a\u0009Bye
コミット後にコミットメッセージを含むメッセージを送信するという同じ考えがありました。最初に私は似たようなことを試みましたが、ここではautorとしてでした。しかし、後に、より優れたシンプルなソリューションが見つかりました。
メッセージを送信するphpファイルを作成し、wgetで呼び出します。フック/受信後:
wget -qO - "http://localhost/git.php"
git.phpで:
chdir("/opt/git/project.git");
$git_log = exec("git log -n 1 --format=oneline | grep -o ' .\+'");
そして、JSONを作成し、PHPスタイルでCURLを呼び出します