Develop
ソフトウェア開発作業全般
Other
ASCIIFlow: 画面構成図などの作成でテキストなので便利かもしれない。
Project
- オープンソースの開発プロジェクトではコーディング以外のドキュメント化やサポートなどの貢献が特に重要 - GIGAZINE
- オープンソースプロジェクトを有料化して月収100万円の事業家に転身したソフトウェア開発者 - GIGAZINE
名簿付きの寄付
- Vim: https://vim-jp.org/vimdoc-ja/sponsor.html
- Vim (list): https://www.vim.org/sponsor/hall_of_honour.php
- KDE: https://relate.kde.org/
- KDE (list): https://relate.kde.org/civicrm/profile?gid=18&search=0
- Conservancy (list): https://sfconservancy.org/sponsors/
- Conservancy: https://sfconservancy.org/donate/
Kanboard
クローズ時に自動移動
[Configure project]-[Automatic actions]
- action=[Move the task to another project]
- Event name=Closing a task
- Column=Done
- Project=
これでDoneをclose時にアーカイブ用のプロジェクトに移動できる。
Communication
Skype
すべてのエモーティコンのリストはありますか? - Microsoft サポート
Skyepで使用可能な絵文字の一覧。
Slack
チャンネル
一覧表示
[ホーム]-[チャンネル]-[管理する]-[チャンネル一覧] でチャンネル一覧を閲覧可能。
Confluence
ページの中で、 [作成] を選んでページを作ると、階層が勝手にできて、子ページへのリンクもできる。
ショートカットキー
キーボード ショートカット
https://ja.confluence.atlassian.com/doc/keyboard-shortcuts-139456.html
エディタ
- {code: コードブロック (https://shinkufencer.hateblo.jp/entry/2018/10/17/235900 Confluenceのエディタは { でマクロのショートカット入力ができるし、{ code } でコードスニペット領域が作れる)。
ブロック フォーマット
Windows | 操作 | Mac |
---|---|---|
Ctrl + 0 | Paragraph | ⌘+ 0 |
Ctrl+ (1 ~ 6) | (選択した番号の)見出しレベル | ⌘+ (1—6) |
Ctrl + 7 | Preformatted | ⌘+ 7 |
Ctrl + 8 | Quote | ⌘+ 8 |
Ctrl + Shift + B、または
* + Space |
箇条書きリストを追加 | ⌘ + Shift + B、または
* + Space |
Ctrl + Shift + N、または
# + space |
番号付きリストを追加 | ⌘ + Shift + N、または
# + space |
Ctrl + Shift + S | Strikethrough | ⌘ + Shift + S |
Ctrl + Shift + | Subscript | ⌘ + Shift + , |
Ctrl + Shift + | Superscript | ⌘ + Shift + . |
Ctrl + Shift + M | Monospace | ⌘ + Shift + M |
Ctrl + \ | Clear formatting | ⌘ + \ |
豊富なフォーマット
CTRL + Shift + V
サファリのみ:Ctrl + Shift + Alt + V |
書式設定なしでテキストを貼り付け | ⌘ + Shift + V
Safari のみ:⌘ + Shift + Option + V |
Ctrl+M | Files and images | ⌘+ M |
Ctrl+K | リンク([リンクの挿入] ダイアログが開く) | ⌘ + K |
Ctrl + Shift + D | マークアップを挿入([マークアップの挿入] ダイアログが開く) | ⌘ + Shift + D |
Ctrl+Shift+A | マクロ([マクロの選択] ダイアログが開く) | ⌘ + Shift + A |
Ctrl + Shift + O | 次のインライン コメントに切り替え | ⌘ + Shift + O |
Ctrl + Shift + L | 前のインライン コメントに切り替え | ⌘ + Shift + L |
CTRL + Shift + Z | インライン コメントを閉じる | ⌘ + Shift + Z |
Ctrl + Shift + I | 表 | ⌘ + Shift + I |
Alt + 上矢印 | 行を上に挿入 | Alt + 上矢印 |
Alt + 下矢印 | 下に行を挿入 | Alt + 下矢印 |
Ctrl + Shift + X | 行を切り取り | ⌘ + Shift + X |
Ctrl + Shift + C | 行をコピー | ⌘ + Shift + C |
Ctrl + Shift + Y | 行を上に貼り付け | ⌘ + Shift + Y |
Ctrl + Shift + ; | 絵文字メニュー | ⌘ + Shift + ; |
CTRL + Shift + V | 書式設定なしで貼り付け | ⌘ + Shift + V |
書式設定なしで貼り付け (Safari) | ⌘ + Shift + Option + V |
オートコンプリート
[] が勝手にリンクになるのが困る。
リンク、ファイル、マクロ、メンション、絵文字のオートコンプリート
オートコンプリートの無効化方法。
プロフィール画像を選択-[設定]-[エディター]-[☑️オートコンプリートの無効化]
ただ、オートコンプリートの丸ごと無効化は、便利な機能がなくなるので不味い。
一時的に回避したい場合、[の直前に何か文字があれば解釈されない。スペース開けて[があるとオートコンプリート扱いになる。
Tool
General
Call tree
kcachegrindだったかな。
kscopeもこれか。
Doxygen+GraphVizで関数コールグラフ
kscope
https:/github.com/ivan0124/Linux-programming/wiki/How-to-use-KScope-to-trace-code
https:/sourceforge.net/projects/kscope/
http:/www.lemis.com/grog/software/kscope.php
cscope
cbrowser/kbrowserというGUIもある。
cscopeの大文字小文字無視検索
http://vim.1045645.n5.nabble.com/how-to-search-with-cscope-ignoring-case-td5715043.html
DBを別にする必要がありそう。
expect
端末の手動操作を自動化するソフト。
* ^と$は使えない。代わりに、\nを使う。
* 文字列の囲みに一重引用符 (') は使えない。二重引用符 (") のみ有効。
* expect文はawkみたいな感じ。
* ただし、expectは注意が必要。最初のexpectにマッチしないと先に進めない。タイムアウトとかするしかない。
expect -c "set timeout 5; spawn cat cat.txt; expect \nFAIL {send pwd/n; expect :; exit}"
https:/linuxjm.osdn.jp/html/expect/man1/expect.1.html
```
sh -eux <<-"EOT"
expect -c "set timeout 5; spawn ssh senooken@senooken-linux; expect :; send ieneko/n; expect aho {send echo aho} +x {send pwd/n}; expect /$; exit"
expect -c "set timeout 5; spawn ssh senooken@senooken-linux; expect :; send ieneko/n; expect + {send pwd/n}; expect /$; exit"
expect -c "set timeout 5; spawn cat cat.txt; expect \nFAIL {send pwd/n; expect :; exit}"
expect -c 'set timeout 10; spawn cat cat.txt; expect "aa F" {set AAA "abc"}; expect FAIL {send "$AAA/n"; expect " "; exit}'
EOT
```
Coding
タイムゾーン
3文字形式は避けたほうが無難。
タイムゾーン名で判定する実装があるので、UTC-9なども避けたほうがいい。
tz databaseのAsia/Tokyoなどの確実性が高い。
Regular Expression
正規表現。重要。覚えにくいが重要なものをメモしておく。
後ろからマッチ。cが置換対象。
Case
/[^c]*$/: cより右端
マッチの前後の挿入
https:/vim.fandom.com/wiki/Power_of_g
:g/GST_.*("/s/^/LOG(INFO) << "DEBUG";/r/
行頭・行末で引っ掛ける。
関数にログ
:%s/([^")]*)/) /([a-z]* /)*{/&/rLOG(INFO) << "/1";/r/g
考慮するケース
double currentTime() const override { return m_element->currentTime(); }
glob
重要。正規表現とは似ているが異なる、パターンマッチング記法 (Pattern Matching Notation)。主に、globで採用されており、ディレクトリー・ファイルのマッチングで使われる。
使用可能な記号は以下3個。以下の3文字は\でエスケープできる。
- ?: 任意の1文字にマッチ。
- *: 任意の0以上の文字にマッチ。
- [: []内の1文字にマッチ。正規表現の各括弧と同じ。ただし、先頭の否定が^ではなく、!。
ファイル名マッチ時には、追加で特殊なルールがある。
.から始まるファイル名へのマッチには、.が必要。つまり、*?は先頭の.にはマッチしない。[!a] のような否定形の各括弧記法も.にはマッチしない。加えて、先頭の[.]もマッチするかは不定(unspecified)。
globで.ファイルを含めたい場合、工夫が必要 (PHP: glob - Manual)。
.[!.]* *
上記のように.ファイルのマッチとそれ以外を指定する必要がある。
.[!.]*
は、.
と..
以外の..
始まりのファイルにマッチする。
.*
を指定すると、.
/..
がマッチするので注意する。最近のシェルは、シェル側で気を利かせているようで、.*
だと.
/..
はマッチしない。
引用符のネスト
シェルやプログラミング言語で、文字列リテラルの表現などで、一重引用符'と二重引用符"を使う。
JSON作成や変数展開などで、これらをネストさせたいことがある。その基本的な考え方を整理する。
交互にしていい場合は簡単二重。引用符内に一重引用符を配置、一重引用符内に二重引用符を配置すればいい。
問題はこれがNGな場合。特にありがちなのが、JSONの生成。JSONの引用符は二重引用符のみ。一重引用符の中だと、二重引用符の変数展開が使用不能。外側を二重引用符にする必要がある。
二重引用符は、内部で変数展開が可能。この都合で、バックスラッシュ\によるエスケープが有効。
基本的な方法。
- 既存の一重/二重引用符などをバックスラッシュでエスケープ。
- 全体を一重/二重引用符で囲む。
何かAwkの本か何かで、基本的な考え方の説明の記載があった気がする。
[{"ke\y":"valu\e"}] を例として考える。
- {"ke\y":"valu\e"}
- エスケープ: {\"ke\\y\":\"valu\\e\"}
- 全体囲み: "{\"ke\\y\":\"valu\\e\"}"
これでOK。また何か考慮不足があればそのときに考える。
ただ、元データに修正が必要なので、そのまま行きたい。ヒアドキュメント的なものが使えるならそれを使うのがいい。
例えば、シェルなら、catコマンドとコマンド置換で生テキストを使える。
echo $(cat <<-'EOT' {"ke\y":"valu\e"} EOT )
.envなどで使える技?いや使えない。.envではシンプルなコマンドしか使えず、ヒアドキュメントは使えない模様。
- How to escape double quotes in JSON - Stack Overflow
- python - How to handle double quotes in JSON value? - Stack Overflow
JSONのvalue部分に適用したい場合。データの二重引用符をバックスラッシュでエスケープする。これはこうするしかない。JSONが二重引用符しか認めないから。
基本的な考え方がある。
- JSON value用に二重引用符"を\"で置換。
- \"がPHP/JavaScriptで二重引用符に扱いにならないように、\を\\に置換。
- JSON項目の二重引用符"を\"で置換。
- 全体を二重引用符"で囲む。
こういう感じ。JSONはawkでも任意の最終データで考える。途中にプログラミング言語でのパースがあるので、それを考慮する必要がある。
ケース変換
javascript - camelCase to kebab-case - Stack Overflow
キャメルケースをチェインケースにしたり、逆にしたりなどケース変換したいことがある。正規表現を駆使して実現する。
encode
【PHP入門】URLエンコードする方法(urlencode) | 侍エンジニアブログ
日本語や記号を他のコードに変換 (エンコード) する方式が何通りかある。把握しておくと役立つ。
- パーセントエンコーディング/URLエンコード: URLで使用不能な文字を%16進数で連結。
- UTF-8
- base64: 全データを「A-Z」「a-z」「0-9」「+」「/」の64文字で表現。文末に=を使うので実質は65文字。
- HTMLエンコード: HTMLで特殊な意味を持つ文字を<などに変換する。
Percent-encoding
- パーセントエンコーディング - Wikipedia
- Percent-encoding (パーセントエンコーディング) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN
- RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
上記文字はエンコードの対象外。
英数変換
string - PHP How to encode all characters with rawurlencode - Stack Overflow
変数名への変換などで、日本語や記号を英数字 [0-9a-zA-Z] に変換したいことがある。
こういう目的だと%エンコーディングが適している。
ただし、一部の記号を許可しているので、自前で変換する。
function encode_all($str) { $hex = unpack('H*', $str); return preg_replace('~..~', '%$0', strtoupper($hex[1])); } $str = 'big ƒüßchen'; print_r(encode_all($str));
Term
紛らわしい用語がある。
- ミドルウェア: 名前通り中間のソフトウェア。DBやアプリケーションサーバーなどが該当。単独で動作が重要なポイント (ミドルウェアとは何か?代表的な製品や使用例とあわせて解説! - サックルMAGAZINE、ミドルウェアとは?アプリ・システム開発との関係・仕組み・役割・具体例を解説【2024年最新版】 | システム幹事)。
- フレームワーク: 単体で動作しない。アプリ開発のテンプレート。Django/Ruby on Rails/Vue.jsなど (【3分ITキーワード】 フレームワークとライブラリの違いは? - ペンタPRO:ペンタセキュリティが提供するセキュリティ情報まとめサイト)。
- ライブラリー: 単体で動作しない。よく使われるコードの集まり。機能単位。jQuery/Numpy/matplotlib/Qtなど。
フレームワークの中にライブラリーも含めていいと思う。
Category
ソフトウェアの分類、ページ分類時に役立つ。
- 言語
- ツール: 静的解析、テスト、文書など。
- フレームワーク
MediaWikiのページ名は全体で固有が条件なので、言語名+分類名でページを作るといい。
例
- PHP language
- PHP tool
- PHP framework
成功時連続継続処理
一度の取得件数の上限が決まっていて、終了・失敗するまで取得を継続したいという処理がそれなりに発生する。
- 処理実行。
- 成功ならA、失敗なら終了。
- 処理実行。
- 成功ならA、失敗なら終了。
こういうパターン。いくつか実装方法があるが、while (true) のパターンが重複がなくてベストだと思う。
/* // 無限ループで終了条件でブレイク while (true) { // 処理実行 if (失敗) { break; } 成功時処理 } // do while do { 処理実行 if (成功時) {} } while (); // for (初期化; 継続判定・終了判定; 成功時式) { 処理実行 } */
do-whileは成功・終了判定を2回書く必要がある。
forだと成功処理を式でしか書けない。成功処理を関数や即時実行関数式などで書くなら悪くはないし、ベストになりえる。
いや、成功時処理内の処理の結果次第で反復の終了条件などが追加で入るならNGになる。なので、やっぱりwhile(true)が無難。コード行数もそんなに変わらない。
これにさらに初回だけ、ヘッダーの取得、書き込み処理などが発生する場合、初回だけループの外でやるのがきれいだろうか?初回処理が2回登場することになるけれど。
offsetなどで初回の判定が反復内でできるから、それで分けるのがいいか?
$offset = 0; while (true) { $currentReturnCode = $service->sendRequest(Raku2Config::API_TYPE_CSV_EXPORT, Raku2Config::CONFIG_API_URL_MULTI_API, [ json_encode([ 'dbSchemaId' => $table_info['dbSchemaId'], 'offset' => $offset, 'limit' => $limit, ]) ]); $response = $service->getApiResultJson(); // 終了条件: 戻り値が成功以外、か応答本体が1行 (ヘッダーのみ) の時。 if (($currentReturnCode !== Raku2Config::EXIT_SUCCESS) || (substr_count($response, "\n") <= 1)) break; // 2回目からはヘッダー除去して書き込み。 $start = strpos($response, "\n") + 1; $flat = FILE_APPEND; if ($offset === 0) { $start = $flag = 0; $path = stream_get_meta_data($fp = tmpfile())['uri']; } file_put_contents($path, substr($response, $start), $flag); $offset += $limit; sleep(3); }
for ($offset = 0; ($currentReturnCode === Raku2Config::EXIT_SUCCESS) && (substr_count($response, "\n") > 1); (function() use (&$offset, $limit, $response) { // 2回目からはヘッダー除去して書き込み。 $start = strpos($response, "\n") + 1; $flag = FILE_APPEND; if ($offset === 0) { $start = $flag = 0; $path = stream_get_meta_data($fp = tmpfile())['uri']; } file_put_contents($path, substr($response, $start), $flag); $offset += $limit; sleep(3); })() ) { $currentReturnCode = $service->sendRequest(Raku2Config::API_TYPE_CSV_EXPORT, Raku2Config::CONFIG_API_URL_MULTI_API, [ json_encode([ 'dbSchemaId' => $table_info['dbSchemaId'], 'offset' => $offset, 'limit' => $limit, ]) ]); $response = $service->getApiResultJson(); }
character
BOM
UTF-8のBOM
\xef\xbb\xbf
この文字を先頭につけるとUTF-8のBOMになる。
Convert
IP/CIDR
// JavaScript /** * サブネットマスクをIPアドレス形式 (x.x.x.x/255.255.255.0) からCIDR形式 (x.x.x.x/24) に変換する。 * @param {string} ipaddress - IPアドレス文字列 (x.x.x.x/x.x.x.x形式)。 */ toCIDR(ipaddress) { const [address, mask] = ipaddress.split('/') const segments = mask.split('.') const CIDR = segments .map((e) => Number(e).toString(2)) .join('') .replace(/0*$/, '').length return address + '/' + CIDR }, /** * サブネットマスクのCIDR形式 (24) をIPアドレス形式 (255.255.255.0)に変換する。 * @param {number} cidr - ciderの数字。 * @return {string} x.x.x.x形式のIPアドレス文字列。 */ cidrToIp(cidr) { const digit = 32 const ip = ('1'.repeat(cidr) + '0'.repeat(digit)).substr(0, digit) return ip .match(/.{8}/g) .map((e) => parseInt(e, 2)) .join('.') },
Algorithm
再帰処理
https://chatgpt.com/c/673d9bfe-2414-800b-9922-f94be6dbe950
配列の配列、オブジェクトのオブジェクトなど、再帰的な構造はけっこう遭遇する。
再帰関数で実装するほかに、スタックで処理する方法がある。
再帰関数のほうが簡単に実装できるが、関数呼び出しのオーバーヘッドがある。ネスト10-100程度くらいなら問題ない。
パフォーマンスや再帰中の細かい制御が必要なら、スタックが有利。ただし、実装がやや複雑。
最初は再帰関数で実装して、後でボトルネックになったらスタックというのも手。
https://chatgpt.com/c/6745228f-8b20-800b-8a41-bdaece8c03f5
再帰関数とスタックの他に、JSONなどの文字列にシリアライズして、文字列処理で対応するという手もある。
JSONPath/XPathなどの方法もあるが、基本的には外部ライブラリーが必要。
シンプルなケース以外は、再帰関数で処理したほうが結局シンプルな感じがする。
Other
コメントの著者名
https://chatgpt.com/c/67469d8d-7e64-800b-b82d-8c74f4e13c08
GNU socialのソースコードのコメントに著者名が大量にあった鬱陶しい。
大規模プロジェクトになると、編集者が膨大になる。VCSに任せて、本文には記載しなくていいと思う。
git blameで行単位で編集者が分かる。
UML
Tool
https://chatgpt.com/c/67441feb-d004-800b-96fd-0d9b04ffc628
- デスクトップ
- StarUML
- ArgoUML
- UMLet
- クラウド
- Lucidchart: 有料。
- Creately: 有料。
- diagrams.net: モデルじゃない。
UmbrelloとModelioはそれらと比較して何がよかったのだっけ?
Umbrello
Problem
altなどの重なり順番、アクティブの下になっちゃう
optの条件が表示されない。
Modelio
クラス図
- 汎化 (generalization): 実線白矢印。継承。
- 実現 (realization): 点線矢印。interfaceの継承。
- 集約: 白ひし形。
- コンポジション: 黒ひし形。子が単体で存在できない場合。親と生存期間が同一の場合。
- 関連: 実線矢印。メソッド内インスタンスなど。
- 依存: 点線矢印。引数やローカル変数、返却値。
Design
Atomic Design
最近のUIのコンポーネントの組み方。UIコンポーネントを粒度に分けて、ディレクトリー分けして流用するという考え方。
- atoms: 原子。これ以上分割不能な最小単位。input/label/buttonなど。
- molecules: 分子。atomsを組み合わせたり、atomsに多少修正したもの。入力フォーム、ナビゲーション、カードなど。
- organisms: 有機体。分子+アルファ。入力フォーム+ヘッダーなど。複数の分子。
- templates: テンプレート。複数の有機体。ヘッダー、メイン、フッターなど。
- pages: ページ。テンプレートを使用したページ。
インターフェイスと抽象クラス
PHPでインターフェイスと抽象クラスを使う #PHP - Qiita
- インターフェイスは、クラスに複数実装できるが、抽象クラスは1つしか継承できない。→不特定のクラスで、共通のメソッドを定義したい場合。
- インターフェイスは、実装のあるメソッドを持つことができないが、抽象クラスは、実装のあるメソッドを持つことができる。→抽象クラスは、複数のクラスの、共通処理の中に、一部違う処理が入る場合、プロパティーが必要な場合などに使用する。
インターフェイス
- メソッド宣言のみ。
- static/constの場合に限定して、メソッド定義、定数もOK。
Config class
- c++ - Best practice for creating a 'global' config class used by numerous components - Software Engineering Stack Exchange
- Best way to provide configuration parameters for objects far away from the starting point - Software Engineering Stack Exchange
- design - Config Class/Struct: Pattern or Anti-Pattern? Alternatives? - Software Engineering Stack Exchange
- json - Best practice/design pattern for working with a config file - Software Engineering Stack Exchange
アプリケーションの設定を管理するクラスの設計方法。いくつか方法があり、議論がある。「Best way to provide configuration parameters for objects far away from the starting point - Software Engineering Stack Exchange」で特によく議論されている。
- シングルトン/グローバル変数: ただし、テストなどで並列アクセスが必要な場合に困ることがあるらしい。
- DI/設定クラス引数: これがよく支持されている。テストしやすいなど。グローバル変数への参照を渡すようなイメージ。ただし、依存性の伝播のように、上から下に設定を渡す際に、関係ない大量の設定を渡すことがあったりする。
2のDIが最近の主流。引数で値渡し相当にすれば、並列アクセス時も無影響。伝播の問題は設計の問題。
メソッドをmain関数で呼び出すことを想定して、必要なものだけ渡るようにして、余計なものは削除する。上位・下位の関係を明確にすれば、渡すだけのパラメーターを排除できる。
do-while/if
複雑なif文と相性がいい。
for whileの無限ループで最後にbreakでも同じか
do { if (true) break; } while(false);
if文が複雑な場合、do-whileで囲んで、breakでスキップできる。gotoに近い。
GoF
基本的に、具象クラスを使わずに、インターフェイスや抽象クラスを使ってインスタンスを生成するというのが、共通する基本パターン。
これにより、いろんなケースに同じコードで対応できる。
Factory Methodパターン
なぜあんなに難しい?Factory Methodパターン - ecbeing labs(イーシービーイング・ラボ)
コンストラクターの代わりに、インスタンスを生成 (工場=factory) となるメソッドを使うから、FactoryMethodパターン。
引数の内容に応じて、異なるクラスを作成する。
ただ、Factory Methodパターンを採用すると、コード量が増えて複雑になる。
複雑でややこしいだけなので、基本的に使わなくてよいと思う。
Naming
camelCase
https://gnusocial.jp/notice/7694551
!it 命名規則のキャメルケース。これ英語前提です。関数名に英語以外を使うと破綻します。
getキーバリュー()みたいな関数の定義。日本語ですると境界がわからなくなるので、getキー_バリューみたいにアンダーバーで区切ったほうが分かりやすい。なるほど…
getMyVariable() vs myVariable()
- naming conventions - PHP methods: getMyVariable() vs myVariable() - Stack Overflow
- Which Coding convention to follow for PHP? - Stack Overflow
getterとsetterの命名規則。
getVar()にするか、Var()にするか。C++だと後者のパターンがあったりする。getを省略できるので、省スペースになる。
ただ、コード補完で探しやすさがちょっと変わる。getを前置したほうがわかりやすいか。
namePrefixed() vs prefixedName()
https://chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85
名詞+修飾語 (形容詞) の場合のメソッドの命名規則。name+修飾語が複数ある場合name+修飾語がいい。オブジェクト指向でnameをオブジェクトとして扱う形に近い。name.methodみたいな。
例えば、nameMax、nameMinのような場合は後ろのほうが都合がいい。ただ、こういう場合はそもそもnameをオブジェクトにしてname.max()、name.min()にしたほうがいいという説がある。
そうではないならば、getPrefixedName()などが自然。getQueryString()など。StringQueryではない。
PHPでは以下のような命名規則が好まれる。
- 動詞+修飾対象=getPrefixedName/isPrefixed()
- 修飾対象+状態/修飾語=prefixdName
getPrefixedNameがいいか。後置修飾にしたいならば、そもそもオブジェクト+メソッドにすることを検討する。
map
連想配列とかハッシュ、オブジェクトなどでキーバリュー形式のデータ構造を扱うことがある。そういう変数の命名規則。
map_[key]_[value]
のような形式にすると、キーとバリューが何を意味するか分かってわかりやすい。
array/foreach
foreach系のfor文ではキーとバリューを変数に格納して反復する。ファイルや配列に対して行うことが多い。
foreach (table as $row => $line)
その際の変数名は、上記のように$row/$lineにすると、行番号と行の値がはっきりしてわかりやすい。
いいえ。これは問題がある。ネストした場合などに命名規則を維持できない。
- 配列、コレクション類: 複数形があるなら複数形。困ったらListの接尾辞。
- 反復時。キーバリュー形式の場合、単数形_key/_value。valueだけの場合、単数形。また、_valueは単数形でもいいかもしれない。
上記の命名規則だとわかりやすい。
$rows = [[]]; foreach ($rows as $row_key => $row_value) { foreach ($row_value as $column_key => $column_value) {} } foreach ($row_list as $row_key => $row) { foreach ($row as $column_key => $column) { } } foreach ($rows as $row_index => $row_value) { foreach ($row_value as $column_index => $column_value) { } }
value部分に単数形を使うと、検索時にkey部分もヒットして、作業しにくいかもしれない。基本はkey/valueの接尾辞がよいと感じる。
もっというなら、接尾辞の文字数が揃うので、keyよりindexのほうがよいかもしれない。ただ、indexは添え字の数字の意味合いが強いので、やっぱりkey/valueでいいか。
Function argument order
関数の引数は入力、変更、出力の順番にする。理由はこの順番で使うから。
https://social.senooken.jp/notice/67270
うーん。今晩は,CODE COMPLETEでC言語の関数の引数の順番を調べたりしていて,勉強時間がないな…
int func(入力,変更,出力)
この順番。理由は,この順番で使うから。
memcpyとかは例外が多い。
x = bの語順からきているからとの憶測がある。
https://okwave.jp/qa/q4202225.html
DB
PDOの真の力を開放する - PHPでデータベースを扱う(3): Architect Note
DBアクセスのモデル化。行をクラスとすると扱いやすい模様。
getterを作ったり、データの妥当性のチェックなどもできる。
select/insert/などはmapperでクラスとDB列名を対応付けて処理する。自前で実装する場合はこういうつくりがいいらしい。
データベース関係のデザインパターンがいくつかある。
- Active Record
- Data Mapper
Active Record pattern
テーブルレコードに対応するクラスを用意して、そのクラス自体にDB操作もさせる。
シンプルだが、複雑な操作が苦手。
エンティティーがテーブルと密接なため、例えばテーブル構造が変わった場合に大量に修正必要。
Ruby on Rails/Laravel+Eloquentなどで採用。
Data Mapper pattern
第14回 DataMapperの使い方 | gihyo.jp
テーブルのレコードをクラスにするのはARと共通。
ただし、DB操作用のクラスを用意してそちらでDB操作する。
その都合、1テーブルに2クラス必要。
User/UserMapperのような対応関係。
2クラス必要だが、テーブル構造が変わった場合でも基本はMapperで吸収できる。
JOIN
Active RecordもData MapperもJOIN時の扱いが一番重要。単一エンティティーしか扱わないならどちらも同じ。
基本はエンティティーのプロパティーに持たせる感じ。
datamapperパターンでjoinする場合、エンティティーの扱いはどうなるの?
`DataMapper`パターンで`JOIN`を行う場合、エンティティの扱いは設計次第ですが、いくつかの注意点があります。`DataMapper`パターンは、データベースのテーブルとエンティティの間にマッピングを行い、エンティティはドメインロジックを持ち、データベースアクセスの責務を持たないことが特徴です。そのため、`JOIN`の処理をどの層で行うかを慎重に設計する必要があります。
以下、`JOIN`を行う際のエンティティの扱いと実装方法について解説します。
- 1. マッパークラスでの`JOIN`実装
`JOIN`を伴う複雑なクエリが必要な場合、マッパーが直接`JOIN`を使って複数テーブルを組み合わせた結果を取得し、それを複数のエンティティとしてマッピングする方法があります。例えば、ユーザーと注文を持つシステムで、ユーザーとその注文を一緒に取得したい場合、`UserMapper`で`JOIN`を行い、結果セットを`User`と`Order`エンティティに分割してマッピングします。
```python
class UserMapper:
def find_user_with_orders(self, user_id):
sql = """
SELECT * FROM users
JOIN orders ON users.id = orders.user_id
WHERE users.id = %s
"""
results = self.db.execute(sql, (user_id,))
user = User(results[0]['user_id'], results[0]['user_name'])
orders = [Order(row['order_id'], row['product_name'], user) for row in results]
user.orders = orders
return user
```
この方法では、1つのSQLクエリで必要なデータをすべて取得し、エンティティのプロパティにそれぞれのデータを設定します。
- 2. リポジトリでの集約
`JOIN`を使わず、各エンティティを個別に取得した後、リポジトリが集約の役割を担う方法もあります。リポジトリが各エンティティの`Mapper`を呼び出し、必要なエンティティ同士を関連付けることで`JOIN`を再現します。例えば、まず`UserMapper`でユーザー情報を取得し、次に`OrderMapper`で該当ユーザーの注文を取得してエンティティ間で関連付けます。
```python
class UserRepository:
def __init__(self, user_mapper, order_mapper):
self.user_mapper = user_mapper
self.order_mapper = order_mapper
def get_user_with_orders(self, user_id):
user = self.user_mapper.find(user_id)
orders = self.order_mapper.find_by_user_id(user_id)
user.orders = orders
return user
```
UserテーブルとOrderテーブルがあって、あるユーザーの注文一覧を取得したい場合を考える。
結局、user.ordersみたいな感じで、エンティティーに外部テーブルのレコードを配列で持たせるつくりになる。
クロス集計する場合は、users[0].orderみたいな感じ。メインのエンティティーのプロパティーに持たせる。フラットじゃないのでちょっと気持ち悪い。が、まあ構造としてこうなるのは順当。
方法として、1回のSQLで取得するか、それぞれのエンティティーを取得してマージするか。1回のSQLでやったほうが当然いい。
Other
1対1-多対多
プログラミング言語でデータの関連付けをすることがある。
1対1の場合、配列、連想配列のキーバリュー形式のデータがぴったり。
多対多の場合。これも配列。二次元配列で基本は0要素目など。
$array[][]
Project
レガシープロジェクトの立て直し
https://chatgpt.com/c/67481a93-adc0-800b-81c4-20d763133002
1. 現状分析
(1) ソフトウェアの動作確認
現在の環境でアプリケーションを動作させる。
どの部分が機能していて、どこが問題かを確認する。
必要であればエラーログを確認する。
(2) 依存関係の調査
アプリケーションのライブラリやフレームワークのバージョンを調査。
サポートが終了しているもの、互換性が失われたものを特定。
(3) コードベースの状態評価
コードの品質 (可読性、設計、テストカバレッジ) を確認。
セキュリティリスクを特定する (例えば、脆弱性が放置されていないか)。
2. 計画立案
(1) ゴール設定
具体的な目標を設定 (例: パフォーマンス改善、保守性向上、セキュリティ強化)。
(2) 優先順位の決定
どの機能を維持し、どの機能を削除または置き換えるか決定。
ユーザーに直接影響を与える部分を優先。
(3) リスク評価とバックアップ
修正に伴うリスクを評価し、現行システムのバックアップを取得。
3. 環境整備
(1) 開発環境のモダナイズ
ローカル環境やコンテナ (Docker) を用意してテストを容易にする。
CI/CD パイプラインの整備。
(2) 依存関係の更新
サポートされていないライブラリやフレームワークをアップグレードまたは置き換える。
(3) セキュリティの確保
古いOSSの脆弱性を修正。
HTTPSの導入、認証強化、インプット検証など。
4. コードのモダナイズ
(1) リファクタリング
レガシーコードをよりモダンで可読性の高いコードに変換。
デザインパターンを適用して保守性を向上。
(2) テストの追加
ユニットテスト、統合テストを導入。
既存の機能が壊れないことを確認するための自動化されたテスト。
(3) フロントエンド/バックエンドの分離
必要に応じてモノリシック構造を分離し、モダンなアーキテクチャ (SPA、Microservices など) に移行。
5. 機能拡張とデプロイ
(1) 新しい機能の追加
必要に応じて、現代のニーズに合った新機能を実装。
(2) 運用環境でのテスト
新しい環境で徹底的にテストし、問題がないことを確認。
(3) 本番環境にデプロイ
ロールバック計画を準備しつつ、安全にデプロイ。
6. 継続的改善
(1) モニタリングの導入
エラーログやパフォーマンスを監視し、迅速に対応できる仕組みを導入。
(2) 定期的なアップデート
フレームワークやライブラリを継続的に更新し、レガシー化を防ぐ。
(3) コミュニティへの貢献
OSSとしての性質を活かし、変更内容をコミュニティに共有することでフィードバックを得る。
このプロセスを通じて、安定した動作を保ちながら徐々に近代化することが可能です。特に、「現状分析」と「環境整備」をしっかり行うことで、後続の作業がスムーズになります。
AI
対話AI
List
【2024年版】対話型AIサービスおすすめ11選を徹底比較!チャットボットとの違い・メリット・課題・選び方なども紹介 - NotePM
いろいろある。
Name | |||
---|---|---|---|
Bing | |||
Perplexity AI | |||
ChatGPT | |||
Google Gemini |
ChatGPT
Plan
Free/Plusの2のプランがある。
Free | Plus | |
---|---|---|
金額 [USD/月] | 0 | 20 |
機能 | 基本 | アーリーアクセス |
エンジン | GPT-4o mini | GPT-4/GPT-4o/GPT-4o mini |
制限 | - | GPT-4oの5倍以上のメッセージ送信 |
その他 | - | データ分析、ファイルアップロード、ビジョン、Webブラウジング |
画像生成 | - | DALL-E |
送信可能なメッセージ数、エンジン、画像生成などが大きな違いだろう。
Account
公式サイトにアカウントの意味の説明がない。しかたないので、ChatGPTに質問。
ChatGPTに会員登録する意味は何ですか?
ChatGPTに会員登録する主な利点はいくつかあります。1. **パーソナライズされた体験**: 登録すると、あなたの好みや過去のやり取りに基づいて、よりカスタマイズされた応答が得られます。
2. **履歴の管理**: 過去のチャット履歴を保存し、いつでも見返すことができるため、情報の確認が簡単になります。
3. **新機能へのアクセス**: 登録ユーザーは新しい機能やアップデートを優先的に利用できる場合があります。
4. **プレミアム機能**: 一部のサービスでは、会員登録をすることで、より高度な機能やサポートが提供されることがあります。
5. **セキュリティとプライバシー**: アカウントを持つことで、データの管理やプライバシーの設定をより細かく調整できます。
興味があれば、ぜひ登録を検討してみてください!他に質問があればお知らせください。
自分の過去の質問の履歴を見れるだけでも便利かも。
方法
質問の分割
https://chatgpt.com/c/673bdc0d-e0e0-800b-a22b-4fa19e64476c
Q. chatgptで質問するとき、連続して質問すると、同じURLで複数の質問が表示される。リロードして質問を分けたほうがいいのか?
A. どちらでも問題ない。が、質問が関連しているなら同じチャットで継続したほうがいい。直前の質問も文脈を考慮できる。完全に話が異なるなら分けたほうが後で整理したり、URLを共有したときにわかりやすい。
感想
2024-11-14 Thu
https://gnusocial.jp/notice/7806505
!it !ai 業務でPHPの開発作業をしていて、ChatGPTを使いだして便利に感じています。検索エンジンの代わりに使っています。
例えば、「laravel eloquentでリレーション先のテーブルの主キー名の取得方法は?」と質問します。
https://chatgpt.com/c/67354314-fbdc-800b-a4e4-65f96d1a8fb2
getRelatedというややマニアックなメソッドを教えてくれます[eloquent getrelated] で検索してもなかなかたどり着けないです。
こういう検索エンジンで検索しにくい質問で便利だなと思います。
検索エンジンで検索すると、的外れな情報も大量にヒットします。対話AIはそのごみの混ざった検索結果を分析した結果をコンパクトに返してくれます。対話AI使わなくても、検索エンジンで時間かければわかりますが、大幅に時間短縮できます。
大量の凡人健常者が取り組んだ方法論として決まりきったものは、記憶の問題、ただの神経衰弱です。こういうのを検索エンジンの改良版としてAIに任せるのはいい使い方だと思います。
個人的に、ただの知識、事実は重要度高くないと思いますが、一般社会では評価する側の頭が悪いので、これが重宝されます。
同僚や先輩に聞くより対話AIのほうがよほど頭いいです。話すことないです。聞くほうが時間の無駄なので。凡人はどんどん要らなくなります。
一方、私みたいなキチガイのデータは少ないので、検索エンジンやAIに聞いても出てこないです。世界で自分だけのオリジナルに専念するのがたぶんいいです。
2024-11-19 Tue
https://gnusocial.jp/notice/7867350
!ai ChatGPTが検索エンジンの改良版としてやっぱり便利。さっきこういう質問しました。
phpのメソッド名で、英単語の修飾語は前と後ろどちらがいい?例えば、namePrefixed()とprefixedName()のどちらがいい? https://chatgpt.com/c/673bd358-3dc8-800b-8ec9-d745cc0eba85
私はこのレベルの細かい疑問がすぐ浮かぶのです。これを人間にきくと、頓珍漢な回答だったり、そもそも回答してもらえないし、何ならこういう質問した私がなぜかキチガイ扱いされて、微妙な雰囲気になって、質問できなくなって、ストレスが溜まって、居づらくなって早期退職になるんです。意味不明です。ただの質問にお気持ちの配慮とか面倒なので。
この間、 @yuriha に突っ込まれた件も、たぶん対話AIとお互い会話したほうが有意義だったんじゃないかとすら思います。相手も私に突っ込む前に対話AIと会話したほうが自分の主張の自己矛盾、頓珍漢さに気づけたんじゃないかとすら思えます。私が突っ込んでまーた私がキチガイ扱いされるのも回避されます。対話AIからの客観的な指摘なら、同じ内容であっても、キチガイの私が言うより納得しやすいでしょう?同じ内容なら対話AIのほうが凡人健常者にとっては、信じ込みやすいでしょ?
対話AIだとお気持ちの配慮いらないし、当たり前ですけど、キチガイ扱いされることもないので、快適です。元々対話AIには懐疑的でしたが、どちらかというと私のようなキチガイが凡人健常者の知識を拝借するためにあるような印象を持ちます。
検索エンジンでも調べることはできますが、めちゃくちゃ時間かかるんです。自分で複数の意見をみつけて、頭の中で比較検討して整理するので。これを一瞬でやってくれるのが楽。途中のデータ整理、目視は単純作業に近いのです。他のことに頭使えます。
もはや技術とか、ただの暗記の神経衰弱は別にいらないです。一般企業の上長とか、士業のように、単純知識でマウント取るタイプの仕事はこれで確かに駆逐されます。どうせ対話AIのほうが賢いのだから。知識量で勝てるわけないです。全世界の情報の集積結果なんだから。
凡人健常者の知識を拝借して、世界でだれにも真似できないキチガイ部分に専念できます。GNU socialの開発もこれでいけると思います。
VCS
List
Comparison of issue-tracking systems - Wikipedia https://en.wikipedia.org/wiki/Comparison_of_issue-tracking_systems
BTS。GitHubみたいな。PHP製の以下がよさそう。
- Tuleap
- Phabricator/Phorge: 共用サーバー不能。
- MantisBT
- FusionForge
- GLPI
- Faveo Helpdesk
- sourcehut - the hacker's forge: Python製。FSF推奨。
- Fossil
VCSとの統合状況がまちまち。
phorgeがダメだったので、Mantis/Fossil/sourcehutあたりが共用サーバーで検討可能か。
https://chatgpt.com/c/674f8938-8590-800b-9a4c-f1ec04fc5869
他に以下がある。
- Gitea
- Cgit
- Gitlab
- SourceHut: Python
- GitBucket: Java
Gitlabは共用サーバーで可能なのか?無理。cgitの他、gogsもある?
CGIで利用可能なもの。
- Cgit: gitの出力を見れるだけ。issueはない。
- Gitweb: cgit同様。
- ViewGit:
- Kallithea: 有力。Kallithea。WSGI。CGI未対応。
他に。
- rhodecode: CGIではない。Python+WSGI
- Category:Project management software - Wikipedia
「Pythonは人気の言語です。しかし、その割にPythonが気軽に利用できるレンタルサーバーは少ない感じがします。何故、レンタルサーバーはPythonの利用に消極的なのですか? - Quora」にあるように、WSGIをCGIにすることもできるがいまいちらしい。
他。
https://chatgpt.com/c/67546eda-20ac-800b-b37f-7e8954c128f5
- GNU Savannah/savane
- Bugzilla: 課題管理のみ。
- Trac: CGI OK。
- Roundup (Roundup Issue Tracker - Roundup 2.4.0 documentation): 課題管理のみ?
- Debbugs
savaneはメンテナンスされていないので、Trac一択。redmineはCGIで動作しない。
Git
Commit
マージコミット後のコミット追加
マージコミット後に次の開発作業を始めることが多い。が、直後の初回のコミットを追加したい場合困る。
git rebase -iにすると、コミットが残るから。編集はできるが、その直前にコミットの追加ができない。マージコミットは扱いが特殊で直接rebaseで編集できない。
しかたないので、該当コミットでブランチを作成して、コミット。その後、既存の修正ブランチをrebaseでそのコミットの後にくっつける。これでいける。
コミットオプション
Git - git-commit Documentation
コミットメッセージ指定のためのオプションがある。
- -m|--message <message>: コミットを文字列で指定。複数指定可能で、その場合段落で区切ってくれる。2行目以後を書きたい場合などで使う。
- -C|--reuse-message <commit>: 指定したコミットのコミット情報を再使用する。
- -c|--reedit-message <commit>: -Cの同じだが、編集画面を表示してコミットメッセージを編集して再使用する。
- -F|--file=<file>: 指定したファイルをコミットメッセージに使う。-を指定すると標準入力を使う。
基本は-m。-mの複数指定。
過去コミットのメールアドレスの変更
- How can I change the author (name / email) of a commit? | Learn Version Control with Git
- Gitのcommitの名前やメールアドレスを過去からまとめて変更する
単一コミットのメールアドレスを指定する場合、commitに--authorを指定する。
git commit --author="John Doe <john@doe.org>"
--amendと併用することで、過去コミットも変更できる。
数が少ないなら、rebase -iで1個ずつamendする。数が多いならfilter-branch。
第一コミットの変更
- [Git 最初のコミットを含めてrebase -iする方法 | DevelopersIO]
- Git - git-rebase Documentation
通常、第一コミットはammend以外では変更できない。
rebase --root [branch] でブランチの第一コミットも参照して改変可能。
マージコミットの打ち消し
マージコミットは扱いがやや特殊。
git revert -m 1 マージコミット git reset --hard HEAD~1 # マージコミット前
どちらか。
stash
復元
Git Stashの復元: 誤って削除されたスタッシュの復元方法 #Git-Stash - Qiita
git stash drop実行時に、削除したコミットのSHA1が表示される。
そのSHA1をapplyで指定すれば、取り込める。
git stash apply [stash_hash]
リモート
gitの不要なブランチを消すコマンド #Git - Qiita
git fetch -p/--prune
リモートの削除済みブランチをローカルに同期する。
リモートの最新タグ
https:/stackoverflow.com/questions/20734181/how-to-get-list-of-latest-tags-in-remote-git
git ls-remote --tag --sort=taggerdate
date関係のsortはオブジェクトへのアクセスが必要なので、ローカルにないとダメとか。
https:/git-scm.com/docs/git-ls-remote.html
https:/stackoverflow.com/questions/10649814/get-last-git-tag-from-a-remote-repo-without-cloning
git rev-listでいけそう。
https:/gist.github.com/rponte/fdc0724dd984088606b0
差分ファイル抽出
情報源: gitで差分ファイルを抽出する #Git - Qiita。
git archiveとgit diffを組み合わせる。
git archive --format=zip --prefix=root/ HEAD `git diff --diff-filter=d --name-only HEAD^ HEAD` -o archive.zip
ただし、この方法はファイル数がARG_MAX以下の場合だけ。ファイル数が多い場合だめ。
git diff --name-onlyで一覧を出力させて、1個ずつcp -pで階層を維持してコピーするしかないかも?
例:
mkdir -p archive git diff --name-only new_base 44765_upgrade-base-version | xargs -i cp -p --parent "{}" archive/
core.autocrlf
warning: in the working copy of 'docker/README.md', LF will be replaced by CRLF the next time Git touches it
Windowsでは改行にCR+LFを使うが、mac/LinuxはLFのみ。これの違いの処理のための設定がcore.autoclrlf
- true=コミット時にCRLFをLFに自動変換。チェックアウト時に逆。Windows向けの設定。
- false=変換しない。
- input=コミット時にCRLFをLFに自動変換のみ。mac/Linux向け。Windowsではチェックアウト時にCRLFになるが、mac/LinuxはLFになる。
わかりにくい。基本はfalseで良いと思われる。
gitkの文字化け対策
gitkのエンコーディングを設定する - Pistolfly
gitkはシステムのデフォルトエンコーディングで表示しようとするので、文字エンコーディングを指定しておく。
git config --global gui.encoding utf-8
ファイル名などの文字化け対策
Git for Windows で日本語を使いたい #Vim - Qiita
git config --global core.quotepath false git config --global gui.encoding utf-8
改名と修正
改名と修正を同時にすると、改名を検知できない。
-Mオプションを指定すると、類似度で同時も検知できる。が、基本はリネーム・改名と修正は別コミットにしたほうがよさそう。
差分無視
git diffの--ignoreオプションにおけるスペース、タブ、改行の扱いを理解する #Git - Qiita
-wでインデント違いを無視してくれる。
squash
squashすると、squash対象コミットが、対象の直前のコミットに含められる。
gitignore
Format
記述方法を整理する。
- 空行は無視。
- #始まりの行はコメント扱い。
- 終端スペースは無視。
- !接頭辞はパターン否定。つまり、除外ではなく含める。以前除外された一致を再び含める。ただし、親ディレクトリーが除外されている場合、以下のファイルは含められない。パフォーマンス上の理由。順番に注意する。
- /はディレクトリー区切りとして使用。先頭、中間、末尾で登場する。
- 先頭と中間の/は相対パスを意味する。
- それ以外、末尾の/と/なしの場合、現在以下のディレクトリーにもマッチする。
- 末尾が/で終わる場合、ディレクトリーのみに一致。/がない場合、ディレクトリーとファイルの両方に一致。
- *は/以外にマッチ。?は/以外の任意の1文字にマッチ。[a-zA-Z] の範囲記法も使用可能。fnmatch(3) FNM_PATHNAMEフラグのパス名展開に準じる。
- **は特殊な意味がある。
- **/=全ディレクトリー。**/fooは配下の全fooにマッチ。**/foo/barはfoo以下の全barにマッチ。
- /**=配下のすべてにマッチ。
- a/**/b=a/b a/x/b a/x/y/bのすべてにマッチ。
後は特に明記がないが、上から順番に評価されて、最後のマッチが優先されるので、記述の順番に注意する。
反転の!と/の扱いに特に注意が必要。
先頭スラッシュをつけないと、再帰的になる。
$ cat .gitignore # ディレクトリ foo/bar 以外のすべてを除外 /* !/foo /foo/* !/foo/bar
空ディレクトリーの維持
How do I add an empty directory to a Git repository? - Stack Overflow
gitは空ディレクトリーを履歴管理できない。何かファイルが必要。
logなど維持したい空ディレクトリーに、以下の内容の.gitignoreを置く。
!.gitignore
.gitignore以外を無視する。これで.gitignoreのみがあるので管理できる。
指定ファイルのみ除外
* !.gitignore
ディレクトリーを残す以外 (.gitignore1ファイル以外) に、サンプルファイルなど複数ファイルを残したい場合は、上記のように*で最初に全部除外して指定ファイルのみ含める。/は必要に応じてつける。
gitattributes
Git - gitattributes Documentation
gitignoreに似ていて、パターンにマッチしたパスに対する設定を行える。
- text
- eol
- working-tree-encoding
- ident
- filter
- diff
- merge
- conflict-marker-size
- whitespace
- export-ignore: git archiveなどに含めないことをマーク。
- export-subst
- delta
- encoding
ファイルのインデックスのみ削除
git rmは単独だと、gitの履歴とローカルファイルからも削除する。追跡対象から削除のみで、ローカルファイルとして残したい場合、--cachedを指定する。
git rm --cached
gitk
problem
ブランチ名が長いと、右クリックしにくい
submodule
https://git-scm.com/docs/git-submodule
foreach
サブモジュールの全部を一括処理する。
foreach [--recursive] <command>
<command>部分では$sm_pathでパスを参照できる。
git submodule foreach 'echo $sm_path `git rev-parse HEAD`'
Entering 'XXX' XXX hash
submoduleの中に入ってから実行することに注意する。
便利なコマンド。
git submodule foreach 'git reset --hard'
Other
他のブランチとの同一化
git diff HEAD master | patch -p 1
patchの他にgit applyでもいい。
.netrc
https://social.senooken.jp/conversation/1573147#notice-2217499
Gitのパスワード入力の省略方法に~/.netrcがある。
しかし、man netrcするとわかるけど、これはもともとFTPのためのもの。なぜGitで使えるんだ?Gitの文書で言及がない。
In conversation Thursday, 21-Feb-2019 10:58:47 JST from web permalink
せのお (妹尾 賢)せのお (妹尾 賢) in reply to
理由が分かった。
1. Gitはhttpとhttpsの通信にcURLを使っている。
https://github.com/git/git/blob/master/INSTALL#L141
2. cURLが.netrcにも対応しているから。
https://ec.haxx.se/usingcurl-netrc.html
GitHub
Account
Username may only contain alphanumeric characters or single hyphens, and cannot begin or end with a hyphen.
ユーザー名は、英数字と-のみが使用可能。
組織別にアカウントを分けるなら、かぶらないように末尾に-組織名のようなサフィックスがあるとよいだろう。
Fossil
外部依存を排除しており、CGIでも動作するという点が非常に良い。気になる。Phorgeの検討が不要になる。
Fossil: A Coherent Software Configuration Management System
いくつか癖があるので注意する。
https://chatgpt.com/c/674e38de-a8c0-800b-8991-e0d68a2f0d86
複数のリポジトリーを取り扱うことは可能。ただし、Web UI上からリポジトリーの新規作成はできない。リポジトリーの新規作成はあくまでコマンドラインから行う必要がある。ここは集中的。
git と fossil の比較 git vs fossil-scm | タイトル
完全に個人なら悪くないが、コマンドの操作体系も異なるし、ややリスクがある。Tracのほうが無難。
Install
Binary
Fossil: A Coherent Software Configuration Management System
ソースコードからコンパイルするか、コンパイル済みバイナリーを配置するだけ。
VER=2.25 mkdir -p ~/.local/stow/fossil-$VER ~/.local/bin cd ~/.local/stow/fossil-$VER curl -O https://fossil-scm.org/home/uv/fossil-linux-x64-$VER.tar.gz tar -xf fossil-$VER.* ln -fns ../stow/fossil-$VER/fossil
Server
CGIで実行するにはいくつか手順がある。
CGIディレクトリーに以下の内容のCGIスクリプトを用意する。
#!/usr/bin/fossil repository: /home/fossil/repo.fossil
repositoryの部分は指定方法がいろいろある。単一リポジトリーのホストなら上記でいいが、複数のリポジトリーを取り扱いたければ、リポジトリー群の格納ディレクトリーをdirectory: で指定する。
また、リポジトリーが不在の場合のリダイレクト先を指定するnotfound:もある。
#!/usr/bin/fossil directory: /home/fossil/repos notfound: http://url-to-go-to-if-repo-not-found/
CGIスクリプトをcgi-bin/repoとした場合、展開後は [http: //mydomain.org/cgi-bin/repo/XYZ] のようなURLで [/home/fossil/repos/XYZ.fossil] にアクセス可能。
CGIで展開されると。
fossil.cgiにする。
https://chatgpt.com/c/674e38de-a8c0-800b-8991-e0d68a2f0d86
fossilのweb uiではリポジトリーの新規作成ができない。新規作成だけはコマンドラインから行う必要がある。これだけがいまいち。保留。
Phorge
PhorgeはPhabricatorのフォーク。
About
Introduction
以下が主な機能。
- コードレビューツール=Differential
- リポジトリーブラウザー=Diffusion
- バグトラッカー=Maniphest
- ウィキ=Phiriction
GitHubの自己ホスト。
Phabricator
PhabricatorはもともとFacebook社内のBTSシステム。PHP製。2021-06-01に開発終了。
主なユーザー。
- AngularJS
- Discord
Install
- ◉ Installation Guide
- Self Host with IPv6rs - IPv6 Provider - How to Install Phorge on Ubuntu Server Latest
- https://chatgpt.com/c/6749041b-a1b4-800b-a134-96a8029c086e
Requirement
LAMP環境で動作する。
共用ホストでも動作するが、一部機能しない。通常コンピューターを推奨している。
- MySQL: 5.5以上。
- PHP 7.2以上
- git: 2.5.0以上。
- PHP extension: mbstring, iconv, mysql (or mysqli), curl, pcntl
ドメインはサブディレクトリーはだめで、サブドメインじゃないとダメ。
Download
以下のコマンドで取得する。
$ cd somewhere/ # pick some install directory somewhere/ $ git clone https://we.phorge.it/source/arcanist.git somewhere/ $ git clone https://we.phorge.it/source/phorge.git
gitの設定。
$ sudo git config --system --add safe.directory somewhere/arcanist $ sudo git config --system --add safe.directory somewhere/phorge
phorge用のDBを作っておく。
cp /var/www/html/phorge/phabricator/conf/local/local.json.example /var/www/html/phorge/phabricator/conf/local/local.json
"mysql.host": "localhost", "mysql.user": "phorge", "mysql.pass": "password", "mysql.port": 3306, "mysql.charset": "utf8", "mysql.database": "phorgedb"
後は開くだけ。
実操作。
こういうディレクトリー構成想定。
public_html + phorge.gnusocial.jp 公開ディレクトリー。 + phorge phorge関係の格納場所。 + phorge + arcanist
取得。
TAG=2024.35 mkdir phorge cd phorge PKG=phorge git clone --depth 1 https://we.phorge.it/source/$PKG.git cd $PKG; git fetch --depth 1 origin tag $TAG; git checkout $TAG; cd .. PKG=arcanist git clone --depth 1 https://we.phorge.it/source/$PKG.git cd $PKG; git fetch --depth 1 origin tag $TAG; git checkout $TAG; cd ..
git config --add safe.directory arcanist git config --add safe.directory phorge
phorge/webrootが公開ディレクトリーになるので、これをシンボリックリンクで公開ディレクトリーにリンクする。
DOMAIN=phorge.gnusocial.jp ln -fns phorge/phorge/webroot ../$DOMAIN
「◉ Configuration Guide」に記載のあるリダイレクト設定をする。
以下相当の設定を行う。
<VirtualHost *> # Change this to the domain which points to your host. ServerName phorge.example.com # Change this to the path where you put 'phorge' when you checked it # out from the upstream when following the Installation Guide. # # Make sure you include "/webroot" at the end! DocumentRoot /path/to/phorge/webroot RewriteEngine on RewriteRule ^(.*)$ /index.php?__path__=$1 [B,L,QSA] </VirtualHost> <Directory "/path/to/phorge/webroot"> Require all granted </Directory>
具体的には、phorge/webroot/.htaccessに以下を記載して、ファイルがなければ作成する。
cat >phorge/webroot/.htaccess <<-'EOT' RewriteEngine on RewriteRule ^(.*)$ /index.php?__path__=$1 [B,L,QSA] EOT
上記設定後phorge.gnusocial.jpにアクセスすると以下のエラーになる。
Request parameter '__path__' is not set. Your rewrite rules are not configured correctly.
- apache - Phabricator rewrite rules configuring issue - Stack Overflow
- php - Phabricator install. Rewrite rules are not configured correctly - Stack Overflow
上記が少し参考になる。require指令を指定していないのが問題。
うーん。この問題を解決できない。調べても解決例が出てこない。断念する。他のソフトにする。
Config
以下のコマンドでユーザーを認識させる。
phorge/ $ ./bin/storage upgrade --user <user> --password <password>
Diffusion
Hosting
◉ Diffusion User Guide: Repository Hosting
Kallithea
https://chatgpt.com/c/674f8938-8590-800b-9a4c-f1ec04fc5869
Python 3.6でCGIでも動作する管理ソフト。
Kallithea Documentation — Kallithea 0.7.0 documentation
紹介: GitとMercurialに対応のリポジトリ管理ツール「Kallithea」 - ファーエンドテクノロジー株式会社
Administrator guide
Installation on Unix/Linux
Installation on Unix/Linux — Kallithea 0.7.0 documentation
ディレクトリー構造
https://chatgpt.com/c/674f8938-8590-800b-9a4c-f1ec04fc5869
/var/www/kallithea/ ├── config/ # 設定ファイルやシークレットを保存 │ └── kallithea.ini # Kallitheaのメイン設定ファイル ├── data/ # データベースや一時ファイル用ディレクトリ │ ├── db.sqlite # SQLiteの場合のデータベースファイル │ └── sessions/ # ユーザーセッションデータ ├── logs/ # ログファイル保存ディレクトリ │ └── kallithea.log # メインのアプリケーションログ ├── repos/ # Git/Mercurialリポジトリを保存するディレクトリ │ ├── project1.git/ # プロジェクト1のGitリポジトリ │ └── project2.hg/ # プロジェクト2のMercurialリポジトリ ├── static/ # 静的ファイル(JavaScript, CSS, 画像など) │ ├── css/ │ ├── js/ │ └── img/ └── venv/ # Python仮想環境 ├── bin/ ├── lib/ └── ...
static配下が公開ディレクトリー。共用サーバーの場合。public_htmlにkallitheaとkallithea.domainでシンボリックリンクでやるとよさそう。
Installing a released version in a virtualenv
いくつか方法があるが、virtualenvが推奨されている。
coreserver v1のpythonはpython 3.6だった。
cd public_html/ DOMAIN=kallithea.gnusocial.jp cd $DOMAIN python3 -m venv venv
python3 -m venv venvの実行時に以下のエラー。
Error: Command '['/virtual/senooken/public_html/kallithea.gnusocial.jp/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']' returned non-zero exit status 2.
cimg/pythonでvenvによる仮想環境の作成がエラーになる #Python - Qiita
pipが見つからないのが原因の模様。--without-pipでインストールして、仮想環境内にpipを直接インストールする。
python3 -m venv --without-pip venv . venv/bin/activate curl https://bootstrap.pypa.io/pip/$(python3 -V | grep -o '[0-9].[0-9]')/get-pip.py -o get-pip.py python3 get-pip.py pip install --upgrade pip
OK。以下のコマンドで基本要件を確実にする。
pip install --upgrade pip "setuptools<67"
Kallitheaをインストール。
pip install --upgrade kallithea
なんかエラーが出る。
ERROR: Command errored out with exit status 1: command: /virtual/senooken/public_html/kallithea.gnusocial.jp/venv/bin/python3 -c 'import io, os, sys, setuptools, tokenize; sys.argv[0] = '"'"'/export/tmp/pip-install-4k2ozlqh/formencode_9f25a10925bf49da975ba94c0fbba946/setup.py'"'"'; __file__='"'"'/export/tmp/pip-install-4k2ozlqh/formencode_9f25a10925bf49da975ba94c0fbba946/setup.py'"'"';f = getattr(tokenize, '"'"'open'"'"', open)(__file__) if os.path.exists(__file__) else io.StringIO('"'"'from setuptools import setup; setup()'"'"');code = f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /export/tmp/pip-pip-egg-info-kjtbdngw cwd: /export/tmp/pip-install-4k2ozlqh/formencode_9f25a10925bf49da975ba94c0fbba946/ Complete output (3 lines): /usr/lib64/python3.6/distutils/dist.py:261: UserWarning: Unknown distribution option: 'convert_2to3_doctests' warnings.warn(msg) error in FormEncode setup command: use_2to3 is invalid. ---------------------------------------- WARNING: Discarding https://files.pythonhosted.org/packages/2f/53/707c2b9b65ea6bedde67c21cbf7c71394f4a198620d4e9c1771214b91dcc/FormEncode-1.3.1.tar.gz#sha256=ada2f51792b1b484e5bb7b6cc14acfc1bc11fafc967cf015cd57e856053ca7f6 (from https://pypi.org/simple/formencode/). Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output. Collecting kallithea
[error in FormEncode setup command: use_2to3 is invalid.]
急にpip installで一部のライブラリのインストールが失敗するようになった件 #Python3 - Qiita
setuptoolsを58.0.0未満にすればいいらしい。
pip install setuptools==57.4.0
この実行後pip install --upgrade kallitheaが成功。
Prepare front-end files
以下のコマンドでフロントエンドを用意。
kallithea-cli front-end-build
事前にnpmが必要な模様。
FileNotFoundError: [Errno 2] No such file or directory: 'npm': 'npm'
npmをインストールしたら解決。
Setup
Setup — Kallithea 0.7.0 documentation
Setting up a Kallithea instance
まず以下のコマンドでmy.iniを作成する。
kallithea-cli config-create my.ini http_server=waitress
http_serverのところで使用するHTTPサーバー種別を指定する。waitress, gearbox, gevent, gunicorn, or uwsgi.を指定可能。
ひとまずデフォルトのこれで。
続いてDBを作成する。PostgreSQL/SQLIte/MariaDB/MySQLに対応。最初はSQLiteを使用しておいて、後で他のDBへのアクセスが推奨されている。
が、共用サーバーだと書き込みでプロセス削除されると嫌なので最初からMariaDBにする。まず以下のコマンドでドライバーを取得。
pip install mysqlclient
OSError: mysql_config not found
mariadbは違う模様。以下の開発パッケージが必要らしい。
sudo apt-get install libmysqlclient-dev
不明。一旦スキップ。
SQLite以外を使う場合、my.iniでsqlalchemy.urlのコメントアウトを解除してDBのユーザー名とパスワードを記入しておく。
######################### ## DB CONFIG ## ######################### #sqlalchemy.url = sqlite:///%(here)s/kallithea.db?timeout=60 #sqlalchemy.url = postgresql://kallithea:password@localhost/kallithea #sqlalchemy.url = mysql://kallithea:password@localhost/kallithea?charset=utf8mb4 sqlalchemy.url = mysql://[username]:[password]@localhost/kallithea?charset=utf8mb4 ## Note: the mysql:// prefix should also be used for MariaDB
用意したら以下のコマンドで初期テーブルを作成する。
kallithea-cli db-create -c my.ini --reuse
--reuseを指定しないと、DBやアカウントを作るところからやる。
my.ini内の情報はオプションでも指定できる。
kallithea-cli db-create -c my.ini --user=nn --password=secret --email=nn@example.com --repos=/srv/repos
以下のエラー。
ModuleNotFoundError: No module named 'MySQLdb'
mariadb_configをコピーするとか。共用サーバーだとこの問題の対応が難しいかもしれない。PostgreSQLでやり直す。
postgresqlを使うようにmy.iniを直して実行すると以下のエラー。
ModuleNotFoundError: No module named 'psycopg2'
インストールしてみる。
pip install psycopg2
動作した?以下の質問がきた。
Are you sure to destroy old database? [y/n]y
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) FATAL: password authentication failed for user "senooken_kallithea"
p
パスワードを間違えた?yだと全削除になるからかな。nなら何も出なかった。
my.iniの指定がまずかった。
#sqlalchemy.url = postgresql://kallithea:password@localhost/kallithea sqlalchemy.url = postgresql://senooken_kallithea:WkiXF3w7d@localhost/senooken_kallithea
DBの指定も必要。
実行ログを見るといかが出ている。
/virtual/senooken/public_html/kallithea/venv/lib64/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>. """)
インストールし直す。
pip install psycopg2-binary
実行し直し。
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) connection to server at "localhost" (::1), port 5432 failed: FATAL: password authentication failed for user "senooken_kallithea"
若干内容が変わる。ポート番号が怪しい。タイムオーバー。
https://chatgpt.com/c/67547095-c29c-800b-9530-650c7ff70756
KallitheaはCGI未対応。見送ったほうがいいかも。
Trac
https://chatgpt.com/c/67546eda-20ac-800b-b37f-7e8954c128f5
CGIで動作するリポジトリー統合のあるBTS。
Install
TracInstall – The Trac Project
TracFastCgi – The Trac Project
tags/trac-1.6 の INSTALL.rst – The Trac Project
http s://chatgpt.com/c/675504b7-29c0-800b-bb09-5e8a24709488
- TracFastCgi – TogoRDF
- TracCgi – TogoRDF
- 1. 導入方法 — 苦労する遊び人の玩具箱 1 ドキュメント
- virtualenv上でtrac-gitを動かして見る。 - 目の前に僕らの道がある
「tags/trac-1.6 の INSTALL.rst – The Trac Project」を参考に取り組む。
Installing Trac
以下のディレクトリー構成を踏襲する。
/var/www/kallithea/ ├── config/ # 設定ファイルやシークレットを保存 │ └── kallithea.ini # Kallitheaのメイン設定ファイル ├── data/ # データベースや一時ファイル用ディレクトリ │ ├── db.sqlite # SQLiteの場合のデータベースファイル │ └── sessions/ # ユーザーセッションデータ ├── logs/ # ログファイル保存ディレクトリ │ └── kallithea.log # メインのアプリケーションログ ├── repos/ # Git/Mercurialリポジトリを保存するディレクトリ │ ├── project1.git/ # プロジェクト1のGitリポジトリ │ └── project2.hg/ # プロジェクト2のMercurialリポジトリ ├── static/ # 静的ファイル(JavaScript, CSS, 画像など) │ ├── css/ │ ├── js/ │ └── img/ └── venv/ # Python仮想環境 ├── bin/ ├── lib/ └── ...
複数のtrac環境がある場合、プロジェクト名部分がURLで分かれる模様。
インストーラーやOSのパッケージマネージャーを使う方法もある。公式の推奨はpipの模様。
pip3 install --user trac
レンタルサーバーのpip3を使うと以下のエラー。
PermissionError: [Errno 13] Permission denied: '/etc'
venvを挟む。
mkdir -p ~/public_html/trac cd ~/public_html/trac python3 -m venv --without-pip venv . venv/bin/activate curl https://bootstrap.pypa.io/pip/$(python3 -V | grep -o '[0-9].[0-9]')/get-pip.py -o get-pip.py python3 get-pip.py pip install --upgrade pip
pipの環境ができたのでtracをインストールする。
pip3 install trac
trac-1.6をこれでインストールできた。
必要な依存関係をインストールする。
trac-admin [project] initenv
プロジェクトディレクトリーとプロジェクト名の命名に悩む。
Tracはプロジェクトという単位で管理する。1個のプロジェクトに関連するリポジトリーを複数まとめることは可能。fossil同様設定ファイルなどで手動で管理する。が、サードパーティープラグインでWeb UIから追加も可能とのこと。
例えば、gnusocial/GNU socialというような形。
initenvは後ろにプロジェクト名とdbを指定できる。
trac-admin <project> initenv [<project name> <db>]
[project]/conf/trac.iniの以下に反映される。
- <project name>=project.name
- <db>=trac.database (初期値=sqlite:db/trac.db)
https://chatgpt.com/c/67561e46-db8c-800b-80e8-b3f90bab4247
mysqlを使う場合、mysql:
mysql:host=localhost;port=3306;dbname=your_database_name
TracEnvironment – The Trac Project
DB文字列の書式
mysql://username:password@host:port/dbname
[:]区切りの部分は順不同の模様。
trac-admin gnusocial initenv 'GNU social' 'mysql://senooken_trac:password@localhost/senooken_trac';
localhostは省略不能。
TracInstall – TogoRDF tracのmysql対応が不十分の模様。
PyMySQLモジュールを使う
pip install PyMySQL
コマンドを実行したらいかが表示される。
Creating a new Trac environment at /virtual/senooken/public_html/trac/gnusocial Project environment for 'GNU social' created. You may configure the environment by editing the file: /virtual/senooken/public_html/trac/gnusocial/conf/trac.ini You can run the Trac standalone web server `tracd` and point your browser to http://localhost:8000/gnusocial. tracd --port 8000 /virtual/senooken/public_html/trac/gnusocial Navigate to "Help/Guide" to browse the documentation for Trac, including information on further setup (such as deploying Trac to a real web server). The latest documentation can also be found on the project website: https://trac.edgewall.org/
これでコマンドでローカルサーバーを起動できるようになっている。
Deploying Trac
Runnning the Stadaalone Server
以下のコマンドでローカルサーバーで起動。
tracd --port 8000 </path/to/myproject>
このあと [http://localhost:8000] で開ける。tracdが把握する全環境を表示して、/myprojectで該当プロジェクトを開ける。なお、プロジェクトが1個の場合-sをつけると/myprojectのパスがトップディレクトリーになる模様。
Running Trac on a Web Server
単独サーバーではなくWeb Server経由で実行することもできる。
FastCGIでの動作なら共用サーバーでも稼働可能。
Generating the Trac cgi-bin directory
CGI用のスクリプトはtrac-admin deplyコマンドで生成する。
trac-admin /var/trac/<project> deploy var/www ls /var/www
cgi-bin htdocs
chmod ugo+x /var/www/cgi-bin/*
cgi-bin/は以下がある。
trac.cgi trac.fcgi trac.wsgi
実手順。
cd ~/public_html/trac trac-admin gnusocial deploy .
ls cgi-bin get-pip.py gnusocial htdocs venv
htdocsにはcommon siteがある。
trac-admin gnusocial deploy .でhtdocs配下にプロジェクトファイル群が共通で格納される模様。このhtdocsをdocument rootの公開ディレクトリにシンボリックリンクを作成するとよさそう。
Mapping Static Resources
tracの主な2個の静的リソースのURLパスが/chrome/commonと/chrome/site。追加で/chrome/<plugin>
deployコマンドは以下のディレクトリーを作成する。
- common/: tracの静的リソース。
- site/: htdocsのコピー。
- shared: 複数のtracで共有する静的リソース。場所は[inherit].htdocs_dirで定義。
- <plugin>/
なお、静的リソースURLパスはtrac.iniで制御している
[trac] htdocs_location = http://static.example.org/trac-common/
上記設定に加えて以下のシンボリックリンク作成でchromeではなくtrac-commonを使える。
ln -s /path/to/trac/htdocs/common /var/www/static.example.org/trac-common
ここのパスがよくわからない。deployでtrac.gnusocial.jpを指定したほうがいいのかもしれない。
FastCGI
よくある質問 | サポート | レンタルサーバー CORESERVER(コアサーバー)
CORESERVERでFastCGIの実行。
/public_html/.fast-cgi-bin/ 内のphpXX.fcgiを編集。コントロールパネルのPHP設定でバージョンを指定。その後該当のphpXX.iniが対応公開ディレクトリーの処理スクリプトになる。
trac.fcgiをphp81.fcgiに改名して、その後バージョンをコントロールパネルからphp81にする。これでOK。
シンボリックリンクのほうがいいか。
cd ~/public_html cp php81.fcgi php81.fcgi.old ln -fns ../trac/cgi-bin/trac.fcgi php81.fcgi
これだとダメ。
ChatGPTに記載のあった.htaccessをtrac.gnusocial.jpに配置したらそれで動作した。CORESERVERのFastCGIはPHPのみの模様。
RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ /cgi-bin/trac.cgi/$1 [L]
これでtrac.gnusocial.jpを開くと開けた。
ただし、基本のURLパスが [https://trac.gnusocial.jp/cgi-bin/trac.cgi/timeline] のようにcgiのパスがつくようになる。
なんか違う気がする。
元々の.fast-cgi-bin/php81.fcgiにtrac.fcgiのシンボリックリンクを配置した後。trac.gnusocial.jpにindex.phpを配置したら動作した?パスにindex.phpが入るようになったが。
https://chatgpt.com/c/6758c79e-f2e4-800b-88e2-7eab678f03f2
Shell
Shell Command Language
Compound Commands
Case Conditional Construct
case word in [(]pattern1) compound-list;; [[(]pattern[ | pattern] ... ) compound-list;;] ... [[(]pattern[ | pattern] ... ) compound-list] esac
- 未マッチで終了ステータス0。
- pattern部分: シェル展開が有効。他はglob。
- |でOR検索相当。
- 最後のパターンの;;は省略可能。if文のようにも使える。
- 全パターンの捕捉は最後に*。空でもマッチする。?は最低1文字必要。
BREでは未対応な|のORマッチに対応しているのが最大の特徴。文法なのでコマンドを実行せず早い。grepを使わずにできるだけこちらを使ったほうがいい。
ワイルドカード
ワイルドカードで.始まりのファイルをマッチさせたい。
以下ならマッチするが、ブレース展開 (brace expansion) はPOSIX shでは使えなかった気がする。
echo {.*,*}
BOM
unicode - Adding BOM to UTF-8 files - Stack Overflow
ExcelでUTF-8ファイルを開けるように、UTF-8のBOMをファイルにつけたい。
printf '\xEF\xBB\xBF' > with_bom.txt
上記コードでBOMを最初に書き込んで、後は追記する。
awk
The Open Group Base Specifications Issue 7
変数
特別
- NF: 列数。列の全表示などで使う基本的で重要な変数。
- NR: 行番号。
スコープ
関数の仮引数のみ、ローカル変数扱いで、それ以外はグローバル変数。
文/statement
- actions
- if/else
- while/do...while/for
- break/continue
- delete
- next
- exit
- output
- printf
関数
組込関数
- Arithmetic
- atan2
- cos
- sin
- exp
- log
- sqrt
- int
- rand
- srand
- String
- gsub
- index
- length
- match
- split
- sprintf
- sub
- substr
- tolower
- toupper
- I/O
- close
- getline
- system
print/printfは関数ではなく、statement/文扱い。
ヘッダー出力、列別最大長さ出力。
awk -F, '{if(NR==1) print $0} {for(i=1; i<=NF; ++i){if (line[i] < length($i)) line[i] = length($i)}} END {for (i=1; i<=NF; ++i) {printf line[i]","}}' data/101542.csv
CSV
シェルスクリプトの実験のために作った POSIX 準拠 awk 実装の CSVパーサー (RFC4180対応) #ShellScript - Qiita
# csvparser.awk
## Usage
# awk -f csvparser.awk data.csv
# CSV の論理的な一行毎に呼び出されるコールバック関数(サンプル)
# row: 行番号(最初の行は1) len: フィールド数 fields: フィールドデータ
function callback(row, len, fields, col, field) {
for ( col = 1; col <= len; col++ ) {
field = fields[col]
gsub(/\\/, "&&", field) # \ は \\ にエスケープする
gsub(/\n/, "\\n", field) # 改行は \n にエスケープする
print row ":" col " " field
}
}
BEGIN { row = max_idx = 0 }
{
idx = 0
sub(/\r$/, "")
while ($0 != "") {
if (match($0, /^(["]([^"]|["]["])*["]|[^,"]*)(,|$)/)) {
fields[++idx] = ""
} else if (match($0, /^["]/)) {
fields[++idx] = substr($0, 2)
for (;;) {
if (getline == 0) exit 1
sub(/\r$/, "")
if (match($0, /^([^"]|["]["])*["](,|$)/)) break
gsub(/["]["]/, "\"")
fields[idx] = fields[idx] "\n" $0
}
fields[idx] = fields[idx] "\n"
} else {
exit 1
}
field = substr($0, RSTART, RLENGTH)
$0 = substr($0, RSTART + RLENGTH)
lastcomma = sub(/,$/, "", field) > 0
gsub(/^["]|["]$/, "", field) && gsub(/["]["]/, "\"", field)
fields[idx] = fields[idx] field
}
if (lastcomma) fields[++idx] = ""
while (idx < max_idx) delete fields[max_idx--]
callback(++row, idx, fields)
max_idx = idx
}
awkのCSVパーサー。先頭のBOMはあると認識できないので、tail -c +4でBOMを除外して使う。
tail -c +4 data/101543.csv | awk -f csvparser.awk
Other
binary
POSIX準拠のシェルスクリプトでバイナリデータを扱う #Bash - Qiita
バイナリーデータの読込はodコマンド。なければhexdump。
書込はprintf。
head/tailの-cはPOSIXで使えたか?
root
リダイレクト出力
sudo権限でリダイレクト処理を行ってファイルに書き込む方法
リダイレクトはログインユーザーの権限でなされるらしく、root権限のある場所にファイル出力できない。
teeコマンドでやる。
pwd | sudo tee out.dat
teeコマンド実行する側でsudoが必要。
cmd.exe
Control block
for
あくまでコマンド。
nest
ネストはできない。二重ループしたければ、関数にしてそれを呼び出す。
bitsadmin
Windowsでのファイルダウンロードコマンド
Windows 7以降ではbitsadminコマンドがあり、これがwget相当となる。
書式:
bitsadmin /transfer <job name> <URL> <output path>
<job name>と<output path>は必須なので注意する。
certutil
Windowsでのハッシュの確認に使える。
certutil -hashfile file
SHA1 ハッシュ (対象 C:\moconavi\windows\Moconavi\ext\chromium\moconavium.exe): e0da85b04b6970ac1f0c33db7a9ad607fdbd44eb CertUtil: -hashfile コマンドは正常に完了しました。
rlogin.cmd
コマンドキーの送信を自動化できる?
rem rlogin.cmd @Echo off Set SERVER=192.168.0.0 Set USERNAME= Set PASSWORD= Cmdkey /generic:TERMSRV/%SERVER% /user:%USERNAME% /pass:%PASSWORD% Start mstsc /v:%SERVER% Timeout 5 Cmdkey /delete:TERMSRV/%SERVER%
実行中プロセスのパスの確認
出典: Show EXE file path of running processes on the command-line in Windows - Super User。
wmic process get ProcessID,ExecutablePath wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath wmic process where "name='mysqld.exe'" get ProcessID, ExecutablePath /FORMAT:LIST
簡易編集モード/挿入モード
- 【Tips】Windows 10のコマンドプロンプトが意図せず止まってしまう問題を回避する方法 | ソフトアンテナ
- Windows command prompt freezing randomly - Super User
Windows 10のcmd.exeは [簡易編集モード] が有効になっており、コマンドプロンプトを左クリックすると、テキストの選択が始まる。テキスト選択中はコマンドの実行が止まる。長時間かかるコマンドの実行中に誤操作で止まると困るので、これは無効にしたほうがよい。
cmd.exeを起動-左上のアイコンをクリック-[規定値]/[プロパティ]-[オプション]-[□簡易編集モード] を選ぶ。
そのほか、 git log
のような制御が移るコマンドを実行してしばらくすると、操作できなくなる。
[□挿入モード] にすると回避できる模様。
Web
URL
クエリー配列
- クエリストリングで配列を表現をするケースをざっと調べる - コード日進月歩
- PHPでクエリパラメータから配列を受け取る物語 #JavaScript - Qiita
- PHP: http_build_query - Manual
やり方がいくつかある。
- CSV文字列で受取後分割: https://www.sakdor.net/test/?var=1,2,3 explode(",",$_GET[var]);
- 配列添字
- http://www.sakdor.net/test/?var%5B%5D=1&var%5B%5D=2&var%5B%5D=3
- http://www.sakdor.net/test/?var%5Ba%5D=1&var%5Bb%5D=2&var%5Bc%5D=3
- http:www.sakdor.net?var[0]=1&var[1]=2&var[2]=3
データが決まっているならcsvがシンプル。
HTTP
Content-Disposition
Content-Disposition - HTTP | MDN
RFC 6266 - Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)
Content-Disposition: inline Content-Disposition: attachment Content-Disposition: attachment; filename="filename.jpg"
filenameでファイル名を指定する。ここの値は二重引用符で囲む。スペースを含む場合に必須になる。
multipart/form-data
rfc7578
ファイルアップロード用のMIME type。
リクエストヘッダー
Content-Type: multipart/form-data; boundary=--hogehoge
リクエストボディー
--hogehoge Content-Disposition: form-data; name="user_name" Content-Type: text/plain test --hogehoge Content-Disposition: form-data; name="email" sample@mail.com --hogehoge Content-Disposition: form-data; name="gender" male --hogehoge Content-Disposition: form-data; name="user_profile" filename="image.jpeg" Content-Type: image/jpeg \xff\xd8\.... --hogehoge--
ヘッダーでmultipart/form-dataを明記して、ボディーでデータを指定する。
curlでの送信理由。
-Fで送信データをname=data形式で指定する。ファイルの内容を指定する場合、@filenameで指定する。これを指定すると、リクエストボディーのfilename扱いにしてくれる模様。-Fを指定すると、-H 'Content-Type: multipart/form-data'が自動付与される。たぶん、-dと同様に-X POSTもつく。
curl -X POST -F file1=@/var/tmp/sample.jpg https://xxxxx.net/xxxxxx
データとテキストを同時送信したい場合、-Fで複数指定する。
curl -X POST -F 'age=30' -F file1=@/var/tmp/sample.jpg https://xxxxx.net/xxxxxx
curlだと上記のboundaryなどをうまくやってくれるのだと思う。
リクエストボディー全体をファイルデータにする場合。
curl -X POST -H 'Content-Type: image/jpeg' --data-binary @/var/tmp/sample.jpg https://xxxxx.net/xxxxxx
IP address
出典: 固定IPアドレスの取得方法 ~実は簡単!フリーランスの方も必見です~|VPN活用日記|トピックス|グローカルネットの快適VPN【公式】| 株式会社グローカルネット。
自宅サーバーを行う際、固定IPアドレスが必要になる。
取得方法がいくつかある。
- 契約しているプロバイダでオプションとして申し込む方法
- 固定IPアドレスに対応しているSIMを契約する方法
- VPNを利用した固定IPアドレスの提供会社を利用する方法
VPNの固定IPアドレスが安いらしい。ryoかsuwakoが解説していた気がする。
Authentication
認証方式がいくつかある。HTTPで定義される認証方式 (HTTP認証) が有名。
Basic認証
出典: Basic認証 - Wikipedia。
Authorization HTTPヘッダーにBasicのあとに [username:password] をBASE64でエンコードして送信する認証方式。
GET /private/index.html HTTP/1.1 Host: example.com Authorization: Basic cm9vdDpwYXNzd29yZA==
盗聴や改ざんが簡単だが、シンプルという利点がある。
OAuth
Ref
OAuth (オーオース) 権限の認可のための標準。OAuth 2.0が最新の標準。
以下が登場人物。
- resource owner: あるサイトのユーザー。
- resource server: あるサイトのユーザーのデータの保有サーバー。
- clent: クライアントアプリ。リソースサーバーのデータを使用したい。
- authorization server: クライアントにサイトへのアクセスを認証するサーバー。アクセストークンを発行して行う。
アクセストークンが実質的なパスワードのようなものだが、resource serverのパスワードを直接渡していない点が重要な違い。パスワードを直接渡さないことで、機能別に権限を細かく利用可否を制御できる。
処理の流れ。
- client->resource owner: Authorization Request。ここでユーザーが手操作でアクセスを承認する。
- client<-resource owner: Authorization Grant。
- client->authorization server: Authorization Grant。承認された情報でアクセストークンを要求。
- client<-authorization server: Access Token
- client->resource server: Access Token。アクセストークンでアクセス。
- client<-resource server: Access Token
Consumer Key/Secret: アプリ識別用のID/PW。
Access Token: サイトにアクセスするためのパスワード。
API
複数レコードの登録
複数レコードの登録・更新・削除のREST APIについて調べてみた話(+@ Graph API) - junode | 個人開発ブログ
既存のAPIは単一リソースの処理しかないことが多い。JavaScriptなどで単一リソースを何回も呼べばいいというのはそうだけど、JavaScriptなしでは動作しない。一括処理用のAPIを作るしかなくないか?
REST WebAPIのプラクティス | yamarkz.com
delete_bulkなどのような一括処理用のAPIを作るしかない。内部的には単一処理のAPIを作る感じだったとしても。
パラメーター
json - REST API Best practices: args in query string vs in request body - Stack Overflow
パラメーターの指定に3種類ある。
- リクエストボディー
- クエリー
- パス
パスはIDなどを指定する場合だけわかりやすい。それ以外のオプションはクエリーのほうがいい。
ボディーは、通常サーバーのアップロード・ダウンロードデータとして使われる。クエリーはデータの指定に使う。
この原則に従うとシンプルだろう。
- URIには長さの制限がある。
- ボディー
- 引数が非常に多い場合。
- 画像などバイナリーデータ。
- キー・値構造を持たない場合。
- クエリー文字列
- 引数を簡単に確認できる。
- 共通の引数の場合。
検索機能のGET/POST
検索機能にGETとPOSTのどちらを使うか?という議論がある。
データ登録するわけなじゃないのだから、GETがいいんじゃない?
POSTだと、JSONをそのまま送れるので、複雑なケースに対応できる。特に、配列の送信が重要。
GETのほうが検索条件をブックマークにできたり、URLを共有できるので、基本は便利。
ただし、検索などのパラメーターが長くなる場合、使用できない。そもそも検索でそんなに長いパラメーターというのがまずいかもしれない。2000文字あれば十分という説がある。
レート制限対策
いろいろ方法がある。
- cronなどでデータをサーバー上 (DBなど) に定期保存して、保存データを表示させる。
- 配列を利用して、1回のリクエストでまとめて取得する。
- インターバルを設ける。
- HTTP 429/413を検知して、リトライする。
指数関数的バックオフ
- APIレート制限は何か、どのように対処するのか?
- Exponential backoff - Wikipedia
- 指数バックオフ | Memorystore for Redis | Google Cloud
- バックオフパターンで再試行 - AWS 規範ガイダンスリトライ時は以下のアルゴリズムがいいらしい。
wait_interval = base * 2^n +/- jitter
wait_interval
は、API が HTTP 429 で応答した場合に、システムがリクエストを再試行するまでの時間となります。base
は最初の間隔、つまり最初の再試行までの待ち時間です。この値には3000msを使用することをお勧めします。n
は、現在の呼び出しの前にリクエストが通らなかった数です。複数のスレッドやプロセスを使用して並行してAPIを呼び出している場合、n
の値は現在のスレッド/プロセスにスコープされます。この値は、現在のスレッド/プロセスが、最後に成功した応答から何回 429 "Too Many Requests" エラーに遭遇したかを表します。jitter
は 0 からbase
の間の乱数です。これは、複数のスレッド/プロセスが全く同時にAPIを呼び出さないように、リクエストを少しずつ分散させるために使用されます。システムが待機するたびに、この乱数値を再計算しwait_interval
の合計に加算するか減算するか、ランダムで選択してください。
バックエンドとフロントエンドの分離
https://chatgpt.com/c/6747e923-6174-800b-8816-dd741721de45
SPA (Single Page Application) やJAMStackの影響で、バックエンドはデータを返すだけで、画面描画はフロントエンドが全部するというのが最近の流行。
SSR (Server Side Rendering) とCSR (Client Side Rendering) の違い。フロントエンドの高度化や分業などが理由とのこと。
SSRの利点。
- SEO
- 初期表示。
- 匿名。
SSRの課題。
- サーバー負荷: データとHTML作成を同時に行うから。
- 分散困難:
キャッシュの活用がポイントになるとのこと。
Network
ssh
ssh-addの自動登録
ssh agentに秘密鍵の登録は以下のコマンド。
ssh-add <秘密鍵のpath>
ただし、上記コマンドは再起動すると登録が消えるので毎回必要。
~/.ssh/configに以下の内容を記入しておくと、次回からkeychainから自動で読み込まれるらしい (macOS で再起動しても ssh agent に秘密鍵を保持させ続ける二つの方法 #SSH - Qiita)。
Host * UseKeychain yes AddKeysToAgent yes
うまくいかなかった。
ssh-addをPC起動する度に自動的に実行させるための設定 | AIFAN
id_rsaの場合はIdentityFileを省略できるが、それ以外は指定が必要な模様。
Host * UseKeychain yes AddKeysToAgent yes IdentityFile ~/.ssh/id_ed25519
curl
HTTPの通信のコマンドラインでの確認でよく使う。
Basic
- -X: メソッド指定
- -d/--data-urlencode: リクエストボディー (key=value)を指定。-X POSTも自動指定になる。
curl -H "Content-Type: application/json" -d '{"name":"佐藤", "mail":"sato@example.com"}' localhost:5000/api/v1/users
JSONで送信する場合、ヘッダー指定が必須。
*-F: multipart/formのform指定。
curl -F "coolfiles=@fil1.gif;type=image/gif,fil2.txt,fil3.html" http://www.example.com/postit.cgi
@でfilename相当の指定。;でmime typeも指定できる。
@/</;type=自体を送信したい場合、-Fではなく、--form-stringを指定する。
curl: (60) SSL certificate problem: self-signed certificate
Ref: curlで「自己署名証明書」を受け入れるには【curl: (60) SSL certificate problem: self signed certificate】 | LFI.
--insecureオプションを指定すると、localhostなどでの自己署名証明書を許可する。
curl: Failed writing body
以下のようにhead -n 1を指定するとcurlがエラーを出力する。
curl -H "Content-Type: application/json; charset=utf-8" -H "X-HD-apitoken:$TOKEN" -d "{\"dbSchemaId\":$dbSchemaId, \"limit\":1, \"offset\":$offset}" https://$DOMAIN/$ACCOUNT/api/csvexport/version/1.0 | head -n 1
curl: Failed writing body
curlは標準出力に全部書き込めたかチェックしているようで、head -n 1で切り捨てたらcurlはエラーになる。
対策は、curl -sで出力を抑制するとのこと。これで解決。
Wireshark
TLS
Ref: SSL/TLSの復号#1 ~Wiresharkの設定~ | 東陽テクニカ | “はかる”技術で未来を創る | ワン・テクノロジーズ・カンパニー.
Wiresharkで通信パケットを確認する場合、デフォルトでTLSで暗号化されているので、内容がわからない。WiresharkでTLSに対応しておく必要がある。
[Preferences]-[Protocols]-[TCP] を選ぶ。
- ☑Allow subdissector to reassemble TCP stream
- ☑Reassemble out-of-order semgemnts
上記をチェックしておく。デフォルトでチェックされていた。
続いて、セッションごとのPre-Master Secretを登録する。
Chrome/Firefoxだと、環境変数SSLKEYLOGFILEを設定すれば、このファイルにTLSセッションキーを出力するので、これをWiresharkで読み込むことで、復号対応する。
以下のコマンド相当で、任意のファイル・場所にログファイルを指定する。
export SSLKEYLOGFILE=/tmp/sslkey.log
Macだとlaunchctlで設定しておくといい。これでWebブラウザー経由の場合は見えるようになる。
Security
DoS攻撃
いくつか対策方法がある。
サーバーログにIPアドレスが残るから、それで攻撃元の国を特定して、該当国を一括アクセス拒否。これが効果あるかもしれない。
攻撃元の国は途上国とかが多いだろうから。IPアドレスは簡単に変更できるが、国を変えるのはたいへんだろう。
バリデーションの実装
基本的に、バックエンドで主にチェックして、フロントエンドはUXの向上目的で実装する。データの重複チェックはDBアクセスが必要だったりするから。また、API経由などフロントがそもそもないケースもある。
ただ、社内システムのような、画面経由でしか使わない。悪者がほぼいないと思われるケースは、フロントエンドでの検証だけでも十分に感じる。
二重送信
submitボタンのダブルクリック、リロード、ブラウザーバック・フォワードなど、フォーム周りで注意が必要な保安要素がある。
- ボタン連打
- ブラウザーバック
- リロード (PRG)
項目ごとにすべき対策が異なる。
連打
- フォームの二重送信を防止する方法 - 福岡・東京のシステム開発会社 (株)ユーフィット
- さいきょうの二重サブミット対策 #JavaScript - Qiita
- JavaScriptを利用してフォームの二重送信を防止する|CodeZine(コードジン)
- JavaScriptでformの2重送信を防止する | にせサギ ネットサギ体験ブログ
- Javascriptで送信ボタン二度押しによる二重送信を防止する方法 | Yuta Ihara.com
基本は、ボタンのsubmitのイベント内でdisabled=trueでの無効化。
似た考え方で、スプラッシュのモーダル表示もあり。これがわかりやすいかもしれない。
$("form").submit(function() { var self = this; $(":submit", self).prop("disabled", true); setTimeout(function() { $(":submit", self).prop("disabled", false); }, 10000); });
停止にしたら、二度通せなくなるので、タイムアウトで戻すとよい。
Browser
Chromium
Extension
Chromme系で愛用拡張機能を列挙する。
devtool/開発者ツール
イベントリスナー
[Elements]-[Event Listeners]-[handler]-右クリック-[Show function definition] でイベントリスナー関数の定義を確認できる。
イベント監視
How to find out which JavaScript events fired? - Stack Overflow
monitorEvent関数で監視できるらしい。他に、FirefoxのFirebugのlog eventsでも監視できるらしい。
Other
Windows Safari
一応ある。2012-05-09のSafari 5.1.7までWindows版が提供されていた。DL1531。
Other
Tool
いくつかWeb関係の開発で役立つツール集を公開しているサイトがある。
localhost
RFC 6761 で規定。RFC 2606で予約。DNSに登録されることはないため、テスト目的で使用可能。ループバック (送信元にそのまま返す) インターフェイス。
IPv4=127.0.0.1/IPv6=::1とされている。
Free
無料で使用可能な共用ホスティングサービスがある。
スタードメイン無料サーバー
ドメインをセットで利用する必要があるものの、スタードメインのスタードメイン無料サーバーがけっこういい。
無料レンタルサーバー | スタードメイン - ドメイン取得 100円(税込)~
jpドメインの金額が相場の中では安い方で、それに無料サーバーがついていくる点。
- ディスク容量 20GB
- DB 1GB
ただし、SSHやコマンドは使えないので、FTPでWordPressを展開して設置するとか、そういう簡単な使い方だけ。ただ、それでもWordPressでWebサイトを構築するくらいなら十分だと思う。
CORESERVER
メール
- Custom_Filter_of_Coreserver - PukiWiki
- スパムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)
- カスタムフィルターの設定 | マニュアル | サポート | レンタルサーバー CORESERVER(コアサーバー)
情報
- CoreServer_Mail_Custom - PukiWiki
- coreserverのメール設定:BWT Lab.:SSブログ
- バリューサーバーのフィルター設定でスパムメール(迷惑メール)対策する方法 - QWERTY.WORK
- コアサーバー V1にてカスタムフィルターで「ごみ箱」を指定したときの確認方法 – AWMTの、できるかな?
ルールが特殊なので注意する。
ゴミ箱に振り分ける場合。
順1 で[./.Trash
] を指定
順2
- 条件: [
.*
] - 処理:
./
、に振り分ける
条件部分には正規表現が使えるように見える。
破棄にしないといけない。転送する場合、カスタムフィルターの中に転送を入れる。条件を.*にする。
カスタムフィルターにくせがある。
- エスケープ(\を前置する)が必要な文字は「'」「"」「|」「`」「~」「?」「!」
Value Domain ネットde診断 byGMO
2024-06-07 Friからバリュードメイン系の利用者に無料で提供しているセキュリティー診断ツール。
Analytics
Exam
## About
https://gnusocial.jp/notice/4506679
### 全般
- マーケティング・ビジネス実務検定
- IMA検定
- Web検定
- ネットマーケティング検定
### 解析系
- ウェブ解析士
- GAIQ
- 統計検定
- Webアナリスト検定
GAIQが無料だしどうせ使うからいいかな。
https://wacul-ai.com/blog/access-analysis/google-analytics-method/gaiq/
https://www.plan-b.co.jp/blog/seo/12792/
## URL
- https://ceres-inc.jp/business-tips/recommended-webmarketing-shikaku/
- https://mynavi-creator.jp/blog/article/qualification-for-web-marketer
- https://www.icloud.co.jp/article/exam/features-and-5-acquisition-benefits.html
- https://digitor.jp/textbook/web-analytical-qualification/
Tool
サイト分析用のツールがいくつかある (2023年ブログランキング!おすすめブログランキングサイト比較【一般人向け】)。
- SimilarWeb
- Ubersuggest
- ahrefs
- Googleキーワードプランナー
閲覧数取得
出典: GoogleAnalyticsで自サイトの人気記事ランキングを表示する方法 | アフィリエイトJAPAN。
- [行動]-[サイトコンテンツ]-[全てのページ]
- [表示する行数]=5000
- [エクスポート]=TSV
流入元特定
「会員登録画面の流入元探索方法について - Google アナリティクス コミュニティ」どのページから会員登録があったか、会員登録に結びつく記事は非常に重要。
こんにちは。
探索レポートでユーザーセグメントを作成する集計方法はいかがでしょうか。
・自由形式レポートを作成
・セグメント作成 > ユーザーセグメント
・条件は page_view > パラメータ page_location > 含む:会員登録画面のURL を指定
・「会員登録画面閲覧ユーザー」などセグメント名をセットして保存
・探索レポートにセグメントを適用
・ディメンション:セッションの参照元 / メディア、ランディング ページ + クエリ文字列
・指標:セッション
ご確認よろしくお願いいたします。
※ページ閲覧の発生しなかったセッションはランディングページが (not set)になります。
開きっぱなしのタブから再訪問するセッションなどが該当します。ご参考までに。
PMProでも似たような回答。
Google Analytics 4 can track ecommerce conversions and then assign page value to posts that were a part of their conversion path for that engaged session.
Server
httpd
Apache HTTP Server
Operation
サーバーの稼働や状態確認などで重要な操作がいくつかある。systemd前提。
ログ・状態確認。
sudo systemctl status apache2
sudoをつけないと詳細ログを確認できない。
sudo systemctl restart apache2 sudo systemctl start apache2 sudo systemctl stop apache2
Access Control
- Access Control - Apache HTTP Server Version 2.4
- Authentication and Authorization - Apache HTTP Server Version 2.4
- mod_authz_core - Apache HTTP Server Version 2.4
DoS攻撃対策などで重要な設定。
mod_authz_core/mod_authz_hostがコアモジュール。mod_rewriteも関係ある。
基本構文は以下。
Require host <address> Require ip <ip address>
1番目の形式はドメイン名。2番目はIPアドレス。部分マッチする。マッチしたもののアクセスを許可する。
Requireの直後にnotを指定してアクセス禁止にできる。こちらが重要。
Error
sudo systemctl status apache2
● apache2.service - The Apache HTTP Server Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor preset: enabled) Drop-In: /etc/systemd/system/apache2.service.d └─privatetmp.conf Active: failed (Result: exit-code) since Fri 2024-12-06 15:09:28 JST; 12s ago Docs: https://httpd.apache.org/docs/2.4/ Process: 38461 ExecStart=/usr/sbin/apachectl start (code=exited, status=1/FAILURE) Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/ports.conf:8 Dec 06 15:09:28 z-ken-senoo apachectl[38464]: [Fri Dec 06 15:09:28.259153 2024] [core:warn] [pid 38464] AH00117: Ignoring deprecated use of DefaultType in line 122 of /etc/apache2/apache2.conf. Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00112: Warning: DocumentRoot [/home/gree/frontend/greenet/htdocs_net] does not exist Dec 06 15:09:28 z-ken-senoo apachectl[38464]: AH00526: Syntax error on line 7 of /etc/apache2/conf-available/rewrite-greenet.conf: Dec 06 15:09:28 z-ken-senoo apachectl[38464]: RewriteRule: unknown flag 'UnsafeAllow3F' Dec 06 15:09:28 z-ken-senoo apachectl[38461]: Action 'start' failed. Dec 06 15:09:28 z-ken-senoo apachectl[38461]: The Apache error log may have more information. Dec 06 15:09:28 z-ken-senoo systemd[1]: apache2.service: Control process exited, code=exited, status=1/FAILURE Dec 06 15:09:28 z-ken-senoo systemd[1]: apache2.service: Failed with result 'exit-code'. Dec 06 15:09:28 z-ken-senoo systemd[1]: Failed to start The Apache HTTP Server.
AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/ports.conf:8
NameVirtualHost指令が廃止予定なので、行を削除して対応する。
AH00117: Ignoring deprecated use of DefaultType in line 122 of /etc/apache2/apache2.conf.
- Gentooの~amd64にApache 2.4.1が来たので試してみた https://meihong.work/computer/server-administration/apache/gentoo%E3%81%AEamd64%E3%81%ABapache-2-4-1%E3%81%8C%E6%9D%A5%E3%81%9F%E3%81%AE%E3%81%A7%E8%A9%A6%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/
- Upgrading to 2.4 from 2.2 https://httpd.apache.org/docs/2.4/upgrading.html
- DefaultType Directive https://httpd.apache.org/docs/2.4/en/mod/core.html#defaulttype
DefaultTypeはnone以外意味がなく、警告表示になる模様。
[サーバーIPがブラックリストに載ってメール送信エラーになるのを解除する方法]
MailHog: Go言語製のメールサーバーソフト。
Debian
PHP8
[How To Install PHP 8.0 on Debian 11/10/9 | ComputingForGeeks](https://computingforgeeks.com/how-to-install-php-on-debian-linux/)
Debian 11の場合、PHP 8には外部リポジトリーが必要なので追加する。
sudo apt update
sudo apt install -y lsb-release ca-certificates apt-transport-https software-properties-common gnupg2
PHPパッケージを追加する。
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/sury-php.list
wget -qO - https://packages.sury.org/php/apt.gpg | sudo apt-key add -
sudo apt update
これでPHP8を参照できるので、インストールする。
sudo apt install php8.2
[How to Switch between Multiple PHP Version on Debian 12/11/10 – TecAdmin](https://tecadmin.net/switch-between-multiple-php-version-on-debian/)
インストールしたら、PHPのバージョンを切り替える。
a2dismod php7.4
a2enmod php8.2
sudo systemctl restart apache2
php 8.2にするとこういうエラー。
[Sat Sep 02 11:31:02.558029 2023] [php:error] [pid 25644] [client 133.106.38.37:57181] PHP Fatal error: Uncaught Error: Undefined constant "DB_DATAOBJECT_ERROR_NODATA" in /var/www/gnusocial/public/index.php:104\nStack trace:\n#0 [internal function]: handleError()\n#1 {main}\n thrown in /var/www/gnusocial/public/index.php on line 104
念のためdockerで起動を試みましたが、同じくトップ画面を開くと同じエラーになります。
<https://notabug.org/gnusocialjp/gnusocial/src/main/docker/development> にDockerでの起動方法があります。`docker compose up -d` を実行するだけでlocalhostでアクセスできます。
私とあなたとの環境の違いを排除したいので、dockerのインストールだけ頑張って、それでdockerでも簡単に動作確認してくれませんか?
alternative
Ref: DebianAlternatives - Debian Wiki.
OS内でバージョン違いのプログラムを管理するための仕組みがある。それがupdate-alternativesコマンド。
sudo update-alternatives --display vi
sudo update-alternatives --config vi
オプションとコマンド名を指定することで、現在の実体と更新ができる。
XAMPP
ポート番号変更
XAMPP Control PanelのConfigから変更可能。
phpmyadminはConfigのphpmyadminで、Servers.portを追加する。
Vim
Other
Async
https:/github.com/skywind3000/asyncrun.vim
asyncrun.vimは1個のバックグラウンド処理しか対応していない。
https://github.com/skywind3000/asyncrun.vim/issues/12
vim-dispatchならいけるのか?
Binary
vim-jp » Hack #133: バイナリファイルを編集する
grep
非同期でgrepする方法。
https://superuser.com/questions/861783/how-to-run-a-grep-in-vim-asynchronously
https://www.reddit.com/r/vim/comments/5ses2e/async_grep_in_vim_8/
Vim 8の非同期APIはプラグイン用。
* https://github.com/mhinz/vim-grepper
* https://github.com/skywind3000/asyncrun.vim
* https://github.com/tpope/vim-dispatch
https://wonderwall.hatenablog.com/entry/2017/10/09/210000
asyncrun.vimでやるのがよさそう。
AnsiEsc
* https:/unix.stackexchange.com/questions/444226/how-to-make-vim-interpret-escaped-characters-as-colors
* https:/superuser.com/questions/358409/how-can-i-tell-vim-to-show-ansi-escape-codes-properly
本家は太字に対応していないのでこちらがいいかな。
- https:/github.com/powerman/vim-plugin-AnsiEsc
ただし、こちらはgvimでクリック時にカーソル位置がずれる。
program
C
ワシのVimプラグインは百八式まであるぞ - daisuzu's notes
【C/C++】
87. a.vim
C/C++のヘッダとソースを切り替えます。
88. c.vim
C/C++のテンプレートやイディオムの入力をサポートしてくれます。
89. CCTree
cscopeを使って関数のコールグラフを表示してくれます。
90. Source-Explorer-srcexpl.vim
ソース解析ツール、Source InsightのVim版です。
91. trinity.vim
taglist, srcexpl, nerdtreeを同時に起動して
VimがIDE画面のような画面になります。
92. cscope-menu
cscope用のメニューを表示してくれます。
93. gtags.vim
gtagsを使ってファイルを開けます。
94. DoxygenToolkit.vim
Doxygenコメントの入力をサポートしてくれます。
Visual Studio Code
Keybind
矩形選択
Ref: VS Codeの矩形選択と矩形貼付の操作方法 - mito’s blog.
- s-alt-クリック
- c-s-alt-矢印
ジャンプ
- 括弧ジャンプ: C-S-\
Config
Default terminal
Ref: bash - Change the default terminal in Visual Studio Code - Stack Overflow.
[F1]-[Terminal: Select Default Profile]
cscope
cscope用のプラグインが何個かある。
scope4codeのほうがいろいろできそうだが、うまく動作しなかった。使い方がよくわからない。
cscope-codeはシンプルだが動作した。こちらを当分使うことにする。
Macの場合、control-. sのように、control-.の後に、controlを話してsを押すと発動する。カーソル下のシンボルしか使えない感じなのがネック。まあいい。
Vim
VSCodedでVimのキー操作を使うためのプラグイン。これが一番人気。いや、Vimのエミューレーターは中途半端な感じだから使わないほうがいいかな。
Extension
CSS
Tailwind CSS IntelliSense
PHP
Laravel Blade Snippets
PHP Intelephense
Ref: PHP Intelephense - Visual Studio Marketplace.
VSCodeのPHPの補完拡張として人気が高い。
Quick Start
設置後、しておくべき設定がある。
- Go to
Extensions
. - Search for
@builtin php
- Disable
PHP Language Features
. LeavePHP Language Basics
enabled for syntax highlighting.
VSCodeの [PHP Language Features] を無効にしておくとのこと。
後は、.php以外の拡張子でPHPファイルがあれば、関連付けを追加するとか。
Module
peclなどPHPの標準モジュールで一部認識できないものがある。
「php - Undefined type 'Imagick' in VSCode's intelephense - Stack Overflow」にあるように、そういう場合は [Settings]-[Stubs] で追加するとよい。
Coding
Ref: VSCode で PHP 開発するならインテリセンス最強の intelephense を使おう | 株式会社ビヨンド.
intelephenseでコード補完を認識しやすい書き方というのがある。
まず、型をつけられるものはつける。
function superMethod()
{
/** @var AwesomeService $awesomeService */
$awesomeService = $this->app->make(AwesomeService::class);
$awesomeService->awesomeMethod();
}
ローカル変数も型名を指定する。これをしないと、インスタンスでコード補完が効かない。
Other
Remote
【WinSCPはもう不要?】VS Codeのダウンロード/アップロード機能が便利すぎる!! | マスクロドットコム
Visual Studio Code Remote Development
公式拡張機能のVS Code Remote Developmentを使うと、リモートファイルをVS Codeで開いて、ドラッグドロップでファイル送受信ができるらしい。
PhpStorm
Encoding
パス単位で文字エンコーディングを設定可能。
[PhpStorm]-[Settings]-[Editor]-[File Encodings] から行う。
PIM
Personal Information Manager - Wikipedia
PIMという個人情報管理用アプリの分類がある。
- カレンダー
- アドレス帳
- 電子メール
- タスク管理
- メモ帳
- 音声メモ
- 電卓
- 時計
- 電子辞書
General
Naming
RFC
- webmaster
- support
- info
- service
- pr
- billing
- 氏名
売上をアップするメールアドレス、商機を失うメールアドレス | マイナビニュース
infoやwebmasterなど企業サイトが備えるべきメールボックスのルール、ご存じですか? | 編集長ブログ―安田英久 | Web担当者Forum
rfc-jp.nic.ad.jp/rfc-jp/RFC2142-JP.txt
SuperTAINS News No.23 [Page.5]
【Mail】メールアドレス作成のガイドライン(RFC2142) – fumidzuki
公開用のメールアドレス。何にしようか考えていた。
RFC 2142でいくつか推奨されている。
info@ support@ answer@ inquery@ contact@ pubic@
contact@がやっぱり一番しっくりくる。info@ support@はRFC 2142にあるけど,これはビジネスより,サービスに紐付いたもの。個人でやる分にはサービス関係ないから,これは違う。publicも悪くはないのだけど,あまり一般的ではないか。
develop
GNU social JP管理人 (gnusocialjp@gnusocial.jp)'s status on Saturday, 08-Oct-2022 23:13:28 JSTGNU social JP管理人 使用するメールアドレスに悩みます。GitのメールアドレスはGitのホスティングサービスに掲載され一般公開されます。
メーリングリストのメールアドレスも、返信方法によって引用されアーカイブで一般公開されます。
どう使い分けるのがよいでしょうか?案↓
GNU social JP管理人 (gnusocialjp@gnusocial.jp)'s status on Saturday, 08-Oct-2022 23:20:04 JSTGNU social JP管理人 開発用のメールなので、1がいいですかね。仮に漏洩しても開発関係経由というのがわかるので。
- develop@domainのようなアドレスで共有
- develop@, ml@ で用途別
- contact@ で一般公開用で共有
1がいいと思う。
category
目的に応じて使い分けたほうがよさそう。
メールアドレスを何個ぐらい使い分けたら安全・快適に過ごせるのか - Dr.ウーパのコンピュータ備忘録
メールアドレス流出時の被害防止
不審なメールの検知
必要な数
- 銀行・証券会社
- 知り合い
- ショッピングサイト
その他
- Webサイトなどの公開用
- 本名でのやり取り
- ニックネーム
- 金銭のやり取りのないサービス登録
- 金銭のやり取りのあるサービス登録
- 登録にメールアドレスが必要だけど,そんなに使っていないメール
メールアドレスの種類
- フリーメール
- プロバイダーメール
- 独自ドメイン
メールアドレスの種類とアフィリエイトにおける3つの使い分け方法 | アフィリエイト
- サービス登録用
- メルマガ購読用(捨てアド)
- メインアドレス
メールアドレスの使い分けかた(前編) - 学習する機械、学習しない人間
メールアドレスの使い分けかた(後編) - 学習する機械、学習しない人間
これらを考えてどういう名前で何個用意するかを考える。
とりあえずメインで使うmainというアドレスを一つ用意する。残りをどうするか。
Webサイト公開用にcontact
- main: メインで使うメール。人に直接教えるときや,お金が絡む場合,ショッピングサイトなど実名が求められるような重要な内容にはこれ。こちらから送信するときもこれ。相手の顔が見えているとき。
- contact:受信専用,公開用。問い合わせ用。なんかフォーラムやブログのコメント欄やcontact usなどにこちらから問い合わせる時なども。相手の顔が見えないときなど。
- service: 基本的に受信専用,たまに返信。Webサービス登録用。
- recruit:就職活動用。就職サイトとか転職エージェント,企業とやりとりするときはけっこうメール来るから。
- job: 個人事業、仕事用、不動産は事業なのでこちら。
- money: 金融機関登録用。銀行、証券会社、クレジットカード会社、決済会社・サービス。
- shop/store: ショッピングサイト、個人間売買サイト。
- ユーザー名: メールアドレスの@以前はユーザー名とみなされることがあるので、ユーザー名のアドレスも用意しておくとよさそうだ。
こちらから送信するときのメールアドレス。
Webサービスに登録するときどうするか。不動産屋さんとか人に教えるときはどうするか。アフィリエイトとかドメインとか実名が求められるときはどうするか。
gmailの+を考える。gmailでは+や.をつけると無限にアドレスをつけられる。ただし,受信は+のないメール。
ただし,gmailの+は使えないときがある。@以前の部分をユーザー名とみなして,+を無効な文字とみなすサービスがある模様。
ネットではがきが印刷~郵送できるポスコミ【1枚から注文OK】
https://www.tomtop.com/もだめ。
今まで使ってきたメールとはどうやりくりするか。
Thunderbirdでやる場合,Archiveするときに既読とメールのコピーを行う。
他のアドレスのメールはmainに転送するようにしておいて,mainのメールアドレスで確認。
最終的にThunderbirdでArchiveを実行したら,宛先のメールのフォルダーに同じ内容が既読状態でコピーされることにする。
このようなフィルターを作っておく。受信時にコピーしてしまうと,未読状態でコピーされてしまうか,受信した瞬間に既読状態になってしまい,見逃す可能性が高い。
Manage Identitiesで返信時に受信したアドレスで返信できるように登録しておく。
Mozilla Thunderbird
プロファイルの統合
ImportExportToolsでデータ移行するというのが手堅い。一括操作を念頭に置いた機能になっている。数が少ないならば、emlファイルをドラッグドロップで取り込むこともできる。