44import fnmatch
55import itertools
66import os
7+ import pathlib
78import re
89import sys
910import tomllib
1011
12+ PROJECT_ROOT_DIR = pathlib .Path (__file__ ).resolve ().parent .parent .parent
13+
1114SCALECODEC_RE = r'\bparity_scale_codec(_derive)?::'
1215JSONRPSEE_RE = r'\bjsonrpsee[_a-z0-9]*::'
1316
@@ -145,6 +148,32 @@ def check_workspace_and_package_versions_equal():
145148 return result
146149
147150
151+ # Ensure that each crate's Cargo.toml has a version field and it's always "version.workspace = true".
152+ def check_crate_version_inherits_workspace_version ():
153+ print ("==== Ensuring that each crate's version inherits its value from the workspace" )
154+
155+ result = True
156+
157+ for path in cargo_config_files ():
158+ path = pathlib .Path (path ).resolve ()
159+ if path .name == "Cargo.toml" and not path .parent == PROJECT_ROOT_DIR :
160+ with open (path , "rb" ) as file :
161+ rel_path = path .relative_to (PROJECT_ROOT_DIR )
162+ toml_file = tomllib .load (file )
163+ version = toml_file ["package" ].get ("version" )
164+
165+ if version is None :
166+ print (f"{ rel_path } : missing 'package.version', the version defaults to 0.0.0" )
167+ result = False
168+ elif not isinstance (version , dict ) or version .get ("workspace" ) != True :
169+ print (f"{ rel_path } : the package version must be inherited from the workspace (use 'version.workspace = true')" )
170+ result = False
171+
172+ print ()
173+
174+ return result
175+
176+
148177# Retrieve an item from arbitrarily nested dicts given a list of keys.
149178# E.g. get_from_nested_dicts({'a': {'b': 1, 'c': 2}}, ['a', 'b']) will
150179# return 1.
@@ -385,6 +414,7 @@ def run_checks():
385414 check_local_licenses (),
386415 check_crate_versions (),
387416 check_workspace_and_package_versions_equal (),
417+ check_crate_version_inherits_workspace_version (),
388418 check_dependency_versions_patch_version (),
389419 check_todos (),
390420 check_trailing_whitespaces (),
@@ -393,5 +423,8 @@ def run_checks():
393423
394424
395425if __name__ == '__main__' :
426+ # Note: this script expects the current directory to be the project root.
427+ os .chdir (PROJECT_ROOT_DIR )
428+
396429 if not run_checks ():
397430 sys .exit (1 )
0 commit comments