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 6 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
148 changes: 148 additions & 0 deletions templates/install/tricks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
# Tips and Tricks about Lean Projects

These tips and tricks about managing Lean projects should be considered workarounds or common practice. Some care is adviced when trying these non-standard setups.
joneugster marked this conversation as resolved.
Show resolved Hide resolved

*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, e.g. because you have little
joneugster marked this conversation as resolved.
Show resolved Hide resolved
disk space available, it might be worth setting them up using one centralised mathlib instead of
letting every project download there own clone.
joneugster marked this conversation as resolved.
Show resolved Hide resolved

Here is a guide on best practise on how to achieve that.
joneugster marked this conversation as resolved.
Show resolved Hide resolved

1) First, clone the version of mathlib somewhere on your computer:
joneugster marked this conversation as resolved.
Show resolved Hide resolved
```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.

(If you don't have git setup correctly using an SSH key, you might want to use `git clone --branch v4.10.0 https://github.com/leanprover-community/mathlib4.git` instead.)
joneugster marked this conversation as resolved.
Show resolved Hide resolved
2) Go inside your mathlib and download cache:
joneugster marked this conversation as resolved.
Show resolved Hide resolved
```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) Now if you don't already have a Lean project, create it
joneugster marked this conversation as resolved.
Show resolved Hide resolved
```bash
lake new MyProject math.lean
cd MyProject
```
5) In the project `MyProject` you need to modify two things:
<!-- 1) Make sure `lean-toolchain` contains the string `leanprover/lean4:v4.10.0` with the same version your shared mathlib is at. -->
joneugster marked this conversation as resolved.
Show resolved Hide resolved
* 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
````
joneugster marked this conversation as resolved.
Show resolved Hide resolved
*(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 save action as it only contains build artifacts that are fully recovered by the next `lake` call.)*
joneugster marked this conversation as resolved.
Show resolved Hide resolved
* Your project should be ready and when you add `import Mathlib` in a file and click "Restart File" in VSCode, it should be reasonably quick without rebuilding mathlib.
joneugster marked this conversation as resolved.
Show resolved Hide resolved
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.
Comment on lines +63 to +71
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.
6) Updating your global mathlib should, 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 whatever broke again.

You should not need to lake update a relative dependency. (as path dependencies are not versioned).


## 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)
```