Tar

Tar.createFunction
create(
    [ predicate, ] dir, [ tarball ];
    [ skeleton, ] [ portable = false ]
) -> tarball

    predicate :: String --> Bool
    dir       :: AbstractString
    tarball   :: Union{AbstractString, AbstractCmd, IO}
    skeleton  :: Union{AbstractString, AbstractCmd, IO}
    portable  :: Bool

ディレクトリ dir の tar アーカイブ("tarball")を作成します。生成されたアーカイブは、tarball のパスに書き込まれるか、パスが指定されていない場合は、一時的なパスが作成され、関数呼び出しによって返されます。tarball が IO オブジェクトの場合、tarball の内容はそのハンドルに書き込まれます(ハンドルはオープンのままです)。

predicate 関数が渡されると、dir を再帰的に検索している間に遭遇した各システムパスに対して呼び出され、predicate(path) が true の場合のみ path が tarball に含まれます。もし predicate(path) がディレクトリに対して false を返すと、そのディレクトリは完全に除外されます:そのディレクトリの下にあるものはアーカイブに含まれません。

skeleton キーワードが渡されると、指定されたファイルまたは IO ハンドルが tarball を生成するための「スケルトン」として使用されます。extract コマンドに skeleton キーワードを渡すことでスケルトンファイルを作成します。そのスケルトンファイルとともに create が呼び出され、抽出されたファイルが変更されていなければ、同一の tarball が再作成されます。skeletonpredicate の引数は一緒に使用することはできません。

portable フラグが true の場合、パス名が Windows での有効性をチェックされ、不正な文字を含まないか、予約された名前を持たないことが保証されます。詳細については https://stackoverflow.com/a/31976060/659248 を参照してください。

source
Tar.extractFunction
extract(
    [ predicate, ] tarball, [ dir ];
    [ skeleton = <none>, ]
    [ copy_symlinks = <auto>, ]
    [ set_permissions = true, ]
) -> dir

    predicate       :: Header --> Bool
    tarball         :: Union{AbstractString, AbstractCmd, IO}
    dir             :: AbstractString
    skeleton        :: Union{AbstractString, AbstractCmd, IO}
    copy_symlinks   :: Bool
    set_permissions :: Bool

指定されたパス tarball にある tar アーカイブ("tarball")をディレクトリ dir に抽出します。tarball がパスではなく IO オブジェクトの場合、アーカイブの内容はその IO ストリームから読み取られます。アーカイブは dir に抽出され、dir は既存の空のディレクトリであるか、新しいディレクトリとして作成できる存在しないパスでなければなりません。dir が指定されていない場合、アーカイブは一時ディレクトリに抽出され、そのディレクトリが extract によって返されます。

predicate 関数が渡されると、tarball を抽出している間に遭遇する各 Header オブジェクトに対して呼び出され、predicate(hdr) が true の場合のみエントリが抽出されます。これにより、アーカイブの一部のみを選択的に抽出したり、extract がエラーをスローするエントリをスキップしたり、抽出プロセス中に何が抽出されたかを記録することができます。

Header オブジェクトは、predicate 関数に渡される前に、tarball の生ヘッダーから若干修正されます:path フィールドは . エントリを削除し、複数の連続スラッシュを単一のスラッシュに置き換えるように正規化されます。エントリが :hardlink タイプの場合、リンクターゲットパスも同様に正規化され、ターゲットエントリのパスと一致するようになります;サイズフィールドはターゲットパスのサイズに設定されます(これはすでに見たファイルでなければなりません)。

skeleton キーワードが渡されると、抽出された tarball の「スケルトン」が指定されたファイルまたは IO ハンドルに書き込まれます。このスケルトンファイルは、create 関数に skeleton キーワードを渡すことで、同一の tarball を再作成するために使用できます。skeletonpredicate 引数は一緒に使用することはできません。

copy_symlinkstrue の場合、シンボリックリンクをそのまま抽出するのではなく、tarball 内部にあり、可能であればリンク先のコピーとして抽出されます。/etc/passwd へのリンクのような非内部シンボリックリンクはコピーされません。何らかの形で循環しているシンボリックリンクもコピーされず、スキップされます。デフォルトでは、extractdir にシンボリックリンクを作成できるかどうかを検出し、作成できない場合は自動的にシンボリックリンクをコピーします。

set_permissionsfalse の場合、抽出されたファイルには権限が設定されません。

