Artifacts

An artifact is an object that represents a file system entry. There are three kinds of artifacts: directories, files, and symlinks.

type Artifact = tg.Directory | tg.File | tg.Symlink;

Files

A file is an object that represents a file. It stores:

type File = {
// The file's contents as a blob.
contents: tg.Blob;
// An array of artifacts that the file depends on. When the file is checked out, the dependencies will also be checked out. This is how executable files in Tangram are able to access their dynamic libraries and other files they are wrapped with.
dependencies: Array<tg.Artifact>;
// A boolean indicating if the file is executable. Tangram files do not store permissions other than the executable bit.
executable: boolean;
};

In Tangram TypeScript, use the file constructor tg.file to create a file.

// Create a file from a string.
let file = tg.file("Hello, World!");
// Create a file by specifying all fields.
let file = tg.file({
contents: new Uint8Array(),
executable: false,
references: [],
});

Directories

A directory is an object that represents a directory. It stores entries, which are names mapped to artifacts.

type Directory = {
entries: { [name: string]: Artifact };
};

The directory constructor makes it easy to build and compose directories.

// Create a directory with nested paths.
let a = tg.directory({
"hello.txt": tg.file("Hello, World!"),
directory: tg.directory({
"path/to/hello.txt": "Hello, World!",
}),
});
// Create a directory with a symlink.
let b = tg.directory({
bar: tg.symlink("./foo"),
});
// Merge the directories together.
let c = tg.directory(a, b);

A symlink is an object that represents a symlink. It stores:

  • artifact: An artifact that the symlink references.
  • path: A path, relative to artifact if it is set, otherwise relative to the symlink itself.
/// A simple symlink.
let symlink = tg.symlink("./foo/bar/baz");
/// A symlink referring to a path within an artifact.
let symlink = tg.symlink(artifact, "./subpath");

Checkin and Checkout

Artifacts can be checked in and checked out from the filesystem.

$ echo "Hello, World\!" > hello.txt
$ tg checkin hello.txt
fil_01r4jx5ae6bkr2q5gbhewjrdzfban0kx9pmqmvh2prhkxwxj45mg6g
$ tg checkout fil_01r4jx5ae6bkr2q5gbhewjrdzfban0kx9pmqmvh2prhkxwxj45mg6g world.txt
world.txt
$ cat world.txt
Hello, World!

Virtual Filesystem

Artifacts are exposed via a virtual filesystem, either FUSE or NFS, mounted by default at $HOME/.tangram/artifacts. The virtual filesystem makes it so that artifacts are downloaded only when they are accessed and common files between artifacts do no need to be duplicated.

$ tg checkin hello.txt
fil_01r4jx5ae6bkr2q5gbhewjrdzfban0kx9pmqmvh2prhkxwxj45mg6g
$ cat $HOME/.tangram/artifacts/fil_01r4jx5ae6bkr2q5gbhewjrdzfban0kx9pmqmvh2prhkxwxj45mg6g
Hello, World!

Bundling

Bundling an artifact creates a new artifact which is the same as the original, but with all dependencies removed and placed in a subdirectory at .tangram/artifacts. Here is an example:

export default tg.target(() => {
let foo = tg.file({
contents: fooBytes,
dependencies: [libBaz],
executable: true,
});
let bar = tg.symlink(barArtifact, "bin/bar");
return tg.directory({
"bin/foo": foo,
"bin/bar": bar,
});
});
$ tg build -c output
output
$ tree output
output
.tangram/artifacts
dir_bar
bin
bar
dir_libbaz
lib
libbaz.so
bin
foo
bar -> ../.tangram/artifacts/dir_bar/bin/bar

When you check out a bundled artifact, it no longer has a dependency on Tangram, because all its are contained in the checked out bundle. For more information on bundling, see wrappers.