Skip to content

Commit

Permalink
Add forc BuildPlan. Change GitHub dependencies to general git suppo…
Browse files Browse the repository at this point in the history
…rt. Add `Forc.lock` for more deterministic builds. (FuelLabs#825)

* Construct `pkg_graph` at beginning of `forc build`

This is a start at separating the construction of the dependency graph
and fetching of dependency source from the compilation process. This is
done under a new `fetch_pkgs` function where, given the manifest of the
package we're compiling, it produces a graph where each node represents
a package at a known, pinned version/commit along with a `Path` to a
local copy of their source (under `.forc/git/checkouts` for git deps).

The `pkg_graph` also contains our root-level package, allowing us to
treat all packages in the compilation process as equal, avoiding special
case code for the top-level program.

The compilation order of packages is determined by performing a toposort
of the `pkg_graph`. By compiling packages in this order, each node is
always guaranteed to have access to the compiled artifacts of each of
its dependencies.

This PR also introduces the `git2` crate for fetching and working with
git dependencies. This should allow us to remove the current
github-specific dependency handling in favour of more general git
support.

---

I think the next step in this PR will be replacing the existing
`dependency_graph` mutable hash map reference with an immutable
reference to the newly constructed `pkg_graph`. It seems this may also
involve populating the `Namespace` prior to the rest of compilation too?
I'm still familiarising myself with `sway-core`, so will need to dive a
bit deeper to be sure.

* Replace old dependency compilation with new `pkg_graph` approach

This removes the old dependency-specific compilation logic in favour of
flattening the graph into a list of compilation steps and using the same
`compile_pkg` function to compile all packages, including at the
top-level package.

* Move `pkg`-specific code into a new `pkg` submodule

* Address cargo fmt and clippy nits

* Remove implied pkg from idents in pkg submodule

* Add support for specifying git dependency via tag

* Fix dependency path handling to be relative to parent

* Remove github-specific logic in favour of new git pkg handling

See FuelLabs#829.

This also temporarily disables `forc update` and the related
`forc_dep_check` module pending more general `git` support and
committing updates to a `Forc.lock` file.

* Improve support for determinism and cachability with `Forc.lock`

This adds a `Forc.lock` file that for the most part mirrors the
`Cargo.lock` file.

If a `Forc.lock` doesn't exist, a `Lock` structure is created from the
package graph and serialised to TOML before being written to the
`Forc.lock` file path.

If a `Forc.lock` *does* exist, we construct the build graph from the
`Lock` structure, re-using the previously fetched source for the pinned
dependencies.

TODO:

- Make `forc update` update the lock file.
- Add support for updating individual packages.

* Move `BuildPlan` under `pkg` module in anticipation for `forc update`

* Update `forc update` for lock. Print removed and added deps.

A new `lock::Diff` type is added to collect added/removed packages.

* Address doc comment nits

* Validate `Lock` in accordance with `Manifest`

This ensures that if any `Forc.toml` dependencies are added, removed or
modified, the change is detected during `forc build` and the `Forc.lock`
file is updated accordingly.

* Improve formatting of `Forc.lock` related stdout

* Update sway-core petgraph version so that it matches forc

* Update test and examples to pin via git tag rather than version field

Addresses FuelLabs#829.

Also allows for putting off FuelLabs#831 while we discuss FuelLabs#830.

* Update some E2E tests due to unpinned `core` dep in `std`

None of the `std` releases so far pin `core` to a version. As a result,
it pulls the `core` master branch by default, despite the top-level
project also dependending on `core` at a specific version. Most E2E
tests seemt to work regardless, but this subset requires updating.
Following the lock file work landing, we should update versioned `std`
releases to refer to versioned `core` via git tag.

* Only fetch pkgs that are missing, rather than whole pkg graph

Previously if any of the pkgs that exist in `Forc.lock` were not already
available in `~/.forc/git/checkouts`, we would update the entire lock
file and re-fetch all dependencies. Now, if the local copy of a pkg is
missing, we just fetch that individual pkg and continue.

This commit also updates the `fetch_pkgs` code to re-use pre-fetched git
commits. Previously, all packages would be re-fetched when the
`Forc.lock` file was updated. Now, we only fetch if the path for that
commit doesn't already exist.

* Update forc git dep from 0.13 to 0.14

* Fix forc Cargo.toml dependency order

* Update Cargo.lock for the addition of git2, petgraph

* Add Forc.lock files for sway examples

* Ensure `Namespace` only contains a package's dependencies

Previously one namespace was used to collect *all* items. This meant
that when passed to the package that was being compiled, the namespace
contained not only the names for its dependencies, but sometimes other
unrelated names that happened to be earlier in the compilation order.

This commit fixes this issue, creating a fresh namespace purely for each
package in order to collect only its dependencies. This fixes some
shadowing errors that were appearing in the E2E tests.

* Pin tests by adding their `Forc.lock` files for reproducibility

As a follow-up, we should update all of the tests to depend on `master`
and then update the lock files. This will save us from having to change
versions tags to pin all the time.

Note: You can clear all test lock files with

```
rm ./test/src/e2e_vm_tests/test_programs/*/Forc.lock
```

* Temporarily warn about `version` field in dependencies

We no longer use the GitHub REST API and in turn no longer map the
`version` field to GitHub "release"s. Instead, we now support git more
generally. Warn about appearances of the `version` field in dependencies
and suggest using `branch` or `tag` as an alternative.

* Address nits uncaught in anyhow PR review

* Fix formatting following rebase onto forc anyhow PR
  • Loading branch information
mitchmindtree authored Mar 4, 2022
1 parent e2fd41e commit 45250e4
Show file tree
Hide file tree
Showing 201 changed files with 2,978 additions and 1,015 deletions.
69 changes: 64 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions examples/fizzbuzz/Forc.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[[package]]
name = 'core'
source = 'git+http://github.com/FuelLabs/sway-lib-core?reference=master#c331ed20ebc9d646acec6b8ee8f408627ce3b573'
dependencies = []

[[package]]
name = 'core'
source = 'git+http://github.com/FuelLabs/sway-lib-core?reference=v0.0.1#45c54ab37abde32a10e20964264cf7362dd73caa'
dependencies = []

[[package]]
name = 'fizzbuzz'
dependencies = [
'core git+http://github.com/FuelLabs/sway-lib-core?reference=v0.0.1#45c54ab37abde32a10e20964264cf7362dd73caa',
'std git+http://github.com/FuelLabs/sway-lib-std?reference=v0.0.1#5a0938f8248d820ef178b6efd9c105463c543226',
]

[[package]]
name = 'std'
source = 'git+http://github.com/FuelLabs/sway-lib-std?reference=v0.0.1#5a0938f8248d820ef178b6efd9c105463c543226'
dependencies = ['core git+http://github.com/FuelLabs/sway-lib-core?reference=master#c331ed20ebc9d646acec6b8ee8f408627ce3b573']
4 changes: 2 additions & 2 deletions examples/fizzbuzz/Forc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ license = "Apache-2.0"
name = "fizzbuzz"

[dependencies]
std = { git = "http://github.com/FuelLabs/sway-lib-std", version = "v0.0.1" }
core = { git = "http://github.com/FuelLabs/sway-lib-core", version = "v0.0.1" }
std = { git = "http://github.com/FuelLabs/sway-lib-std", tag = "v0.0.1" }
core = { git = "http://github.com/FuelLabs/sway-lib-core", tag = "v0.0.1" }
21 changes: 21 additions & 0 deletions examples/hello_world/Forc.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[[package]]
name = 'core'
source = 'git+http://github.com/FuelLabs/sway-lib-core?reference=master#c331ed20ebc9d646acec6b8ee8f408627ce3b573'
dependencies = []

[[package]]
name = 'core'
source = 'git+http://github.com/FuelLabs/sway-lib-core?reference=v0.0.1#45c54ab37abde32a10e20964264cf7362dd73caa'
dependencies = []

[[package]]
name = 'hello_world'
dependencies = [
'core git+http://github.com/FuelLabs/sway-lib-core?reference=v0.0.1#45c54ab37abde32a10e20964264cf7362dd73caa',
'std git+http://github.com/FuelLabs/sway-lib-std?reference=v0.0.1#5a0938f8248d820ef178b6efd9c105463c543226',
]

[[package]]
name = 'std'
source = 'git+http://github.com/FuelLabs/sway-lib-std?reference=v0.0.1#5a0938f8248d820ef178b6efd9c105463c543226'
dependencies = ['core git+http://github.com/FuelLabs/sway-lib-core?reference=master#c331ed20ebc9d646acec6b8ee8f408627ce3b573']
4 changes: 2 additions & 2 deletions examples/hello_world/Forc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ license = "Apache-2.0"
name = "hello_world"

[dependencies]
std = { git = "http://github.com/FuelLabs/sway-lib-std", version = "v0.0.1" }
core = { git = "http://github.com/FuelLabs/sway-lib-core", version = "v0.0.1" }
std = { git = "http://github.com/FuelLabs/sway-lib-std", tag = "v0.0.1" }
core = { git = "http://github.com/FuelLabs/sway-lib-core", tag = "v0.0.1" }
21 changes: 21 additions & 0 deletions examples/subcurrency/Forc.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[[package]]
name = 'core'
source = 'git+http://github.com/FuelLabs/sway-lib-core?reference=master#c331ed20ebc9d646acec6b8ee8f408627ce3b573'
dependencies = []

[[package]]
name = 'core'
source = 'git+http://github.com/FuelLabs/sway-lib-core?reference=v0.0.1#45c54ab37abde32a10e20964264cf7362dd73caa'
dependencies = []

[[package]]
name = 'std'
source = 'git+http://github.com/FuelLabs/sway-lib-std?reference=v0.0.1#5a0938f8248d820ef178b6efd9c105463c543226'
dependencies = ['core git+http://github.com/FuelLabs/sway-lib-core?reference=master#c331ed20ebc9d646acec6b8ee8f408627ce3b573']

[[package]]
name = 'subcurrency'
dependencies = [
'core git+http://github.com/FuelLabs/sway-lib-core?reference=v0.0.1#45c54ab37abde32a10e20964264cf7362dd73caa',
'std git+http://github.com/FuelLabs/sway-lib-std?reference=v0.0.1#5a0938f8248d820ef178b6efd9c105463c543226',
]
4 changes: 2 additions & 2 deletions examples/subcurrency/Forc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ license = "Apache-2.0"
name = "subcurrency"

[dependencies]
std = { git = "http://github.com/FuelLabs/sway-lib-std", version = "v0.0.1" }
core = { git = "http://github.com/FuelLabs/sway-lib-core", version = "v0.0.1" }
std = { git = "http://github.com/FuelLabs/sway-lib-std", tag = "v0.0.1" }
core = { git = "http://github.com/FuelLabs/sway-lib-core", tag = "v0.0.1" }
21 changes: 21 additions & 0 deletions examples/wallet_smart_contract/Forc.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[[package]]
name = 'core'
source = 'git+http://github.com/FuelLabs/sway-lib-core?reference=master#c331ed20ebc9d646acec6b8ee8f408627ce3b573'
dependencies = []

[[package]]
name = 'core'
source = 'git+http://github.com/FuelLabs/sway-lib-core?reference=v0.0.1#45c54ab37abde32a10e20964264cf7362dd73caa'
dependencies = []

[[package]]
name = 'std'
source = 'git+http://github.com/FuelLabs/sway-lib-std?reference=v0.0.1#5a0938f8248d820ef178b6efd9c105463c543226'
dependencies = ['core git+http://github.com/FuelLabs/sway-lib-core?reference=master#c331ed20ebc9d646acec6b8ee8f408627ce3b573']

[[package]]
name = 'wallet_smart_contract'
dependencies = [
'core git+http://github.com/FuelLabs/sway-lib-core?reference=v0.0.1#45c54ab37abde32a10e20964264cf7362dd73caa',
'std git+http://github.com/FuelLabs/sway-lib-std?reference=v0.0.1#5a0938f8248d820ef178b6efd9c105463c543226',
]
4 changes: 2 additions & 2 deletions examples/wallet_smart_contract/Forc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ license = "Apache-2.0"
name = "wallet_smart_contract"

[dependencies]
std = { git = "http://github.com/FuelLabs/sway-lib-std", version = "v0.0.1" }
core = { git = "http://github.com/FuelLabs/sway-lib-core", version = "v0.0.1" }
std = { git = "http://github.com/FuelLabs/sway-lib-std", tag = "v0.0.1" }
core = { git = "http://github.com/FuelLabs/sway-lib-core", tag = "v0.0.1" }
10 changes: 6 additions & 4 deletions forc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ anyhow = "1.0.41"
clap = { version = "3.1.2", features = ["env", "derive"] }
clap_complete = "3.1"
dirs = "3.0.2"
flate2 = "1.0.20"
fuel-asm = "0.1"
fuel-asm = "0.1"
fuel-gql-client = { version = "0.3", default-features = false }
fuel-tx = "0.5"
fuel-vm = "0.4"
futures = "0.3"
git2 = "0.14"
hex = "0.4.3"
petgraph = { version = "0.6.0", features = ["serde-1"] }
prettydiff = "0.5.0"
reqwest = { version = "0.11.4", default-features = false, features = ["json", "rustls-tls"] }
semver = "1.0.3"
Expand All @@ -38,11 +39,12 @@ term-table = "1.3"
termcolor = "1.1"
tokio = { version = "1.8.0", features = ["macros", "rt-multi-thread", "process"] }
toml = "0.5"
unicode-xid = "0.2.2"
ureq = "2.4"
url = "2"
uwuify = { version = "^0.2", optional = true }
warp = "0.3"
whoami = "1.1"
unicode-xid = "0.2.2"
uwuify = { version = "^0.2", optional = true }

[features]
default = []
Expand Down
2 changes: 2 additions & 0 deletions forc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#![allow(dead_code)]
mod cli;
mod lock;
mod ops;
mod pkg;
mod utils;

#[cfg(feature = "test")]
Expand Down
Loading

0 comments on commit 45250e4

Please sign in to comment.