source
Tar.listFunction
list(tarball; [ strict = true ]) -> Vector{Header}
list(callback, tarball; [ strict = true ])

    callback  :: Header, [ <data> ] --> Any
    tarball   :: Union{AbstractString, AbstractCmd, IO}
    strict    :: Bool

指定されたパス tarball にある tar アーカイブ(「tarball」)の内容をリストします。tarball が IO ハンドルの場合、そのストリームから tar の内容を読み取ります。Header 構造体のベクターを返します。詳細については Header を参照してください。

callback が提供されている場合、ヘッダーのベクターを返す代わりに、各 Header に対してコールバックが呼び出されます。これは、tarball 内のアイテムの数が多い場合や、tarball 内のエラーの前にアイテムを調べたい場合に便利です。callback 関数が Vector{UInt8} または Vector{Pair{Symbol, String}} のいずれかの型の第二引数を受け入れることができる場合、ヘッダーの生データの表現を単一のバイトベクターまたはフィールド名を生データにマッピングするペアのベクターとして呼び出されます(これらのフィールドが連結されている場合、結果はヘッダーの生データになります)。

デフォルトでは、listextract 関数が抽出を拒否するような tarball の内容に遭遇した場合にエラーを返します。strict=false の場合、これらのチェックをスキップし、extract が抽出するかどうかにかかわらず、tar ファイルのすべての内容をリストします。悪意のある tarball は、あなたを騙して何か悪いことをさせようとするために、さまざまな巧妙で予期しないことを行う可能性があることに注意してください。

tarball 引数がスケルトンファイル(extract および create を参照)である場合、list はファイルヘッダーからそれを検出し、スケルトンファイルのヘッダーを適切にリストまたは反復します。

source
Tar.rewriteFunction
rewrite(
    [ predicate, ] old_tarball, [ new_tarball ];
    [ portable = false, ]
) -> new_tarball

    predicate   :: Header --> Bool
    old_tarball :: Union{AbstractString, AbstractCmd, IO}
    new_tarball :: Union{AbstractString, AbstractCmd, IO}
    portable    :: Bool

old_tarballcreateが生成する標準形式に書き換えつつ、extractがエラーを引き起こす原因となるものが含まれていないことを確認します。これは機能的には次のことと同等です。

Tar.create(Tar.extract(predicate, old_tarball), new_tarball)

ただし、ディスクに何も抽出せず、代わりにseek関数を使用して古いtarballのデータをナビゲートします。new_tarball引数が渡されない場合、新しいtarballは一時ファイルに書き込まれ、そのパスが返されます。

predicate関数が渡されると、old_tarballを抽出している間に遭遇する各Headerオブジェクトに対して呼び出され、predicate(hdr)が真でない限りエントリはスキップされます。これにより、アーカイブの一部のみを選択的に書き換えたり、extractがエラーを投げる原因となるエントリをスキップしたり、書き換えプロセス中に遭遇したコンテンツを記録したりすることができます。

predicate関数に渡される前に、Headerオブジェクトはtarballの生のヘッダーから若干修正されます:pathフィールドは.エントリを削除し、連続するスラッシュを単一のスラッシュに置き換えるように正規化されます。エントリが:hardlinkタイプの場合、リンクターゲットパスも同様に正規化され、ターゲットエントリのパスと一致するようになります;サイズフィールドはターゲットパスのサイズに設定されます(これはすでに見たファイルでなければなりません)。

portableフラグが真の場合、パス名はWindows上での有効性がチェックされ、不正な文字を含まないことや予約された名前を持たないことが保証されます。詳細については https://stackoverflow.com/a/31976060/659248 を参照してください。

source
Tar.tree_hashFunction
tree_hash([ predicate, ] tarball;
          [ algorithm = "git-sha1", ]
          [ skip_empty = false ]) -> hash::String

    predicate  :: Header --> Bool
    tarball    :: Union{AbstractString, AbstractCmd, IO}
    algorithm  :: AbstractString
    skip_empty :: Bool

