はじめに
Go1.23連載の6本目です。
Go1.23のos.CopyFSの追加、path/filepath パッケージの更新について解説します。
更新内容
os.CopyFS の追加
プロポーサルは#62484です。
io.fs/FSをローカルにコピーできるようになりました。
バージョン1.22まではディレクトリのコピーなどは、filepath.Walkなどを使い再帰的にコピーを行うか、外部ライブラリなどを利用する必要がありました。
1.23では標準パッケージを利用しつつ簡単な実装でディレクトリコピーをできるようになりました。
package main |
os.CopyFSの第2引数は io/fs.FSのinterfaceに対応していれば良いので、標準パッケージではあれば go:embed で埋め込んだファイルリストをコピー可能、is/fs.FSに準拠した外部ライブラリを利用すればS3やメモリ上にある仮想ファイルシステムをローカルにコピーすることも可能です。
embedのos.CopyFS利用のサンプルです。
package main |
io.fs/FSは Openしか用意されていないためio.fs/FS=>ローカル方向へのコピーのみである点はご注意ください。
ちなみに後ほど紹介するLocalizeがos.CopyFSの内部で利用されています。
(こちらで利用されているのはinternalパッケージですが)
Windowsおける os.Readlink と filepath.EvalSymlinks を(ほぼ)シンボリックリンクの評価のみに変更
プロポーサルは#63703です。
os.Readlinkの実装がドキュメントの記載である
Readlink returns the destination of the named symbolic link.
とは異なり、readlinkコマンドの挙動と一致させるような複雑な実装になっていました。
その結果深刻なバグ(#39786, #40176)が発生しおり、filepath.EvalSymlinks も内部でos.Readlinkを利用しているため影響を受けていました。
今回の変更により以下のように変更されてます。
| 対象 | Before | After |
|---|---|---|
| os.Lstat | symlinksとmount pointsを両方考慮 | symlinksのみ考慮 |
| os.Readlink | windows.GetFinalPathNameByHandleの結果からsymlinksとmount pointsを両方考慮 |
シンボリックリンクのターゲット ( IO_REPARSE_TAG_SYMLINK)を利用し返却 |
Window上でシンボリックを張り1.23rc2と1.22.5の違いを確認しましたが、単純なパターンでは結果は変わりませんでした。
確認ソースコード
シンボリックリンク準備コマンド
C:\gotest>type nul > ori.txt |
package main |
filepath.Localize の追加
プロポーサルは#57151です。
filepath.Localizeはスラッシュ区切りのパスをOSに合わせ安全に変換する機能です。
返却される値、エラーの有無はテストケース見ると分かりやすいです。
具体例をいくつか上げます。
| 入力値 | 返却値 (Windows) |
返却値 (UNIX) |
|---|---|---|
| a | a | a |
| . | . | . |
| a/b/c | a\b\c | a/b/c |
| a/ | (error) | (error) |
| a/./b | (error) | (error) |
| a/.. | (error) | (error) |
| a\b:c | (error) | a\b:c ( \,:を区切りとして扱わない) |
| c: | (error) | c: |
| /a | (error) | (error) |
. (.のみを除く)や..が含まれていた場合、先頭末尾にスラッシュが入った場合にもエラーになるためかなり厳しくチェックすることが可能です。
まとめ
今回はos, path/filepathを中心に3件のアップデートを紹介しました。
os.CopyFSはローカルに対するコピーの利便性向上、後半2つは安全性、安定性向上のアップデートでした。
明日は大江さんの keep-alive,Cookie です。