Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doc: add tips about lake usage #510

Open
wants to merge 10 commits into
base: lean4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion templates/install/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ a portmanteau of `lean` and `make`).
This page describes the basic use of this tool, and should be sufficient
for everyday use.
If this is not enough for your purposes, you can read the
full [lake documentation](https://github.com/leanprover/lake/blob/master/README.md).
full [lake documentation](https://github.com/leanprover/lean4/blob/master/src/lake/README.md).

## Working on an existing project

Expand Down Expand Up @@ -123,6 +123,16 @@ More information about Lake can be found [here](https://github.com/leanprover/le

See [How to contribute to mathlib](https://leanprover-community.github.io/contribute/index.html).

## Further Tips and Tricks

If you are interested in a custom setup,
you can read [Tips and Tricks](tricks.html).

This contains some notes about
* Setting up a shared, *global/centralised* mathlib installation.
* Automatically follow stable versions of dependencies.
* Using build options to switch to local package versions.

## Troubleshooting

* Some Windows users have reported an error like this when running `lake exe cache get`:
Expand Down
160 changes: 160 additions & 0 deletions templates/install/tricks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
# Tips and Tricks about Lean Projects

These tips and tricks about managing Lean projects should be considered workarounds.
Some care is adviced when trying these non-standard setups.

*Note:* Things here might change as `lake` is being developed, as features described here are not necessarily officially supported by `lake`. This file has been written for Lean `v4.10.0`. If in doubt, ask for help on [Zulip](https://leanprover.zulipchat.com).

## Shared Mathlib

If you start many projects which all use the latest stable version of mathlib
by default each project will download its own clone.
If you, for example, have little disk space available,
it might be worth setting them up using one centralised copy of mathlib instead.

*Note*: This means additional effort when upgrading the mathlib version,
as you need to update all your projects at once.

*Note*: Whenever this tutorial mentions the `lakefile.lean`, you should make the mentioned
modifications to your `lakefile.toml` if you have this instead. Every Lean project
has exactly one of these two configuration files.

Here is the current best practice to achieve this.

1) First, clone a version of mathlib somewhere on your computer:
```bash
git clone --branch v4.10.0 [email protected]:leanprover-community/mathlib4.git
```
Note that `v4.10.0` is the tag of the latest release, you can look at [mathlib's tags](https://github.com/leanprover-community/mathlib4/tags) to find out which is the most recent release version.

The above line assumes you have set up git using an SSH key.
If you have not set this up correctly, you may want to
use `git clone --branch v4.10.0 https://github.com/leanprover-community/mathlib4.git` instead.

2) Go inside your mathlib and download the current cache:
```bash
cd mathlib
lake exe cache get
```
3) If you ever want to **update** your global mathlib, come back to the mathlib directory and call
```bash
git checkout v4.11.0
lake exe cache get
```
with the [version](https://github.com/leanprover-community/mathlib4/tags) you'd like to update to.
4) If you don't already have a Lean project, create it.
```bash
lake new MyProject math.lean
cd MyProject
```
5) In the project `MyProject` you need to modify the following things:
* Make sure `lean-toolchain` contains the string `leanprover/lean4:v4.10.0` with the same version your shared mathlib is at.
* In `lakefile.lean`, replace the line `require "leanprover-community" / "mathlib"` with
```
require mathlib from ".." / "relative" / "path" / "to" / "mathlib4"
```
* Now inside `MyProject` you need to clean up lake:
```bash
rm -rf .lake # because `lake clean` does not remove `.lake/packages/mathlib` which might have been downloaded by `lake new`.
lake clean # or potentially `lake update -R mathlib` instead
```
*(note: it looks like a bug that with a simple `lake clean`, there might still be a folder `.lake/packages/mathlib` floating around from before you changed the `lakefile.lean`. However, deleting `.lake/` is a reasonably safe action as it only contains build artifacts that are fully recovered by the next `lake` call.)*
* Your project should be ready: when you add `import Mathlib` in a file and click "Restart File" in VSCode, it should be reasonably quick, without rebuilding mathlib.
6) When you updated your global mathlib it might be enough to call
```
lake update -R mathlib
```
which would in theory update everything automatically.
However, if there are breaking changes to the `lakefile` parsing, you might need to
* edit `lean-toolchain` to be the same as your global mathlib.
* make sure `lakefile.lean` parses without error in the new version.
* try `lake update -R mathlib` again.

## Following stable versions of dependencies

If your Lean project only wants to following the stable releases of dependencies (i.e. `v4.10.0`, `v4.11.0`, etc.) you could do the following trick:

In your `lakefile.lean`, add

```lean
def leanVersion : String := s!"v{Lean.versionString}"
```

and then suffix all `require`s with `@ leanVersion`:

```
require "leanprover-community" / "mathlib" @ leanVersion
```

*Note:* for this to work, the repository of each dependency needs to have a tag (or branch) for the Lean version you're using, e.g. look at [the mathlib tags](https://github.com/leanprover-community/mathlib4/tags).

If you specified the version for all dependencies in your project, you can then update your project simply by

* Edit `lean-toolchain` to have the new toolchain `leanprover/lean4:v4.11.0`.
* Call `lake update -R`.

*(note: a blank `lake update -R` is only reasonable if **all** required dependencies in your project have a version specified with `@`)*



## Using local dev version of a dependency

In rare circumstances you might want to use a local copy of a dependency (e.g. `mathlib`) when developing, i.e. to test changes immediately.

You could do this by using a local dependency while developing
```
require mathlib from ".." / "mathlib4"
```
and then change it back to the remote dependency before pushing changes:
```
require "leanprover-community" / "mathlib"
```

However, if you want to do this frequently, here might be a better setup. With the suggested modifications to the `lakefile.lean` below, you get the following behaviour:

* To use the local dependency, call
```
lake update -R -Kmathlib.useDev mathlib
```
* To switch back to the remote dependency, call
```
lake update -R mathlib
```
* Anybody `require`-ing your project as dependency in there own project will automatically get the remote version of the dependencies.

(*Note:* make sure to read the chapter above about specifying versions when using `lake update`).

For this you need to replace `require "leanprover-community" / "mathlib"` in your `lakefile.lean` with the following instructions:

```lean
/-- The local dependency. Using a relative path. -/
def LocalMathlib : Dependency := {
name := `mathlib
src? := some <| .path (".." / "mathlib4")
scope := ""
version? := none
opts := {}
}

/-- The remote dependency. Note that "master" is the tag/branch you want to clone from. -/
def RemoteMathlib : Dependency := {
name := `mathlib
/--
You can also write `src? := none` to get the package from Reservoir instead
(if `scope` is specified correctly),
or you can replace `"master"` with `none` to not specify the input branch/tag.
-/
src? := some <| .git "https://github.com/leanprover-community/mathlib4.git" "master" none
scope := "leanprover-community"
version? := none
opts := {}
}

/- Choose `mathlib` dependency locally if `-Kmathlib.useDev` is provided. -/
open Lean in
#eval (do
let depName := if get_config? mathlib.useDev |>.isSome then
``LocalMathlib else ``RemoteMathlib
modifyEnv (fun env => Lake.packageDepAttr.ext.addEntry env depName)
: Elab.Command.CommandElabM Unit)
```