With this package you can both create and extract tar archives using
createArchive List (Metadata, Data) -> Bytes
extractArchive : Bytes -> List ( MetaData, Data )The Data type discriminates between string and binary data:
type Data
= StringData String
| BinaryData BytesThe MetaData type is complex and reflects the official tar specification:
type alias MetaData =
{ filename : String
, mode : Mode
, ownerID : Int
, groupID : Int
, fileSize : Int
, lastModificationTime : Int
, linkIndicator : Link
, linkedFileName : String
, userName : String
, groupName : String
, fileNamePrefix : String
, typeFlag : Ascii
}The mode carries Unix file permissions, e.g., 644. The fileNamePrefix
can be thought of as the name of the folder/directory in which the files
to be processed live.
Because filling out this record is something a pain, a defaultMetadata : MetaData
value is provided. It can be modified as needed.
To give a simple example, we make define some binary data and check that it is what we think it is:
> import Hex -- from jxxcarlson/hex
> import Bytes.Encode as E -- from elm/bytes
> null = E.encode (E.unsignedInt8 0)
<1 bytes> : Bytes.Bytes
> bytes = Hex.toBytes "0001A1FF" |> Maybe.withDefault null
<4 bytes> : Bytes.Bytes
> Hex.fromBytes bytes
"0001A1FF" : StringNext, we create an archive consisting of one text file and one binary file:
import Tar exposing(..)
metadata = { defaultMetadata | filename = "test123.txt" }
text = "This is a test (ho ho ho).\nIt is a frabjous day!"
metadata2 = { defaultMetadata | filename = "foo.binary" }
> archive = createArchive [ ( metadata, StringData text ), ( metadata2, BinaryData bytes ) ]
<3072 bytes> : Bytes.Bytes
File.Download.bytes "test.tar" "application/x-tar" archive
<internals> : Cmd msg -- You can't do this one in the repl.(1) There is an unresolved problem of how to properly encode the metadata
of text files so that extractArchive knows to decode the content
as a string. At the moment, archived files whose content is to be
decoded as a string are recognized by their file extension. The
admissible text files have extension in the list
[ "text", "txt", "tex", "csv" ]This is an unsatisfactory solution, but at the moment, I don't know how to get around it.
(2) The fileNamePrefix in the metadata is the name of the folder
into which the files willl be decoded.
As Runar Furenes (@ruf) pointed out to me, there was an asymmetry in the
way metadata was treated: not the same for extractArchive as for createArchive.
This sort of thing is almost always a sign of bad design and poor esthetic judgement.
I've fixed it, so the type signatures are now as above. Much better!
Well, we really do need some tests, as @ruf also noted. [Thanks Runar!] We do have some rudimentary ones now:
> import Tests exposing(..)
> checkListAsString stringTestData
[(0,True),(1,True),(2,True)]
> checkListAsBinary binaryTestData
> [(0,True),(1,True)] : List ( Int, Bool )See the module Test to see what these results
mean. Basically, (k, True) means that the k-th test passes. More detalis in Tests.md.
For a demo, run elm make Main.elm in /examples, then click on the resulting index.html file.
I've used https://en.wikipedia.org/wiki/Tar_(computing) as my reference for the tar file format.
Many thanks to Folkert deVries for important bug fix (handling of unicode characters)