##// END OF EJS Templates
rust: change minimum supported version everywhere applicable...
Raphaël Gomès -
r52599:541292a0 default
parent child Browse files
Show More
@@ -1,177 +1,177 b''
1 # flake.nix - Nix-defined package and devel env for the Mercurial project.
1 # flake.nix - Nix-defined package and devel env for the Mercurial project.
2 #
2 #
3 # Copyright 2021-2023 Pacien TRAN-GIRARD <pacien.trangirard@pacien.net>
3 # Copyright 2021-2023 Pacien TRAN-GIRARD <pacien.trangirard@pacien.net>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 # Usage summary, from the root of this repository:
8 # Usage summary, from the root of this repository:
9 #
9 #
10 # Enter a shell with development tools:
10 # Enter a shell with development tools:
11 # nix develop 'hg+file:.?dir=contrib/nix'
11 # nix develop 'hg+file:.?dir=contrib/nix'
12 #
12 #
13 # Running mercurial:
13 # Running mercurial:
14 # nix run 'hg+file:.?dir=contrib/nix' -- version
14 # nix run 'hg+file:.?dir=contrib/nix' -- version
15 #
15 #
16 # Running the test suite in a sandbox:
16 # Running the test suite in a sandbox:
17 # nix build 'hg+file:.?dir=contrib/nix#mercurial-tests' -L
17 # nix build 'hg+file:.?dir=contrib/nix#mercurial-tests' -L
18
18
19 {
19 {
20 inputs = {
20 inputs = {
21 nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11";
21 nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11";
22 nixpkgs-black.url = "github:NixOS/nixpkgs/c7cb72b0"; # black 20.8b1
22 nixpkgs-black.url = "github:NixOS/nixpkgs/c7cb72b0"; # black 20.8b1
23 # rust-overlay.url = "github:oxalica/rust-overlay";
23 # rust-overlay.url = "github:oxalica/rust-overlay";
24 flake-utils.url = "github:numtide/flake-utils";
24 flake-utils.url = "github:numtide/flake-utils";
25 flaky-utils.url = "git+https://cgit.pacien.net/libs/flaky-utils";
25 flaky-utils.url = "git+https://cgit.pacien.net/libs/flaky-utils";
26 };
26 };
27
27
28 outputs = {
28 outputs = {
29 self
29 self
30 , nixpkgs
30 , nixpkgs
31 , nixpkgs-black
31 , nixpkgs-black
32 # , rust-overlay
32 # , rust-overlay
33 , flake-utils
33 , flake-utils
34 , flaky-utils
34 , flaky-utils
35 }:
35 }:
36 flake-utils.lib.eachDefaultSystem (system:
36 flake-utils.lib.eachDefaultSystem (system:
37 let
37 let
38 # overlays = [ (import rust-overlay) ];
38 # overlays = [ (import rust-overlay) ];
39 pkgs = import nixpkgs { inherit system; };
39 pkgs = import nixpkgs { inherit system; };
40
40
41 # We're in the contrib/nix sub-directory.
41 # We're in the contrib/nix sub-directory.
42 src = ../..;
42 src = ../..;
43
43
44 # For snapshots, to satisfy extension minimum version requirements.
44 # For snapshots, to satisfy extension minimum version requirements.
45 dummyVersion = "99.99";
45 dummyVersion = "99.99";
46
46
47 pin = {
47 pin = {
48 # The test suite has issues with the latest/current versions of Python.
48 # The test suite has issues with the latest/current versions of Python.
49 # Use an older recommended version instead, matching the CI.
49 # Use an older recommended version instead, matching the CI.
50 python = pkgs.python39;
50 python = pkgs.python39;
51
51
52 # The project uses a pinned version (rust/clippy.toml) for compiling,
52 # The project uses a pinned version (rust/clippy.toml) for compiling,
53 # but uses formatter features from nightly.
53 # but uses formatter features from nightly.
54 # TODO: make cargo use the formatter from nightly automatically
54 # TODO: make cargo use the formatter from nightly automatically
55 # (not supported by rustup/cargo yet? workaround?)
55 # (not supported by rustup/cargo yet? workaround?)
56 # rustPlatform = pkgs.rust-bin.stable."1.61.0".default;
56 # rustPlatform = pkgs.rust-bin.stable."1.79.0".default;
57 # rustPlatformFormatter = pkgs.rust-bin.nightly."2023-04-20".default;
57 # rustPlatformFormatter = pkgs.rust-bin.nightly."2023-04-20".default;
58
58
59 # The CI uses an old version of the Black code formatter,
59 # The CI uses an old version of the Black code formatter,
60 # itself depending on old Python libraries.
60 # itself depending on old Python libraries.
61 # The formatting rules have changed in more recent versions.
61 # The formatting rules have changed in more recent versions.
62 inherit (import nixpkgs-black { inherit system; }) black;
62 inherit (import nixpkgs-black { inherit system; }) black;
63 };
63 };
64
64
65 in rec {
65 in rec {
66 apps.mercurial = apps.mercurial-rust;
66 apps.mercurial = apps.mercurial-rust;
67 apps.default = apps.mercurial;
67 apps.default = apps.mercurial;
68 apps.mercurial-c = flake-utils.lib.mkApp {
68 apps.mercurial-c = flake-utils.lib.mkApp {
69 drv = packages.mercurial-c;
69 drv = packages.mercurial-c;
70 };
70 };
71 apps.mercurial-rust = flake-utils.lib.mkApp {
71 apps.mercurial-rust = flake-utils.lib.mkApp {
72 drv = packages.mercurial-rust;
72 drv = packages.mercurial-rust;
73 };
73 };
74
74
75 packages.mercurial = packages.mercurial-rust;
75 packages.mercurial = packages.mercurial-rust;
76 packages.default = packages.mercurial;
76 packages.default = packages.mercurial;
77
77
78 packages.mercurial-c = pin.python.pkgs.buildPythonApplication {
78 packages.mercurial-c = pin.python.pkgs.buildPythonApplication {
79 format = "other";
79 format = "other";
80 pname = "mercurial";
80 pname = "mercurial";
81 version = "SNAPSHOT";
81 version = "SNAPSHOT";
82 passthru.exePath = "/bin/hg";
82 passthru.exePath = "/bin/hg";
83 inherit src;
83 inherit src;
84
84
85 postPatch = ''
85 postPatch = ''
86 echo 'version = b"${toString dummyVersion}"' \
86 echo 'version = b"${toString dummyVersion}"' \
87 > mercurial/__version__.py
87 > mercurial/__version__.py
88
88
89 patchShebangs .
89 patchShebangs .
90
90
91 for f in **/*.{py,c,t}; do
91 for f in **/*.{py,c,t}; do
92 # not only used in shebangs
92 # not only used in shebangs
93 substituteAllInPlace "$f" '/bin/sh' '${pkgs.stdenv.shell}'
93 substituteAllInPlace "$f" '/bin/sh' '${pkgs.stdenv.shell}'
94 done
94 done
95 '';
95 '';
96
96
97 buildInputs = with pin.python.pkgs; [
97 buildInputs = with pin.python.pkgs; [
98 docutils
98 docutils
99 ];
99 ];
100
100
101 nativeBuildInputs = with pkgs; [
101 nativeBuildInputs = with pkgs; [
102 gettext
102 gettext
103 installShellFiles
103 installShellFiles
104 ];
104 ];
105
105
106 makeFlags = [
106 makeFlags = [
107 "PREFIX=$(out)"
107 "PREFIX=$(out)"
108 ];
108 ];
109
109
110 buildPhase = ''
110 buildPhase = ''
111 make local
111 make local
112 '';
112 '';
113
113
114 # Test suite is huge ; run on-demand in a separate package instead.
114 # Test suite is huge ; run on-demand in a separate package instead.
115 doCheck = false;
115 doCheck = false;
116 };
116 };
117
117
118 packages.mercurial-rust = packages.mercurial-c.overrideAttrs (super: {
118 packages.mercurial-rust = packages.mercurial-c.overrideAttrs (super: {
119 cargoRoot = "rust";
119 cargoRoot = "rust";
120 cargoDeps = pkgs.rustPlatform.importCargoLock {
120 cargoDeps = pkgs.rustPlatform.importCargoLock {
121 lockFile = "${src}/rust/Cargo.lock";
121 lockFile = "${src}/rust/Cargo.lock";
122 };
122 };
123
123
124 nativeBuildInputs = (super.nativeBuildInputs or []) ++ (
124 nativeBuildInputs = (super.nativeBuildInputs or []) ++ (
125 with pkgs.rustPlatform; [
125 with pkgs.rustPlatform; [
126 cargoSetupHook
126 cargoSetupHook
127 rust.cargo
127 rust.cargo
128 rust.rustc
128 rust.rustc
129 ]
129 ]
130 );
130 );
131
131
132 makeFlags = (super.makeFlags or []) ++ [
132 makeFlags = (super.makeFlags or []) ++ [
133 "PURE=--rust"
133 "PURE=--rust"
134 ];
134 ];
135 });
135 });
136
136
137 packages.mercurial-tests = pkgs.stdenv.mkDerivation {
137 packages.mercurial-tests = pkgs.stdenv.mkDerivation {
138 pname = "mercurial-tests";
138 pname = "mercurial-tests";
139 version = "SNAPSHOT";
139 version = "SNAPSHOT";
140 inherit src;
140 inherit src;
141
141
142 buildInputs = with pkgs; [
142 buildInputs = with pkgs; [
143 pin.python
143 pin.python
144 pin.black
144 pin.black
145 unzip
145 unzip
146 which
146 which
147 sqlite
147 sqlite
148 ];
148 ];
149
149
150 postPatch = (packages.mercurial.postPatch or "") + ''
150 postPatch = (packages.mercurial.postPatch or "") + ''
151 # * paths emitted by our wrapped hg look like ..hg-wrapped-wrapped
151 # * paths emitted by our wrapped hg look like ..hg-wrapped-wrapped
152 # * 'hg' is a wrapper; don't run using python directly
152 # * 'hg' is a wrapper; don't run using python directly
153 for f in **/*.t; do
153 for f in **/*.t; do
154 substituteInPlace 2>/dev/null "$f" \
154 substituteInPlace 2>/dev/null "$f" \
155 --replace '*/hg:' '*/*hg*:' \
155 --replace '*/hg:' '*/*hg*:' \
156 --replace '"$PYTHON" "$BINDIR"/hg' '"$BINDIR"/hg'
156 --replace '"$PYTHON" "$BINDIR"/hg' '"$BINDIR"/hg'
157 done
157 done
158 '';
158 '';
159
159
160 buildPhase = ''
160 buildPhase = ''
161 export HGTEST_REAL_HG="${packages.mercurial}/bin/hg"
161 export HGTEST_REAL_HG="${packages.mercurial}/bin/hg"
162 export HGMODULEPOLICY="rust+c"
162 export HGMODULEPOLICY="rust+c"
163 export HGTESTFLAGS="--blacklist blacklists/nix"
163 export HGTESTFLAGS="--blacklist blacklists/nix"
164 make check 2>&1 | tee "$out"
164 make check 2>&1 | tee "$out"
165 '';
165 '';
166 };
166 };
167
167
168 devShell = flaky-utils.lib.mkDevShell {
168 devShell = flaky-utils.lib.mkDevShell {
169 inherit pkgs;
169 inherit pkgs;
170
170
171 tools = [
171 tools = [
172 pin.python
172 pin.python
173 pin.black
173 pin.black
174 ];
174 ];
175 };
175 };
176 });
176 });
177 }
177 }
@@ -1,162 +1,162 b''
1 ===================
1 ===================
2 Mercurial Rust Code
2 Mercurial Rust Code
3 ===================
3 ===================
4
4
5 This directory contains various Rust code for the Mercurial project.
5 This directory contains various Rust code for the Mercurial project.
6 Rust is not required to use (or build) Mercurial, but using it
6 Rust is not required to use (or build) Mercurial, but using it
7 improves performance in some areas.
7 improves performance in some areas.
8
8
9 There are currently four independent Rust projects:
9 There are currently four independent Rust projects:
10
10
11 - chg. An implementation of chg, in Rust instead of C.
11 - chg. An implementation of chg, in Rust instead of C.
12 - hgcli. A project that provides a (mostly) self-contained "hg" binary,
12 - hgcli. A project that provides a (mostly) self-contained "hg" binary,
13 for ease of deployment and a bit of speed, using PyOxidizer. See
13 for ease of deployment and a bit of speed, using PyOxidizer. See
14 ``hgcli/README.md``.
14 ``hgcli/README.md``.
15 - hg-core (and hg-cpython): implementation of some
15 - hg-core (and hg-cpython): implementation of some
16 functionality of mercurial in Rust, e.g. ancestry computations in
16 functionality of mercurial in Rust, e.g. ancestry computations in
17 revision graphs, status or pull discovery. The top-level ``Cargo.toml`` file
17 revision graphs, status or pull discovery. The top-level ``Cargo.toml`` file
18 defines a workspace containing these crates.
18 defines a workspace containing these crates.
19 - rhg: a pure Rust implementation of Mercurial, with a fallback mechanism for
19 - rhg: a pure Rust implementation of Mercurial, with a fallback mechanism for
20 unsupported invocations. It reuses the logic ``hg-core`` but
20 unsupported invocations. It reuses the logic ``hg-core`` but
21 completely forgoes interaction with Python. See
21 completely forgoes interaction with Python. See
22 ``rust/rhg/README.md`` for more details.
22 ``rust/rhg/README.md`` for more details.
23
23
24 Using Rust code
24 Using Rust code
25 ===============
25 ===============
26
26
27 Local use (you need to clean previous build artifacts if you have
27 Local use (you need to clean previous build artifacts if you have
28 built without rust previously)::
28 built without rust previously)::
29
29
30 $ make PURE=--rust local # to use ./hg
30 $ make PURE=--rust local # to use ./hg
31 $ ./tests/run-tests.py --rust # to run all tests
31 $ ./tests/run-tests.py --rust # to run all tests
32 $ ./hg debuginstall | grep -i rust # to validate rust is in use
32 $ ./hg debuginstall | grep -i rust # to validate rust is in use
33 checking Rust extensions (installed)
33 checking Rust extensions (installed)
34 checking module policy (rust+c-allow)
34 checking module policy (rust+c-allow)
35
35
36 If the environment variable ``HGWITHRUSTEXT=cpython`` is set, the Rust
36 If the environment variable ``HGWITHRUSTEXT=cpython`` is set, the Rust
37 extension will be used by default unless ``--no-rust``.
37 extension will be used by default unless ``--no-rust``.
38
38
39 One day we may use this environment variable to switch to new experimental
39 One day we may use this environment variable to switch to new experimental
40 binding crates like a hypothetical ``HGWITHRUSTEXT=hpy``.
40 binding crates like a hypothetical ``HGWITHRUSTEXT=hpy``.
41
41
42 Special features
42 Special features
43 ================
43 ================
44
44
45 In the future, compile-time opt-ins may be added
45 In the future, compile-time opt-ins may be added
46 to the ``features`` section in ``hg-cpython/Cargo.toml``.
46 to the ``features`` section in ``hg-cpython/Cargo.toml``.
47
47
48 To use features from the Makefile, use the ``HG_RUST_FEATURES`` environment
48 To use features from the Makefile, use the ``HG_RUST_FEATURES`` environment
49 variable: for instance ``HG_RUST_FEATURES="some-feature other-feature"``.
49 variable: for instance ``HG_RUST_FEATURES="some-feature other-feature"``.
50
50
51 Profiling
51 Profiling
52 =========
52 =========
53
53
54 Setting the environment variable ``RUST_LOG=trace`` will make hg print
54 Setting the environment variable ``RUST_LOG=trace`` will make hg print
55 a few high level rust-related performance numbers. It can also
55 a few high level rust-related performance numbers. It can also
56 indicate why the rust code cannot be used (say, using lookarounds in
56 indicate why the rust code cannot be used (say, using lookarounds in
57 hgignore).
57 hgignore).
58
58
59 Creating a ``.cargo/config`` file with the following content enables
59 Creating a ``.cargo/config`` file with the following content enables
60 debug information in optimized builds. This make profiles more informative
60 debug information in optimized builds. This make profiles more informative
61 with source file name and line number for Rust stack frames and
61 with source file name and line number for Rust stack frames and
62 (in some cases) stack frames for Rust functions that have been inlined::
62 (in some cases) stack frames for Rust functions that have been inlined::
63
63
64 [profile.release]
64 [profile.release]
65 debug = true
65 debug = true
66
66
67 ``py-spy`` (https://github.com/benfred/py-spy) can be used to
67 ``py-spy`` (https://github.com/benfred/py-spy) can be used to
68 construct a single profile with rust functions and python functions
68 construct a single profile with rust functions and python functions
69 (as opposed to ``hg --profile``, which attributes time spent in rust
69 (as opposed to ``hg --profile``, which attributes time spent in rust
70 to some unlucky python code running shortly after the rust code, and
70 to some unlucky python code running shortly after the rust code, and
71 as opposed to tools for native code like ``perf``, which attribute
71 as opposed to tools for native code like ``perf``, which attribute
72 time to the python interpreter instead of python functions).
72 time to the python interpreter instead of python functions).
73
73
74 Example usage::
74 Example usage::
75
75
76 $ make PURE=--rust local # Don't forget to recompile after a code change
76 $ make PURE=--rust local # Don't forget to recompile after a code change
77 $ py-spy record --native --output /tmp/profile.svg -- ./hg ...
77 $ py-spy record --native --output /tmp/profile.svg -- ./hg ...
78
78
79 Developing Rust
79 Developing Rust
80 ===============
80 ===============
81
81
82 Minimum Supported Rust Version
82 Minimum Supported Rust Version
83 ------------------------------
83 ------------------------------
84
84
85 The minimum supported rust version (MSRV) is specified in the `Clippy`_
85 The minimum supported rust version (MSRV) is specified in the `Clippy`_
86 configuration file at ``rust/clippy.toml``. It is set to be ``1.61.0`` as of
86 configuration file at ``rust/clippy.toml``. It is set to be ``1.79.0`` as of
87 this writing, but keep in mind that the authoritative value is the one
87 this writing, but keep in mind that the authoritative value is the one
88 from the configuration file.
88 from the configuration file.
89
89
90 We bump it from time to time, with the general rule being that our
90 We bump it from time to time, with the general rule being that our
91 MSRV should not be greater that the version of the Rust toolchain
91 MSRV should not be greater that the version of the Rust toolchain
92 shipping with Debian testing, so that the Rust enhanced Mercurial can
92 shipping with Debian testing, so that the Rust enhanced Mercurial can
93 be eventually packaged in Debian.
93 be eventually packaged in Debian.
94
94
95 To ensure that you are not depending on features introduced in later
95 To ensure that you are not depending on features introduced in later
96 versions, you can issue ``rustup override set x.y.z`` at the root of
96 versions, you can issue ``rustup override set x.y.z`` at the root of
97 the repository.
97 the repository.
98
98
99 Build and development
99 Build and development
100 ---------------------
100 ---------------------
101
101
102 Go to the ``hg-cpython`` folder::
102 Go to the ``hg-cpython`` folder::
103
103
104 $ cd rust/hg-cpython
104 $ cd rust/hg-cpython
105
105
106 Or, only the ``hg-core`` folder. Be careful not to break compatibility::
106 Or, only the ``hg-core`` folder. Be careful not to break compatibility::
107
107
108 $ cd rust/hg-core
108 $ cd rust/hg-core
109
109
110 Simply run::
110 Simply run::
111
111
112 $ cargo build --release
112 $ cargo build --release
113
113
114 It is possible to build without ``--release``, but it is not
114 It is possible to build without ``--release``, but it is not
115 recommended if performance is of any interest: there can be an order
115 recommended if performance is of any interest: there can be an order
116 of magnitude of degradation when removing ``--release``.
116 of magnitude of degradation when removing ``--release``.
117
117
118 For faster builds, you may want to skip code generation::
118 For faster builds, you may want to skip code generation::
119
119
120 $ cargo check
120 $ cargo check
121
121
122 For even faster typing::
122 For even faster typing::
123
123
124 $ cargo c
124 $ cargo c
125
125
126 You can run only the rust-specific tests (as opposed to tests of
126 You can run only the rust-specific tests (as opposed to tests of
127 mercurial as a whole) with::
127 mercurial as a whole) with::
128
128
129 $ cargo test --all
129 $ cargo test --all
130
130
131 Formatting the code
131 Formatting the code
132 -------------------
132 -------------------
133
133
134 We use ``rustfmt`` to keep the code formatted at all times. For now, we are
134 We use ``rustfmt`` to keep the code formatted at all times. For now, we are
135 using the nightly version because it has been stable enough and provides
135 using the nightly version because it has been stable enough and provides
136 comment folding.
136 comment folding.
137
137
138 Our CI enforces that the code does not need reformatting. Before
138 Our CI enforces that the code does not need reformatting. Before
139 submitting your changes, please format the entire Rust workspace by running::
139 submitting your changes, please format the entire Rust workspace by running::
140
140
141
141
142 $ cargo +nightly fmt
142 $ cargo +nightly fmt
143
143
144 This requires you to have the nightly toolchain installed.
144 This requires you to have the nightly toolchain installed.
145
145
146 Linting: code sanity
146 Linting: code sanity
147 --------------------
147 --------------------
148
148
149 We're using `Clippy`_, the standard code diagnosis tool of the Rust
149 We're using `Clippy`_, the standard code diagnosis tool of the Rust
150 community.
150 community.
151
151
152 Our CI enforces that the code is free of Clippy warnings, so you might
152 Our CI enforces that the code is free of Clippy warnings, so you might
153 want to run it on your side before submitting your changes. Simply do::
153 want to run it on your side before submitting your changes. Simply do::
154
154
155 % cargo clippy
155 % cargo clippy
156
156
157 from the top of the Rust workspace. Clippy is part of the default
157 from the top of the Rust workspace. Clippy is part of the default
158 ``rustup`` install, so it should work right away. In case it would
158 ``rustup`` install, so it should work right away. In case it would
159 not, you can install it with ``rustup component add``.
159 not, you can install it with ``rustup component add``.
160
160
161
161
162 .. _Clippy: https://doc.rust-lang.org/stable/clippy/
162 .. _Clippy: https://doc.rust-lang.org/stable/clippy/
@@ -1,1 +1,1 b''
1 msrv = "1.61.0"
1 msrv = "1.79.0"
General Comments 0
You need to be logged in to leave comments. Login now