#!/usr/bin/env python3 """Check release, development, dirty, exported and cached Cargo version behavior.""" from pathlib import Path import os import shutil import subprocess import sys import tempfile import unittest project = Path(__file__).resolve().parents[2] sys.path.insert(0, str(project/'tools')) from fds_version import version class Versions(unittest.TestCase): def setUp(self): self.temporary = tempfile.TemporaryDirectory(prefix='fds-version-') self.addCleanup(self.temporary.cleanup) self.root = Path(self.temporary.name) self.git('init', '-q') self.git('config', 'user.name', 'FDS test') self.git('config', 'user.email', 'test@example.invalid') (self.root/'source').write_text('first\n') self.commit() def git(self, *args): return subprocess.check_output(['git', '-C', str(self.root), *args], text=True).strip() def commit(self): self.git('add', '.') self.git('commit', '-qm', 'fixture') def test_git_versions(self): revision=self.git('rev-parse','--short=12','HEAD') self.assertEqual(version(self.root), f'0.dev.g{revision}') self.git('tag','unrelated') self.assertEqual(version(self.root), f'0.dev.g{revision}') self.git('tag','-a','1.0','-m','Release 1.0') self.assertEqual(version(self.root),'1.0') (self.root/'source').write_text('changed\n') self.assertEqual(version(self.root),'1.0.dirty') self.commit() self.assertEqual(version(self.root),f'1.0.r1.g{self.git("rev-parse","--short=12","HEAD")}') self.git('tag','v1.1') self.assertEqual(version(self.root),'1.1') (self.root/'new').write_text('new\n') self.assertEqual(version(self.root),'1.1') self.git('add', 'new') self.assertEqual(version(self.root),'1.1.dirty') def test_export_is_independent_of_containing_git(self): self.git('tag','1.0') exported=self.root/'export';exported.mkdir() (exported/'FDS_VERSION').write_text('0.dev.gabcdef123456\n') self.assertEqual(version(exported),'0.dev.gabcdef123456') (exported/'FDS_VERSION').write_text('../bad\n') with self.assertRaises(ValueError):version(exported) (exported/'FDS_VERSION').unlink() with self.assertRaises(FileNotFoundError):version(exported) def test_cargo_rebuilds_on_new_tags_and_edits(self): (self.root/'tools').mkdir() for name in ['version','fds_version.py','version-build.rs']: shutil.copy2(project/'tools'/name,self.root/'tools'/name) crate=self.root/'rust/probe';(crate/'src').mkdir(parents=True) (self.root/'Cargo.toml').write_text('[workspace]\nmembers=["rust/probe"]\nresolver="2"\n') (self.root/'.gitignore').write_text('/target/\n__pycache__/\n') (crate/'Cargo.toml').write_text('[package]\nname="probe"\nversion="0.0.0"\nedition="2024"\nbuild="../../tools/version-build.rs"\n') (crate/'src/main.rs').write_text('fn main() { println!("{}", env!("FDS_BUILD_VERSION")); }\n') self.commit() def run(): return subprocess.check_output(['cargo','run','--quiet','--offline','-p','probe'],cwd=self.root,text=True).strip() self.assertEqual(run(),version(self.root)) self.commit() # Cargo generated its lockfile on the first run. self.git('tag','1.0') self.assertEqual(run(),'1.0') (self.root/'source').write_text('edited\n') self.assertEqual(run(),'1.0.dirty') self.git('checkout','--','source') self.assertEqual(run(),'1.0') self.git('tag','-d','1.0') self.assertEqual(run(),version(self.root)) # A frozen source tree builds with its saved identity without Git. with tempfile.TemporaryDirectory(prefix='fds-export-') as directory: exported=Path(directory)/'source' shutil.copytree(self.root,exported,ignore=shutil.ignore_patterns('.git','target','__pycache__')) (exported/'FDS_VERSION').write_text('1.0\n') output=subprocess.check_output(['cargo','run','--quiet','--offline','-p','probe'],cwd=exported,text=True).strip() self.assertEqual(output,'1.0') if __name__=='__main__': unittest.main()