mario-eth / soldeer

Solidity Package Manager written in rust
MIT License
241 stars 26 forks source link

feat!: v0.4.0 rewrite #202

Closed beeb closed 1 month ago

beeb commented 2 months ago

Version 0.4.0 marks a big step in the evolution of the soldeer codebase and implements many new features and improvements compared to previous releases. Below are the main points.

New code structure

The codebase has been split into 3 crates to enable integration of the soldeer core logic and CLI commands with other applications.

In the future, I would like to further reduce the coupling between the soldeer-core crate and cliclack UI library, so that logging can be made agnostic of the (T)UI, but still be integrated nicely with it.

Version requirement specifiers

Dependencies were previously specified with at least a name and a version. Starting with this release, the version can be a version requirement specifier. The format follows the semver::VersionReq comparator specification, with the notable exception that the absence of an operator is considered to mean "exact" (similar to what solidity does).

Remappings format

In remappings, the default behavior is to include the version requirement string as a suffix to the left-hand side path. As an example, this enables the following:

[profile.default]
remappings = [
    "forge-std-1/=dependencies/forge-std-1.9.2/",
    "@openzeppelin-contracts-5/=dependencies/@openzeppelin-contracts-5.0.2/",
    "@openzeppelin-contracts-legacy/=dependencies/@openzeppelin-contracts-4.9.6/"
]

[dependencies]
forge-std = "1"
"@openzeppelin-contracts" = "5"
"@openzeppelin-contracts-legacy" = "4.9.6"

Remappings customization is now also handled properly, meaning that the left-hand side part can be customized to anything, which won't get overwritten when commands are ran without the --regenerate-remappings option. The right part can likewise be customized to include additional path segments after the dependency's directory. Examples:

[profile.default]
remappings = [
    "forge-std/=dependencies/forge-std-1.9.2/src/",
    "@openzeppelin/contracts/=dependencies/@openzeppelin-contracts-5.0.2/contracts/",
    "@openzeppelin/contracts-legacy/=dependencies/@openzeppelin-contracts-upgradeable-4.9.6/contracts/"
]

New progress and prompts UI

The UI now uses cliclack to display progress and prompt the user for information. This is a significantly nicer experience than previously.

Improved install command

The install command now avoids to perform useless work by checking already installed dependencies and skipping associated downloads. For git dependencies, most operations leverage available git commands to avoid unnecessary clones.

Each dependency is installed in parallel, with more pipelining and thus a shorter total install time even if all dependencies must be installed.

Improved update command

Previously the update command was not performing according to user expectations. Now, the command updates dependencies which satisfy these requirements:

The lockfile stores the exact installed version so that installs are reproducible. When the update command is ran, the lockfile is updated with the new versions.

Improved init command

The init command is now smarter and does slightly more:

New lockfile format

The new lockfile format has differentiated entries for Git vs HTTP dependencies, allowing for a more concise and explicit representation. For HTTP dependencies, the zip archive checksum is stored and checked upon downloading. If the hash is different, installation is aborted. Likewise, the unzipped dependency is hashed upon installation and checked to avoid re-installing an existing dependency.

New test suite

All tests have been rewritten to enable running them in parallel. All IO side effects are contained to special temporary folders thanks to testdir. API mocking is performed with mockito and environment variables are mocked with temp-env.

The new suite runs significantly faster than the old one and can be efficiently parallelized with cargo-nextest, which is the recommended way to run them.

All tests are now ran in CI on Linux, macOS and Windows.

Various fixes and performance improvements

Various bugfixes have been implemented during the refactor, either as a result of the change in architecture or because they showed up in unit/integration tests. Some functions have been refactored to improve performance and parallelism.

Closes #188 Closes #182 Closes #181 Closes #156 Closes #155 Closes #153 Closes #152 Closes #144 Closes #138 Closes #134 Closes #120 Closes #108 Closes #46