Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/content/en-US/docs/2.reference/3.lockfile.md
blob: af53ae246bfaec33d7f6a5978f1f363e4235eef0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
---
title: "The lockfile"
description: "LOCK.sqlite3 lies beside the project file."
source: "https://github.com/Progmasoft/tazel/blob/main/Documents/LOCKFILE.md"
---

<!-- SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com> -->
<!-- SPDX-License-Identifier: MPL-2.0 WITH AdditionRef-Progmasoft-Exception-2.0 -->

`LOCK.sqlite3` lies beside the project file. It is an SQLite database that records what the project declares: its
dependencies, with their features, and the plugins that evaluated the project file, with the digest of each JAR. It
records declarations, not a solved dependency graph; Tazel cannot fetch packages from ViGet yet, so there is nothing to
solve.

Commit `LOCK.sqlite3` with the project file. Its text form, `LOCK.dump`, is for reading and reviewing a change.

## When it is written

| Command | What happens to `LOCK.sqlite3` |
| --- | --- |
| `tazel lock resolve` | written for the project and for every member of its workspace |
| `tazel check`, `build`, `run` | written before a project is compiled, when it no longer records what the project declares |
| `tazel lock graph` | written when it is missing or out of date; with `--locked` an out-of-date file is an error instead |
| `tazel lock create-dump` | read only |

"Out of date" is decided by content: Tazel reads the file and compares what it records with what the project file
declares now. A file of an older format, a damaged file and a missing one are all out of date.

A new lockfile is written to a temporary file in the same directory and then moved over the old one, atomically where
the file system allows it, so an interrupted write never leaves half a lockfile behind.

## Format 5

The `metadata` table holds the format: `format_version` is `5`. Format 5 is format 4 with the stability `RC`, so a file
of format 4 is read as it is and stays until the project changes. A lockfile of any other format is not read; Tazel
asks for `tazel lock resolve`, which writes the current one. Versions of Tazel before format 5 refuse a file of format
5 the same way.

| Table | Key | Columns |
| --- | --- | --- |
| `metadata` | `key` | `value`; holds `format_version` |
| `packages` | `name`, `scope` | `stability`, `version`, `feature` (the feature of this project that brings the package in, or `NULL`), `default_features` (`0` or `1`) |
| `package_features` | `package_name`, `scope`, `feature` | `enabled` (`0` or `1`): the features of the dependency itself that the project turns on or off |
| `local_packages` | `path`, `scope` | the `.vipkg` files the project names, relative to the project file |
| `plugins` | `publisher`, `name` | `version`, `api_version`, `sha256` (64 hex digits) |

`name` in `packages` is the coordinate of the package, `Publisher.Name`. `scope` is `BUILD` for `dependency` and
`localDependency`, `TEST` for `testDependency` and `localTestDependency`. Every table is `WITHOUT ROWID`: a row is identified by
its key alone, so one package cannot be recorded twice in one scope.

For this project file:

```kotlin
dependencies {
  dependency("Publisher") {
    name = "Toml"
    version = "1.0.0"
    feature = "TOML"
    defaultFeatures = false
    feature("Serde") { enabled = true }
  }
  localDependency { path = "Libraries/Shared.vipkg" }
}
```

the lockfile holds:

| Table | Row |
| --- | --- |
| `packages` | `Publisher.Toml`, `BUILD`, `STABLE`, `1.0.0`, `TOML`, `0` |
| `package_features` | `Publisher.Toml`, `BUILD`, `Serde`, `1` |
| `local_packages` | `Libraries/Shared.vipkg`, `BUILD` |

## The text dump

```text
tazel lock create-dump
tazel lock create-dump --path reviews/Locks.sql
```

`LOCK.dump` is SQL that SQLite can replay: a header comment, `PRAGMA foreign_keys=OFF;`, then one transaction with the
`CREATE TABLE` statement of every table followed by its rows. Tables come in the order of their names and rows in the
order of their columns, so the same lockfile always gives the same bytes and a diff shows only what changed.

To turn a dump back into a database:

```text
sqlite3 LOCK.sqlite3 < LOCK.dump
```

The dump is never written over the binary lockfile, and its folder has to exist; see
[the command](/docs/reference/commands#writing-the-lockfile-as-text).

## The dependency graph

`tazel lock graph` draws what the lockfiles record, so it renews them first. It shows each project of the workspace as
a root, its ViGet and local packages below it, and the test dependencies under `[test]`. A package that a feature
brings in is shown only while that feature is on. The options are described with [the command](/docs/reference/commands#the-dependency-graph).