tarballが含むファイルツリーのツリーハッシュ値を計算します。デフォルトでは、これはgitのツリーハッシュアルゴリズムを使用し、SHA1セキュアハッシュ関数を使用します(現在のgitのバージョンのように)。これは、gitが表現できるファイルツリーを持つ任意のtarball、つまりファイル、シンボリックリンク、および非空のディレクトリのみを持つtarballに対して、この関数によって計算されるハッシュ値が、そのファイルツリーに対してgitが計算するハッシュ値と同じであることを意味します。tarballは空のディレクトリを持つファイルツリーを表現できることに注意してください。gitはそれを保存できませんが、この関数はそれらのハッシュを生成できます。デフォルトでは(この動作を変更する方法については以下のskip_emptyを参照)、これらの空のディレクトリを省略したtarballのハッシュとは異なります。要するに、ハッシュ関数はgitが表現できるすべてのツリーに対してgitと一致しますが、gitが表現できない他のツリーに対してハッシュ可能なツリーのドメインを一貫した方法で拡張します。

predicate関数が渡されると、tarballを処理している間に遭遇する各Headerオブジェクトに対して呼び出され、predicate(hdr)がtrueの場合にのみエントリがハッシュされます。これは、アーカイブの一部のみを選択的にハッシュしたり、extractがエラーをスローする原因となるエントリをスキップしたり、ハッシュ処理中に抽出されたものを記録するために使用できます。

Headerオブジェクトは、predicate関数に渡される前に、tarball内の生のヘッダーから若干修正されます:pathフィールドは、.エントリを削除し、連続するスラッシュを単一のスラッシュに置き換えるように正規化されます。エントリのタイプが:hardlinkの場合、リンクターゲットパスも同様に正規化され、ターゲットエントリのパスと一致するようになります;サイズフィールドはターゲットパスのサイズに設定されます(これはすでに見たファイルでなければなりません)。

現在サポートされているalgorithmの値は、git-sha1(デフォルト)およびgit-sha256で、これはgit-sha1と同じ基本アルゴリズムを使用しますが、SHA1ハッシュ関数をSHA2-256に置き換えます。これは、gitが将来的に使用することになるハッシュ関数です(SHA1に対する既知の攻撃のため)。将来的には他のファイルツリーハッシングアルゴリズムのサポートが追加される可能性があります。

skip_emptyオプションは、再帰的にファイルやシンボリックリンクを含まないディレクトリがハッシュに含まれるか無視されるかを制御します。一般的に、tarballやファイルツリーの内容をハッシュする場合、空でないディレクトリだけでなくすべてのディレクトリに関心があるため、これらを計算されたハッシュに含めることがデフォルトです。では、なぜこの関数は空のディレクトリをスキップするオプションを提供するのでしょうか?それは、gitが空のディレクトリを保存することを拒否し、それらをリポジトリに追加しようとすると無視するからです。したがって、ファイルをgitリポジトリに追加してからgitにツリーハッシュを要求すると、得られるハッシュ値は、skip_empty=truetree_hashによって計算されたハッシュ値と一致します。言い換えれば、このオプションはtree_hashが空のディレクトリを持つツリーをgitがどのようにハッシュするかをエミュレートできるようにします。ただし、空のディレクトリを含むツリー(つまり、gitリポジトリから来ていないもの)をハッシュする場合は、空のディレクトリを無視しないツール(このツールなど)を使用してハッシュすることをお勧めします。

source
Tar.HeaderType

Header型は、tarファイル内の単一レコードに関する基本的なメタデータを表す構造体で、以下の定義があります:

struct Header
    path :: String # ルートに対する相対パス
    type :: Symbol # タイプインジケーター(以下参照)
    mode :: UInt16 # モード/権限(8進数で表示するのが最適)
    size :: Int64  # レコードデータのサイズ(バイト単位)
    link :: String # シンボリックリンクのターゲットパス
end

タイプは以下のシンボルで表されます:filehardlinksymlinkchardevblockdevdirectoryfifo、または不明なタイプの場合は、タイプフラグ文字をシンボルとして使用します。注意すべきは、extractfilesymlinkdirectory以外のレコードタイプの抽出を拒否し、liststrict=falseで呼び出された場合にのみ他の種類のレコードをリストします。

tarフォーマットには、ユーザーおよびグループID、ユーザーおよびグループ名、タイムスタンプなど、レコードに関するさまざまな他のメタデータが含まれていますが、Tarパッケージは設計上、これらを完全に無視します。tarファイルを作成する際、これらのフィールドは常にゼロ/空に設定されます。tarファイルを読み取る際、これらのフィールドは、すべてのフィールドの各ヘッダーレコードのヘッダーチェックサムを検証することを除いて無視されます。

source